mirror of
https://github.com/blendogames/quadrilateralcowboy.git
synced 2024-11-24 21:11:49 +00:00
363 lines
9.7 KiB
C++
363 lines
9.7 KiB
C++
|
|
#include "../idlib/precompiled.h"
|
|
#pragma hdrstop
|
|
|
|
#include "Game_local.h"
|
|
|
|
#define ROCKETSPEED 256
|
|
#define AIMAHEAD_DISTANCE 256
|
|
|
|
|
|
#define LIGHT_AHEADDISTANCE 32
|
|
|
|
const idEventDef EV_zeppelinactivate( "zeppelinactivate", "d" );
|
|
|
|
CLASS_DECLARATION( idAnimatedEntity, idZeppelinBig )
|
|
EVENT( EV_zeppelinactivate, idZeppelinBig::Event_zeppelinactivate )
|
|
END_CLASS
|
|
|
|
void idZeppelinBig::Save( idSaveGame *savefile ) const
|
|
{
|
|
savefile->WriteInt(state);
|
|
savefile->WriteInt(nextAttackTime);
|
|
savefile->WriteInt(nextVolleyTime);
|
|
savefile->WriteInt(volleyCount);
|
|
savefile->WriteInt(maxVolley);
|
|
savefile->WriteInt(attackDelay);
|
|
savefile->WriteFloat(initialDelay);
|
|
|
|
savefile->WriteObject(beam1Start);
|
|
savefile->WriteObject(beam1End);
|
|
savefile->WriteObject(beam2Start);
|
|
savefile->WriteObject(beam2End);
|
|
savefile->WriteObject(light);
|
|
}
|
|
|
|
void idZeppelinBig::Restore( idRestoreGame *savefile )
|
|
{
|
|
savefile->ReadInt(state);
|
|
savefile->ReadInt(nextAttackTime);
|
|
savefile->ReadInt(nextVolleyTime);
|
|
savefile->ReadInt(volleyCount);
|
|
savefile->ReadInt(maxVolley);
|
|
savefile->ReadInt(attackDelay);
|
|
savefile->ReadFloat(initialDelay);
|
|
|
|
savefile->ReadObject(reinterpret_cast<idClass *&>(beam1Start));
|
|
savefile->ReadObject(reinterpret_cast<idClass *&>(beam1End));
|
|
savefile->ReadObject(reinterpret_cast<idClass *&>(beam2Start));
|
|
savefile->ReadObject(reinterpret_cast<idClass *&>(beam2End));
|
|
savefile->ReadObject(reinterpret_cast<idClass *&>(light));
|
|
}
|
|
|
|
void idZeppelinBig::Event_zeppelinactivate(int value)
|
|
{
|
|
if (value > 0 && state == OFF)
|
|
{
|
|
this->Show();
|
|
beam1Start->Show();
|
|
beam2Start->Show();
|
|
light->On();
|
|
|
|
if (initialDelay > 0)
|
|
{
|
|
nextAttackTime = gameLocal.time + (initialDelay);
|
|
}
|
|
|
|
StartSound( "snd_activate", SND_CHANNEL_BODY2, 0, false, NULL );
|
|
|
|
state = ON;
|
|
}
|
|
else
|
|
{
|
|
this->Hide();
|
|
beam1Start->Hide();
|
|
beam2Start->Hide();
|
|
light->Off();
|
|
|
|
state = OFF;
|
|
}
|
|
}
|
|
|
|
void idZeppelinBig::AimBeam(const char *jointName, idBeam *beamEnd, idVec3 aimPos)
|
|
{
|
|
jointHandle_t beamJoint;
|
|
idVec3 dirToPlayer;
|
|
idVec3 beamPos;
|
|
idMat3 beamAngle;
|
|
trace_t tr;
|
|
|
|
beamJoint = this->GetAnimator()->GetJointHandle( jointName );
|
|
animator.GetJointTransform( beamJoint, gameLocal.time, beamPos, beamAngle);
|
|
|
|
beamPos = this->GetPhysics()->GetOrigin() + beamPos * this->GetPhysics()->GetAxis();
|
|
dirToPlayer = aimPos - beamPos;
|
|
dirToPlayer.Normalize();
|
|
|
|
animator.SetJointAxis( beamJoint, JOINTMOD_WORLD, dirToPlayer.ToMat3() );
|
|
|
|
//do traceline.
|
|
gameLocal.clip.TracePoint( tr, beamPos, beamPos + (dirToPlayer * 16384), MASK_SOLID, this );
|
|
|
|
//beamEnd->GetPhysics()->SetOrigin(tr.endpos);
|
|
beamEnd->SetOrigin(tr.endpos);
|
|
}
|
|
|
|
void idZeppelinBig::Think( void )
|
|
{
|
|
//aim the spotlight ahead of the player.
|
|
|
|
if (state == OFF)
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
trace_t tr;
|
|
jointHandle_t gunJoint;
|
|
idVec3 gunPos;
|
|
idMat3 gunAxis;
|
|
idVec3 playerPos;
|
|
|
|
gunJoint = this->GetAnimator()->GetJointHandle( "gun" );
|
|
animator.GetJointTransform( gunJoint, gameLocal.time, gunPos, gunAxis);
|
|
gunPos = this->GetPhysics()->GetOrigin() + gunPos * this->GetPhysics()->GetAxis();
|
|
|
|
playerPos = gameLocal.GetLocalPlayer()->GetPhysics()->GetOrigin() + idVec3(0,0,32);
|
|
gameLocal.clip.TracePoint( tr, gunPos, playerPos, MASK_SOLID, this );
|
|
|
|
|
|
/*
|
|
gameLocal.GetLocalPlayer()->DebugMessage(va("%f %f %f\n", gameLocal.GetLocalPlayer()->GetPhysics()->GetLinearVelocity().x,
|
|
gameLocal.GetLocalPlayer()->GetPhysics()->GetLinearVelocity().y,
|
|
gameLocal.GetLocalPlayer()->GetPhysics()->GetLinearVelocity().z));
|
|
*/
|
|
|
|
//Find a point 32 units in front of player.
|
|
if (tr.fraction >= 1)
|
|
{
|
|
trace_t lightTrace;
|
|
idVec3 lightPos;
|
|
idAngles playerAng = gameLocal.GetLocalPlayer()->viewAngles;
|
|
playerAng.pitch = 0;
|
|
playerAng.roll = 0;
|
|
idVec3 playerForwardPos = gameLocal.GetLocalPlayer()->GetPhysics()->GetOrigin() + (playerAng.ToForward() * LIGHT_AHEADDISTANCE);
|
|
|
|
idVec3 aimPos1 = playerForwardPos;
|
|
idVec3 aimPos2 = playerForwardPos;
|
|
|
|
//Give spotlight a little idle sway.
|
|
aimPos1.x += idMath::Sin(gameLocal.time * 0.0005f) * 32.0f;
|
|
aimPos1.y += idMath::Sin(gameLocal.time * 0.0004f) * 32.0f;
|
|
|
|
aimPos2.x += idMath::Sin(gameLocal.time * 0.0003f) * 32.0f;
|
|
aimPos2.y += idMath::Sin(gameLocal.time * 0.0006f) * 32.0f;
|
|
|
|
//Aim the beams.
|
|
|
|
lightPos = beam1End->GetPhysics()->GetOrigin();
|
|
lightPos += playerAng.ToForward() * 32;
|
|
lightPos.x += idMath::Sin(gameLocal.time * 0.001f) * 32.0f;
|
|
lightPos.y += idMath::Sin(gameLocal.time * 0.001f) * 32.0f;
|
|
|
|
AimBeam( "beam1" , beam1End, aimPos1);
|
|
AimBeam( "beam2" , beam2End, aimPos2);
|
|
|
|
|
|
gameLocal.clip.TracePoint( lightTrace, gunPos, lightPos, MASK_SOLID, this );
|
|
light->SetOrigin( lightTrace.endpos + idVec3(0, 0, 32) );
|
|
}
|
|
|
|
|
|
|
|
|
|
//GUN CODE.
|
|
if (gameLocal.time > nextAttackTime && gameLocal.time >= nextVolleyTime && gameLocal.GetLocalPlayer()->health > 0 && g_skill.GetInteger() > 0 && !gameLocal.GetLocalPlayer()->noclip)
|
|
{
|
|
if (tr.fraction >= 1)
|
|
{
|
|
const idDict * projectileDef;
|
|
idVec3 dirToPlayer;
|
|
|
|
float aheadModifier = 1.0f;
|
|
idVec3 playerVelocity = gameLocal.GetLocalPlayer()->GetPhysics()->GetLinearVelocity();
|
|
|
|
if (playerVelocity.x <= 0 && playerVelocity.y <= 0 && playerVelocity.z <= 0)
|
|
{
|
|
aheadModifier = 0.5f;
|
|
}
|
|
|
|
idVec3 playerAngle = gameLocal.GetLocalPlayer()->viewAngles.ToForward();
|
|
playerAngle.Normalize();
|
|
playerPos += playerAngle * (AIMAHEAD_DISTANCE * aheadModifier);
|
|
|
|
|
|
|
|
//random variation.
|
|
float aimVariation = spawnArgs.GetFloat("aim_variation");
|
|
if (aimVariation > 0)
|
|
{
|
|
playerPos.x += -aimVariation + gameLocal.random.RandomFloat() * (aimVariation * 2);
|
|
playerPos.y += -aimVariation + gameLocal.random.RandomFloat() * (aimVariation * 2);
|
|
}
|
|
|
|
|
|
|
|
|
|
dirToPlayer = playerPos - gunPos;
|
|
dirToPlayer.Normalize();
|
|
|
|
StartSound( "snd_fire", SND_CHANNEL_ANY, 0, false, NULL );
|
|
|
|
|
|
|
|
trace_t groundTr;
|
|
gameLocal.clip.TracePoint( groundTr, gunPos, gunPos + (dirToPlayer * 4096), MASK_SOLID, this );
|
|
|
|
|
|
if (tr.fraction >= 1)
|
|
{
|
|
idEntity * bulletEnt;
|
|
//idStaticEntity* markerEnt;
|
|
//idStaticEntity* beamEnt;
|
|
|
|
|
|
/*
|
|
idDict args;
|
|
args.Clear();
|
|
args.Set( "model", "models/zeppelin_hitmarker/tris.ase" );
|
|
args.SetVector( "origin", groundTr.endpos);
|
|
markerEnt = ( idStaticEntity * )gameLocal.SpawnEntityType( idStaticEntity::Type, &args );
|
|
markerEnt->SetAxis(groundTr.c.normal.ToMat3());
|
|
*/
|
|
|
|
|
|
idVec3 dirToGun = gunPos - groundTr.endpos;
|
|
dirToGun.Normalize();
|
|
|
|
|
|
/*
|
|
args.Clear();
|
|
args.Set( "model", "models/beam_light/tris_512.ase" );
|
|
args.SetVector( "origin", groundTr.endpos);
|
|
args.Set( "skin", "skins/beam_light/lasersight");
|
|
beamEnt = ( idStaticEntity * )gameLocal.SpawnEntityType( idStaticEntity::Type, &args );
|
|
beamEnt->SetAxis(dirToGun.ToMat3());
|
|
*/
|
|
|
|
|
|
//FIRE.
|
|
idProjectile *bullet;
|
|
projectileDef = gameLocal.FindEntityDefDict( spawnArgs.GetString( "projectile", "projectile_rocket"), false );
|
|
gameLocal.SpawnEntityDef( *projectileDef, &bulletEnt, false );
|
|
bullet = ( idProjectile * )bulletEnt;
|
|
bullet->Create( this, gunPos, dirToPlayer );
|
|
bullet->Launch( gunPos, dirToPlayer, dirToPlayer * ROCKETSPEED );
|
|
//bullet->spawnArgs.Set("markername", markerEnt->GetName());
|
|
//bullet->spawnArgs.Set("beamname", beamEnt->GetName());
|
|
bullet->SetAxis(dirToPlayer.ToMat3());
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//gameRenderWorld->DebugCircle(idVec4(1,1,1,1), gunPos, idVec3(0,0,1), 32, 9, 2000);
|
|
|
|
//gameRenderWorld->DebugCircle(idVec4(1,1,1,1), playerPos, idVec3(0,0,1), 32, 9, 2000);
|
|
//gameRenderWorld->DebugLine(idVec4(1,1,1,1), playerPos, gunPos, 2000);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
volleyCount++;
|
|
nextVolleyTime = gameLocal.time + volleyDelay;
|
|
|
|
if (volleyCount >= maxVolley)
|
|
{
|
|
nextAttackTime = gameLocal.time + attackDelay;
|
|
nextVolleyTime = 0;
|
|
volleyCount = 0;
|
|
}
|
|
}
|
|
|
|
|
|
idAnimatedEntity::Present();
|
|
}
|
|
|
|
void idZeppelinBig::SpawnBeam(idBeam *beamStart, idBeam *beamEnd, const char *attachJoint)
|
|
{
|
|
jointHandle_t spotlightJoint;
|
|
idDict args;
|
|
idVec3 muzzlePos;
|
|
idMat3 muzzleAxis;
|
|
|
|
beamEnd = ( idBeam * )gameLocal.SpawnEntityType( idBeam::Type, &args );
|
|
spotlightJoint = this->GetAnimator()->GetJointHandle( attachJoint );
|
|
this->GetAnimator()->GetJointTransform( spotlightJoint, gameLocal.time, muzzlePos, muzzleAxis );
|
|
|
|
muzzlePos = this->GetPhysics()->GetOrigin() + muzzlePos * this->GetPhysics()->GetAxis();
|
|
|
|
beamStart->Event_SetWidth(64);
|
|
beamStart->SetOrigin(muzzlePos );
|
|
beamStart->BindToJoint( this, spotlightJoint, false );
|
|
|
|
|
|
}
|
|
|
|
void idZeppelinBig::Spawn( void )
|
|
{
|
|
idDict args;
|
|
bool startOff;
|
|
|
|
startOff = this->spawnArgs.GetBool("start_off", "1");
|
|
|
|
beam1End = ( idBeam * )gameLocal.SpawnEntityType( idBeam::Type );
|
|
beam2End = ( idBeam * )gameLocal.SpawnEntityType( idBeam::Type );
|
|
|
|
args.Clear();
|
|
args.Set( "target", beam1End->name.c_str() );
|
|
args.SetBool( "start_off", startOff );
|
|
args.Set( "skin", "skins/spotlight");
|
|
beam1Start = ( idBeam * )gameLocal.SpawnEntityType( idBeam::Type, &args );
|
|
|
|
args.Clear();
|
|
args.Set( "target", beam2End->name.c_str() );
|
|
args.SetBool( "start_off", startOff );
|
|
args.Set( "skin", "skins/spotlight");
|
|
beam2Start = ( idBeam * )gameLocal.SpawnEntityType( idBeam::Type, &args );
|
|
|
|
SpawnBeam(beam1Start, beam1End, "beam1");
|
|
SpawnBeam(beam2Start, beam2End, "beam2");
|
|
|
|
|
|
args.Clear();
|
|
args.Set( "texture", "lights/spotlight" );
|
|
args.SetInt( "alarmlight", 0 );
|
|
light = ( idLight * )gameLocal.SpawnEntityType( idLight::Type, &args );
|
|
light->SetColor(.73, .9, 1);
|
|
light->SetRadius( 128 );
|
|
|
|
|
|
volleyDelay = spawnArgs.GetFloat( "volleydelay", "0.4") * 1000;
|
|
maxVolley = spawnArgs.GetInt("maxvolley", "3");
|
|
initialDelay = spawnArgs.GetFloat( "initialdelay", "3" ) * 1000;
|
|
attackDelay = spawnArgs.GetFloat("attackdelay", "3") * 1000;
|
|
nextAttackTime = 0;
|
|
state = OFF;
|
|
nextVolleyTime = 0;
|
|
volleyCount = 0;
|
|
BecomeActive( TH_THINK );
|
|
|
|
//make it non solid.
|
|
//GetPhysics()->SetContents( 0 );
|
|
|
|
if (startOff)
|
|
{
|
|
this->Event_zeppelinactivate(0);
|
|
}
|
|
}
|
|
|