mirror of
https://github.com/blendogames/quadrilateralcowboy.git
synced 2024-11-21 19:51:04 +00:00
256 lines
5.9 KiB
C++
256 lines
5.9 KiB
C++
|
|
||
|
#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);
|
||
|
}
|
||
|
}
|