PHP Code:
class CProjectileRocket : public CEntity
{
private:
bool *m_bCritical;
public:
DECLARE_CLASS(CProjectileRocket, CEntity);
bool IsCritical ( void ) { return *m_bCritical; }
void SetCritical ( bool bCritical ) { *m_bCritical = bCritical; }
virtual void Spawn ( void );
virtual void RocketThink ( void );
};
LINK_ENTITY_TO_CLASS(tf_projectile_rocket, CProjectileRocket);
void m_bCriticalRocketProxy( const SendProp *pProp, const void *pStructBase, const void *pData, DVariant *pOut, int iElement, int objectID )
{
CProjectileRocket *pRocket = dynamic_cast<CProjectileRocket*>(CEntity::Instance(objectID));
if(pRocket) {
pOut->m_Int = pRocket->IsCritical();
}
}
void CProjectileRocket :: Spawn ( void )
{
AddEffects(EF_NODRAW); //Hide entity until we're done with it (prevents occasionall wierdness with rockets not showing up as crits)
static int m_iCriticalOffset = g_Util.GetOffset("DT_TFProjectile_Rocket","m_bCritical");
m_bCritical = (bool *)((char *)BaseEntity() + m_iCriticalOffset);
static bool bProxyInstalled = false;
if(!bProxyInstalled)
{
ServerData()->HookSendProxy("CTFProjectile_Rocket", "m_bCritical", m_bCriticalRocketProxy);
bProxyInstalled = true;
}
SetThink( &CProjectileRocket::RocketThink );
SetNextThink( gpGlobals->curtime );
}
void CProjectileRocket :: RocketThink ( void )
{
RemoveEffects(EF_NODRAW);
}
class CSentryRocket : public CProjectileRocket
{
public:
DECLARE_CLASS(CSentryRocket, CProjectileRocket);
virtual void Spawn ( void );
virtual void IgniteThink ( void );
virtual void SeekThink ( void );
};
LINK_ENTITY_TO_CLASS(tf_projectile_sentryrocket, CSentryRocket);
void CSentryRocket :: Spawn ( void )
{
BaseClass::Spawn();
if(!fa_sentrygun_homingrockets.GetBool())
{
RemoveEffects(EF_NODRAW);
SetThink(NULL);
SetNextThink (TICK_NEVER_THINK);
return;
}
int iCritChance = fa_sentrygun_homingrockets_critchance.GetInt();
if(iCritChance > 0)
{
if( g_Util.RandomInt(0,100) >= (100 - iCritChance) ) {
SetCritical ( true );
}
}
SetThink( &CSentryRocket::IgniteThink );
SetNextThink( gpGlobals->curtime );
}
void CSentryRocket :: IgniteThink ( void )
{
RemoveEffects(EF_NODRAW);
Vector vecForward;
AngleVectors( GetLocalAngles(), &vecForward );
SetAbsVelocity( vecForward * fa_sentrygun_homingrockets_speed.GetFloat() );
SetThink( &CSentryRocket::SeekThink );
SetNextThink( gpGlobals->curtime );
}
void CSentryRocket :: SeekThink( void )
{
CEntity *pBestVictim = NULL;
float flBestVictim = MAX_TRACE_LENGTH;
float flVictimDist;
CBaseEntity *pBaseEntity = NULL;
while(pBaseEntity = g_Util.FindEntityInSphere(pBaseEntity, GetAbsOrigin(), 2048))
{
CEntity *pEntity = CEntity::Instance(pBaseEntity);
if(!pEntity)
continue;
if(!pEntity->IsPlayer())
continue;
CPlayer *pPlayer = GetPlayerPointer( pEntity->BaseEntity() );
Assert( pPlayer );
if(!pPlayer)
continue;
if(!pPlayer->IsAlive())
continue;
//As much as I hate spies as engineer, they too have rights...
if(pPlayer->GetPlayerClass() == PLAYERCLASS_SPY)
{
//Cloaky
if(pPlayer->GetPlayerCond() & PLAYERCOND_SPYCLOAK) {
continue;
}
//Disguised
if(pPlayer->IsDisguised() && pPlayer->GetDisguisedTeam() == GetTeam())
continue;
}
if(pEntity->GetTeam() != GetTeam() && FVisible(pEntity, MASK_OPAQUE, NULL) )
{
flVictimDist = (GetAbsOrigin() - pEntity->GetAbsOrigin()).Length();
//Find closest
if ( flVictimDist < flBestVictim )
{
pBestVictim = pEntity;
flBestVictim = flVictimDist;
}
}
}
//No victims :(
if ( pBestVictim == NULL ) {
SetNextThink( gpGlobals->curtime );
return;
}
//truncated...
}
Just thought I'd throw it up there.