cod5-sdk/raw/maps/_zombiemode_dogs.gsc
2009-09-18 00:00:00 +00:00

955 lines
21 KiB
Text

#include maps\_utility;
#include common_scripts\utility;
#include maps\_zombiemode_utility;
#include maps\_zombiemode_net;
#include maps\_music;
init()
{
level.enemy_dog_spawns = [];
level.enemy_dog_locations = [];
flag_init( "dog_round" );
flag_clear( "dog_round" );
flag_init( "dog_clips" );
PreCacheRumble( "explosion_generic" );
// this gets rounded down to 40 damage after the dvar 'player_meleeDamageMultiplier' runs its calculation
if ( !IsDefined( level.dogs_enabled ) )
{
return;
}
if ( !level.dogs_enabled )
{
return;
}
if ( GetDvar( "zombie_dog_animset" ) == "" )
{
SetDvar( "zombie_dog_animset", "zombie" );
}
if ( GetDvar( "scr_dog_health_walk_multiplier" ) == "" )
{
SetDvar( "scr_dog_health_walk_multiplier", "4.0" );
}
if ( GetDvar( "scr_dog_run_distance" ) == "" )
{
SetDvar( "scr_dog_run_distance", "500" );
}
level.melee_range_sav = GetDvar( "ai_meleeRange" );
level.melee_height_sav = GetDvar( "ai_meleeWidth" );
level.melee_width_sav = GetDvar( "ai_meleeHeight" );
SetSavedDvar( "dog_MeleeDamage", "100" );
set_zombie_var( "dog_fire_trail_percent", 50 );
level._effect[ "lightning_dog_spawn" ] = Loadfx( "maps/zombie/fx_zombie_dog_lightning_buildup" );
level._effect[ "dog_eye_glow" ] = Loadfx( "maps/zombie/fx_zombie_dog_eyes" );
level._effect[ "dog_gib" ] = Loadfx( "maps/zombie/fx_zombie_dog_explosion" );
level._effect[ "dog_trail_fire" ] = Loadfx( "maps/zombie/fx_zombie_dog_fire_trail" );
level._effect[ "dog_trail_ash" ] = Loadfx( "maps/zombie/fx_zombie_dog_ash_trail" );
level thread dog_clip_monitor();
animscripts\dog_init::initDogAnimations();
// Init dog targets - mainly for testing purposes.
// If you spawn a dog without having a dog round, you'll get SREs on hunted_by.
dog_spawner_init();
if( !isdefined( level.dog_round_track_override ) )
{
level.dog_round_track_override = ::dog_round_tracker;
}
level thread [[level.dog_round_track_override]]();
}
dog_spawner_init()
{
dogs = getEntArray( "zombie_dog_spawner", "script_noteworthy" );
later_dogs = getentarray("later_round_dog_spawners", "script_noteworthy" );
dogs = array_combine( dogs, later_dogs );
for( i = 0; i < dogs.size; i++ )
{
if( maps\_zombiemode_spawner::is_spawner_targeted_by_blocker( dogs[i] ) )
{
dogs[i].locked_spawner = true;
}
}
assert( dogs.size > 0 );
level.dog_health = 100;
array_thread( dogs, ::add_spawn_function, ::dog_init );
level.enemy_dog_spawns = getEntArray( "zombie_spawner_dog_init", "targetname" );
}
dog_round_spawning()
{
level endon( "intermission" );
level.dog_targets = getplayers();
for( i = 0 ; i < level.dog_targets.size; i++ )
{
level.dog_targets[i].hunted_by = 0;
}
assert( level.enemy_dog_spawns.size > 0 );
/#
level endon( "kill_round" );
if ( GetDVarInt( "zombie_cheat" ) == 2 || GetDVarInt( "zombie_cheat" ) >= 4 )
{
return;
}
#/
if( level.intermission )
{
return;
}
level.dog_intermission = true;
level thread dog_round_aftermath();
players = get_players();
array_thread( players, ::play_dog_round );
wait(7);
if( level.dog_round_count < 3 )
{
max = players.size * 6;
}
else
{
max = players.size * 8;
}
/#
if( GetDVar( "force_dogs" ) != "" )
{
max = GetDvarInt( "force_dogs" );
}
#/
level.zombie_total = max;
dog_health_increase();
count = 0;
while( count < max )
{
/* iPrintLnBold(count + "-" + max);*/
num_player_valid = get_number_of_valid_players();
while( get_enemy_count() >= num_player_valid * 2 )
{
wait( 2 );
num_player_valid = get_number_of_valid_players();
}
//update the player array.
players = get_players();
favorite_enemy = get_favorite_enemy();
if ( IsDefined( level.dog_spawn_func ) )
{
spawn_loc = [[level.dog_spawn_func]]( level.enemy_dog_spawns, favorite_enemy );
ai = spawn_zombie( level.enemy_dog_spawns[0] );
if( IsDefined( ai ) )
{
ai.favoriteenemy = favorite_enemy;
spawn_loc thread dog_spawn_fx( ai, spawn_loc );
level.zombie_total--;
count++;
}
}
else
{
// Old method
spawn_point = dog_spawn_sumpf_logic( level.enemy_dog_spawns, favorite_enemy );
ai = spawn_zombie( spawn_point );
if( IsDefined( ai ) )
{
ai.favoriteenemy = favorite_enemy;
spawn_point thread dog_spawn_fx( ai );
level.zombie_total--;
count++;
}
}
waiting_for_next_dog_spawn( count, max );
}
}
waiting_for_next_dog_spawn( count, max )
{
default_wait = 1.5;
if( level.dog_round_count == 1)
{
default_wait = 3;
}
else if( level.dog_round_count == 2)
{
default_wait = 2.5;
}
else if( level.dog_round_count == 3)
{
default_wait = 2;
}
else
{
default_wait = 1.5;
}
default_wait = default_wait - ( count / max );
wait( default_wait );
}
get_number_of_valid_players()
{
players = get_players();
num_player_valid = 0;
for( i = 0 ; i < players.size; i++ )
{
if( is_player_valid( players[i] ) )
num_player_valid += 1;
}
return num_player_valid;
}
dog_round_aftermath()
{
level waittill( "last_dog_down" );
power_up_origin = level.last_dog_origin;
if( IsDefined( power_up_origin ) )
{
//level thread randomize_dog_powerup_drop(power_up_origin);
for ( i = 0; i < level.zombie_powerup_array.size; i++ )
{
if ( level.zombie_powerup_array[i] == "full_ammo" )
{
level.zombie_powerup_index = i;
break;
}
}
play_sound_2D( "bright_sting" );
level.zombie_vars["zombie_drop_item"] = 1;
level.powerup_drop_count = 0;
level thread maps\_zombiemode_powerups::powerup_drop( power_up_origin );
}
wait(2);
clientnotify( "dog_stop" );
wait(6);
level.dog_intermission = false;
//level thread dog_round_aftermath();
}
//
// In Sumpf, the dog spawner targets a struct to spawn from.
// In Factory, there's a single spawner and the struct is passed in as the second argument.
dog_spawn_fx( ai, ent )
{
if ( !IsDefined(ent) )
{
ent = GetStruct( self.target, "targetname" );
}
if ( isdefined( ent ) )
{
// face the enemy
angle = VectorToAngles( ai.favoriteenemy.origin - ent.origin );
angles = ( ai.angles[0], angle[1], ai.angles[2] );
ai ForceTeleport( ent.origin, angles );
Playfx( level._effect["lightning_dog_spawn"], ent.origin );
playsoundatposition( "pre_spawn", ent.origin );
wait( 1.5 );
playsoundatposition( "bolt", ent.origin );
Earthquake( 0.5, 0.75, ent.origin, 1000);
PlayRumbleOnPosition("explosion_generic", ent.origin);
playsoundatposition( "spawn", ent.origin );
}
assertex( IsDefined( ai ), "Ent isn't defined." );
assertex( IsAlive( ai ), "Ent is dead." );
assertex( ai enemy_is_dog(), "Ent isn't a dog;" );
assertex( is_magic_bullet_shield_enabled( ai ), "Ent doesn't have a magic bullet shield." );
ai zombie_setup_attack_properties_dog();
ai stop_magic_bullet_shield();
wait( 0.1 ); // dog should come out running after this wait
ai show();
}
//
// Dog spawning logic for swamp
dog_spawn_sumpf_logic( dog_array, favorite_enemy)
{
assertex( dog_array.size > 0, "Dog Spawner array is empty." );
dog_array = array_randomize( dog_array );
for( i = 0; i < dog_array.size; i++ )
{
if( IsDefined( level.old_dog_spawn ) && level.old_dog_spawn == dog_array[i] )
{
continue;
}
if( DistanceSquared( dog_array[i].origin, favorite_enemy.origin ) > ( 400 * 400 ) && DistanceSquared( dog_array[i].origin, favorite_enemy.origin ) < ( 800 * 800 ) )
{
if(distanceSquared( ( 0, 0, dog_array[i].origin[2] ), ( 0, 0, favorite_enemy.origin[2] ) ) > 100 * 100 )
{
continue;
}
else
{
level.old_dog_spawn = dog_array[i];
return dog_array[i];
}
}
}
return dog_array[0];
}
//
// Dog spawning logic for Factory.
// Makes use of the _zombiemode_zone_manager and specially named structs for each zone to
// indicate dog spawn locations instead of constantly using ents.
//
dog_spawn_factory_logic( dog_array, favorite_enemy)
{
dog_locs = array_randomize( level.enemy_dog_locations );
assertex( dog_locs.size > 0, "Dog Spawner locs array is empty." );
for( i = 0; i < dog_locs.size; i++ )
{
if( IsDefined( level.old_dog_spawn ) && level.old_dog_spawn == dog_locs[i] )
{
continue;
}
dist_squared = DistanceSquared( dog_locs[i].origin, favorite_enemy.origin );
if( dist_squared > ( 400 * 400 ) && dist_squared < ( 1000 * 1000 ) )
{
level.old_dog_spawn = dog_locs[i];
return dog_locs[i];
}
}
return dog_locs[0];
}
get_favorite_enemy()
{
dog_targets = getplayers();
least_hunted = dog_targets[0];
for( i = 0; i < dog_targets.size; i++ )
{
if ( !IsDefined( dog_targets[i].hunted_by ) )
{
dog_targets[i].hunted_by = 0;
}
if( !is_player_valid( dog_targets[i] ) )
{
continue;
}
if( !is_player_valid( least_hunted ) )
{
least_hunted = dog_targets[i];
}
if( dog_targets[i].hunted_by < least_hunted.hunted_by )
{
least_hunted = dog_targets[i];
}
}
least_hunted.hunted_by += 1;
return least_hunted;
}
dog_health_increase()
{
players = getplayers();
if( level.dog_round_count == 1 )
{
level.dog_health = 400;
}
else if( level.dog_round_count == 2 )
{
level.dog_health = 900;
}
else if( level.dog_round_count == 3 )
{
level.dog_health = 1300;
}
else if( level.dog_round_count == 4 )
{
level.dog_health = 1600;
}
if( level.dog_health > 1600 )
{
level.dog_health = 1600;
}
}
dog_round_tracker()
{
level.dog_round_count = 1;
// PI_CHANGE_BEGIN - JMA - making dog rounds random between round 5 thru 7
// NOTE: RandomIntRange returns a random integer r, where min <= r < max
level.next_dog_round = randomintrange( 5, 8 );
// PI_CHANGE_END
sav_func = level.round_spawn_func;
while ( 1 )
{
level waittill ( "between_round_over" );
/#
if( GetDVarInt( "force_dogs" ) > 0 )
{
level.next_dog_round = level.round_number;
}
#/
if ( level.round_number == level.next_dog_round )
{
sav_func = level.round_spawn_func;
dog_round_start();
level.round_spawn_func = ::dog_round_spawning;
level.next_dog_round = level.round_number + randomintrange( 4, 6 );
/#
get_players()[0] iprintln( "Next dog round: " + level.next_dog_round );
#/
}
else if ( flag( "dog_round" ) )
{
dog_round_stop();
level.round_spawn_func = sav_func;
level.dog_round_count += 1;
}
}
}
dog_round_start()
{
flag_set( "dog_round" );
flag_set( "dog_clips" );
play_sound_2D( "dark_sting" );
if(!IsDefined (level.doground_nomusic))
{
level.doground_nomusic = 0;
}
level.doground_nomusic = 1;
level notify( "dog_round_starting" );
clientnotify( "dog_start" );
SetDvar( "ai_meleeRange", "100" );
SetDvar( "ai_meleeWidth", "25" );
SetDvar( "ai_meleeHeight", "20" );
}
dog_round_stop()
{
flag_clear( "dog_round" );
flag_clear( "dog_clips" );
if(!IsDefined (level.doground_nomusic))
{
level.doground_nomusic = 0;
}
level.doground_nomusic = 0;
level notify( "dog_round_ending" );
clientnotify( "dog_stop" );
SetDvar( "ai_meleeRange", level.melee_range_sav );
SetDvar( "ai_meleeWidth", level.melee_width_sav );
SetDvar( "ai_meleeHeight", level.melee_height_sav );
}
play_dog_round()
{
self playlocalsound("dog_round_start");
wait(1);
players = getplayers();
variation_count =5;
playsoundatposition("ann_vox_dog_left", (8330, 592, -160));
playsoundatposition("ann_vox_dog_right", (11793, 1632, -160));
wait(2);
//index = maps\_zombiemode_weapons::get_player_index(players[0]);
//player_index = "plr_" + index + "_";
//num_variants = maps\_zombiemode_spawner::get_number_variants(player_index + "vox_dog_spawn");
wait (1);
//Plays a random start line on one of the characters
random = randomintrange(0,players.size);
level thread add_dog_dialog(players[random]);
//players[i] maps\_zombiemode_spawner::do_player_playdialog ("plr_" + i + "_vox_dog_spawn" + "_" + randomintrange(0, 4));
wait (4.5);
play_sound_2D( "ann_vox_dog_start" );
// setmusicstate("mx_dog_round");
}
add_dog_dialog(player)
{
index = maps\_zombiemode_weapons::get_player_index(player);
player_index = "plr_" + index + "_";
if(!IsDefined (player.vox_dog_spawn))
{
num_variants = maps\_zombiemode_spawner::get_number_variants(player_index + "vox_dog_spawn");
player.vox_dog_spawn = [];
for(i=0;i<num_variants;i++)
{
player.vox_dog_spawn[player.vox_dog_spawn.size] = "vox_dog_spawn_" + i;
}
player.vox_dog_spawn_available = player.vox_dog_spawn;
}
sound_to_play = random(player.vox_dog_spawn_available);
player.vox_dog_spawn_available = array_remove(player.vox_dog_spawn_available,sound_to_play);
if (player.vox_dog_spawn_available.size < 1 )
{
player.vox_dog_spawn_available = player.vox_dog_spawn;
}
player maps\_zombiemode_spawner::do_player_playdialog(player_index, sound_to_play, 0.25);
}
dog_init()
{
self.targetname = "zombie_dog";
self.script_noteworthy = undefined;
self.animname = "zombie_dog";
self.ignoreall = true;
self.allowdeath = true; // allows death during animscripted calls
self.allowpain = false;
self.gib_override = true; // needed to make sure this guy does gibs
self.is_zombie = true; // needed for melee.gsc in the animscripts
self.has_legs = true; // Sumeet - This tells the zombie that he is allowed to stand anymore or not, gibbing can take
// out both legs and then the only allowed stance should be prone.
self.gibbed = false;
self.head_gibbed = false;
animscripts\dog_init::change_anim_set( getdvar( "zombie_dog_animset" ) );
// self.disableArrivals = true;
// self.disableExits = true;
self.grenadeawareness = 0;
self.badplaceawareness = 0;
self.ignoreSuppression = true;
self.suppressionThreshold = 1;
self.noDodgeMove = true;
self.dontShootWhileMoving = true;
self.pathenemylookahead = 0;
self.badplaceawareness = 0;
self.chatInitialized = false;
health_multiplier = 1.0;
if ( GetDvar( "scr_dog_health_walk_multiplier" ) != "" )
{
health_multiplier = GetDvarFloat( "scr_dog_health_walk_multiplier" );
}
self.maxhealth = int( level.dog_health * health_multiplier );
self.health = int( level.dog_health * health_multiplier );
self thread dog_run_think();
self thread dog_stalk_audio();
self thread maps\_zombiemode::round_spawn_failsafe();
self hide();
self thread magic_bullet_shield();
self dog_fx_eye_glow();
self dog_fx_trail();
self thread dog_death();
self disable_pain();
self ClearEnemy();
self ClearGoalVolume();
self.flame_damage_time = 0;
self maps\_zombiemode_spawner::zombie_history( "zombie_dog_spawn_init -> Spawned = " + self.origin );
}
dog_fx_eye_glow()
{
self.fx_dog_eye = Spawn( "script_model", self GetTagOrigin( "J_EyeBall_LE" ) );
assert( IsDefined( self.fx_dog_eye ) );
self.fx_dog_eye.angles = self GetTagAngles( "J_EyeBall_LE" );
self.fx_dog_eye SetModel( "tag_origin" );
self.fx_dog_eye LinkTo( self, "J_EyeBall_LE" );
}
dog_fx_trail()
{
if( randomint( 100 ) > level.zombie_vars["dog_fire_trail_percent"] )
{
self.fx_dog_trail_type = level._effect[ "dog_trail_ash" ];
self.fx_dog_trail_sound = "dog_trail_fire_breath";
}
else
{
//fire dogs will explode during death
self.a.nodeath = true;
self.fx_dog_trail_type = level._effect[ "dog_trail_fire" ];
self.fx_dog_trail_sound = "dog_trail_fire";
}
self.fx_dog_trail = Spawn( "script_model", self GetTagOrigin( "tag_origin" ) );
assert( IsDefined( self.fx_dog_trail ) );
self.fx_dog_trail.angles = self GetTagAngles( "tag_origin" );
self.fx_dog_trail SetModel( "tag_origin" );
self.fx_dog_trail LinkTo( self, "tag_origin" );
}
dog_death()
{
self waittill( "death" );
if( get_enemy_count() == 0 && level.zombie_total == 0 )
{
level.last_dog_origin = self.origin;
level notify( "last_dog_down" );
}
// score
if( IsPlayer( self.attacker ) )
{
self.attacker maps\_zombiemode_score::player_add_points( "death", self.damagemod, self.damagelocation, true );
}
// sound
self stoploopsound();
// fx
assert( IsDefined( self.fx_dog_eye ) );
self.fx_dog_eye delete();
assert( IsDefined( self.fx_dog_trail ) );
self.fx_dog_trail delete();
if ( IsDefined( self.a.nodeath ) )
{
level thread dog_explode_fx( self.origin );
self delete();
}
}
dog_explode_fx( origin )
{
fx = network_safe_spawn( "dog_death_fx", 2, "script_model", origin );
assert( IsDefined( fx ) );
fx SetModel( "tag_origin" );
PlayFxOnTag( level._effect["dog_gib"], fx, "tag_origin" );
fx playsound( "zombie_dog_death" );
wait( 5 );
fx delete();
}
// this is where zombies go into attack mode, and need different attributes set up
zombie_setup_attack_properties_dog()
{
self maps\_zombiemode_spawner::zombie_history( "zombie_setup_attack_properties()" );
self thread dog_behind_audio();
// allows zombie to attack again
self.ignoreall = false;
self.pathEnemyFightDist = 64;
self.meleeAttackDist = 64;
// turn off transition anims
self.disableArrivals = true;
self.disableExits = true;
}
//COLLIN'S Audio Scripts
stop_dog_sound_on_death()
{
self waittill("death");
self stopsounds();
}
dog_behind_audio()
{
self thread stop_dog_sound_on_death();
self endon("death");
self waittill_any( "dog_running", "dog_combat" );
while(1)
{
wait(.25);
players = get_players();
for(i=0;i<players.size;i++)
{
dogAngle = AngleClamp180( vectorToAngles( self.origin - players[i].origin )[1] - players[i].angles[1] );
if(isAlive(players[i]) && !isDefined(players[i].revivetrigger))
{
if ((abs(dogAngle) > 90) && distance2d(self.origin,players[i].origin) > 100)
{
self playsound( "zdog_close" );
}
}
}
}
}
//
// Keeps dog_clips up if there is a dog running around in the level.
dog_clip_monitor()
{
clips_on = false;
level.dog_clips = GetEntArray( "dog_clips", "targetname" );
while (1)
{
for ( i=0; i<level.dog_clips.size; i++ )
{
level.dog_clips[i] trigger_off();
level.dog_clips[i] ConnectPaths();
}
flag_wait( "dog_clips" );
for ( i=0; i<level.dog_clips.size; i++ )
{
level.dog_clips[i] trigger_on();
level.dog_clips[i] DisconnectPaths();
wait_network_frame();
}
dog_is_alive = true;
while ( dog_is_alive || flag( "dog_round" ) )
{
dog_is_alive = false;
dogs = GetEntArray( "zombie_dog", "targetname" );
for ( i=0; i<dogs.size; i++ )
{
if ( IsAlive(dogs[i]) )
{
dog_is_alive = true;
}
}
wait( 1 );
}
flag_clear( "dog_clips" );
wait(1);
}
}
//
// Allows dogs to be spawned independent of the round spawning
special_dog_spawn( spawners, num_to_spawn )
{
dogs = GetAISpeciesArray( "all", "dog" );
if ( IsDefined( dogs ) && dogs.size >= 2 )
{
return false;
}
if ( !IsDefined(num_to_spawn) )
{
num_to_spawn = 1;
}
spawn_point = undefined;
count = 0;
while ( count < num_to_spawn )
{
//update the player array.
players = get_players();
favorite_enemy = get_favorite_enemy();
if ( IsDefined( spawners ) )
{
spawn_point = spawners[ RandomInt(spawners.size) ];
ai = spawn_zombie( spawn_point );
if( IsDefined( ai ) )
{
ai.favoriteenemy = favorite_enemy;
spawn_point thread dog_spawn_fx( ai );
// level.zombie_total--;
count++;
flag_set( "dog_clips" );
}
}
else
{
if ( IsDefined( level.dog_spawn_func ) )
{
spawn_loc = [[level.dog_spawn_func]]( level.enemy_dog_spawns, favorite_enemy );
ai = spawn_zombie( level.enemy_dog_spawns[0] );
if( IsDefined( ai ) )
{
ai.favoriteenemy = favorite_enemy;
spawn_loc thread dog_spawn_fx( ai, spawn_loc );
// level.zombie_total--;
count++;
flag_set( "dog_clips" );
}
}
else
{
// Old method
spawn_point = dog_spawn_sumpf_logic( level.enemy_dog_spawns, favorite_enemy );
ai = spawn_zombie( spawn_point );
if( IsDefined( ai ) )
{
ai.favoriteenemy = favorite_enemy;
spawn_point thread dog_spawn_fx( ai );
// level.zombie_total--;
count++;
flag_set( "dog_clips" );
}
}
}
waiting_for_next_dog_spawn( count, num_to_spawn );
}
return true;
}
dog_run_think()
{
self endon( "death" );
self waittill_any( "dog_running", "dog_combat" );
self playsound( "zdog_close" );
// decrease health
if ( self.health > level.dog_health )
{
self.maxhealth = level.dog_health;
self.health = level.dog_health;
}
// start glowing eyes
assert( IsDefined( self.fx_dog_eye ) );
network_safe_play_fx_on_tag( "dog_fx", 2, level._effect["dog_eye_glow"], self.fx_dog_eye, "tag_origin" );
// start trail
assert( IsDefined( self.fx_dog_trail ) );
network_safe_play_fx_on_tag( "dog_fx", 2, self.fx_dog_trail_type, self.fx_dog_trail, "tag_origin" );
self playloopsound( self.fx_dog_trail_sound );
}
dog_stalk_audio()
{
self endon( "death" );
self endon( "dog_running" );
self endon( "dog_combat" );
while(1)
{
self playsound( "hellhound_stalk", "stalk_vox_done" );
self waittill( "stalk_vox_done" );
wait randomfloatrange(1,4);
}
}