quadrilateralcowboy/d3xp/itemgate.cpp

256 lines
5.9 KiB
C++
Raw Normal View History

2020-06-12 21:06:25 +00:00
#include "../idlib/precompiled.h"
#pragma hdrstop
#include "Game_local.h"
const idEventDef EV_staticactivate( "staticactivate", "d" );
CLASS_DECLARATION( idTrigger, idItemGate )
EVENT( EV_Touch, idItemGate::Event_Touch )
EVENT( EV_staticactivate, idItemGate::Event_staticactivate)
END_CLASS
void idItemGate::Save( idSaveGame *savefile ) const
{
savefile->WriteInt(nextTriggerTime);
savefile->WriteVec3(throwDir);
savefile->WriteString(className);
savefile->WriteString(weaponName);
savefile->WriteString(callName);
savefile->WriteInt(force);
savefile->WriteBool(hasFoundTarget);
savefile->WriteBool(isOn);
savefile->WriteVec3(throwDestination);
savefile->WriteInt(nextHitSoundTime);
}
void idItemGate::Restore( idRestoreGame *savefile )
{
savefile->ReadInt(nextTriggerTime);
savefile->ReadVec3(throwDir);
savefile->ReadString(className);
savefile->ReadString(weaponName);
savefile->ReadString(callName);
savefile->ReadInt(force);
savefile->ReadBool(hasFoundTarget);
savefile->ReadBool(isOn);
savefile->ReadVec3(throwDestination);
savefile->ReadInt(nextHitSoundTime);
}
void idItemGate::Spawn( void )
{
className = spawnArgs.GetString( "class" );
if ( !className.Length() )
{
gameLocal.Error( "idItemGate '%s' at (%s) doesn't have 'classname' key specified", name.c_str(), GetPhysics()->GetOrigin().ToString(0) );
}
weaponName = spawnArgs.GetString( "weapon" );
if ( !weaponName.Length() )
{
gameLocal.Error( "idItemGate '%s' at (%s) doesn't have 'weapon' key specified", name.c_str(), GetPhysics()->GetOrigin().ToString(0) );
}
callName = spawnArgs.GetString( "callname" );
force = spawnArgs.GetInt( "force", "160" );
nextTriggerTime = 0;
GetPhysics()->SetContents( CONTENTS_TRIGGER );
StartSound( "snd_hum", SND_CHANNEL_BODY, 0, false, NULL );
isOn = true;
hasFoundTarget = false;
nextHitSoundTime = 0;
BecomeActive( TH_THINK );
}
void idItemGate::Think( void )
{
//11-4-2015
//why does the trigger spin in circles sometimes?
//why does adding this empty function fix this bug?
//??????????
}
void idItemGate::Event_staticactivate( int value )
{
isOn = value;
if (value >= 1)
{
StartSound( "snd_hum", SND_CHANNEL_BODY, 0, false, NULL );
}
else
{
StopSound( SND_CHANNEL_BODY, false );
}
}
void idItemGate::repel( idEntity *ent )
{
idDict args;
ent->GetPhysics()->SetLinearVelocity(throwDir * force);
if (gameLocal.time > nextHitSoundTime)
{
StartSound( "snd_hit", SND_CHANNEL_ANY, 0, false, NULL );
nextHitSoundTime = gameLocal.time + 1500;
}
args.Clear();
args.SetVector( "origin", ent->GetPhysics()->GetOrigin() );
args.Set( "model", "magnetfire.prt" );
args.SetBool( "start_off", false );
gameLocal.SpawnEntityType( idExplodable::Type, &args );
}
void idItemGate::Event_Touch( idEntity *other, trace_t *trace )
{
if (!isOn || g_skill.GetInteger() <= 0)
{
return;
}
if (!hasFoundTarget)
{
FindTargets();
RemoveNullTargets();
if ( !targets.Num() )
{
gameLocal.Error( "idItemGate '%s' at (%s) doesn't have 'target' key specified", name.c_str(), GetPhysics()->GetOrigin().ToString(0) );
}
throwDir = targets[0].GetEntity()->GetPhysics()->GetOrigin() - GetPhysics()->GetOrigin();
throwDir.Normalize();
throwDestination = targets[0].GetEntity()->GetPhysics()->GetOrigin();
hasFoundTarget = true;
}
if ( nextTriggerTime > gameLocal.time )
{
// can't retrigger until the wait is over
return;
}
if ( !other )
{
return;
}
nextTriggerTime = gameLocal.time + 1;
//if player is holding item, then force player to drop the item.
if (gameLocal.GetLocalPlayer()->pickerWeapon.dragEnt.IsValid())
{
if (gameLocal.GetLocalPlayer()->pickerWeapon.dragEnt.GetEntity()->spawnArgs.GetString("classname") == className)
{
idEntity *dragee;
dragee = gameLocal.GetLocalPlayer()->pickerWeapon.dragEnt.GetEntity();
gameLocal.GetLocalPlayer()->pickerWeapon.StopDrag(true, false);
repel(dragee);
return;
}
}
//if in inventory, then remove item from inventory and spawn into world.
if (gameLocal.GetLocalPlayer()->Event_hasWeapon(weaponName))
{
if (gameLocal.GetLocalPlayer()->RemoveWeaponItem(weaponName))
{
idVec3 spawnPos;
idAngles forward;
trace_t tr;
//BC 8-20-2015 if player has the weapon currently selected, then switch to a different weapon.
if (idStr::Icmp( weaponName, gameLocal.GetLocalPlayer()->GetCurrentWeapon()) == 0)
{
gameLocal.GetLocalPlayer()->SelectWeapon(0, true); //select unarmed weapon.
}
//BC 10-20-2015 simplify this to just spawn the item in the middle of the trigger.
//BC 11-4-2015 allow for manually-placed spawnpoint for the spawned item.
idStr spawnpointname = spawnArgs.GetString( "spawnpoint", "" );
if (spawnpointname.Length())
{
idEntity *spawnEnt = gameLocal.FindEntity(spawnpointname.c_str());
if (spawnEnt)
{
spawnPos = spawnEnt->GetPhysics()->GetOrigin();
}
}
else
{
//center of the bounding box.
spawnPos = this->GetPhysics()->GetAbsBounds().GetCenter();
}
//weapon removed. now spawn it.
//first, determine whether the item already exists in the world. (is this case specific to the deck?)
gameLocal.GetLocalPlayer()->Event_hudMessage( common->GetLanguageDict()->GetString( "#str_02118" ) );
idEntity *launchee = gameLocal.FindEntityUsingDef(NULL, className);
if (launchee)
{
launchee->SetOrigin( spawnPos );
if (callName)
{
gameLocal.GetLocalPlayer()->UseFrob( launchee, callName );
}
repel(launchee);
return;
}
else
{
//doesn't exist. spawn it.
idDict args;
idEntity *spawnee;
args.Clear();
args.SetVector( "origin", spawnPos );
gameLocal.SpawnEntityDef( args, &spawnee );
if (callName)
{
gameLocal.GetLocalPlayer()->UseFrob( spawnee, callName );
}
repel(spawnee);
return;
}
}
}
if ( other->spawnArgs.GetString("classname") == className )
{
//launch the item.
repel(other);
}
}