424 lines
8.8 KiB
C++
424 lines
8.8 KiB
C++
//-----------------------------------------------------------------------------
|
|
//
|
|
// $Logfile:: /Quake 2 Engine/Sin/code/game/ctf_turret.cpp $
|
|
// $Revision:: 14 $
|
|
// $Author:: Aldie $
|
|
// $Date:: 3/19/99 5:50p $
|
|
//
|
|
// Copyright (C) 1997 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.
|
|
//
|
|
// $Log:: /Quake 2 Engine/Sin/code/game/ctf_turret.cpp $
|
|
//
|
|
// 14 3/19/99 5:50p Aldie
|
|
// Added MINLIGHT
|
|
//
|
|
// 13 3/19/99 5:49p Aldie
|
|
// Added minlight
|
|
//
|
|
// 12 3/19/99 5:13p Aldie
|
|
// Made turret non-droppable
|
|
//
|
|
// 11 3/17/99 3:55p Aldie
|
|
// Incremental CTF update
|
|
//
|
|
// 10 3/12/99 6:14p Markd
|
|
// added precaching and increased damages on heligun
|
|
//
|
|
// 9 3/11/99 1:46p Aldie
|
|
// Fix movement of turrets
|
|
//
|
|
// 8 3/05/99 5:51p Markd
|
|
// made vehicles respawn in CTF, fixed up turrets a bit more
|
|
//
|
|
// 7 3/05/99 5:10p Markd
|
|
// Fixed turrets being able to shoot themselves
|
|
//
|
|
// 6 2/26/99 7:42p Markd
|
|
// Fixed turrets some more
|
|
//
|
|
// 5 2/26/99 5:53p Markd
|
|
// Fixed up turrets a lot more
|
|
//
|
|
// 4 2/23/99 5:56p Markd
|
|
//
|
|
// 3 2/22/99 5:45p Aldie
|
|
// Removed stray ;
|
|
//
|
|
// 2 2/19/99 7:49p Markd
|
|
// implemented turret for CTF
|
|
//
|
|
// 1 2/19/99 6:03p Markd
|
|
//
|
|
// DESCRIPTION:
|
|
// CTF turret, usable turret
|
|
//
|
|
|
|
#include "g_local.h"
|
|
#include "vehicle.h"
|
|
#include "ctf_turret.h"
|
|
#include "heligun.h"
|
|
#include "player.h"
|
|
|
|
|
|
CLASS_DECLARATION( DrivableVehicle, CTFTurret, "ctf_turret" );
|
|
|
|
ResponseDef CTFTurret::Responses[] =
|
|
{
|
|
{ &EV_Use, ( Response )CTFTurret::DriverUse },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
CTFTurret::CTFTurret()
|
|
{
|
|
takedamage = DAMAGE_YES;
|
|
setModel( "ctf_turret.def" );
|
|
modelIndex( "ctf_turretgun.def" );
|
|
modelIndex( "view_ctf_turretgun.def" );
|
|
setOrigin( origin - Vector( "0 0 30") );
|
|
drivable = false;
|
|
setMoveType( MOVETYPE_NONE );
|
|
setSize( "-24 -24 -64", "24 24 0" );
|
|
edict->s.renderfx |= RF_MINLIGHT;
|
|
}
|
|
|
|
void CTFTurret::DriverUse
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
Entity * old_driver;
|
|
|
|
old_driver = driver;
|
|
DrivableVehicle::DriverUse( ev );
|
|
if ( old_driver != driver )
|
|
{
|
|
if ( driver )
|
|
{
|
|
setSolidType( SOLID_NOT );
|
|
takedamage = DAMAGE_NO;
|
|
hideModel();
|
|
}
|
|
else
|
|
{
|
|
setSolidType( SOLID_BBOX );
|
|
takedamage = DAMAGE_YES;
|
|
showModel();
|
|
}
|
|
}
|
|
setMoveType( MOVETYPE_NONE );
|
|
}
|
|
|
|
#define MAX_PITCH 45
|
|
float CTFTurret::SetDriverPitch
|
|
(
|
|
float pitch
|
|
)
|
|
{
|
|
if ( pitch > 180 )
|
|
{
|
|
if ( pitch < 360 - MAX_PITCH )
|
|
{
|
|
pitch = 360 - MAX_PITCH;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( pitch > MAX_PITCH )
|
|
{
|
|
pitch = MAX_PITCH;
|
|
}
|
|
if ( pitch < -MAX_PITCH )
|
|
{
|
|
pitch = -MAX_PITCH;
|
|
}
|
|
}
|
|
return pitch;
|
|
}
|
|
|
|
CLASS_DECLARATION( HeliGun, CTFTurretGun, "ctf_weapon_turretgun" );
|
|
|
|
ResponseDef CTFTurretGun::Responses[] =
|
|
{
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
CTFTurretGun::CTFTurretGun
|
|
(
|
|
)
|
|
|
|
{
|
|
SetModels( "ctf_turretgun.def", "view_ctf_turretgun.def" );
|
|
}
|
|
|
|
void CTFTurretGun::Shoot
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
FireBullets( 1, "20 20 20", 48, 64, DAMAGE_BULLET, MOD_CTFTURRET, false );
|
|
NextAttack( 0 );
|
|
}
|
|
|
|
qboolean CTFTurretGun::IsDroppable
|
|
(
|
|
void
|
|
)
|
|
|
|
{
|
|
return false;
|
|
}
|
|
|
|
|
|
//
|
|
// CTF turret which is lagged but has angle limits set on it.
|
|
//
|
|
CLASS_DECLARATION( DrivableVehicle, CTFDrivableTurret, "ctf_fixedturret" );
|
|
|
|
ResponseDef CTFDrivableTurret::Responses[] =
|
|
{
|
|
{ &EV_Use, ( Response )CTFDrivableTurret::DriverUse },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
CTFDrivableTurret::CTFDrivableTurret()
|
|
{
|
|
ClassDef *cls;
|
|
|
|
takedamage = DAMAGE_YES;
|
|
setModel( "ctf_fixedturret.def" );
|
|
setOrigin( origin - Vector( "0 0 30") );
|
|
baseangles = angles;
|
|
|
|
shotdamage = G_GetFloatArg( "shotdamage", 48 );
|
|
maxpitch = G_GetFloatArg( "maxpitch", 30 );
|
|
maxyaw = G_GetFloatArg( "maxyaw", 75 );
|
|
|
|
cls = getClass( "Sentient" );
|
|
if ( cls )
|
|
{
|
|
gunholder = ( Sentient * )cls->newInstance();
|
|
gunholder->hideModel();
|
|
}
|
|
cls = getClass( "BulletWeapon" );
|
|
if ( cls )
|
|
{
|
|
gun = ( BulletWeapon * )cls->newInstance();
|
|
gun->SetModels( "ctf_fixedturret.def", "ctf_fixedturret.def" );
|
|
gun->SetOwner( gunholder );
|
|
gun->hideModel();
|
|
}
|
|
|
|
setSize( "-24 -24 -64", "24 24 0" );
|
|
lastbutton = -1;
|
|
entertime = -1;
|
|
exittime = -1;
|
|
setMoveType( MOVETYPE_NONE );
|
|
edict->s.renderfx |= RF_MINLIGHT;
|
|
}
|
|
|
|
void CTFDrivableTurret::Postthink
|
|
(
|
|
void
|
|
)
|
|
|
|
{
|
|
Vector temp;
|
|
Vector diff;
|
|
|
|
// make sure we don't move
|
|
velocity = vec_zero;
|
|
|
|
if ( cmd_angles[ 0 ] > maxturnrate )
|
|
{
|
|
cmd_angles[ 0 ] = maxturnrate;
|
|
}
|
|
else if ( cmd_angles[ 0 ] < -maxturnrate )
|
|
{
|
|
cmd_angles[ 0 ] = -maxturnrate;
|
|
}
|
|
if ( cmd_angles[ 1 ] > maxturnrate )
|
|
{
|
|
cmd_angles[ 1 ] = maxturnrate;
|
|
}
|
|
else if ( cmd_angles[ 1 ] < -maxturnrate )
|
|
{
|
|
cmd_angles[ 1 ] = -maxturnrate;
|
|
}
|
|
|
|
temp = angles + cmd_angles;
|
|
|
|
diff = temp - baseangles;
|
|
diff.x = angledist( diff.x );
|
|
diff.y = angledist( diff.y );
|
|
gi.dprintf( "diff x%5.2f y%5.2f\n", diff.x, diff.y );
|
|
|
|
if ( diff.x > maxpitch )
|
|
{
|
|
temp.x = baseangles.x + maxpitch;
|
|
}
|
|
else if ( diff.x < -maxpitch )
|
|
{
|
|
temp.x = baseangles.x - maxpitch;
|
|
}
|
|
|
|
if ( maxyaw < 180 )
|
|
{
|
|
if ( diff.y > maxyaw )
|
|
{
|
|
temp.y = baseangles.y + maxyaw;
|
|
}
|
|
else if ( diff.y < -maxyaw )
|
|
{
|
|
temp.y = baseangles.y - maxyaw;
|
|
}
|
|
}
|
|
|
|
setAngles( temp );
|
|
|
|
|
|
if ( driver )
|
|
{
|
|
Vector i,j,k;
|
|
Player * player;
|
|
|
|
i = Vector( orientation[ 0 ] );
|
|
j = Vector( orientation[ 1 ] );
|
|
k = Vector( orientation[ 2 ] );
|
|
|
|
player = ( Player * )( Sentient * )driver;
|
|
player->setOrigin( worldorigin + i * driveroffset[0] + j * driveroffset[1] + k * driveroffset[2] );
|
|
if ( drivable )
|
|
{
|
|
player->velocity = vec_zero;
|
|
player->setAngles( angles );
|
|
player->SetViewAngles( angles );
|
|
player->SetDeltaAngles();
|
|
}
|
|
}
|
|
|
|
CheckWater();
|
|
WorldEffects();
|
|
|
|
// save off last origin
|
|
last_origin = worldorigin;
|
|
|
|
if ( !driver && !velocity.length() && groundentity && !( watertype & CONTENTS_LAVA ) )
|
|
{
|
|
flags &= ~FL_POSTTHINK;
|
|
if ( drivable )
|
|
setMoveType( MOVETYPE_NONE );
|
|
}
|
|
if ( driver )
|
|
{
|
|
if ( buttons & BUTTON_ATTACK )
|
|
{
|
|
if ( !lastbutton )
|
|
{
|
|
lastbutton = 1;
|
|
RandomAnimate( "fire", NULL );
|
|
}
|
|
Fire();
|
|
}
|
|
else if ( buttons & BUTTON_USE )
|
|
{
|
|
Event * event;
|
|
|
|
if ( level.time > ( entertime + 0.5f ) )
|
|
{
|
|
event = new Event( EV_Use );
|
|
event->AddEntity( driver );
|
|
ProcessEvent( event );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( lastbutton )
|
|
{
|
|
lastbutton = 0;
|
|
RandomAnimate( "idle", NULL );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CTFDrivableTurret::Fire
|
|
(
|
|
void
|
|
)
|
|
|
|
{
|
|
setSolidType( SOLID_NOT );
|
|
gunholder->setOrigin( origin );
|
|
gunholder->setAngles( angles );
|
|
gun->FireBullets( 1, "20 20 20", shotdamage, shotdamage * 1.5f, DAMAGE_BULLET, MOD_CTFTURRET, true );
|
|
setSolidType( SOLID_BBOX );
|
|
}
|
|
|
|
float CTFDrivableTurret::SetDriverPitch
|
|
(
|
|
float pitch
|
|
)
|
|
{
|
|
return pitch;
|
|
}
|
|
|
|
qboolean CTFDrivableTurret::Drive
|
|
(
|
|
usercmd_t *ucmd
|
|
)
|
|
|
|
{
|
|
if ( !driver || !driver->isClient() )
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
DrivableVehicle::Drive( ucmd );
|
|
ucmd->buttons &= ~BUTTON_ATTACK;
|
|
ucmd->buttons &= ~BUTTON_USE;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
void CTFDrivableTurret::DriverUse
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
Entity * old_driver;
|
|
|
|
if ( !driver && ( level.time < ( exittime + 0.5f ) ) )
|
|
return;
|
|
|
|
cmd_angles[ 0 ] = 0;
|
|
cmd_angles[ 1 ] = 0;
|
|
cmd_angles[ 2 ] = 0;
|
|
buttons = 0;
|
|
lastbutton = -1;
|
|
setMoveType( MOVETYPE_NONE );
|
|
RandomAnimate( "idle", NULL );
|
|
|
|
old_driver = driver;
|
|
|
|
DrivableVehicle::DriverUse( ev );
|
|
|
|
if ( old_driver != driver )
|
|
{
|
|
if ( driver )
|
|
{
|
|
entertime = level.time;
|
|
}
|
|
else
|
|
{
|
|
exittime = level.time;
|
|
}
|
|
}
|
|
}
|