cod4-sdk/raw/maps/_zpu.gsc
2008-01-19 00:00:00 +00:00

264 lines
7.1 KiB
Text

#include common_scripts\utility;
#include maps\_utility;
#include maps\_anim;
/* info:
you can have the zpu target multiple triggers, the trigger that has script_noteworthy = "dismount" will
dismount the AI and he will come after the player. the spanwner's count determines howmany times the AI
will spawn into the zpu if you trigger the zpu again assuming the previous AI is dead or dismounted.
zpu: script_model
targetname "zpu"
*/
main( model )
{
// init: get zpu and gunners
zpus = getentarray( "zpu", "targetname" );
allZpuFlags = [];
for ( i = 0; i < zpus.size; i++ )
{
assertEX( isdefined( zpus[ i ].script_flag ), "Each ZPU entity should have a unique script_flag string set on it." );
allZpuFlags[ i ] = zpus[ i ].script_flag;
}
for ( j = 0; j < allZpuFlags.size; j++ )
{
dupeCheckSize = allZpuFlags.size - 1;
for ( k = j; k < dupeCheckSize; k++ )
{
assertEX( allZpuFlags[ j ] != allZpuFlags[ k + 1 ], "Duplicate script_flag on different ZPUs found. Make them unique." );
waittillframeend;
}
}
// load anims
load_zpu_anims();
load_zpugunner_anims();
array_thread( zpus, ::per_zpu_init );
level.zpu_fx = loadfx( "muzzleflashes/zpu_flash_wv" );
}
per_zpu_init()
{
self endon( "death" );
zpu_targets = getentarray( self.target, "targetname" );
zpu_triggers = [];
// Player cancels further respawns by hitting a trigger placed by the designer such that the player won't see the guy spawn.
// The trigger sets the cancellation flag unique to that ZPU.
assertEX( isdefined( self.script_flag ), "Each ZPU entity should have a unique script_flag string set on it." );
flag_init( self.script_flag );
zpu_gunner_spawner = undefined;
zpu_dismount_trig = undefined;
for ( j = 0; j < zpu_targets.size; j++ )
{
zpu_target = zpu_targets[ j ];
if ( issubstr( zpu_target.classname, "actor" ) )
{
zpu_gunner_spawner = zpu_target;
}
else
if ( isdefined( zpu_target.script_noteworthy ) && zpu_target.script_noteworthy == "dismount" )
{
zpu_dismount_trig = zpu_target;
}
else
if ( isdefined( zpu_target.script_noteworthy ) && zpu_target.script_noteworthy == "kill_zpu_spawner" )
{
zpu_cancel_trig = zpu_target;
zpu_cancel_trig thread zpu_cancel( self.script_flag );
}
else
{
zpu_triggers[ zpu_triggers.size ] = zpu_target;
}
}
waittill_trigger_array( zpu_triggers );
while ( 1 )
{
if ( zpu_gunner_spawner.count > 0 )
{
zpu_gunner = zpu_gunner_spawner spawn_gunner();
zpu_gunner linkto( self, "tag_driver", ( 0, 0, 0 ), ( 0, 0, 0 ) );
// call animation
zpu_gunner thread zpugunner_animation_think( self );
zpu_gunner thread monitor_gunner( self );
zpu_gunner thread gunner_death_think( self );
// either dismount of AI or death of AI will restart this loop
if ( isdefined( zpu_dismount_trig ) )
{
waittill_death_or_dismount( zpu_dismount_trig, zpu_gunner, self );
// Simulate theoretical time for reinforcements to reoccupy the ZPU and start firing it again
// Keeping the ZPU active and firing by an AI as long as the player has not hit the 'too close' trigger
zpu_recycle( self.script_flag );
if ( flag( self.script_flag ) )
break;
else
zpu_gunner_spawner.count = 1;
}
}
else
break;
}
}
zpu_cancel( flag )
{
self waittill( "trigger" );
flag_set( flag );
level notify( flag );
}
zpu_recycle( flag )
{
level endon( flag );
wait 20; // recycle time before respawning unless stopped by player hitting the cancel trigger
}
waittill_death_or_dismount( trig, gunner, zpu )
{
gunner endon( "death" );
gunner endon( "damage" );
trig add_wait( ::waittill_msg, "trigger" );
gunner add_wait( ::waittill_msg, "doFlashBanged" );
gunner add_endon( "death" );
do_wait_any();
zpu waittillmatch( "looping anim", "end" );
zpu notify( "stop_looping" );
gunner thread zpugunner_dismount( zpu );
}
monitor_gunner( zpu )
{
self waittill( "death" );
zpu setanim( level.scr_anim[ zpu.animName ][ "fire_loop" ][ 0 ], 1, 1, 0 );
zpu setanim( level.scr_anim[ zpu.animName ][ "fire_loop" ][ 1 ], 1, 1, 0 );
}
gunner_death_think( zpu )
{
self.health = 5000;
self endon( "dismount" );
self waittill( "damage" );
if ( !isdefined( self ) )
return;
self notify( "dying_damage" );
self.a.nodeath = true;
self.deathAnim = level.scr_anim[ "zpu_gunner" ][ "deathslouch" ];
zpu thread anim_single_solo( self, "deathslouch", "tag_driver" );
wait( 0.5 );
self die();
}
spawn_gunner()
{
spawn = self maps\_utility::spawn_ai();
if ( spawn_failed( spawn ) )
{
assertex( 0, "spawn failed from zpu" );
return;
}
spawn endon( "death" );
spawn.allowDeath = true;
return spawn;
}
// if any trigger is activated in a trigger array
waittill_trigger_array( triggers )
{
for ( k = 1; k < triggers.size; k++ )
triggers[ k ] endon( "trigger" );
triggers[ 0 ] waittill( "trigger" );
}
#using_animtree( "zpu" );
load_zpu_anims()
{
level.scr_animtree[ "zpu_gun" ] = #animtree;
level.scr_anim[ "zpu_gun" ][ "fire_loop" ][ 0 ] = %zpu_gun_fire_a;
level.scr_anim[ "zpu_gun" ][ "fire_loop" ][ 1 ] = %zpu_gun_fire_b;
addNotetrack_sound( "zpu_gun", "fire_1", "fire_loop", "zpu_fire1" );
addNotetrack_sound( "zpu_gun", "fire_2", "fire_loop", "zpu_fire2" );
addNotetrack_customFunction( "zpu_gun", "fire_1", ::zpu_shoot1 );
addNotetrack_customFunction( "zpu_gun", "fire_2", ::zpu_shoot2 );
}
#using_animtree( "generic_human" );
load_zpugunner_anims()
{
level.scr_anim[ "zpu_gunner" ][ "deathslouch" ] = %zpu_gunner_deathslouch;
level.scr_anim[ "zpu_gunner" ][ "deathslouchidle" ] = %zpu_gunner_deathslouchidle;
level.scr_anim[ "zpu_gunner" ][ "dismount" ] = %zpu_gunner_dismount;
level.scr_anim[ "zpu_gunner" ][ "fire_loop" ][ 0 ] = %zpu_gunner_fire_a;
level.scr_anim[ "zpu_gunner" ][ "fire_loop" ][ 1 ] = %zpu_gunner_fire_b;
}
zpu_shoot1( gun )
{
playfxontag( level.zpu_fx, gun, "tag_flash" );
playfxontag( level.zpu_fx, gun, "tag_flash2" );
}
zpu_shoot2( gun )
{
playfxontag( level.zpu_fx, gun, "tag_flash1" );
playfxontag( level.zpu_fx, gun, "tag_flash3" );
}
zpugunner_animation_think( zpu )
{
// initially shooting
self endon( "death" );// idle when dead
self endon( "dismount gunner" );// gunner left
zpu endon( "dismount gunner" );// gunner left
zpu endon( "new gunner" );// new gunner
self.animName = "zpu_gunner";
zpu.animName = "zpu_gun";
zpu assign_animtree();
loopPacket = [];
loopPacket[ loopPacket.size ] = self anim_at_entity( zpu, "tag_driver" );
loopPacket[ loopPacket.size ] = zpu anim_at_self();
zpu thread anim_loop_packet( loopPacket, "fire_loop", "stop_looping" );
}
zpugunner_dismount( zpu )
{
self endon( "death" );
self endon( "dying_damage" );
self.animName = "zpu_gunner";
zpu.animName = "zpu_gun";
zpu assign_animtree();
self thread anim_single_solo( self, "dismount", "tag_driver", undefined, zpu );
wait( 0.8 );
self.health = 100;
self notify( "dismount" );
self.deathAnim = undefined;
self unlink();
}