348 lines
8.1 KiB
Text
348 lines
8.1 KiB
Text
|
|
object scud_trigger : hackable_objective {
|
|
void syncFields();
|
|
|
|
void OnHacked( entity p );
|
|
|
|
void vSetActive( boolean value );
|
|
|
|
boolean TryFire( entity firer );
|
|
void FireThread( entity firer );
|
|
void FireThreadFake();
|
|
void TrackScud();
|
|
|
|
void vSetTargetEntity( entity ent );
|
|
void vSetOwner( entity ent );
|
|
void vStartObjective();
|
|
|
|
void OnActiveChanged();
|
|
void OnPostMapSpawn();
|
|
void OnObjectiveIndexChanged();
|
|
void OnScudChanged();
|
|
|
|
void DestroyTarget( entity targetEnt );
|
|
void SpawnDestroyEffect( vector position );
|
|
entity vGetSpectateEntity();
|
|
boolean vIsObjectiveComplete();
|
|
|
|
entity targetEnt;
|
|
entity owner;
|
|
entity trackingScud;
|
|
|
|
boolean active;
|
|
|
|
boolean AllowHack() { return active; }
|
|
}
|
|
|
|
void scud_trigger::syncFields() {
|
|
syncBroadcast( "objectiveIndex" );
|
|
syncCallback( "objectiveIndex", "OnObjectiveIndexChanged" );
|
|
|
|
syncBroadcast( "trackingScud" );
|
|
syncCallback( "trackingScud", "OnScudChanged" );
|
|
|
|
syncBroadcast( "active" );
|
|
syncCallback( "active", "OnActiveChanged" );
|
|
|
|
syncBroadcast( "owner" );
|
|
}
|
|
|
|
void scud_trigger::OnObjectiveIndexChanged() {
|
|
SetObjectiveIndex( objectiveIndex );
|
|
}
|
|
|
|
void scud_trigger::OnScudChanged() {
|
|
if ( trackingScud != $null_entity ) {
|
|
thread TrackScud();
|
|
}
|
|
}
|
|
|
|
void scud_trigger::OnPostMapSpawn() {
|
|
// TEMP: for old style shields
|
|
targetEnt = getEntityKey( "target" );
|
|
}
|
|
|
|
void scud_trigger::OnActiveChanged() {
|
|
if ( active ) {
|
|
setShaderParm( 7, 1 );
|
|
} else {
|
|
setShaderParm( 7, 0 );
|
|
}
|
|
}
|
|
|
|
void scud_trigger::vSetActive( boolean value ) {
|
|
if ( active == value ) {
|
|
return;
|
|
}
|
|
active = value;
|
|
OnActiveChanged();
|
|
}
|
|
|
|
void scud_trigger::OnHacked( entity p ) {
|
|
owner.vSetActive( true );
|
|
vSetActive( false );
|
|
|
|
object oldTeam = getGameTeam();
|
|
object newTeam = p.getGameTeam();
|
|
setGameTeam( newTeam );
|
|
|
|
if ( p != $null_entity ) {
|
|
string statName = newTeam.getName() + "_primary_objective_hacked";
|
|
sys.increaseStatInt( sys.allocStatInt( statName ), p.getEntityNumber(), 1 );
|
|
statName = newTeam.getName() + "_hack_uses";
|
|
sys.increaseStatInt( sys.allocStatInt( statName ), p.getEntityNumber(), 1 );
|
|
sys.increaseStatInt( sys.allocStatInt( "total_objectives_completed" ), p.getEntityNumber(), 1 );
|
|
|
|
handle completeMessage = sys.localizeString( getKeyWithDefault( "complete_message", "maps/generic/obj_hacked" ) );
|
|
objManager.PushCPrintString( p.getUserName() );
|
|
objManager.CPrintEvent( completeMessage, $null );
|
|
}
|
|
|
|
objManager.OnHackComplete( self );
|
|
|
|
objManager.PlaySound( getKey( "snd_hacked_strogg" ), stroggTeam );
|
|
objManager.PlaySound( getKey( "snd_hacked_gdf" ), gdfTeam );
|
|
|
|
thread FireThread( p );
|
|
KillFizzleThread();
|
|
}
|
|
|
|
boolean scud_trigger::TryFire( entity firer ) {
|
|
// set any MCP up to fire
|
|
if ( G_TryFireScud( firer, targetEnt ) ) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void scud_trigger::FireThread( entity firer ) {
|
|
sys.wait( 5.f );
|
|
|
|
if ( !TryFire( firer ) ) {
|
|
objManager.CPrintEvent( sys.localizeString( "game/misc/shield_generator_hacked_reenable" ), gdfTeam );
|
|
objManager.CPrintEvent( sys.localizeString( "game/misc/shield_generator_hacked_attack" ), stroggTeam );
|
|
|
|
while ( true ) {
|
|
if ( TryFire( firer ) ) {
|
|
break;
|
|
}
|
|
sys.wait( 0.2f );
|
|
}
|
|
}
|
|
|
|
objManager.PlaySound( getKey( "snd_launched_strogg" ), stroggTeam );
|
|
objManager.PlaySound( getKey( "snd_launched_gdf" ), gdfTeam );
|
|
}
|
|
|
|
void scud_trigger::FireThreadFake() {
|
|
sys.wait( 5.f );
|
|
|
|
while ( true ) {
|
|
if ( TryFire( $null_entity ) ) {
|
|
break;
|
|
}
|
|
sys.wait( 0.2f );
|
|
}
|
|
|
|
objManager.PlaySound( getKey( "snd_launched_strogg" ), stroggTeam );
|
|
objManager.PlaySound( getKey( "snd_launched_gdf" ), gdfTeam );
|
|
|
|
while ( true ) {
|
|
float count = entitiesOfCollection( "nuke" );
|
|
if ( count > 0 ) {
|
|
trackingScud = getBoundsCacheEntity( 0 );
|
|
break;
|
|
}
|
|
|
|
sys.waitFrame();
|
|
}
|
|
|
|
TrackScud();
|
|
}
|
|
|
|
void scud_trigger::TrackScud() {
|
|
while ( true ) {
|
|
sys.waitFrame();
|
|
|
|
if ( trackingScud == $null_entity ) {
|
|
return;
|
|
}
|
|
|
|
float range = sys.vecLength( trackingScud.getWorldOrigin() - getWorldOrigin() );
|
|
|
|
if ( range > 6144.f ) {
|
|
continue;
|
|
}
|
|
|
|
DestroyTarget( trackingScud );
|
|
|
|
if ( !sys.isClient() ) {
|
|
objManager.PlaySound( getKey( "snd_stopped_strogg" ), stroggTeam );
|
|
objManager.PlaySound( getKey( "snd_stopped_gdf" ), gdfTeam );
|
|
|
|
objManager.OnShieldDestroyedScud( self );
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
void scud_trigger::DestroyTarget( entity targetEnt ) {
|
|
if ( targetEnt.vGetDestroyed() ) {
|
|
return;
|
|
}
|
|
|
|
SpawnDestroyEffect( targetEnt.getWorldOrigin() );
|
|
targetEnt.vSetDestroyed();
|
|
}
|
|
|
|
void scud_trigger::SpawnDestroyEffect( vector position ) {
|
|
vector startPos = owner.getJointPos( owner.getJointHandle( "top_comprezzor_joint" ) ); // start at the roof of the deployable
|
|
vector diff = startPos - position;
|
|
vector forward = '1 0 0';
|
|
diff = sys.vecNormalize( diff );
|
|
vector angles = sys.vecToAngles( diff );
|
|
|
|
// Charge up and cool down effect
|
|
owner.playOriginEffect( "fx_charge", "", startPos, forward, false );
|
|
|
|
// The electrial beam and shockwave
|
|
object effect = owner.spawnClientEffect( "fx_hit" );
|
|
if ( effect != $null_entity ) {
|
|
effect.setEffectLooping( 0 );
|
|
effect.setOrigin( position );
|
|
effect.setEffectEndOrigin( startPos );
|
|
effect.setAngles( angles );
|
|
}
|
|
}
|
|
|
|
void scud_trigger::vSetOwner( entity ent ) {
|
|
owner = ent;
|
|
}
|
|
|
|
void scud_trigger::vSetTargetEntity( entity ent ) {
|
|
targetEnt = ent;
|
|
}
|
|
|
|
void scud_trigger::vStartObjective() {
|
|
thread FireThreadFake();
|
|
}
|
|
|
|
entity scud_trigger::vGetSpectateEntity() {
|
|
float time = sys.getTime();
|
|
if ( lastHackTime >= time - 0.5f ) {
|
|
return hacker;
|
|
}
|
|
return $null_entity;
|
|
}
|
|
|
|
boolean scud_trigger::vIsObjectiveComplete() {
|
|
return hackCount >= maxHackCount;
|
|
}
|
|
|
|
|
|
|
|
object scud_trigger_structure {
|
|
void preinit();
|
|
void syncFields();
|
|
|
|
void vOnDeploy();
|
|
void vSetOwner( entity ent );
|
|
void vSetActive( boolean value );
|
|
|
|
void OnDeadChanged();
|
|
|
|
void BoundsKillThread();
|
|
|
|
void InitEffectThread();
|
|
|
|
string vGetQuickChatString( entity p );
|
|
|
|
scud_trigger triggerEnt;
|
|
entity targetEnt;
|
|
float objectiveIndex;
|
|
|
|
boolean dead;
|
|
|
|
vector effectOffset;
|
|
}
|
|
|
|
void scud_trigger_structure::preinit() {
|
|
effectOffset = getVectorKey( "effect_offset" );
|
|
|
|
thread InitEffectThread();
|
|
|
|
if ( !sys.isClient() ) {
|
|
thread BoundsKillThread();
|
|
}
|
|
}
|
|
|
|
void scud_trigger_structure::syncFields() {
|
|
syncBroadcast( "dead" );
|
|
syncCallback( "dead", "OnDeadChanged" );
|
|
}
|
|
|
|
void scud_trigger_structure::OnDeadChanged() {
|
|
if ( dead ) {
|
|
playAnim( ANIMCHANNEL_ALL, "destroyed" );
|
|
stopEffect( "fx_active" );
|
|
} else {
|
|
playCycle( ANIMCHANNEL_ALL, "idle" );
|
|
playOriginEffect( "fx_active", "", getWorldOrigin() + effectOffset, '1 0 0', true );
|
|
}
|
|
}
|
|
|
|
void scud_trigger_structure::BoundsKillThread() {
|
|
float damageIndex = GetDamage( getKey( "dmg_crush" ) );
|
|
|
|
while ( true ) {
|
|
BoundsDamage( self, damageIndex );
|
|
sys.waitFrame();
|
|
}
|
|
}
|
|
|
|
void scud_trigger_structure::vSetActive( boolean value ) {
|
|
if ( dead == value ) {
|
|
return;
|
|
}
|
|
dead = value;
|
|
|
|
OnDeadChanged();
|
|
}
|
|
|
|
void scud_trigger_structure::vOnDeploy() {
|
|
if ( !sys.isClient() ) {
|
|
triggerEnt = sys.spawn( getKey( "def_trigger" ) );
|
|
triggerEnt.setOrigin( getWorldOrigin() );
|
|
triggerEnt.setAngles( getAngles() );
|
|
triggerEnt.setGameTeam( getGameTeam() );
|
|
triggerEnt.vSetTargetEntity( targetEnt );
|
|
triggerEnt.vSetOwner( self );
|
|
triggerEnt.SetObjectiveIndex( objectiveIndex );
|
|
|
|
objManager.OnShieldDeployed( self, triggerEnt );
|
|
|
|
sys.killThread( "BoundsKillThread_" + getName() );
|
|
}
|
|
|
|
sys.killThread( "InitEffectThread_" + getName() );
|
|
|
|
if ( !dead ) {
|
|
playOriginEffect( "fx_active", "", getWorldOrigin() + effectOffset, '1 0 0', true );
|
|
}
|
|
}
|
|
|
|
void scud_trigger_structure::vSetOwner( entity ent ) {
|
|
targetEnt = ent.getEntityKey( "target" );
|
|
objectiveIndex = ent.getIntKey( "objective_index" );
|
|
}
|
|
|
|
void scud_trigger_structure::InitEffectThread() {
|
|
sys.wait( 5 );
|
|
OnDeadChanged();
|
|
}
|
|
|
|
string scud_trigger_structure::vGetQuickChatString( entity p ) {
|
|
return triggerEnt.vGetQuickChatString( p );
|
|
}
|