2018-12-31 01:00:38 +00:00
|
|
|
/***
|
|
|
|
*
|
|
|
|
* Copyright (c) 2016-2019 Marco 'eukara' Hladik. All rights reserved.
|
|
|
|
*
|
|
|
|
* See the file LICENSE attached with the sources for usage details.
|
|
|
|
*
|
|
|
|
****/
|
|
|
|
|
|
|
|
#define SF_ROT_YAXIS 0
|
|
|
|
#define SF_ROT_OPEN 1
|
|
|
|
#define SF_ROT_BACKWARDS 2
|
|
|
|
#define SF_ROT_PASSABLE 8
|
|
|
|
#define SF_ROT_ONEWAY 16
|
|
|
|
#define SF_ROT_TOGGLE 32
|
|
|
|
#define SF_ROT_ZAXIS 64
|
|
|
|
#define SF_ROT_XAXIS 128
|
|
|
|
#define SF_ROT_USE 256
|
|
|
|
#define SF_DOOR_NOMONSTERS 512
|
|
|
|
#define SF_DOOR_SILENT 0x80000000i
|
|
|
|
|
2019-01-03 01:26:39 +00:00
|
|
|
class func_door_rotating:CBaseTrigger
|
2018-12-31 01:00:38 +00:00
|
|
|
{
|
|
|
|
int m_iMoveSnd;
|
|
|
|
int m_iStopSnd;
|
|
|
|
int m_iDamage;
|
|
|
|
float m_flDistance;
|
|
|
|
float m_flSpeed;
|
|
|
|
float m_flLip;
|
|
|
|
float m_iState;
|
|
|
|
float m_flNextAction;
|
|
|
|
float m_flWait;
|
|
|
|
float m_flDelay;
|
|
|
|
vector m_vecDest;
|
|
|
|
vector m_vecPos1;
|
|
|
|
vector m_vecPos2;
|
|
|
|
vector m_vecMoveDir;
|
|
|
|
virtual void() m_pMove = 0;
|
|
|
|
|
2019-01-03 01:26:39 +00:00
|
|
|
void() func_door_rotating;
|
2018-12-31 01:00:38 +00:00
|
|
|
virtual void() Precache;
|
|
|
|
virtual void() Arrived;
|
|
|
|
virtual void() Returned;
|
|
|
|
virtual void() RotateBack;
|
|
|
|
virtual void() RotateAway;
|
|
|
|
virtual void() Trigger;
|
|
|
|
virtual void() PlayerUse;
|
|
|
|
virtual void() Touch;
|
|
|
|
virtual void() Blocked;
|
|
|
|
virtual void() SetMovementDirection;
|
|
|
|
virtual void( vector angle, void() func ) RotateToDestination;
|
|
|
|
virtual void() RotateToDestination_End;
|
|
|
|
};
|
|
|
|
|
2019-01-03 01:26:39 +00:00
|
|
|
void func_door_rotating::Precache(void)
|
2018-12-31 01:00:38 +00:00
|
|
|
{
|
|
|
|
if ( m_iMoveSnd > 0 && m_iMoveSnd <= 10 ) {
|
|
|
|
precache_sound( sprintf( "doors/doormove%i.wav", m_iMoveSnd ) );
|
|
|
|
} else {
|
|
|
|
precache_sound( "common/null.wav" );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( m_iStopSnd > 0 && m_iStopSnd <= 8 ) {
|
|
|
|
precache_sound( sprintf( "doors/doorstop%i.wav", m_iStopSnd ) );
|
|
|
|
} else {
|
|
|
|
precache_sound( "common/null.wav" );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-03 01:26:39 +00:00
|
|
|
void func_door_rotating::Arrived(void)
|
2018-12-31 01:00:38 +00:00
|
|
|
{
|
|
|
|
m_iState = STATE_RAISED;
|
|
|
|
|
|
|
|
if ( m_iStopSnd > 0 && m_iStopSnd <= 8 ) {
|
|
|
|
sound( this, CHAN_VOICE, sprintf( "doors/doorstop%i.wav", m_iStopSnd ), 1.0, ATTN_NORM );
|
|
|
|
} else {
|
|
|
|
sound( this, CHAN_VOICE, "common/null.wav", 1.0, ATTN_NORM );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !(spawnflags & SF_ROT_USE) ) {
|
|
|
|
touch = Touch;
|
|
|
|
}
|
|
|
|
if ( m_flWait < 0 ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
think = RotateBack;
|
|
|
|
nextthink = ( ltime + m_flWait );
|
|
|
|
}
|
|
|
|
|
2019-01-03 01:26:39 +00:00
|
|
|
void func_door_rotating::Returned(void)
|
2018-12-31 01:00:38 +00:00
|
|
|
{
|
|
|
|
if ( !(spawnflags & SF_ROT_USE) ) {
|
|
|
|
touch = Touch;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_iState = STATE_LOWERED;
|
|
|
|
}
|
|
|
|
|
2019-01-03 01:26:39 +00:00
|
|
|
void func_door_rotating::RotateBack(void)
|
2018-12-31 01:00:38 +00:00
|
|
|
{
|
|
|
|
if ( m_iMoveSnd > 0 && m_iMoveSnd <= 10 ) {
|
|
|
|
sound( this, CHAN_VOICE, sprintf( "doors/doormove%i.wav", m_iMoveSnd ), 1.0, ATTN_NORM );
|
|
|
|
} else {
|
|
|
|
sound( this, CHAN_VOICE, "common/null.wav", 1.0, ATTN_NORM );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !(spawnflags & SF_ROT_USE) ) {
|
|
|
|
touch = __NULL__;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_iState = STATE_DOWN;
|
|
|
|
RotateToDestination( m_vecPos1, Returned );
|
|
|
|
}
|
|
|
|
|
2019-01-03 01:26:39 +00:00
|
|
|
void func_door_rotating::RotateAway(void)
|
2018-12-31 01:00:38 +00:00
|
|
|
{
|
|
|
|
float fDirection = 1.0;
|
|
|
|
|
|
|
|
if ( m_iState == STATE_UP ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( m_iMoveSnd > 0 && m_iMoveSnd <= 10 ) {
|
|
|
|
sound( this, CHAN_VOICE, sprintf( "doors/doormove%i.wav", m_iMoveSnd ), 1.0, ATTN_NORM );
|
|
|
|
} else {
|
|
|
|
sound( this, CHAN_VOICE, "common/null.wav", 1.0, ATTN_NORM );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( m_iState == STATE_RAISED ) {
|
|
|
|
nextthink = ( ltime + m_flWait );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_iState = STATE_UP;
|
|
|
|
|
|
|
|
if ( !( spawnflags & SF_ROT_ONEWAY ) ) {
|
|
|
|
vector vDifference = eActivator.origin - origin;
|
|
|
|
vector vAngles = eActivator.angles;
|
|
|
|
vAngles[0] = vAngles[2] = 0;
|
|
|
|
|
|
|
|
makevectors( vAngles );
|
|
|
|
vector vNext = ( eActivator.origin + ( v_forward * 10 ) ) - origin;
|
|
|
|
|
|
|
|
if ( ( ( vDifference[0] * vNext[1] ) - ( vDifference[1] * vNext[0] ) ) < 0 ) {
|
|
|
|
fDirection = -1.0f;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
RotateToDestination( m_vecPos2 * fDirection, Arrived );
|
|
|
|
}
|
|
|
|
|
2019-01-03 01:26:39 +00:00
|
|
|
void func_door_rotating::Trigger(void)
|
2018-12-31 01:00:38 +00:00
|
|
|
{
|
|
|
|
if ( m_flNextAction > time ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
m_flNextAction = time + m_flWait;
|
|
|
|
|
|
|
|
if ( ( m_iState == STATE_UP ) || ( m_iState == STATE_RAISED ) ) {
|
|
|
|
RotateBack();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
RotateAway();
|
|
|
|
|
|
|
|
if ( m_flDelay ) {
|
|
|
|
#ifdef GS_DEVELOPER
|
2019-01-03 01:26:39 +00:00
|
|
|
print( sprintf( "func_door_rotating: Delayed trigger of `%s`\n", m_strTarget ) );
|
2018-12-31 01:00:38 +00:00
|
|
|
#endif
|
|
|
|
CBaseTrigger::UseTargets_Delay( m_flDelay );
|
|
|
|
} else {
|
|
|
|
#ifdef GS_DEVELOPER
|
2019-01-03 01:26:39 +00:00
|
|
|
print( sprintf( "func_door_rotating: Normal trigger of `%s`\n", m_strTarget ) );
|
2018-12-31 01:00:38 +00:00
|
|
|
#endif
|
|
|
|
CBaseTrigger::UseTargets();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-03 01:26:39 +00:00
|
|
|
void func_door_rotating::PlayerUse(void)
|
2018-12-31 01:00:38 +00:00
|
|
|
{
|
|
|
|
eActivator.gflags &= ~GF_USE_RELEASED;
|
|
|
|
Trigger();
|
|
|
|
}
|
|
|
|
|
2019-01-03 01:26:39 +00:00
|
|
|
void func_door_rotating::Touch(void)
|
2018-12-31 01:00:38 +00:00
|
|
|
{
|
|
|
|
if ( spawnflags & SF_ROT_USE ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( other.movetype == MOVETYPE_WALK ) {
|
|
|
|
if ( other.absmin[2] <= maxs[2] - 2 ) {
|
|
|
|
eActivator = other;
|
|
|
|
Trigger();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
touch = __NULL__;
|
|
|
|
}
|
|
|
|
|
2019-01-03 01:26:39 +00:00
|
|
|
void func_door_rotating::Blocked(void)
|
2018-12-31 01:00:38 +00:00
|
|
|
{
|
|
|
|
if ( m_iDamage ) {
|
2019-01-03 01:26:39 +00:00
|
|
|
Damage_Apply( other, this, m_iDamage, other.origin, FALSE );
|
2018-12-31 01:00:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if ( m_flWait >= 0 ) {
|
|
|
|
if ( m_iState == STATE_DOWN ) {
|
|
|
|
RotateAway ();
|
|
|
|
} else {
|
|
|
|
RotateBack ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-03 01:26:39 +00:00
|
|
|
void func_door_rotating::Respawn(void)
|
2018-12-31 01:00:38 +00:00
|
|
|
{
|
|
|
|
solid = SOLID_BSP;
|
|
|
|
movetype = MOVETYPE_PUSH;
|
|
|
|
setorigin( this, origin );
|
|
|
|
setmodel( this, model );
|
|
|
|
|
|
|
|
blocked = Blocked;
|
|
|
|
use = Trigger;
|
|
|
|
|
|
|
|
if ( spawnflags & SF_ROT_USE ) {
|
|
|
|
touch = __NULL__;
|
|
|
|
gflags |= GF_USABLE;
|
|
|
|
} else {
|
|
|
|
touch = Touch;
|
|
|
|
gflags -= gflags & GF_USABLE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !m_flSpeed ) {
|
|
|
|
m_flSpeed = 100;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_iState = STATE_LOWERED;
|
|
|
|
m_vecPos1 = angles;
|
|
|
|
m_vecPos2 = angles + m_vecMoveDir * m_flDistance;
|
|
|
|
|
|
|
|
if ( spawnflags & SF_ROT_OPEN ) {
|
|
|
|
vector vTemp = m_vecPos2;
|
|
|
|
m_vecPos2 = m_vecPos1;
|
|
|
|
m_vecPos1 = vTemp;
|
|
|
|
angles = m_vecPos1;
|
|
|
|
movedir = movedir * -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-03 01:26:39 +00:00
|
|
|
void func_door_rotating::SetMovementDirection(void)
|
2018-12-31 01:00:38 +00:00
|
|
|
{
|
|
|
|
if ( spawnflags & SF_ROT_ZAXIS ) {
|
|
|
|
m_vecMoveDir = '0 0 1';
|
|
|
|
} else if ( spawnflags & SF_ROT_XAXIS ) {
|
|
|
|
m_vecMoveDir = '1 0 0';
|
|
|
|
} else {
|
|
|
|
m_vecMoveDir = '0 1 0';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-03 01:26:39 +00:00
|
|
|
void func_door_rotating::RotateToDestination_End(void)
|
2018-12-31 01:00:38 +00:00
|
|
|
{
|
|
|
|
angles = m_vecDest;
|
|
|
|
avelocity = '0 0 0';
|
|
|
|
nextthink = -1;
|
|
|
|
m_pMove();
|
|
|
|
}
|
|
|
|
|
2019-01-03 01:26:39 +00:00
|
|
|
void func_door_rotating::RotateToDestination(vector vDestinationAngle, void() func)
|
2018-12-31 01:00:38 +00:00
|
|
|
{
|
|
|
|
vector vecAngleDifference;
|
|
|
|
float flTravelLength, flTravelTime;
|
|
|
|
|
|
|
|
if ( !m_flSpeed ) {
|
|
|
|
objerror( "No speed defined for moving entity! Will not divide by zero." );
|
|
|
|
}
|
|
|
|
vecAngleDifference = ( vDestinationAngle - angles );
|
|
|
|
flTravelLength = vlen( vecAngleDifference );
|
|
|
|
flTravelTime = ( flTravelLength / m_flSpeed );
|
|
|
|
avelocity = ( vecAngleDifference * ( 1 / flTravelTime ) );
|
|
|
|
m_vecDest = vDestinationAngle;
|
|
|
|
m_pMove = func;
|
|
|
|
think = RotateToDestination_End;
|
|
|
|
nextthink = ( ltime + flTravelTime );
|
|
|
|
}
|
|
|
|
|
2019-01-03 01:26:39 +00:00
|
|
|
void func_door_rotating::func_door_rotating(void)
|
2018-12-31 01:00:38 +00:00
|
|
|
{
|
|
|
|
for ( int i = 1; i < ( tokenize( __fullspawndata ) - 1 ); i += 2 ) {
|
|
|
|
switch ( argv( i ) ) {
|
|
|
|
case "speed":
|
|
|
|
m_flSpeed = stof( argv( i + 1 ) );
|
|
|
|
break;
|
|
|
|
case "lip":
|
|
|
|
m_flLip = stof( argv( i + 1 ) );
|
|
|
|
break;
|
|
|
|
case "movesnd":
|
|
|
|
m_iMoveSnd = stoi( argv( i + 1 ) );
|
|
|
|
break;
|
|
|
|
case "stopsnd":
|
|
|
|
m_iStopSnd = stoi( argv( i + 1 ) );
|
|
|
|
break;
|
|
|
|
case "distance":
|
|
|
|
m_flDistance = stof( argv( i + 1 ) );
|
|
|
|
break;
|
|
|
|
case "delay":
|
|
|
|
m_flDelay = stof( argv( i + 1 ) );
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2019-01-03 01:26:39 +00:00
|
|
|
|
2018-12-31 01:00:38 +00:00
|
|
|
if ( !m_flSpeed ) {
|
|
|
|
m_flSpeed = 100;
|
|
|
|
}
|
|
|
|
if ( !m_flLip ) {
|
|
|
|
m_flLip = 90;
|
|
|
|
}
|
|
|
|
if ( !m_flDelay ) {
|
|
|
|
m_flDelay = 4;
|
|
|
|
}
|
|
|
|
if ( !m_flDistance ) {
|
|
|
|
m_flDistance = 90;
|
|
|
|
}
|
2019-01-03 01:26:39 +00:00
|
|
|
|
|
|
|
func_door_rotating::Precache();
|
2018-12-31 01:00:38 +00:00
|
|
|
CBaseEntity::CBaseEntity();
|
2019-01-03 01:26:39 +00:00
|
|
|
func_door_rotating::SetMovementDirection();
|
|
|
|
func_door_rotating::Respawn();
|
2018-12-31 01:00:38 +00:00
|
|
|
}
|