Start of weapon spawner entity.

This commit is contained in:
hlstriker 2013-11-10 19:08:36 +00:00 committed by squeek
parent 63c563747d
commit 89b2c2098b
6 changed files with 293 additions and 3 deletions

View file

@ -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!!

View file

@ -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);
}

View 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);
}

View file

@ -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" );

View file

@ -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"
{

View file

@ -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[] =