quadrilateralcowboy/d3xp/cybervendor.cpp
2020-06-12 14:06:25 -07:00

349 lines
9 KiB
C++

#include "../idlib/precompiled.h"
#pragma hdrstop
#include "Game_local.h"
#define TIME_TO_FRONTMACHINE 400
#define TIME_TO_PAUSE 400
#define TIME_TO_LOOK_UP 500
//const idEventDef EV_ButtonSwitcher_activate( "buttonswitcheractivate", "f" );
CLASS_DECLARATION( idStaticEntity, idCybervendor )
//EVENT( EV_ButtonSwitcher_activate, idButtonSwitcher::Event_buttonswitcheractivate)
END_CLASS
void idCybervendor::Save( idSaveGame *savefile ) const
{
savefile->WriteInt(state);
savefile->WriteInt(nextUpdate);
savefile->WriteInt(lerpStart);
savefile->WriteInt(lerpEnd);
savefile->WriteVec3(posStart);
savefile->WriteVec3(posEnd);
savefile->WriteVec3(angStart);
savefile->WriteVec3(angEnd);
savefile->WriteInt(count);
}
void idCybervendor::Restore( idRestoreGame *savefile )
{
savefile->ReadInt(state);
savefile->ReadInt(nextUpdate);
savefile->ReadInt(lerpStart);
savefile->ReadInt(lerpEnd);
savefile->ReadVec3(posStart);
savefile->ReadVec3(posEnd);
savefile->ReadVec3(angStart);
savefile->ReadVec3(angEnd);
savefile->ReadInt(count);
}
void idCybervendor::Spawn( void )
{
BecomeActive( TH_THINK );
GetPhysics()->SetContents( CONTENTS_SOLID );
GetPhysics()->SetClipMask( MASK_SOLID | CONTENTS_BODY | CONTENTS_CORPSE | CONTENTS_MOVEABLECLIP );
this->noGrab = true;
this->isFrobbable = true;
state = 0;
nextUpdate = 0;
lerpStart = 0;
lerpEnd = 0;
count = 2;
}
void idCybervendor::OnFrob()
{
if (state == 0)
{
float player_z = gameLocal.GetLocalPlayer()->GetPhysics()->GetOrigin().z;
float machine_z = this->GetPhysics()->GetOrigin().z;
if (player_z < machine_z - 4)
{
StartSound( "snd_error", SND_CHANNEL_ANY, 0, false, NULL );
return;
}
count *= 2;
gameLocal.GetLocalPlayer()->Event_setFrozen(1);
isFrobbable = 0;
lerpStart = gameLocal.time;
lerpEnd = gameLocal.time + TIME_TO_FRONTMACHINE; //time to transition to the machine front.
idVec3 forward, right;
GetPhysics()->GetAxis().ToAngles().ToVectors( &forward, &right );
posEnd = this->GetPhysics()->GetOrigin() + (forward * 48) + (right * 12);
posStart = gameLocal.GetLocalPlayer()->GetPhysics()->GetOrigin();
angStart.x = gameLocal.GetLocalPlayer()->viewAngles.pitch;
angStart.y = gameLocal.GetLocalPlayer()->viewAngles.yaw;
angStart.z = gameLocal.GetLocalPlayer()->viewAngles.roll;
if (angStart.y < 0)
angStart.y += 360;
if (angStart.y < 180)
angStart.y += 360;
angEnd.x = GetPhysics()->GetAxis().ToAngles().pitch + 5;
angEnd.y = GetPhysics()->GetAxis().ToAngles().yaw + 180;
angEnd.z = GetPhysics()->GetAxis().ToAngles().roll;
if (angEnd.y < 0)
angEnd.y += 360;
if (angEnd.y < 180)
angEnd.y += 360;
StartSound( "snd_jingle", SND_CHANNEL_ANY, 0, false, NULL );
state = 1;
}
}
void idCybervendor::Think()
{
if (state == 1)
{
//lerp the player to the machine front AND look at the machine front.
float lerp;
float currentTime = gameLocal.time;
float lookTimeMax = this->lerpEnd - this->lerpStart;
float lookTimeMin = this->lerpStart;
currentTime -= this->lerpStart;
lerp = currentTime / lookTimeMax;
idVec3 newPosition;
newPosition.x = idMath::Lerp(posStart.x, posEnd.x, lerp);
newPosition.y = idMath::Lerp(posStart.y, posEnd.y, lerp);
newPosition.z = idMath::Lerp(posStart.z, posEnd.z, lerp);
gameLocal.GetLocalPlayer()->GetPhysics()->SetOrigin(newPosition);
idVec3 lookAng;
lookAng.x = idMath::Lerp(this->angStart.x, this->angEnd.x, lerp);
lookAng.y = idMath::Lerp(this->angStart.y, this->angEnd.y, lerp);
lookAng.z = idMath::Lerp(this->angStart.z, this->angEnd.z, lerp);
//common->Printf("%f : %f : %f %f %f\n", angStart.y, angEnd.y, lookAng.x, lookAng.y, lookAng.z);
gameLocal.GetLocalPlayer()->Event_setviewangle(lookAng);
//common->Printf("%f\n", lerp);
if (lerp >= 1)
{
lerpEnd = gameLocal.time + TIME_TO_PAUSE;
state = 2;
}
}
else if (state == 2)
{
//pause.
if (gameLocal.time >= lerpEnd)
{
angStart.x = gameLocal.GetLocalPlayer()->viewAngles.pitch;
angStart.y = gameLocal.GetLocalPlayer()->viewAngles.yaw;
angStart.z = gameLocal.GetLocalPlayer()->viewAngles.roll;
if (angStart.y < 0)
angStart.y += 360;
if (angStart.y < 180)
angStart.y += 360;
angEnd.x = spawnArgs.GetInt("drillangle", "50");
angEnd.y = GetPhysics()->GetAxis().ToAngles().yaw + 180;
angEnd.z = GetPhysics()->GetAxis().ToAngles().roll;
if (angEnd.y < 0)
angEnd.y += 360;
if (angEnd.y < 180)
angEnd.y += 360;
lerpStart = gameLocal.time;
lerpEnd = gameLocal.time + TIME_TO_LOOK_UP; //time to transition to the machine front.
state = 3;
}
}
else if (state == 3)
{
//look at the hole.
float lerp;
float currentTime = gameLocal.time;
float lookTimeMax = this->lerpEnd - this->lerpStart;
float lookTimeMin = this->lerpStart;
currentTime -= this->lerpStart;
lerp = currentTime / lookTimeMax;
//look up.
idVec3 lookAng;
lookAng.x = idMath::Lerp(this->angStart.x, this->angEnd.x, lerp);
lookAng.y = idMath::Lerp(this->angStart.y, this->angEnd.y, lerp);
lookAng.z = idMath::Lerp(this->angStart.z, this->angEnd.z, lerp);
//common->Printf("%f : %f : %f %f %f\n", angStart.y, angEnd.y, lookAng.x, lookAng.y, lookAng.z);
gameLocal.GetLocalPlayer()->Event_setviewangle(lookAng);
if (lerp >= 1)
{
StartSound( "snd_drill", SND_CHANNEL_ANY, 0, false, NULL );
idVec3 forward, right, up;
GetPhysics()->GetAxis().ToAngles().ToVectors( &forward, &right, &up );
posStart = this->GetPhysics()->GetOrigin() + (forward * 32) + (right * 12) + (up * 55);
gameLocal.GetLocalPlayer()->Event_viewlook(posStart, 0.2f, 0, 1);
lerpEnd = gameLocal.time + 1500;
//gameLocal.GetLocalPlayer()->Event_ToggleBloom(1);
cvarSystem->SetCVarString("g_testpostprocess", "textures/fx/fastforward_fast");
state = 4;
}
}
else if (state == 4)
{
//drilling.
gameLocal.GetLocalPlayer()->Event_setviewangle(angEnd);
if (gameLocal.time >= lerpEnd)
{
gameLocal.GetLocalPlayer()->Event_viewlook(posStart, 0.4f, 1, 0);
StartSound( "snd_ding", SND_CHANNEL_ANY, 0, false, NULL );
angStart.x = gameLocal.GetLocalPlayer()->viewAngles.pitch;
angEnd.x = 20;
angEnd.y = gameLocal.GetLocalPlayer()->viewAngles.yaw;
lerpStart = gameLocal.time;
lerpEnd = gameLocal.time + 300; //time to transition to the machine front.
cvarSystem->SetCVarString("g_testpostprocess", "0");
renderEntity.gui[0]->HandleNamedEvent("done");
//spew some decals into the world.
if (count <= 256)
{
idVec3 forward, right, up;
GetPhysics()->GetAxis().ToAngles().ToVectors( &forward, &right, &up );
idVec3 spitPoint = this->GetPhysics()->GetOrigin() + (forward * 25) + (right * 12) + (up * 128);
int i;
for (i = 0; i < count; i++)
{
idVec3 randSpot;
randSpot = this->GetPhysics()->GetOrigin() + (forward * (25 + gameLocal.random.RandomFloat() * 64)) + (right * (12 - 64 + gameLocal.random.RandomFloat() * 128) ) + (up * 128);
trace_t groundTr;
gameLocal.clip.TracePoint( groundTr, randSpot, randSpot + idVec3(0,0,-1024), MASK_SOLID, this );
if ((randSpot - spitPoint).Normalize() > 64)
continue;
gameLocal.ProjectDecal( groundTr.c.point, -groundTr.c.normal, 0.5f, true, 4 + gameLocal.random.RandomFloat() * 36, spawnArgs.GetString("mtr_oil") );
}
}
state = 5;
}
}
else if (state == 5)
{
//look up.
float lerp;
float currentTime = gameLocal.time;
float lookTimeMax = this->lerpEnd - this->lerpStart;
float lookTimeMin = this->lerpStart;
currentTime -= this->lerpStart;
lerp = currentTime / lookTimeMax;
//look up.
idVec3 lookAng;
lookAng.x = idMath::Lerp(this->angStart.x, this->angEnd.x, lerp);
lookAng.y = angEnd.y;
lookAng.z = 0;
//common->Printf("%f : %f : %f %f %f\n", angStart.y, angEnd.y, lookAng.x, lookAng.y, lookAng.z);
gameLocal.GetLocalPlayer()->Event_setviewangle(lookAng);
if (lerp >= 1)
{
gameLocal.GetLocalPlayer()->Event_setFrozen(0);
isFrobbable = 1;
state = 0;
ActivateTargets( this );
}
}
if (gameLocal.time > nextUpdate && state == 0)
{
//check if player angle faces the FRONT of the machine.
idAngles playerAng = gameLocal.GetLocalPlayer()->viewAngles;
playerAng.pitch = 0;
playerAng.roll = 0;
float vdot = DotProduct( this->GetPhysics()->GetAxis().ToAngles().ToForward(), playerAng.ToForward() );
//check if player is positioned in FRONT of the machine.
idVec3 forward;
GetPhysics()->GetAxis().ToAngles().ToVectors( &forward );
idVec3 frontOfMachinePos = this->GetPhysics()->GetOrigin() + (forward * 24);
idVec3 toPlayer = frontOfMachinePos - gameLocal.GetLocalPlayer()->GetPhysics()->GetOrigin();
idVec3 machineFacing = this->GetPhysics()->GetAxis().ToAngles().ToForward();
float facingResult = DotProduct( toPlayer, machineFacing );
//gameLocal.GetLocalPlayer()->DebugMessage(va("dot %f", facingResult));
if (vdot < -0.1f && facingResult < 0)
{
this->isFrobbable = true;
}
else
{
this->isFrobbable = false;
}
nextUpdate = gameLocal.time + 300; //update every X milliseconds.
}
Present();
}