mirror of
https://github.com/fortressforever/fortressforever-2013.git
synced 2025-02-12 15:05:24 +00:00
Start of weapon spawner entity.
This commit is contained in:
parent
63c563747d
commit
89b2c2098b
6 changed files with 293 additions and 3 deletions
|
@ -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!!
|
||||
|
|
|
@ -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);
|
||||
}
|
221
mp/src/game/server/ff/entities/ff_sv_info_ff_weapon_spawner.cpp
Normal file
221
mp/src/game/server/ff/entities/ff_sv_info_ff_weapon_spawner.cpp
Normal file
|
@ -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<CBaseCombatWeapon> 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(FF_WEAPON_BITS) && iWeaponNum<FF_WEAPON_COUNT; iWeaponNum++)
|
||||
{
|
||||
if(m_iWeaponsAllowed & FF_WEAPON_BITS[iWeaponNum])
|
||||
m_iWeaponArray[m_iNumInArray++] = iWeaponNum;
|
||||
|
||||
if(m_iNumInArray >= sizeof(m_iWeaponArray))
|
||||
break;
|
||||
}
|
||||
|
||||
if(!m_bSpawnMode && m_iNumInArray > 1)
|
||||
{
|
||||
// Shuffle the weapons in the array.
|
||||
int j, t;
|
||||
for(int i=0; i<m_iNumInArray - 1; i++)
|
||||
{
|
||||
j = i + rand() / (VALVE_RAND_MAX / (m_iNumInArray - i) + 1);
|
||||
t = m_iWeaponArray[j];
|
||||
m_iWeaponArray[j] = m_iWeaponArray[i];
|
||||
m_iWeaponArray[i] = t;
|
||||
}
|
||||
}
|
||||
|
||||
// No touching or displaying yet.
|
||||
SetWait();
|
||||
|
||||
// Set the spawners BBOX.
|
||||
SetSolid(SOLID_BBOX);
|
||||
AddSolidFlags(FSOLID_NOT_SOLID | FSOLID_TRIGGER);
|
||||
UTIL_SetSize(this, -Vector(32,32,32), Vector(32,32,32));
|
||||
|
||||
// Go ahead and 'spawn' the initial weapon for this spawner.
|
||||
ForceNextSpawn();
|
||||
}
|
||||
|
||||
void CFF_SV_InfoFFWeaponSpawner::OnTouch( CBaseEntity *pOther )
|
||||
{
|
||||
if(!m_hWeapon)
|
||||
return;
|
||||
|
||||
CBasePlayer *pPlayer = dynamic_cast<CBasePlayer *>(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<CBaseCombatWeapon *>(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);
|
||||
}
|
|
@ -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" );
|
||||
|
||||
|
|
|
@ -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"
|
||||
{
|
||||
|
|
|
@ -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[] =
|
||||
|
|
Loading…
Reference in a new issue