From 89b2c2098bac438096ce0f1c23a0f2da9b48e2b0 Mon Sep 17 00:00:00 2001 From: hlstriker Date: Sun, 10 Nov 2013 19:08:36 +0000 Subject: [PATCH] Start of weapon spawner entity. --- mp/src/game/client/client_ff.vpc | 4 + .../entities/ff_cl_info_ff_weapon_spawner.cpp | 55 +++++ .../entities/ff_sv_info_ff_weapon_spawner.cpp | 221 ++++++++++++++++++ mp/src/game/server/ff/ff_sv_player.cpp | 4 + mp/src/game/server/server_ff.vpc | 1 + mp/src/game/shared/ff/ff_sh_shareddefs.h | 11 +- 6 files changed, 293 insertions(+), 3 deletions(-) create mode 100644 mp/src/game/client/ff/entities/ff_cl_info_ff_weapon_spawner.cpp create mode 100644 mp/src/game/server/ff/entities/ff_sv_info_ff_weapon_spawner.cpp diff --git a/mp/src/game/client/client_ff.vpc b/mp/src/game/client/client_ff.vpc index 9075cc05..89dada1e 100644 --- a/mp/src/game/client/client_ff.vpc +++ b/mp/src/game/client/client_ff.vpc @@ -54,6 +54,10 @@ $Project "Client (FF)" $File "ff\ff_cl_player.cpp" $File "ff\ff_cl_player.h" } + $Folder "Entities" + { + $File "ff\entities\ff_cl_info_ff_weapon_spawner.cpp" + } } // IMPORTANT: remove conflicting hl2dm SDK stuff as we implement our own!! diff --git a/mp/src/game/client/ff/entities/ff_cl_info_ff_weapon_spawner.cpp b/mp/src/game/client/ff/entities/ff_cl_info_ff_weapon_spawner.cpp new file mode 100644 index 00000000..efe7bc44 --- /dev/null +++ b/mp/src/game/client/ff/entities/ff_cl_info_ff_weapon_spawner.cpp @@ -0,0 +1,55 @@ +#include "cbase.h" + + +class CFF_CL_InfoFFWeaponSpawner : public C_BaseAnimating +{ +public: + DECLARE_CLASS( CFF_CL_InfoFFWeaponSpawner, C_BaseAnimating ); + DECLARE_CLIENTCLASS(); + + CFF_CL_InfoFFWeaponSpawner() + { + m_angles.y = RandomFloat(0.0f, 359.0f); + m_bDirection = RandomInt(0, 1); + } + + void Spawn(); + void ClientThink(); + +private: + QAngle m_angles; + bool m_bDirection; +}; + + +LINK_ENTITY_TO_CLASS( info_ff_weapon_spawner, CFF_CL_InfoFFWeaponSpawner ); + +IMPLEMENT_CLIENTCLASS_DT(CFF_CL_InfoFFWeaponSpawner, DT_FF_InfoFFWeaponSpawner, CFF_SV_InfoFFWeaponSpawner) +END_RECV_TABLE() + + +void CFF_CL_InfoFFWeaponSpawner::Spawn() +{ + SetNextClientThink(CLIENT_THINK_ALWAYS); + ClientThink(); +} + +void CFF_CL_InfoFFWeaponSpawner::ClientThink() +{ + m_angles.x = -30.0f; + + if(m_bDirection) + { + m_angles.y += 360.0f / 3.5f * gpGlobals->frametime; + if(m_angles.y >= 360) + m_angles.y -= 360; + } + else + { + m_angles.y -= 360.0f / 3.5f * gpGlobals->frametime; + if(m_angles.y < 0) + m_angles.y += 360; + } + + SetLocalAngles(m_angles); +} \ No newline at end of file diff --git a/mp/src/game/server/ff/entities/ff_sv_info_ff_weapon_spawner.cpp b/mp/src/game/server/ff/entities/ff_sv_info_ff_weapon_spawner.cpp new file mode 100644 index 00000000..9571aca8 --- /dev/null +++ b/mp/src/game/server/ff/entities/ff_sv_info_ff_weapon_spawner.cpp @@ -0,0 +1,221 @@ +#include "cbase.h" +#include "ff_sv_teamcheck_target.h" +#include "ff_sh_shareddefs.h" +#include "ammodef.h" + + +class CFF_SV_InfoFFWeaponSpawner : public CFF_SV_TeamcheckTarget +{ +public: + DECLARE_CLASS( CFF_SV_InfoFFWeaponSpawner, CFF_SV_TeamcheckTarget ); + DECLARE_DATADESC(); + DECLARE_SERVERCLASS(); + + CFF_SV_InfoFFWeaponSpawner() + { + m_iCurIndex = 0; + SetThink(NULL); + } + + void Spawn( void ); + void ForceNextSpawn( void ); + void SetWait( void ); + void ThinkNextSpawn( void ); + + void OnTouch( CBaseEntity *pOther ); + +private: + int m_iWeaponsAllowed; + float m_fRespawnTime; + float m_fGiveAmmoScale; // 0.0 - 1.0 where 1.0 is 100% of that weapons max ammo. + bool m_bSpawnMode; // False = Shuffle. True = Random. + + int m_iCurIndex; // The current index in m_iWeaponArray. This is only used if m_bSpawnMode is set to 'shuffle' (false). + int m_iNumInArray; + int m_iWeaponArray[FF_WEAPON_COUNT]; + + void DeletePreviousWeapon( void ); + CHandle m_hWeapon; +}; + + +LINK_ENTITY_TO_CLASS( info_ff_weapon_spawner, CFF_SV_InfoFFWeaponSpawner ); + +BEGIN_DATADESC( CFF_SV_InfoFFWeaponSpawner ) + // Keyfields. + DEFINE_KEYFIELD_NOT_SAVED( m_iWeaponsAllowed, FIELD_INTEGER, "weapons_allowed" ), + DEFINE_KEYFIELD_NOT_SAVED( m_fRespawnTime, FIELD_FLOAT, "respawn_time" ), + DEFINE_KEYFIELD_NOT_SAVED( m_fGiveAmmoScale, FIELD_FLOAT, "give_ammo_scale" ), + DEFINE_KEYFIELD_NOT_SAVED( m_bSpawnMode, FIELD_BOOLEAN, "spawn_mode" ), + + // Touch functions. + DEFINE_FUNCTION( OnTouch ), + + // Think functions. + DEFINE_THINKFUNC( ThinkNextSpawn ), +END_DATADESC() + +IMPLEMENT_SERVERCLASS_ST( CFF_SV_InfoFFWeaponSpawner, DT_FF_InfoFFWeaponSpawner ) + SendPropExclude("DT_BaseEntity", "m_angRotation"), + SendPropExclude("DT_BaseEntity", "m_angAbsRotation"), +END_SEND_TABLE() + + +void CFF_SV_InfoFFWeaponSpawner::Spawn() +{ + m_iNumInArray = 0; + for(int iWeaponNum=0; iWeaponNum= sizeof(m_iWeaponArray)) + break; + } + + if(!m_bSpawnMode && m_iNumInArray > 1) + { + // Shuffle the weapons in the array. + int j, t; + for(int i=0; i(pOther); + if(!pPlayer) + return; + + SetWait(); + + int ammoToGive = ( GetAmmoDef()->MaxCarry(m_hWeapon->GetPrimaryAmmoType()) + m_hWeapon->GetMaxClip1() ) * m_fGiveAmmoScale; + CBaseCombatWeapon *pOwnedWeapon = pPlayer->Weapon_OwnsThisType(m_hWeapon->GetName()); + + // See if they don't own this weapon yet. + if(!pOwnedWeapon) + { + // Fill the new one with as much ammo as possible. + ammoToGive -= m_hWeapon->GetMaxClip1(); + + if(ammoToGive < 0) + m_hWeapon->m_iClip1 = m_hWeapon->GetMaxClip1() + ammoToGive; + else + m_hWeapon->m_iClip1 = m_hWeapon->GetMaxClip1(); + } + /* + // TODO: Not sure if we should keep this part or not. + else if(pOwnedWeapon->m_iClip1 == 0 && pPlayer->GetAmmoCount(m_hWeapon->GetPrimaryAmmoType()) == 0) + { + // They are completely out of both clip and reserve ammo. Go ahead and fill their current weapons clip to full. + ammoToGive -= pOwnedWeapon->GetMaxClip1(); + + if(ammoToGive < 0) + pOwnedWeapon->m_iClip1 = pOwnedWeapon->GetMaxClip1() + ammoToGive; + else + pOwnedWeapon->m_iClip1 = pOwnedWeapon->GetMaxClip1(); + } + */ + + // Put the rest of the ammo in their reserve. + if(ammoToGive > 0) + pPlayer->GiveAmmo(ammoToGive, m_hWeapon->GetPrimaryAmmoType(), true); + + m_hWeapon->SetLocalOrigin( pPlayer->GetLocalOrigin() ); + m_hWeapon->Touch(pPlayer); + m_hWeapon = NULL; +} + +void CFF_SV_InfoFFWeaponSpawner::SetWait() +{ + SetTouch(NULL); + AddEffects(EF_NODRAW); + + SetNextThink( gpGlobals->curtime + m_fRespawnTime ); + SetThink( &CFF_SV_InfoFFWeaponSpawner::ThinkNextSpawn ); +} + +void CFF_SV_InfoFFWeaponSpawner::ThinkNextSpawn() +{ + ForceNextSpawn(); +} + +void CFF_SV_InfoFFWeaponSpawner::ForceNextSpawn() +{ + SetThink(NULL); + + if(!m_iNumInArray) + return; + + if(m_bSpawnMode) + { + // Spawn mode is random. + m_iCurIndex = RandomInt(0, m_iNumInArray-1); + } + else + { + // Spawn mode is shuffle. + m_iCurIndex++; + if(m_iCurIndex >= m_iNumInArray) + m_iCurIndex = 0; + } + + if(m_iCurIndex >= m_iNumInArray) + return; + + DeletePreviousWeapon(); + + m_hWeapon = dynamic_cast(CreateEntityByName( STRING( FF_WEAPON_NAME[m_iWeaponArray[m_iCurIndex]] ) )); + if(!m_hWeapon) + return; + + DispatchSpawn(m_hWeapon); + m_hWeapon->AddEffects(EF_NODRAW); + + m_hWeapon->VPhysicsDestroyObject(); + m_hWeapon->UseClientSideAnimation(); + + m_hWeapon->SetMoveType(MOVETYPE_NONE); + m_hWeapon->SetSolid(SOLID_NONE); + m_hWeapon->SetSolidFlags(FSOLID_NOT_SOLID); + m_hWeapon->AddSpawnFlags(SF_NORESPAWN); + + m_hWeapon->m_iClip1 = 0; + m_hWeapon->m_iClip2 = 0; + m_hWeapon->SetPrimaryAmmoCount(0); + m_hWeapon->SetSecondaryAmmoCount(0); + + string_t modelName = m_hWeapon->GetModelName(); + SetModel(STRING(modelName)); + + RemoveEffects(EF_NODRAW); + SetTouch( &CFF_SV_InfoFFWeaponSpawner::OnTouch ); +} + +void CFF_SV_InfoFFWeaponSpawner::DeletePreviousWeapon() +{ + if(!m_hWeapon) + return; + + m_hWeapon->AddFlag(FL_KILLME); +} \ No newline at end of file diff --git a/mp/src/game/server/ff/ff_sv_player.cpp b/mp/src/game/server/ff/ff_sv_player.cpp index e1352302..cfee8537 100644 --- a/mp/src/game/server/ff/ff_sv_player.cpp +++ b/mp/src/game/server/ff/ff_sv_player.cpp @@ -207,11 +207,13 @@ void CFF_SV_Player::GiveDefaultItems( void ) { EquipSuit(); + /* CBasePlayer::GiveAmmo( 255, "Pistol"); CBasePlayer::GiveAmmo( 45, "SMG1"); CBasePlayer::GiveAmmo( 1, "grenade" ); CBasePlayer::GiveAmmo( 6, "Buckshot"); CBasePlayer::GiveAmmo( 6, "357" ); + */ if ( GetPlayerModelType() == PLAYER_SOUNDS_METROPOLICE || GetPlayerModelType() == PLAYER_SOUNDS_COMBINESOLDIER ) { @@ -223,9 +225,11 @@ void CFF_SV_Player::GiveDefaultItems( void ) } GiveNamedItem( "weapon_pistol" ); + /* GiveNamedItem( "weapon_smg1" ); GiveNamedItem( "weapon_frag" ); GiveNamedItem( "weapon_physcannon" ); + */ const char *szDefaultWeaponName = engine->GetClientConVarValue( engine->IndexOfEdict( edict() ), "cl_defaultweapon" ); diff --git a/mp/src/game/server/server_ff.vpc b/mp/src/game/server/server_ff.vpc index 59db3639..03f24c64 100644 --- a/mp/src/game/server/server_ff.vpc +++ b/mp/src/game/server/server_ff.vpc @@ -48,6 +48,7 @@ $Project "Server (FF)" $File "ff\entities\ff_sv_teamcheck_target.h" $File "ff\entities\ff_sv_teamcheck_target.cpp" $File "ff\entities\ff_sv_point_ff_message.cpp" + $File "ff\entities\ff_sv_info_ff_weapon_spawner.cpp" } $Folder "Other" { diff --git a/mp/src/game/shared/ff/ff_sh_shareddefs.h b/mp/src/game/shared/ff/ff_sh_shareddefs.h index 8c5ecc29..db0a70c1 100644 --- a/mp/src/game/shared/ff/ff_sh_shareddefs.h +++ b/mp/src/game/shared/ff/ff_sh_shareddefs.h @@ -18,6 +18,7 @@ enum FF_CLASS FF_CLASS_SPY, FF_CLASS_ENGINEER, FF_CLASS_CIVILIAN, + FF_CLASS_COUNT }; @@ -55,9 +56,11 @@ enum FF_TEAM FF_TEAM_TWENTYSIX, FF_TEAM_TWENTYSEVEN, FF_TEAM_TWENTYEIGHT, - FF_TEAM_TWENTYNINE, // WARNING: Do not add more than 31 as more will not work with a bit mask. + FF_TEAM_TWENTYNINE, FF_TEAM_THIRTY, - FF_TEAM_LAST = FF_TEAM_THIRTY // if you're worried about bitmask dont forget FF_TEAM_ONE started from 2 you dork. + FF_TEAM_THIRTYONE, // WARNING: Do not add more than 31 as more will not work with a bit mask. + + FF_TEAM_LAST = FF_TEAM_THIRTYONE }; // if you really want to use int here dont forget 31 is the sign bit @@ -69,7 +72,7 @@ const int FF_TEAM_BITS[] = (1<<13), (1<<14), (1<<15), (1<<16), (1<<17), (1<<18), (1<<19), (1<<20), (1<<21), (1<<22), (1<<23), (1<<24), (1<<25), (1<<26), (1<<27), - (1<<28), (1<<29), (1<<30), (1<<31), + (1<<28), (1<<29), (1<<30) }; enum FF_WEAPON @@ -77,6 +80,8 @@ enum FF_WEAPON FF_WEAPON_PISTOL = 0, FF_WEAPON_PHYSCANNON, FF_WEAPON_SMG1, + + FF_WEAPON_COUNT // WARNING: The weapon count should never be greater than 31. }; const int FF_WEAPON_BITS[] =