ns/releases/3.01/source/mod/AvHPushableBuildable.cpp
Karl 04c334c94b Tagging 3.01 release (again)
git-svn-id: https://unknownworlds.svn.cloudforge.com/ns1@15 67975925-1194-0748-b3d5-c16f83f1a3a1
2005-03-12 22:19:53 +00:00

232 lines
5.7 KiB
C++

#include "extdll.h"
#include "util.h"
#include "cbase.h"
#include "saverestore.h"
#include "func_break.h"
#include "decals.h"
#include "explode.h"
#include "mod/AvHSpecials.h"
#include "mod/AvHPushableBuildable.h"
#include "mod/AvHSharedUtil.h"
char *AvHPushableBuildable :: m_soundNames[3] = { "debris/pushbox1.wav", "debris/pushbox2.wav", "debris/pushbox3.wav" };
AvHPushableBuildable::AvHPushableBuildable(AvHTechID inTechID, AvHMessageID inMessageID, char* inClassName, int inUser3) : AvHBaseBuildable(inTechID, inMessageID, inClassName, inUser3)
{
this->m_lastSound = 0;
this->m_maxSpeed = 0;
this->m_soundTime = 0;
}
void AvHPushableBuildable::SetConstructionComplete()
{
AvHBaseBuildable::SetConstructionComplete();
// if ( pev->spawnflags & SF_PUSH_BREAKABLE )
// AvHBaseBuildable::Spawn();
// else
// Precache( );
//pev->movetype = MOVETYPE_PUSHSTEP;
this->pev->movetype = MOVETYPE_TOSS;
pev->solid = SOLID_BBOX;
//SET_MODEL( ENT(pev), STRING(pev->model) );
SET_MODEL( ENT(pev), this->GetModelName());
Vector theMinSize, theMaxSize;
AvHSHUGetSizeForTech(this->GetMessageID(), theMinSize, theMaxSize);
UTIL_SetSize(this->pev, theMinSize, theMaxSize);
if ( pev->friction > 399 )
pev->friction = 399;
m_maxSpeed = 100;//400 - pev->friction;
SetBits( pev->flags, FL_FLOAT );
pev->friction = 0;
pev->origin.z += 1; // Pick up off of the floor
UTIL_SetOrigin( pev, pev->origin );
// Multiply by area of the box's cross-section (assume 1000 units^3 standard volume)
pev->skin = ( pev->skin * (pev->maxs.x - pev->mins.x) * (pev->maxs.y - pev->mins.y) ) * 0.0005;
m_soundTime = 0;
}
float AvHPushableBuildable::GetMaxSpeed(void)
{
return m_maxSpeed;
}
void AvHPushableBuildable :: Precache( void )
{
AvHBaseBuildable::Precache();
for ( int i = 0; i < 3; i++ )
{
PRECACHE_UNMODIFIED_SOUND( m_soundNames[i] );
}
//if ( pev->spawnflags & SF_PUSH_BREAKABLE )
// AvHBaseBuildable::Precache( );
}
void AvHPushableBuildable :: KeyValue( KeyValueData *pkvd )
{
if ( FStrEq(pkvd->szKeyName, "size") )
{
int bbox = atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
switch( bbox )
{
case 0: // Point
UTIL_SetSize(pev, Vector(-8, -8, -8), Vector(8, 8, 8));
break;
case 2: // Big Hull!?!? !!!BUGBUG Figure out what this hull really is
UTIL_SetSize(pev, VEC_DUCK_HULL_MIN*2, VEC_DUCK_HULL_MAX*2);
break;
case 3: // Player duck
UTIL_SetSize(pev, VEC_DUCK_HULL_MIN, VEC_DUCK_HULL_MAX);
break;
default:
case 1: // Player
UTIL_SetSize(pev, VEC_HULL_MIN, VEC_HULL_MAX);
break;
}
}
else if ( FStrEq(pkvd->szKeyName, "buoyancy") )
{
pev->skin = atof(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else
{
AvHBaseBuildable::KeyValue( pkvd );
}
}
// Pull the func_pushable
void AvHPushableBuildable :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
if(!this->GetIsBuilt())
{
AvHBaseBuildable::Use(pActivator, pCaller, useType, value);
}
else
{
if ( !pActivator || !pActivator->IsPlayer() )
{
if ( pev->spawnflags & SF_PUSH_BREAKABLE )
this->AvHBaseBuildable::Use( pActivator, pCaller, useType, value );
return;
}
if ( pActivator->pev->velocity != g_vecZero )
Move( pActivator, 0 );
}
}
void AvHPushableBuildable :: Touch( CBaseEntity *pOther )
{
if ( FClassnameIs( pOther->pev, "worldspawn" ) )
return;
Move( pOther, 1 );
}
void AvHPushableBuildable :: Move( CBaseEntity *pOther, int push )
{
entvars_t* pevToucher = pOther->pev;
int playerTouch = 0;
// Is entity standing on this pushable ?
if ( FBitSet(pevToucher->flags,FL_ONGROUND) && pevToucher->groundentity && VARS(pevToucher->groundentity) == pev )
{
// Only push if floating
if ( pev->waterlevel > 0 )
pev->velocity.z += pevToucher->velocity.z * 0.1;
return;
}
if ( pOther->IsPlayer() )
{
if ( push && !(pevToucher->button & (IN_FORWARD|IN_USE)) ) // Don't push unless the player is pushing forward and NOT use (pull)
return;
playerTouch = 1;
}
float factor;
if ( playerTouch )
{
if ( !(pevToucher->flags & FL_ONGROUND) ) // Don't push away from jumping/falling players unless in water
{
if ( pev->waterlevel < 1 )
return;
else
factor = 0.1;
}
else
factor = 1;
}
else
factor = 0.25;
// temporarily increase height to allow it over bumps, but only if it's not on the ground already
if(FBitSet(this->pev->flags, FL_ONGROUND))
{
this->pev->origin.z += 10;
}
else
{
int a = 0;
}
pev->velocity.x += pevToucher->velocity.x * factor;
pev->velocity.y += pevToucher->velocity.y * factor;
float length = sqrt( pev->velocity.x * pev->velocity.x + pev->velocity.y * pev->velocity.y );
if ( push && (length > GetMaxSpeed()) )
{
pev->velocity.x = (pev->velocity.x * GetMaxSpeed() / length );
pev->velocity.y = (pev->velocity.y * GetMaxSpeed() / length );
}
if ( playerTouch )
{
pevToucher->velocity.x = pev->velocity.x;
pevToucher->velocity.y = pev->velocity.y;
if ( (gpGlobals->time - m_soundTime) > 0.7 )
{
m_soundTime = gpGlobals->time;
if ( length > 0 && FBitSet(pev->flags,FL_ONGROUND) )
{
m_lastSound = RANDOM_LONG(0,2);
EMIT_SOUND(ENT(pev), CHAN_WEAPON, m_soundNames[m_lastSound], 0.5, ATTN_NORM);
// SetThink( StopSound );
// pev->nextthink = pev->ltime + 0.1;
}
else
STOP_SOUND( ENT(pev), CHAN_WEAPON, m_soundNames[m_lastSound] );
}
}
}
#if 0
void AvHPushableBuildable::StopSound( void )
{
Vector dist = pev->oldorigin - pev->origin;
if ( dist.Length() <= 0 )
STOP_SOUND( ENT(pev), CHAN_WEAPON, m_soundNames[m_lastSound] );
}
#endif