sin-2015/rocket_turret.cpp
1999-04-22 00:00:00 +00:00

199 lines
No EOL
4.4 KiB
C++

// Copyright (C) 1998 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source is may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
// DESCRIPTION:
// Rocket Turret - Shoots slow moving shootable rockets at the player
#include "turret.h"
#include "rocket_turret.h"
#include "shotrocketlauncher.h"
CLASS_DECLARATION( Turret, RocketTurret, "trap_rocketturret" );
Event EV_RocketTurret_Rate( "rocketrate" );
Event EV_RocketTurret_Speed( "rocketspeed" );
ResponseDef RocketTurret::Responses[] =
{
{ &EV_RocketTurret_Rate, ( Response )RocketTurret::SetRate },
{ &EV_RocketTurret_Speed, ( Response )RocketTurret::SetSpeed },
{ NULL, NULL }
};
RocketTurret::RocketTurret
(
void
)
{
Entity *base;
setModel( "launcher_top.def" );
RandomAnimate( "down_idle", NULL );
neworientation = angles.yaw();
setMoveType( MOVETYPE_NONE );
setSolidType( SOLID_BBOX );
flags |= FL_SPARKS;
enemy_oldorigin = vec_zero;
edict->svflags |= SVF_USEBBOX;
base = new Entity;
base->setModel( "launcher_base.def" );
base->setMoveType( MOVETYPE_NONE );
base->setSolidType( SOLID_BBOX );
base->setOrigin( worldorigin );
health = 150;
takedamage = DAMAGE_YES;
wakeupdistance = G_GetFloatArg( "wakeupdistance", 1950 );
firingdistance = G_GetFloatArg( "firingdistance", 2000 );
rate = 8.0;
speed = 300;
}
void RocketTurret::Seek
(
Event *ev
)
{
Entity *ent;
Vector v;
Vector s;
int range;
Vector f;
Vector enemy_velocity;
active = true;
ent = NULL;
if ( enemy )
{
ent = G_GetEntity( enemy );
if ( ( !ent ) || ( ent->health <= 0 ) || ( ent->flags & FL_NOTARGET ) || ( ent == this ) )
{
enemy = 0;
enemy_oldorigin = vec_zero;
ent = NULL;
}
else
{
float delta_t;
// Have an enemy locked on, get the range and calculate velocity
// based on the old origin and the time difference since last locked
// onto him.
range = Range( Distance( ent ) );
delta_t = level.time - lastSightTime;
if ( delta_t )
enemy_velocity = ( ent->worldorigin - enemy_oldorigin ) * (1.0f / delta_t);
else
enemy_velocity = vec_zero;
// Update the enemy's origin and the time we last saw him
enemy_oldorigin = ent->worldorigin;
}
}
if ( ( lastSightTime ) && ( ( lastSightTime + patience ) < level.time ) )
{
ProcessEvent( EV_Turret_GoDown );
}
if ( !enemy )
{
FindTarget();
PostEvent( EV_Turret_Seek, FRAMETIME * 2 );
return;
}
if ( ( range != TURRET_OUTOFRANGE ) && ent && CanSee( ent ) )
{
Vector targ, src, d;
float dist;
lastSightTime = level.time;
// Get distance and orientation to target
targ = ent->centroid;
currentWeapon->GetMuzzlePosition(&src);
d = targ-src;
dist = d.length();
targ += ( enemy_velocity * (dist/sv_rocketspeed->value));
v = targ - src;
v.normalize();
new_orientation = v.toAngles();
}
if ( ( angles[ YAW ] != new_orientation[ YAW ] ) && !turning)
{
Event *event;
event = new Event( EV_Turret_Turn );
event->AddVector( new_orientation );
ProcessEvent( event );
}
if ( range == TURRET_FIRERANGE )
{
// Allow some freetime to let player get somewhere before turret fires on him
if ( level.time < firetime )
{
PostEvent( EV_Turret_Seek, FRAMETIME );
return;
}
ProcessEvent( EV_Turret_Attack );
}
PostEvent( EV_Turret_Seek, FRAMETIME );
}
void RocketTurret::Turn
(
Event *ev
)
{
Vector new_angle = ev->GetVector( 1 );
if ( angles[ YAW ] != new_angle[ YAW ] )
{
turntime = level.time + 0.2;
turning = true;
}
else if ( turntime < level.time )
{
turning = false;
angles[ PITCH ] = -new_angle[ PITCH ];
return;
}
angles[ PITCH ] = -new_angle[ PITCH ];
angles[ YAW ] = AdjustAngle( 32, angles[ YAW ], new_angle[ YAW ] );
setAngles( angles );
PostEvent( ev, FRAMETIME );
}
void RocketTurret::SetRate
(
Event *ev
)
{
rate = ev->GetFloat( 1 );
}
void RocketTurret::SetSpeed
(
Event *ev
)
{
speed = ev->GetFloat( 1 );
}