• Strange bug with my HL2 related Code
    39 replies, posted
weapon_inventory.cpp [code] // Inventory 'weapon' /* It works like this: You select the 'weapon' then you right click to 'scroll' through the different items Then you left click to use them. Simple shit. */ #include "cbase.h" #include "NPCEvent.h" #include "basehlcombatweapon.h" #include "AI_BaseNPC.h" #include "player.h" #include "hl2_player.h" #include "gamerules.h" #include "in_buttons.h" #include "soundent.h" #include "game.h" #include "vstdlib/random.h" #include "gamestats.h" #include "items.h" #include "weapon_inventory.h" #include "tier0/memdbgon.h" //----------------------------------------------------------------------------- // CWeaponInventory //----------------------------------------------------------------------------- IMPLEMENT_SERVERCLASS_ST(CWeaponInventory, DT_WeaponInventory) END_SEND_TABLE() LINK_ENTITY_TO_CLASS( weapon_inventory, CWeaponInventory ); PRECACHE_WEAPON_REGISTER( weapon_inventory ); BEGIN_DATADESC( CWeaponInventory ) DEFINE_FIELD( TimeToNextUse, FIELD_TIME ) //DEFINE_FIELD( m_flAccuracyPenalty, FIELD_FLOAT ), //NOTENOTE: This is NOT tracking game time //DEFINE_FIELD( m_nNumShotsFired, FIELD_INTEGER ), END_DATADESC() //----------------------------------------------------------------------------- // Purpose: Constructor //----------------------------------------------------------------------------- CWeaponInventory::CWeaponInventory( void ) { Batteries = 0; SelectedItem = 0; TimeToNextUse = gpGlobals->curtime; } //----------------------------------------------------------------------------- // Purpose: Precache resources //----------------------------------------------------------------------------- void CWeaponInventory::Precache( void ) { BaseClass::Precache(); } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CWeaponInventory::PrimaryAttack() { if(TimeToNextUse < gpGlobals->curtime) { Warning("Battery Applied? \n"); engine->ServerCommand("give item_flashbattery \n"); //Bit of a hacky method, but this is the best i can do now. ManageItems(1,-1); TimeToNextUse = gpGlobals->curtime + 0.25f; } else return; } void CWeaponInventory::SecondaryAttack( void ) { if(TimeToNextUse < gpGlobals->curtime) { SelectedItem++; if(SelectedItem > 1) { SelectedItem = 0; } Warning("SelectedItem: %i \n",SelectedItem); TimeToNextUse = gpGlobals->curtime + 0.25f; } else return; } void CWeaponInventory::ManageItems(int ItemIndex, int ItemNum) { switch(ItemIndex) { case 1: // 1 = Flashlight Battery Batteries = Batteries + ItemNum; Warning("Battery Added, Batteries left: %i \n",Batteries); break; default: break; } } void CWeaponInventory::ItemPostFrame( void ) { BaseClass::ItemPostFrame(); CBasePlayer *pOwner = ToBasePlayer( GetOwner() ); if( pOwner->m_nButtons & IN_ATTACK ) { PrimaryAttack(); } } void CWeaponInventory::Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator ) { BaseClass::Operator_HandleAnimEvent( pEvent, pOperator ); } [/code]weapon_inventory.h [code] #include "cbase.h" #include "NPCEvent.h" #include "basehlcombatweapon.h" #include "AI_BaseNPC.h" #include "player.h" #include "hl2_player.h" #include "gamerules.h" #include "in_buttons.h" #include "soundent.h" #include "game.h" #include "vstdlib/random.h" #include "gamestats.h" #include "items.h" class CWeaponInventory : public CBaseHLCombatWeapon { DECLARE_DATADESC(); public: DECLARE_CLASS( CWeaponInventory, CBaseHLCombatWeapon ); CWeaponInventory(); DECLARE_SERVERCLASS(); void Precache( void ); void ItemPostFrame( void ); void ManageItems(int ItemIndex, int ItemNum); void PrimaryAttack(); void SecondaryAttack( void ); void Operator_HandleAnimEvent( animevent_t *pEvent, CBaseCombatCharacter *pOperator ); private: int Batteries; int SelectedItem; float TimeToNextUse; }; [/code] So, what it does is when i go in game and i press Mouse1(Primaryattack) it decreases the 'Batteries'. BUT! If i get an item_inv_flashbattery it usually gives me some random number like 153546. And then that will go up by 1. BUT if i press Mouse1 again the supposed same variable should be 0 but it says -2. It's like it's two different variables. I seriously have no fucking clue what the christ makes this act like this. Hope it makes sense. Please halp D:, Also don't comment on the code itself, just help me fix my problem.
Okay, so it starts with 0 batteries and when you primary attack once it decreases two? That's because you're calling PrimaryAttack in ItemPostFrame again. The BaseClass will do this as well. What role does item_flashbattery play? What goes up by 1?
No no no. When i call PrimaryAttack it decreases Batteries by 1. When i pick up an item_flashbattery it should increase Batteries by 1, but it doesn't. I just spits out some random number like 166101 then keeps that number and increases that by 1 everytime. It's like when i increase Batteries it's a 'different' Batteries i increase and vice versa. Yeah, it makes no fucking sense, but that's what it does.
I suggest debugging. Just set a few breakpoints to the code, where it modifies the Batteries-variable to pin-point where exactly it goes wrong.
break... points??
The red points (actually circle-y objects) you can set in VS so that the debugger will halt if the marked line is about to be executed.
[QUOTE=ZeekyHBomb;20458471]The red points (actually circle-y objects) you can set in VS so that the debugger will halt if the marked line is about to be executed.[/QUOTE] Don't really know what that's going to do. I've worked with the damn code for 3-4 hours now.(Not only on that single issue though). I'm really stuck.
That's going to help you pin-point the exact line of code which is causing your 'weapon' to behave unexpectedly. You know what I mean with setting breakpoints and debugging it, right?
[QUOTE=ZeekyHBomb;20458721]That's going to help you pin-point the exact line of code which is causing your 'weapon' to behave unexpectedly. You know what I mean with setting breakpoints and debugging it, right?[/QUOTE] No fucking clue bro. Must've not read about that. I'm a self taught programmer. Has it's benefits and it's down sides.
Well me too and I have no idea how I found out about how to use the debugger, but somehow I did. [url=http://www.learncpp.com/cpp-tutorial/a4-debugging-your-program-stepping-and-breakpoints/]This[/url] and the next page should help you understanding VSs debugger.
Doesn't really help me much. I know where the code is bugging up. But it seemingly have no reason to do so.
Code doesn't just work differently than you wrote it. There must be another reason. Besides, I can't find the line which should add to Batteries upon picking up item_flashbattery in your posted code. Why don't you wanna debug?
item_inv_flashbattery.cpp [code] //=============================================================================// // Purpose: Flashlight batteries for the inventory //=============================================================================// #include "cbase.h" #include "hl2_player.h" #include "basecombatweapon.h" #include "gamerules.h" #include "items.h" #include "engine/IEngineSound.h" #include "weapon_inventory.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" class CItemInvFlashBattery : public CItem { public: DECLARE_CLASS( CItemInvFlashBattery, CItem ); void Spawn( void ) { Precache( ); SetModel( "models/items/battery.mdl" ); //Might aswell use the default battery model for now. BaseClass::Spawn( ); } void Precache( void ) { PrecacheModel ("models/items/battery.mdl"); PrecacheScriptSound( "ItemBattery.Touch" ); } bool MyTouch( CBasePlayer *pPlayer ) { //EmitSound( "ItemBattery.Touch" ); CWeaponInventory *InvPointer; InvPointer->ManageItems(1,1); // HERE HERE HERE return true; } }; LINK_ENTITY_TO_CLASS(item_inv_flashbattery, CItemInvFlashBattery); PRECACHE_REGISTER(item_inv_flashbattery); [/code]Might actually be a problem with this ^
[cpp]engine->ServerCommand("give item_flashbattery \n");[/cpp] You probably mean item_env_flashbattery? [cpp]CWeaponInventory *InvPointer; InvPointer->ManageItems(1,1);[/cpp] [b]Accesing undefined pointer!![/b]
[QUOTE=ZeekyHBomb;20462730]engine->ServerCommand("give item_flashbattery \n");You probably mean item_env_flashbattery? CWeaponInventory *InvPointer; InvPointer->ManageItems(1,1);[B]Accesing undefined pointer!![/B][/QUOTE] Thought it might be that... Could you perhaps tell me how i'd go about getting it to work properly?
Define your pointer. It's current value is NULL, what is it meant to point to?
Nope, it's not even NULL, it's pointing to random memory. Loop through all weapons and check if it is a CWeaponInventory.
[QUOTE=ZeekyHBomb;20469917]Nope, it's not even NULL, it's pointing to random memory. Loop through all weapons and check if it is a CWeaponInventory.[/QUOTE] I still don't know what to do T_T
[cpp]CWeaponInventory *InvPointer; for (int i=0; i<MAX_WEAPONS; ++i) { InvPointer = dynamic_cast<CWeaponInventory*>( pPlayer->GetWeapon( i ) ); if( InvPointer ) break; } if( !InvPointer ) return;[/cpp]
MAX_WEAPONS? The thingie in item_inv_flashbattery.cpp is for the amount of flashbatteries.
Try to guess what that code-snippet does.
[QUOTE=ZeekyHBomb;20474448]Try to guess what that code-snippet does.[/QUOTE] I know, i'll mold it to work with my code. I'll report back within the hour.
Uhh... you know what it does? What's with the response then?
[QUOTE=ZeekyHBomb;20474597]Uhh... you know what it does? What's with the response then?[/QUOTE] ._. pPlayer-GetWeapon whut? No? Please explain.. God i feel so stupid.. Fuck.
[cpp]CWeaponInventory *InvPointer; //create pointer; note: uninitialized! for (int i=0; i<MAX_WEAPONS; ++i) //loop from 0 to MAX_WEAPONS constant { InvPointer = dynamic_cast<CWeaponInventory*>( pPlayer->GetWeapon( i ) ); //pPlayer is the player, who bumped into this item. We get the i-th weapon of his and try to cast it into a CWeaponInventory if( InvPointer ) //if the pointer is not NULL (cast successful) break; //break out of the loop } if( !InvPointer ) //is InvPointer still NULL? return; //player didn't have a CWeaponInventory; abort![/cpp]
I want it to like do a CWeaponInventory->AddItem(1); ish thing. Could i just remove the for loop and just do a dyna cast? Also what's the tags for doing the code like that? [cpp] ?
Yep. [noparse][cpp]code here[/cpp][/noparse]. You could define a GetWeaponInventory-accessor in CBasePlayer, but from what I've seen here you seem to be lacking experience with the Source-engine and maybe even C++. Try to do the tutorials on Valves dev-wiki and if you are indeed lacking some C++ knowledge, do some console-y non-Source stuff first.
[QUOTE=ZeekyHBomb;20474885]Yep. [noparse][cpp]code here[/cpp][/noparse]. You could define a GetWeaponInventory-accessor in CBasePlayer, but from what I've seen here you seem to be lacking experience with the Source-engine and maybe even C++. Try to do the tutorials on Valves dev-wiki and if you are indeed lacking some C++ knowledge, do some console-y non-Source stuff first.[/QUOTE] I lack knowledge of the more advanced stuff like the dynamic_cast stuff. And i usually don't have problems like this D:
Well, you have the choice of either learning the 'advanced stuff' or not implementing this feature. You certainly won't learn well by doing a Sourcemod. Valves code for HL2 looks like it was written mostly by amateurs. They didn't spend enough time with porting their C-code and gparent also said that they started out with VC6, so this probably also added to the fun. Besides, even if it was well written, you'd just look over the code and guess what it does, without really knowing what is going on.
[QUOTE=ZeekyHBomb;20475146]Well, you have the choice of either learning the 'advanced stuff' or not implementing this feature. You certainly won't learn well by doing a Sourcemod. Valves code for HL2 looks like it was written mostly by amateurs. They didn't spend enough time with porting their C-code and gparent also said that they started out with VC6, so this probably also added to the fun. Besides, even if it was well written, you'd just look over the code and guess what it does, without really knowing what is going on.[/QUOTE] Now now, i'm not that inexperienced. Can't i do something like this?: pInv = dynamic_cast<CWeaponInventory*>( CWeaponInventory->Item()); Like, something that directly fiddles with CWeaponInventory things.
Sorry, you need to Log In to post a reply to this thread.