Add assets for zm_ai_pack mod.

This commit is contained in:
JezuzLizard
2024-01-07 18:35:38 -08:00
parent c8972ced8b
commit edbacfed4c
345 changed files with 53950 additions and 0 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,304 @@
// T6 GSC SOURCE
// Generated by https://github.com/xensik/gsc-tool
#include maps\mp\zombies\_zm_zonemgr;
#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\zombies\_zm_net;
#include maps\mp\zombies\_zm_utility;
#include maps\mp\animscripts\zm_utility;
//#include maps\mp\zm_tomb_tank;
#include maps\mp\zombies\_zm_ai_mechz_dev;
#include maps\mp\zombies\_zm_ai_mechz;
#include maps\mp\animscripts\zm_shared;
#include maps\mp\zombies\_zm_spawner;
mechz_in_range_for_jump()
{
if ( !isdefined( self.jump_pos ) )
{
/#
iprintln( "\\nMZ Error: Trying to jump without valid jump_pos\\n" );
#/
self.jump_requested = 0;
return false;
}
dist = distancesquared( self.origin, self.jump_pos.origin );
if ( dist <= 100 )
return true;
return false;
}
mechz_jump_think( spawn_pos )
{
self endon( "death" );
self endon( "stop_jump_think" );
self.closest_jump_point = spawn_pos;
self.goal_pos = self.origin;
self setgoalpos( self.goal_pos );
self thread mechz_jump_stuck_watcher();
while ( true )
{
if ( isdefined( self.jump_requested ) && self.jump_requested )
{
if ( !self mechz_should_jump() )
{
self.jump_requested = 0;
self.jump_pos = undefined;
}
wait 1;
continue;
}
if ( !isdefined( self.ai_state ) || self.ai_state != "find_flesh" )
{
wait 0.05;
continue;
}
if ( isdefined( self.not_interruptable ) && self.not_interruptable )
{
wait 0.05;
continue;
}
/#
if ( isdefined( self.force_behavior ) && self.force_behavior )
{
wait 0.05;
continue;
}
#/
if ( self mechz_should_jump() )
{
self.jump_requested = 1;
self.jump_pos = get_closest_mechz_spawn_pos( self.origin );
if ( !isdefined( self.jump_pos ) )
self.jump_requested = 0;
}
wait 1;
}
}
watch_for_riot_shield_melee()
{
self endon( "new_stuck_watcher" );
self endon( "death" );
while ( true )
{
self waittill( "item_attack" );
/#
if ( getdvarint( #"_id_E7121222" ) > 1 )
println( "\\n\\tMZ: Resetting fail count because of item attack\\n" );
#/
self.fail_count = 0;
}
}
watch_for_valid_melee()
{
self endon( "new_stuck_watcher" );
self endon( "death" );
while ( true )
{
self waittillmatch( "melee_anim", "end" );
if ( isdefined( self.favoriteenemy ) && distancesquared( self.origin, self.favoriteenemy.origin ) < 16384 )
{
/#
if ( getdvarint( #"_id_E7121222" ) > 1 )
println( "\\n\\tMZ: Resetting fail count because of melee\\n" );
#/
self.fail_count = 0;
}
}
}
mechz_jump_stuck_watcher()
{
self notify( "new_stuck_watcher" );
self endon( "death" );
self endon( "new_stuck_watcher" );
self.fail_count = 0;
self thread watch_for_valid_melee();
self thread watch_for_riot_shield_melee();
while ( true )
{
if ( !isdefined( self.goal_pos ) )
{
wait 0.05;
continue;
}
if ( isdefined( self.not_interruptable ) && self.not_interruptable )
{
wait 0.05;
continue;
}
if ( isdefined( self.ai_state ) && self.ai_state != "find_flesh" )
{
wait 0.05;
continue;
}
/#
if ( isdefined( self.force_behavior ) && self.force_behavior )
{
wait 0.05;
continue;
}
#/
if ( !findpath( self.origin, self.goal_pos, self, 0, 0 ) )
{
/#
if ( getdvarint( #"_id_E7121222" ) > 1 )
println( "\\n\\tMZ: Incrementing fail count\\n" );
#/
/#
println( "Mechz could not path to goal_pos " + self.goal_pos );
#/
self.fail_count++;
}
else
{
/#
if ( getdvarint( #"_id_E7121222" ) > 1 )
println( "\\n\\tMZ: Resetting fail count because of good path\\n" );
#/
self.fail_count = 0;
}
wait 1;
}
}
mechz_should_jump()
{
/#
if ( getdvarint( #"_id_E7121222" ) > 1 )
println( "\\n\\tMZ: Checking should jump\\n" );
#/
if ( !isdefined( self.favoriteenemy ) )
{
/#
if ( getdvarint( #"_id_E7121222" ) > 1 )
println( "\\n\\t\\tMZ: Not doing jump because has no enemy\\n" );
#/
return false;
}
dist = distancesquared( self.origin, self.favoriteenemy.origin );
if ( dist >= level.mechz_jump_dist_threshold )
{
/#
if ( getdvarint( #"_id_E7121222" ) > 1 )
println( "\\n\\t\\tMZ: Doing jump because target is too far\\n" );
#/
return true;
}
if ( self.fail_count >= level.mechz_failed_paths_to_jump )
{
/#
if ( getdvarint( #"_id_E7121222" ) > 1 )
println( "\\n\\t\\tMZ: Doing jump because has failed too many pathfind checks\\n" );
#/
return true;
}
return false;
}
mechz_do_jump( wait_for_stationary_tank )
{
self endon( "death" );
self endon( "kill_jump" );
/#
if ( getdvarint( #"_id_E7121222" ) > 0 )
println( "\\nMZ: Doing Jump-Teleport\\n" );
#/
/#
if ( getdvarint( #"_id_E7121222" ) > 1 )
println( "\\nMZ: Jump setting not interruptable\\n" );
#/
self.not_interruptable = 1;
self setfreecameralockonallowed( 0 );
self thread mechz_jump_vo();
self animscripted( self.origin, self.angles, "zm_fly_out" );
self maps\mp\animscripts\zm_shared::donotetracks( "jump_anim" );
self ghost();
self.mechz_hidden = 1;
if ( isdefined( self.m_claw ) )
self.m_claw ghost();
if ( self.fx_field )
self.fx_field_old = self.fx_field;
self thread maps\mp\zombies\_zm_spawner::zombie_eye_glow_stop();
self fx_cleanup();
self animscripted( self.origin, self.angles, "zm_fly_hover" );
wait( level.mechz_jump_delay );
if ( isdefined( wait_for_stationary_tank ) && wait_for_stationary_tank )
level.vh_tank ent_flag_waitopen( "tank_moving" );
self notsolid();
closest_jump_point = get_best_mechz_spawn_pos( 1 );
if ( isdefined( closest_jump_point ) )
self.closest_jump_point = closest_jump_point;
if ( !isdefined( self.closest_jump_point.angles ) )
self.closest_jump_point.angles = ( 0, 0, 0 );
self animscripted( self.closest_jump_point.origin, self.closest_jump_point.angles, "zm_fly_in" );
self solid();
self.mechz_hidden = 0;
self show();
self.fx_field = self.fx_field_old;
self.fx_field_old = undefined;
self setclientfield( "mechz_fx", self.fx_field );
self thread maps\mp\zombies\_zm_spawner::zombie_eye_glow();
if ( isdefined( self.m_claw ) )
self.m_claw show();
self maps\mp\animscripts\zm_shared::donotetracks( "jump_anim" );
self.not_interruptable = 0;
self setfreecameralockonallowed( 1 );
/#
if ( getdvarint( #"_id_E7121222" ) > 1 )
println( "\\nMZ: Jump clearing not interruptable\\n" );
#/
mechz_jump_cleanup();
}
mechz_kill_jump_watcher()
{
self endon( "jump_complete" );
self waittill_either( "death", "kill_jump" );
self mechz_jump_cleanup();
}
mechz_jump_cleanup()
{
self.fx_field = self.fx_field & ~128;
self setclientfield( "mechz_fx", self.fx_field );
self stopanimscripted();
self notify( "jump_complete" );
}

View File

@ -0,0 +1,618 @@
// T6 GSC SOURCE
// Generated by https://github.com/xensik/gsc-tool
#include maps\mp\zombies\_zm_zonemgr;
#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\zombies\_zm_net;
#include maps\mp\zombies\_zm_utility;
#include maps\mp\zm_tomb_utility;
#include maps\mp\animscripts\zm_utility;
//#include maps\mp\zm_tomb_tank;
#include maps\mp\zombies\_zm_ai_mechz_dev;
#include maps\mp\zombies\_zm_ai_mechz;
#include maps\mp\zombies\_zm_ai_mechz_ft;
#include maps\mp\animscripts\zm_shared;
#include maps\mp\zombies\_zm_laststand;
//#include maps\mp\zombies\_zm_weap_riotshield_tomb;
#using_animtree("mechz_claw");
mechz_claw_detach()
{
if ( isdefined( self.m_claw ) )
{
self.m_claw setanim( %ai_zombie_mech_grapple_arm_open_idle, 1, 0.2, 1 );
if ( isdefined( self.m_claw.fx_ent ) )
self.m_claw.fx_ent delete();
self.m_claw unlink();
self.m_claw physicslaunch( self.m_claw.origin, ( 0, 0, -1 ) );
self.m_claw thread mechz_delayed_item_delete();
self.m_claw = undefined;
}
if ( isdefined( self.m_claw_damage_trigger ) )
{
self.m_claw_damage_trigger unlink();
self.m_claw_damage_trigger delete();
self.m_claw_damage_trigger = undefined;
}
}
mechz_claw_release( bopenclaw )
{
self.explosive_dmg_taken_on_grab_start = undefined;
if ( isdefined( self.e_grabbed ) )
{
if ( isplayer( self.e_grabbed ) )
{
self.e_grabbed setclientfieldtoplayer( "mechz_grab", 0 );
self.e_grabbed allowcrouch( 1 );
self.e_grabbed allowprone( 1 );
}
if ( !isdefined( self.e_grabbed._fall_down_anchor ) )
{
trace_start = self.e_grabbed.origin + vectorscale( ( 0, 0, 1 ), 70.0 );
trace_end = self.e_grabbed.origin + vectorscale( ( 0, 0, -1 ), 500.0 );
drop_trace = playerphysicstrace( trace_start, trace_end ) + vectorscale( ( 0, 0, 1 ), 24.0 );
self.e_grabbed unlink();
self.e_grabbed setorigin( drop_trace );
}
self.e_grabbed = undefined;
if ( isdefined( bopenclaw ) && bopenclaw )
self.m_claw setanim( %ai_zombie_mech_grapple_arm_open_idle, 1, 0.2, 1 );
}
}
mechz_claw_shot_pain_reaction()
{
self mechz_interrupt();
self animscripted( self.origin, self.angles, "zm_head_pain" );
self maps\mp\animscripts\zm_shared::donotetracks( "head_pain_anim" );
}
ent_released_from_claw_grab_achievement( e_releaser, e_held_by_mechz )
{
if ( isdefined( e_releaser ) && isdefined( e_held_by_mechz ) && isplayer( e_releaser ) && isplayer( e_held_by_mechz ) )
{
if ( e_releaser == e_held_by_mechz )
e_releaser notify( "mechz_grab_released_self" );
else
e_releaser notify( "mechz_grab_released_friendly" );
}
}
mechz_claw_notetracks()
{
self endon( "death" );
self endon( "kill_claw" );
self waittillmatch( "grapple_anim", "muzzleflash" );
self waittillmatch( "grapple_anim", "end" );
}
mechz_claw_aim( target_pos )
{
self endon( "death" );
self endon( "kill_claw" );
self endon( "claw_complete" );
aim_anim = mechz_get_aim_anim( "zm_grapple", target_pos );
self animscripted( self.origin, self.angles, "zm_grapple_aim_start" );
self thread mechz_claw_notetracks();
self maps\mp\animscripts\zm_shared::donotetracks( "grapple_anim" );
while ( flag( "mechz_launching_claw" ) )
{
self animscripted( self.origin, self.angles, aim_anim );
self maps\mp\animscripts\zm_shared::donotetracks( "grapple_anim" );
self clearanim( %root, 0.0 );
}
}
player_can_be_grabbed()
{
if ( self getstance() == "prone" && ( isdefined( self.is_dtp ) && self.is_dtp ) )
return false;
if ( !is_player_valid( self, 1, 1 ) )
return false;
return true;
}
mechz_claw_explosive_watcher()
{
if ( !isdefined( self.explosive_dmg_taken ) )
self.explosive_dmg_taken = 0;
self.explosive_dmg_taken_on_grab_start = self.explosive_dmg_taken;
}
mechz_unlink_on_laststand( mechz )
{
self endon( "death" );
self endon( "disconnect" );
mechz endon( "death" );
mechz endon( "claw_complete" );
mechz endon( "kill_claw" );
while ( true )
{
if ( isdefined( self ) && self maps\mp\zombies\_zm_laststand::player_is_in_laststand() )
{
mechz thread mechz_claw_release();
return;
}
wait 0.05;
}
}
claw_grapple()
{
self endon( "death" );
self endon( "kill_claw" );
if ( !isdefined( self.favoriteenemy ) )
return;
v_claw_origin = self gettagorigin( "tag_claw" );
v_claw_angles = vectortoangles( self.origin - self.favoriteenemy.origin );
self.fx_field = self.fx_field | 256;
self setclientfield( "mechz_fx", self.fx_field );
self.m_claw setanim( %ai_zombie_mech_grapple_arm_open_idle, 1, 0, 1 );
self.m_claw unlink();
self.m_claw.fx_ent = spawn( "script_model", self.m_claw gettagorigin( "tag_claw" ) );
self.m_claw.fx_ent.angles = self.m_claw gettagangles( "tag_claw" );
self.m_claw.fx_ent setmodel( "tag_origin" );
self.m_claw.fx_ent linkto( self.m_claw, "tag_claw" );
network_safe_play_fx_on_tag( "mech_claw", 1, level._effect["mechz_claw"], self.m_claw.fx_ent, "tag_origin" );
v_enemy_origin = self.favoriteenemy.origin + vectorscale( ( 0, 0, 1 ), 36.0 );
n_dist = distance( v_claw_origin, v_enemy_origin );
n_time = n_dist / 1200;
self playsound( "zmb_ai_mechz_claw_fire" );
self.m_claw moveto( v_enemy_origin, n_time );
self.m_claw thread check_for_claw_move_complete();
self.m_claw playloopsound( "zmb_ai_mechz_claw_loop_out", 0.1 );
self.e_grabbed = undefined;
do
{
a_players = getplayers();
foreach ( player in a_players )
{
if ( !is_player_valid( player, 1, 1 ) || !player player_can_be_grabbed() )
continue;
n_dist_sq = distancesquared( player.origin + vectorscale( ( 0, 0, 1 ), 36.0 ), self.m_claw.origin );
if ( n_dist_sq < 2304 )
{
if ( isdefined( player.hasriotshield ) && player.hasriotshield && player getcurrentweapon() == level.riotshield_name )
{
shield_dmg = level.zombie_vars["riotshield_hit_points"];
//player maps\mp\zombies\_zm_weap_riotshield_tomb::player_damage_shield( shield_dmg - 1, 1 );
wait 1;
//player maps\mp\zombies\_zm_weap_riotshield_tomb::player_damage_shield( 1, 1 );
}
else
{
self.e_grabbed = player;
self.e_grabbed setclientfieldtoplayer( "mechz_grab", 1 );
self.e_grabbed playerlinktodelta( self.m_claw, "tag_attach_player" );
self.e_grabbed setplayerangles( vectortoangles( self.origin - self.e_grabbed.origin ) );
self.e_grabbed playsound( "zmb_ai_mechz_claw_grab" );
self.e_grabbed setstance( "stand" );
self.e_grabbed allowcrouch( 0 );
self.e_grabbed allowprone( 0 );
self.e_grabbed thread mechz_grabbed_played_vo( self );
if ( !flag( "mechz_claw_move_complete" ) )
self.m_claw moveto( self.m_claw.origin, 0.05 );
}
break;
}
}
wait 0.05;
}
while (!flag( "mechz_claw_move_complete" ) && !isdefined( self.e_grabbed ) );
if ( !isdefined( self.e_grabbed ) )
{
a_ai_zombies = get_round_enemy_array();
foreach ( ai_zombie in a_ai_zombies )
{
if ( !isalive( ai_zombie ) || isdefined( ai_zombie.is_giant_robot ) && ai_zombie.is_giant_robot || isdefined( ai_zombie.is_mechz ) && ai_zombie.is_mechz )
continue;
n_dist_sq = distancesquared( ai_zombie.origin + vectorscale( ( 0, 0, 1 ), 36.0 ), self.m_claw.origin );
if ( n_dist_sq < 2304 )
{
self.e_grabbed = ai_zombie;
self.e_grabbed linkto( self.m_claw, "tag_attach_player", ( 0, 0, 0 ) );
self.e_grabbed.mechz_grabbed_by = self;
self.e_grabbed animcustom( ::zombie_grabbed_by_mechz_claw );
break;
}
}
}
self.m_claw clearanim( %root, 0.2 );
self.m_claw setanim( %ai_zombie_mech_grapple_arm_closed_idle, 1, 0.2, 1 );
wait 0.5;
if ( isdefined( self.e_grabbed ) )
n_time = n_dist / 200;
else
n_time = n_dist / 1000;
self mechz_claw_explosive_watcher();
v_claw_origin = self gettagorigin( "tag_claw" );
v_claw_angles = self gettagangles( "tag_claw" );
self.m_claw moveto( v_claw_origin, max( 0.05, n_time ) );
self.m_claw playloopsound( "zmb_ai_mechz_claw_loop_in", 0.1 );
self.m_claw waittill( "movedone" );
v_claw_origin = self gettagorigin( "tag_claw" );
v_claw_angles = self gettagangles( "tag_claw" );
self.m_claw playsound( "zmb_ai_mechz_claw_back" );
self.m_claw stoploopsound( 1 );
if ( maps\mp\zombies\_zm_ai_mechz::sndmechzisnetworksafe( "angry" ) )
self playsound( "zmb_ai_mechz_vox_angry" );
self.m_claw.origin = v_claw_origin;
self.m_claw.angles = v_claw_angles;
self.m_claw clearanim( %root, 0.2 );
self.m_claw linkto( self, "tag_claw", ( 0, 0, 0 ) );
self.m_claw setanim( %ai_zombie_mech_grapple_arm_closed_idle, 1, 0.2, 1 );
self.m_claw.fx_ent delete();
self.m_claw.fx_ent = undefined;
self.fx_field = self.fx_field & ~256;
self setclientfield( "mechz_fx", self.fx_field );
flag_clear( "mechz_launching_claw" );
if ( isdefined( self.e_grabbed ) )
{
if ( !isdefined( self.flamethrower_trigger ) )
self mechz_flamethrower_initial_setup();
if ( isplayer( self.e_grabbed ) && is_player_valid( self.e_grabbed ) )
self.e_grabbed thread mechz_unlink_on_laststand( self );
else if ( isai( self.e_grabbed ) )
self.e_grabbed thread mechz_zombie_flamethrower_gib( self );
self thread check_for_claw_damaged( self.e_grabbed );
self animscripted( self.origin, self.angles, "zm_flamethrower_claw_victim" );
self maps\mp\animscripts\zm_shared::donotetracks( "flamethrower_anim" );
}
flag_clear( "mechz_claw_move_complete" );
}
zombie_grabbed_by_mechz_claw()
{
self endon( "death" );
self setanimstatefromasd( "zm_grabbed_by_mech" );
self.mechz_grabbed_by waittill_any( "death", "claw_complete", "kill_claw" );
}
check_for_claw_damaged( player )
{
player endon( "death" );
player endon( "disconnect" );
self endon( "death" );
self endon( "claw_complete" );
self endon( "kill_claw" );
self thread claw_damaged_mechz_endon_watcher( player );
player thread claw_damaged_player_endon_watcher( self );
self.m_claw setcandamage( 1 );
while ( isdefined( self.e_grabbed ) )
{
self.m_claw waittill( "damage", amount, inflictor, direction, point, type, tagname, modelname, partname, weaponname, idflags );
if ( is_player_valid( inflictor ) )
{
self dodamage( 1, inflictor.origin, inflictor, inflictor, "left_hand", type );
self.m_claw setcandamage( 0 );
self notify( "claw_damaged" );
break;
}
}
}
claw_damaged_mechz_endon_watcher( player )
{
self endon( "claw_damaged" );
player endon( "death" );
player endon( "disconnect" );
self waittill_any( "death", "claw_complete", "kill_claw" );
if ( isdefined( self ) && isdefined( self.m_claw ) )
self.m_claw setcandamage( 0 );
}
claw_damaged_player_endon_watcher( mechz )
{
mechz endon( "claw_damaged" );
mechz endon( "death" );
mechz endon( "claw_complete" );
mechz endon( "kill_claw" );
self waittill_any( "death", "disconnect" );
if ( isdefined( mechz ) && isdefined( mechz.m_claw ) )
mechz.m_claw setcandamage( 0 );
}
check_for_players_mid_grapple()
{
self endon( "movedone" );
while ( true )
{
a_players = getplayers();
foreach ( player in a_players )
{
if ( !is_player_valid( player, 1, 1 ) || !player player_can_be_grabbed() )
continue;
n_dist_sq = distancesquared( player.origin + vectorscale( ( 0, 0, 1 ), 36.0 ), self.origin );
if ( n_dist_sq < 2304 )
{
self moveto( self.origin, 0.05 );
self notify( "movedone" );
return;
}
}
wait 0.05;
}
}
check_for_claw_move_complete()
{
self waittill( "movedone" );
wait 0.05;
flag_set( "mechz_claw_move_complete" );
}
zombie_gib_all()
{
if ( !isdefined( self ) )
return;
if ( isdefined( self.is_mechz ) && self.is_mechz )
return;
a_gib_ref = [];
a_gib_ref[0] = level._zombie_gib_piece_index_all;
self gib( "normal", a_gib_ref );
self ghost();
wait 0.4;
if ( isdefined( self ) )
self self_delete();
}
mechz_zombie_flamethrower_gib( mechz )
{
mechz waittillmatch( "flamethrower_anim", "start_ft" );
if ( isalive( self ) )
{
self thread zombie_gib_all();
self dodamage( self.health, self.origin, self );
}
}
should_do_claw_attack()
{
assert( isdefined( self.favoriteenemy ) );
/#
if ( getdvarint( #"_id_E7121222" ) > 1 )
println( "\\n\\tMZ: Checking should claw\\n" );
#/
if ( !( isdefined( self.has_powerplant ) && self.has_powerplant ) )
{
/#
if ( getdvarint( #"_id_E7121222" ) > 1 )
println( "\\n\\t\\tMZ: Not doing claw because powerplant has been destroyed\\n" );
#/
return false;
}
if ( isdefined( self.disable_complex_behaviors ) && self.disable_complex_behaviors )
{
/#
if ( getdvarint( #"_id_E7121222" ) > 1 )
println( "\\n\\t\\tMZ: Not doing claw because doing force aggro\\n" );
#/
return false;
}
if ( isdefined( self.not_interruptable ) && self.not_interruptable )
{
/#
if ( getdvarint( #"_id_E7121222" ) > 1 )
println( "\\n\\t\\tMZ: Not doing claw because another behavior has set not_interruptable\\n" );
#/
return false;
}
if ( isdefined( self.last_claw_time ) && gettime() - self.last_claw_time < level.mechz_claw_cooldown_time )
{
/#
if ( getdvarint( #"_id_E7121222" ) > 1 )
println( "\\n\\t\\tMZ: Not doing claw because claw is on cooldown\\n" );
#/
return false;
}
if ( !self mechz_check_in_arc() )
{
/#
if ( getdvarint( #"_id_E7121222" ) > 1 )
println( "\\n\\t\\tMZ: Not doing claw because target is not in front arc\\n" );
#/
return false;
}
n_dist_sq = distancesquared( self.origin, self.favoriteenemy.origin );
if ( n_dist_sq < 90000 || n_dist_sq > 1000000 )
{
/#
if ( getdvarint( #"_id_E7121222" ) > 1 )
println( "\\n\\t\\tMZ: Not doing claw because target is not in range\\n" );
#/
return false;
}
if ( !self.favoriteenemy player_can_be_grabbed() )
{
/#
if ( getdvarint( #"_id_E7121222" ) > 1 )
println( "\\n\\t\\tMZ: Not doing claw because player is prone or dtp\\n" );
#/
return false;
}
curr_zone = get_zone_from_position( self.origin + vectorscale( ( 0, 0, 1 ), 36.0 ) );
if ( isdefined( curr_zone ) && "ug_bottom_zone" == curr_zone )
{
/#
if ( getdvarint( #"_id_E7121222" ) > 1 )
println( "\\n\\t\\tMZ: Not doing claw because mech is in main chamber\\n" );
#/
return false;
}
clip_mask = level.physicstracemaskclip | level.physicstracemaskphysics;
claw_origin = self.origin + vectorscale( ( 0, 0, 1 ), 65.0 );
trace = physicstrace( claw_origin, self.favoriteenemy.origin + vectorscale( ( 0, 0, 1 ), 30.0 ), ( -15, -15, -20 ), ( 15, 15, 40 ), self, clip_mask );
b_cansee = trace["fraction"] == 1.0 || isdefined( trace["entity"] ) && trace["entity"] == self.favoriteenemy;
if ( !b_cansee )
{
/#
if ( getdvarint( #"_id_E7121222" ) > 1 )
println( "\\n\\t\\tMZ: Not doing claw because capsule trace failed\\n" );
#/
return false;
}
return true;
}
mechz_do_claw_grab()
{
self endon( "death" );
self endon( "kill_claw" );
/#
if ( getdvarint( #"_id_E7121222" ) > 0 )
println( "\\n\\tMZ: Doing Claw Attack\\n" );
#/
assert( isdefined( self.favoriteenemy ) );
self thread mechz_kill_claw_watcher();
self.last_claw_time = gettime();
target_pos = self.favoriteenemy.origin + vectorscale( ( 0, 0, 1 ), 30.0 );
self thread mechz_stop_basic_find_flesh();
self.ai_state = "grapple_attempt";
flag_set( "mechz_launching_claw" );
self thread mechz_claw_aim( target_pos );
self orientmode( "face enemy" );
self waittillmatch( "grapple_anim", "muzzleflash" );
self claw_grapple();
self mechz_claw_cleanup();
}
mechz_kill_claw_watcher()
{
self endon( "claw_complete" );
self waittill_either( "death", "kill_claw" );
self mechz_claw_cleanup();
}
mechz_claw_cleanup()
{
self.fx_field = self.fx_field & ~256;
self.fx_field = self.fx_field & ~64;
self setclientfield( "mechz_fx", self.fx_field );
self mechz_claw_release();
if ( isdefined( self.m_claw ) )
{
self.m_claw clearanim( %root, 0.2 );
if ( isdefined( self.m_claw.fx_ent ) )
{
self.m_claw.fx_ent delete();
self.m_claw.fx_ent = undefined;
}
if ( !( isdefined( self.has_powerplant ) && self.has_powerplant ) )
{
self mechz_claw_detach();
flag_clear( "mechz_launching_claw" );
}
else
{
if ( !self.m_claw islinkedto( self ) )
{
v_claw_origin = self gettagorigin( "tag_claw" );
v_claw_angles = self gettagangles( "tag_claw" );
n_dist = distance( self.m_claw.origin, v_claw_origin );
n_time = n_dist / 1000;
self.m_claw moveto( v_claw_origin, max( 0.05, n_time ) );
self.m_claw playloopsound( "zmb_ai_mechz_claw_loop_in", 0.1 );
self.m_claw waittill( "movedone" );
v_claw_origin = self gettagorigin( "tag_claw" );
v_claw_angles = self gettagangles( "tag_claw" );
self.m_claw playsound( "zmb_ai_mechz_claw_back" );
self.m_claw stoploopsound( 1 );
self.m_claw.origin = v_claw_origin;
self.m_claw.angles = v_claw_angles;
self.m_claw clearanim( %root, 0.2 );
self.m_claw linkto( self, "tag_claw", ( 0, 0, 0 ) );
}
self.m_claw setanim( %ai_zombie_mech_grapple_arm_closed_idle, 1, 0.2, 1 );
}
}
self notify( "claw_complete" );
}
mechz_claw_damage_trigger_thread()
{
self endon( "death" );
self.m_claw_damage_trigger endon( "death" );
while ( true )
{
self.m_claw_damage_trigger waittill( "damage", amount, inflictor, direction, point, type, tagname, modelname, partname, weaponname, idflags );
if ( self.m_claw islinkedto( self ) )
continue;
if ( is_player_valid( inflictor ) )
{
self dodamage( 1, inflictor.origin, inflictor, inflictor, "left_hand", type );
self.m_claw setcandamage( 0 );
self notify( "claw_damaged" );
}
}
}

View File

@ -0,0 +1,505 @@
// T6 GSC SOURCE
// Generated by https://github.com/xensik/gsc-tool
#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\zombies\_zm_utility;
#include maps\mp\zombies\_zm_net;
#include maps\mp\animscripts\zm_utility;
#include maps\mp\zombies\_zm_ai_mechz;
#include maps\mp\animscripts\zm_shared;
mechz_debug()
{
/#
while ( true )
{
debug_level = getdvarint( #"_id_E7121222" );
if ( isdefined( debug_level ) && debug_level )
{
if ( debug_level == 1 )
{
mechz_array = getentarray( "mechz_zombie_ai" );
for ( i = 0; i < mechz_array.size; i++ )
{
if ( isdefined( mechz_array[i].goal_pos ) )
{
debugstar( mechz_array[i].goal_pos, ( 1, 0, 0 ), 1 );
line( mechz_array[i].goal_pos, mechz_array[i].origin, ( 1, 0, 0 ), 0, 1 );
}
}
}
}
}
#/
}
setup_devgui()
{
/#
setdvar( "spawn_Mechz", "off" );
setdvar( "force_mechz_jump", "off" );
setdvar( "test_mechz_tank", "off" );
setdvar( "test_mechz_robot", "off" );
setdvar( "reset_mechz_thinking", "off" );
setdvar( "test_mechz_sprint", "off" );
setdvar( "mechz_force_behavior", "none" );
setdvarint( "mechz_behavior_orient", 0 );
setdvarint( "mechz_behavior_dist", 300 );
adddebugcommand( "devgui_cmd \"Zombies/Zombie Spawning:2/Spawn Zombie:1/Mech Zombie:1\" \"spawn_Mechz on\"\n" );
adddebugcommand( "devgui_cmd \"Zombies/MechZ:3/Force Behavior:1/Jump In:1\" \"mechz_force_behavior jump_in\"\n" );
adddebugcommand( "devgui_cmd \"Zombies/MechZ:3/Force Behavior:1/Jump Out:2\" \"mechz_force_behavior jump_out\"\n" );
adddebugcommand( "devgui_cmd \"Zombies/MechZ:3/Force Behavior:1/Flamethrower:3\" \"mechz_force_behavior flamethrower\"\n" );
adddebugcommand( "devgui_cmd \"Zombies/MechZ:3/Force Behavior:1/Damage Armor:4\" \"mechz_force_behavior damage_armor\"\n" );
adddebugcommand( "devgui_cmd \"Zombies/MechZ:3/Force Behavior:1/Damage Faceplate:5\" \"mechz_force_behavior damage_faceplate\"\n" );
adddebugcommand( "devgui_cmd \"Zombies/MechZ:3/Force Behavior:1/Claw Attack:5\" \"mechz_force_behavior claw_attack\"\n" );
adddebugcommand( "devgui_cmd \"Zombies/MechZ:3/Force Behavior:1/Melee:6\" \"mechz_force_behavior melee\"\n" );
adddebugcommand( "devgui_cmd \"Zombies/MechZ:3/Force Behavior:1/Angles:7/zero degrees:1\" \"mechz_behavior_orient 0\"\n" );
adddebugcommand( "devgui_cmd \"Zombies/MechZ:3/Force Behavior:1/Angles:7/forty-five degrees:2\" \"mechz_behavior_orient 45\"\n" );
adddebugcommand( "devgui_cmd \"Zombies/MechZ:3/Force Behavior:1/Angles:7/ninety degrees:3\" \"mechz_behavior_orient 90\"\n" );
adddebugcommand( "devgui_cmd \"Zombies/MechZ:3/Force Behavior:1/Angles:7/one thirty five degrees:4\" \"mechz_behavior_orient 135\"\n" );
adddebugcommand( "devgui_cmd \"Zombies/MechZ:3/Force Behavior:1/Angles:7/one eighty degrees:5\" \"mechz_behavior_orient 180\"\n" );
adddebugcommand( "devgui_cmd \"Zombies/MechZ:3/Force Behavior:1/Angles:7/two twenty five degrees:6\" \"mechz_behavior_orient 225\"\n" );
adddebugcommand( "devgui_cmd \"Zombies/MechZ:3/Force Behavior:1/Angles:7/two seventy degrees:7\" \"mechz_behavior_orient 270\"\n" );
adddebugcommand( "devgui_cmd \"Zombies/MechZ:3/Force Behavior:1/Angles:7/three fifteen degrees:8\" \"mechz_behavior_orient 315\"\n" );
adddebugcommand( "devgui_cmd \"Zombies/MechZ:3/Force Behavior:1/Distance:8/one hundred:1\" \"mechz_behavior_dist 100\"\n" );
adddebugcommand( "devgui_cmd \"Zombies/MechZ:3/Force Behavior:1/Distance:8/two hundred:2\" \"mechz_behavior_dist 200\"\n" );
adddebugcommand( "devgui_cmd \"Zombies/MechZ:3/Force Behavior:1/Distance:8/three hundred:3\" \"mechz_behavior_dist 300\"\n" );
adddebugcommand( "devgui_cmd \"Zombies/MechZ:3/Force Behavior:1/Distance:8/four hundred:4\" \"mechz_behavior_dist 400\"\n" );
adddebugcommand( "devgui_cmd \"Zombies/MechZ:3/Force Behavior:1/Distance:8/five hundred:5\" \"mechz_behavior_dist 500\"\n" );
adddebugcommand( "devgui_cmd \"Zombies/MechZ:3/Test Tank Knockdown:2\" \"test_mechz_tank on\"\n" );
adddebugcommand( "devgui_cmd \"Zombies/MechZ:3/Test Robot Knockdown:3\" \"test_mechz_robot on\"\n" );
adddebugcommand( "devgui_cmd \"Zombies/MechZ:3/Test Sprint:4\" \"test_mechz_sprint on\"\n" );
adddebugcommand( "devgui_cmd \"Zombies/MechZ:3/Reset Mech:5\" \"reset_mechz_thinking on\"\n" );
level thread watch_devgui_mechz();
#/
}
watch_devgui_mechz()
{
/#
while ( true )
{
if ( getdvar( #"_id_877D2B64" ) == "on" )
{
mechz_health_increases();
level.mechz_left_to_spawn = 1;
if ( getdvarint( #"_id_FA81816F" ) >= 2 )
level.round_number++;
level notify( "spawn_mechz" );
setdvar( "spawn_Mechz", "off" );
level.mechz_last_spawn_round = 0;
}
if ( getdvar( #"_id_7D9211F9" ) != "none" )
{
behavior = getdvar( #"_id_7D9211F9" );
zombies = getaiarray( "axis" );
for ( i = 0; i < zombies.size; i++ )
{
if ( isdefined( zombies[i].is_mechz ) && zombies[i].is_mechz )
zombies[i] thread mechz_force_behavior( behavior );
}
setdvar( "mechz_force_behavior", "none" );
}
if ( getdvar( #"_id_BD7CA008" ) == "on" )
{
setdvar( "test_mechz_tank", "off" );
mechz = undefined;
zombies = getaiarray( "axis" );
for ( i = 0; i < zombies.size; i++ )
{
if ( isdefined( zombies[i].is_mechz ) && zombies[i].is_mechz )
mechz = zombies[i];
}
if ( !isdefined( mechz ) )
continue;
mechz.not_interruptable = 1;
mechz mechz_stop_basic_find_flesh();
mechz.ai_state = "devgui";
mechz.goal_pos = ( 446, -4318, 200 );
mechz setgoalpos( mechz.goal_pos );
}
if ( getdvar( #"_id_6CF3EB40" ) == "on" )
{
setdvar( "test_mechz_robot", "off" );
mechz = undefined;
zombies = getaiarray( "axis" );
for ( i = 0; i < zombies.size; i++ )
{
if ( isdefined( zombies[i].is_mechz ) && zombies[i].is_mechz )
mechz = zombies[i];
}
if ( !isdefined( mechz ) )
continue;
mechz.not_interruptable = 1;
mechz mechz_stop_basic_find_flesh();
mechz.ai_state = "devgui";
mechz.goal_pos = ( 1657, -336, 92 );
mechz setgoalpos( mechz.goal_pos );
}
if ( getdvar( #"_id_0DE1409A" ) == "on" )
{
setdvar( "test_mechz_sprint", "off" );
zombies = getaiarray( "axis" );
for ( i = 0; i < zombies.size; i++ )
{
if ( isdefined( zombies[i].is_mechz ) && zombies[i].is_mechz )
zombies[i].force_sprint = 1;
}
}
if ( getdvar( #"_id_772BCD39" ) == "on" )
{
setdvar( "reset_mechz_thinking", "off" );
zombies = getaiarray( "axis" );
for ( i = 0; i < zombies.size; i++ )
{
if ( isdefined( zombies[i].is_mechz ) && zombies[i].is_mechz )
{
zombies[i].not_interruptable = 0;
zombies[i].force_sprint = 0;
}
}
}
wait 0.1;
}
#/
}
mechz_force_behavior( behavior )
{
/#
self notify( "kill_force_behavior" );
self thread mechz_stop_basic_find_flesh();
self.ignoreall = 1;
self.force_behavior = 1;
if ( behavior == "jump_in" )
self thread mechz_force_jump_in();
if ( behavior == "jump_out" )
self thread mechz_force_jump_out();
if ( behavior == "flamethrower" )
self thread mechz_force_flamethrower();
if ( behavior == "claw_attack" )
self thread mechz_force_claw_attack();
if ( behavior == "damage_armor" )
self thread mechz_force_damage_armor();
if ( behavior == "damage_faceplate" )
self thread mechz_force_damage_faceplate();
if ( behavior == "melee" )
self thread mechz_force_melee();
if ( behavior == "none" )
{
self.ignoreall = 0;
self.force_behavior = 0;
self notify( "kill_force_behavior" );
}
#/
}
get_behavior_orient()
{
/#
behavior_orient = getdvarint( #"_id_2F660A7B" );
return level.players[0].angles + vectorscale( ( 0, 1, 0 ), 180.0 ) + ( 0, behavior_orient, 0 );
#/
}
setup_force_behavior()
{
/#
if ( !isdefined( level.test_align_struct ) )
{
player = get_players()[0];
pos = player.origin;
offset = anglestoforward( player.angles );
offset = vectornormalize( offset );
level.test_align_struct = spawn( "script_model", pos + 300 * offset );
level.test_align_struct setmodel( "tag_origin" );
level.test_align_struct.angles = player.angles + vectorscale( ( 0, 1, 0 ), 180.0 );
level.test_align_struct thread align_test_struct();
level.test_align_struct.angles = player.angles + vectorscale( ( 0, 1, 0 ), 180.0 );
}
self linkto( level.test_align_struct, "tag_origin", ( 0, 0, 0 ), ( 0, 0, 0 ) );
self.fx_field = self.fx_field & ~64;
self.fx_field = self.fx_field & ~128;
self.fx_field = self.fx_field & ~256;
#/
}
align_test_struct()
{
/#
while ( true )
{
pos = level.players[0].origin;
offset = anglestoforward( level.players[0].angles );
offset = vectornormalize( offset );
dist = getdvarint( #"_id_6DCD047E" );
level.test_align_struct.origin = pos + dist * offset;
level.test_align_struct.angles = get_behavior_orient();
wait 0.05;
}
#/
}
scripted_behavior( anim_scripted_name, notify_name )
{
/#
self animscripted( level.test_align_struct.origin, level.test_align_struct.angles, anim_scripted_name );
self maps\mp\animscripts\zm_shared::donotetracks( notify_name );
#/
}
mechz_force_jump_in()
{
/#
self endon( "kill_force_behavior" );
self setup_force_behavior();
while ( true )
{
self animscripted( self.origin, self.angles, "zm_idle" );
wait 0.2;
self scripted_behavior( "zm_spawn", "jump_anim" );
}
#/
}
mechz_force_jump_out()
{
/#
self endon( "kill_force_behavior" );
self setup_force_behavior();
while ( true )
{
self animscripted( self.origin, self.angles, "zm_idle" );
wait 0.2;
self scripted_behavior( "zm_fly_out", "jump_anim" );
self ghost();
self animscripted( self.origin, self.angles, "zm_fly_hover" );
wait( level.mechz_jump_delay );
self show();
self scripted_behavior( "zm_fly_in", "jump_anim" );
}
#/
}
#using_animtree("mechz_claw");
mechz_force_flamethrower()
{
/#
self endon( "kill_force_behavior" );
self setup_force_behavior();
curr_aim_anim = 1;
curr_timer = 0;
self animscripted( self.origin, self.angles, "zm_idle" );
wait 0.2;
self scripted_behavior( "zm_flamethrower_aim_start", "flamethrower_anim" );
while ( true )
{
if ( curr_timer > 3 )
{
curr_aim_anim++;
curr_timer = 0;
if ( curr_aim_anim < 10 )
iprintln( "Testing aim_" + curr_aim_anim );
}
if ( curr_aim_anim >= 10 )
{
iprintln( "Testing flamethrower sweep" );
curr_aim_anim = 1;
self scripted_behavior( "zm_flamethrower_sweep", "flamethrower_anim" );
self.fx_field = self.fx_field | 64;
self setclientfield( "mechz_fx", self.fx_field );
}
else
{
length = self getanimlengthfromasd( "zm_flamethrower_aim_" + curr_aim_anim, 0 );
self clearanim( %root, 0 );
self scripted_behavior( "zm_flamethrower_aim_" + curr_aim_anim, "flamethrower_anim" );
curr_timer = curr_timer + length;
}
}
#/
}
fake_launch_claw()
{
/#
self.launching_claw = 1;
v_claw_origin = self gettagorigin( "tag_claw" );
v_claw_angles = vectortoangles( self.origin - level.players[0].origin );
self.fx_field = self.fx_field | 256;
self setclientfield( "mechz_fx", self.fx_field );
self.m_claw setanim( %ai_zombie_mech_grapple_arm_open_idle, 1, 0, 1 );
self.m_claw unlink();
self.m_claw.fx_ent = spawn( "script_model", self.m_claw gettagorigin( "tag_claw" ) );
self.m_claw.fx_ent.angles = self.m_claw gettagangles( "tag_claw" );
self.m_claw.fx_ent setmodel( "tag_origin" );
self.m_claw.fx_ent linkto( self.m_claw, "tag_claw" );
network_safe_play_fx_on_tag( "mech_claw", 1, level._effect["mechz_claw"], self.m_claw.fx_ent, "tag_origin" );
self.m_claw clearanim( %root, 0.2 );
self.m_claw setanim( %ai_zombie_mech_grapple_arm_open_idle, 1, 0.2, 1 );
offset = anglestoforward( self.angles );
offset = vectornormalize( offset );
target_pos = self.origin + offset * 500 + vectorscale( ( 0, 0, 1 ), 36.0 );
n_time = 0.0833333;
self.m_claw moveto( target_pos, n_time );
self.m_claw waittill( "movedone" );
self.m_claw clearanim( %root, 0.2 );
self.m_claw setanim( %ai_zombie_mech_grapple_arm_closed_idle, 1, 0.2, 1 );
wait 0.5;
self.m_claw moveto( v_claw_origin, 0.5 );
self.m_claw waittill( "movedone" );
self.m_claw.fx_ent delete();
self.fx_field = self.fx_field & ~256;
self setclientfield( "mechz_fx", self.fx_field );
v_claw_origin = self gettagorigin( "tag_claw" );
v_claw_angles = self gettagangles( "tag_claw" );
self.m_claw.origin = v_claw_origin;
self.m_claw.angles = v_claw_angles;
self.m_claw linkto( self, "tag_claw" );
self.launching_claw = 0;
#/
}
mechz_force_claw_attack()
{
/#
self endon( "kill_force_behavior" );
self setup_force_behavior();
while ( true )
{
self animscripted( self.origin, self.angles, "zm_idle" );
wait 0.2;
self scripted_behavior( "zm_grapple_aim_start", "grapple_anim" );
self thread fake_launch_claw();
while ( isdefined( self.launching_claw ) && self.launching_claw )
{
self clearanim( %root, 0 );
wait 0.05;
self scripted_behavior( "zm_grapple_aim_5", "grapple_anim" );
}
self scripted_behavior( "zm_flamethrower_claw_victim", "flamethrower_anim" );
}
#/
}
mechz_force_damage_armor()
{
/#
self endon( "kill_force_behavior" );
self setup_force_behavior();
if ( !isdefined( self.next_armor_piece ) )
self.next_armor_piece = 0;
self thread scripted_behavior( "zm_idle", "idle_anim" );
if ( self.next_armor_piece == self.armor_state.size )
{
self.next_armor_piece = 0;
for ( i = 0; i < self.armor_state.size; i++ )
{
self.fx_field = self.fx_field & ~( 1 << self.armor_state[i].index );
if ( isdefined( self.armor_state[i].model ) )
self attach( self.armor_state[i].model, self.armor_state[i].tag );
}
}
else
{
self.fx_field = self.fx_field | 1 << self.armor_state[self.next_armor_piece].index;
if ( isdefined( self.armor_state[self.next_armor_piece].model ) )
self detach( self.armor_state[self.next_armor_piece].model, self.armor_state[self.next_armor_piece].tag );
self.next_armor_piece++;
}
self setclientfield( "mechz_fx", self.fx_field );
while ( true )
self scripted_behavior( "zm_idle", "idle_anim" );
#/
}
mechz_force_damage_faceplate()
{
/#
self endon( "kill_force_behavior" );
self setup_force_behavior();
self thread scripted_behavior( "zm_idle", "idle_anim" );
if ( isdefined( self.has_helmet ) && self.has_helmet )
{
self.has_helmet = 0;
self detach( "c_zom_mech_faceplate", "J_Helmet" );
self.fx_field = self.fx_field | 1024;
self.fx_field = self.fx_field & ~2048;
}
else
{
self.has_helmet = 1;
self.fx_field = self.fx_field & ~1024;
self.fx_field = self.fx_field | 2048;
self attach( "c_zom_mech_faceplate", "J_Helmet" );
}
self setclientfield( "mechz_fx", self.fx_field );
while ( true )
self scripted_behavior( "zm_idle", "idle_anim" );
#/
}
mechz_force_melee()
{
/#
self endon( "kill_force_behavior" );
self setup_force_behavior();
while ( true )
{
self animscripted( self.origin, self.angles, "zm_idle" );
wait 0.2;
self scripted_behavior( "zm_melee_stand", "melee_anim" );
}
#/
}

View File

@ -0,0 +1,40 @@
// T6 GSC SOURCE
// Generated by https://github.com/xensik/gsc-tool
#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\zombies\_zm_utility;
mechz_init_start()
{
}
mechz_init_end()
{
}
spawn_start()
{
self.not_interruptable = 1;
}
spawn_end()
{
self.not_interruptable = 0;
}
mechz_round_tracker_start()
{
}
mechz_round_tracker_loop_start()
{
}
mechz_round_tracker_loop_end()
{
}

View File

@ -0,0 +1,548 @@
// T6 GSC SOURCE
// Generated by https://github.com/xensik/gsc-tool
#include maps\mp\zombies\_zm_zonemgr;
#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\zombies\_zm_net;
#include maps\mp\zombies\_zm_utility;
#include maps\mp\animscripts\zm_utility;
//#include maps\mp\zm_tomb_tank;
#include maps\mp\zombies\_zm_ai_mechz_dev;
#include maps\mp\zombies\_zm_ai_mechz;
#include maps\mp\animscripts\zm_shared;
#include maps\mp\_visionset_mgr;
init_flamethrower_triggers()
{
flag_wait( "initial_players_connected" );
level.flamethrower_trigger_array = getentarray( "flamethrower_trigger", "script_noteworthy" );
assert( isdefined( level.flamethrower_trigger_array ) && level.flamethrower_trigger_array.size >= 4 );
for ( i = 0; i < level.flamethrower_trigger_array.size; i++ )
level.flamethrower_trigger_array[i] enablelinkto();
}
mechz_flamethrower_initial_setup()
{
self endon( "death" );
if ( isdefined( self.flamethrower_trigger ) )
self release_flamethrower_trigger();
self.flamethrower_trigger = get_flamethrower_trigger();
if ( !isdefined( self.flamethrower_trigger ) )
{
/#
println( "Error: No free flamethrower triggers! Make sure you haven't spawned more than 4 mech zombies" );
#/
return;
}
self.flamethrower_trigger.origin = self gettagorigin( "tag_flamethrower_FX" );
self.flamethrower_trigger.angles = self gettagangles( "tag_flamethrower_FX" );
self.flamethrower_trigger linkto( self, "tag_flamethrower_FX" );
self thread mechz_watch_for_flamethrower_damage();
}
get_flamethrower_trigger()
{
for ( i = 0; i < level.flamethrower_trigger_array.size; i++ )
{
if ( !( isdefined( level.flamethrower_trigger_array[i].in_use ) && level.flamethrower_trigger_array[i].in_use ) )
{
level.flamethrower_trigger_array[i].in_use = 1;
level.flamethrower_trigger_array[i].original_position = level.flamethrower_trigger_array[i].origin;
return level.flamethrower_trigger_array[i];
}
}
return undefined;
}
release_flamethrower_trigger()
{
if ( !isdefined( self.flamethrower_trigger ) )
return;
self.flamethrower_trigger.in_use = 0;
self.flamethrower_trigger unlink();
self.flamethrower_trigger.origin = self.flamethrower_trigger.original_position;
self.flamethrower_linked = 0;
self.flamethrower_trigger = undefined;
}
mechz_flamethrower_dist_watcher()
{
self endon( "kill_ft" );
wait 0.5;
while ( true )
{
if ( !isdefined( self.favoriteenemy ) || !is_player_valid( self.favoriteenemy, 1, 1 ) || distancesquared( self.origin, self.favoriteenemy.origin ) > 50000 )
{
self notify( "stop_ft" );
return;
}
wait 0.05;
}
}
mechz_flamethrower_arc_watcher()
{
self endon( "death" );
self endon( "kill_ft" );
self endon( "stop_ft" );
aim_anim = undefined;
while ( true )
{
old_anim = aim_anim;
aim_anim = mechz_get_aim_anim( "zm_flamethrower", self.favoriteenemy.origin, 26 );
self.curr_aim_anim = aim_anim;
if ( !isdefined( aim_anim ) )
{
self notify( "stop_ft" );
return;
}
if ( !isdefined( old_anim ) || old_anim != aim_anim )
self notify( "arc_change" );
wait 0.05;
}
}
mechz_play_flamethrower_aim()
{
self endon( "death" );
self endon( "kill_ft" );
self endon( "stop_ft" );
self endon( "arc_change" );
if ( isdefined( self.curr_aim_anim ) )
{
self stopanimscripted();
self animscripted( self.origin, self.angles, self.curr_aim_anim );
self maps\mp\animscripts\zm_shared::donotetracks( "flamethrower_anim" );
}
else
wait 0.05;
}
mechz_flamethrower_aim()
{
self endon( "death" );
self endon( "kill_ft" );
self endon( "stop_ft" );
self waittillmatch( "flamethrower_anim", "end" );
self thread mechz_flamethrower_dist_watcher();
self thread mechz_flamethrower_arc_watcher();
aim_anim = undefined;
while ( true )
self mechz_play_flamethrower_aim();
}
mechz_flamethrower_tank_sweep()
{
self endon( "death" );
self endon( "kill_ft" );
self endon( "stop_ft" );
while ( true )
{
self stopanimscripted();
self.angles = vectortoangles( level.vh_tank.origin - self.origin );
self animscripted( self.origin, self.angles, "zm_flamethrower_sweep_up" );
self maps\mp\animscripts\zm_shared::donotetracks( "flamethrower_anim" );
if ( level.vh_tank ent_flag( "tank_moving" ) )
break;
//a_players_on_tank = get_players_on_tank( 1 );
a_players_on_tank = 0;
if ( !a_players_on_tank.size )
break;
}
self notify( "stop_ft" );
}
mechz_stop_firing_watcher()
{
self endon( "death" );
self endon( "kill_ft" );
self endon( "flamethrower_complete" );
self waittillmatch( "flamethrower_anim", "stop_ft" );
self.firing = 0;
}
mechz_watch_for_flamethrower_damage()
{
self endon( "death" );
while ( true )
{
self waittillmatch( "flamethrower_anim", "start_ft" );
self.firing = 1;
self thread mechz_stop_firing_watcher();
while ( isdefined( self.firing ) && self.firing )
{
do_tank_sweep_auto_damage = isdefined( self.doing_tank_sweep ) && self.doing_tank_sweep && !level.vh_tank ent_flag( "tank_moving" );
players = getplayers();
for ( i = 0; i < players.size; i++ )
{
if ( !( isdefined( players[i].is_burning ) && players[i].is_burning ) )
{
// if ( do_tank_sweep_auto_damage && players[i] entity_on_tank() || players[i] istouching( self.flamethrower_trigger ) )
// players[i] thread player_flame_damage();
}
}
zombies = getaispeciesarray( "axis", "all" );
for ( i = 0; i < zombies.size; i++ )
{
if ( isdefined( zombies[i].is_mechz ) && zombies[i].is_mechz )
continue;
if ( isdefined( zombies[i].on_fire ) && zombies[i].on_fire )
continue;
// if ( do_tank_sweep_auto_damage && zombies[i] entity_on_tank() || zombies[i] istouching( self.flamethrower_trigger ) )
// {
// zombies[i].on_fire = 1;
// zombies[i] promote_to_explosive();
// }
}
wait 0.1;
}
}
}
player_flame_damage()
{
self endon( "zombified" );
self endon( "death" );
self endon( "disconnect" );
n_player_dmg = 30;
n_jugga_dmg = 45;
n_burn_time = 1.5;
if ( isdefined( self.is_zombie ) && self.is_zombie )
return;
self thread player_stop_burning();
if ( !isdefined( self.is_burning ) && is_player_valid( self, 1, 0 ) )
{
self.is_burning = 1;
maps\mp\_visionset_mgr::vsmgr_activate( "overlay", "zm_transit_burn", self, n_burn_time, level.zm_transit_burn_max_duration );
self notify( "burned" );
if ( !self hasperk( "specialty_armorvest" ) )
self dodamage( n_player_dmg, self.origin );
else
self dodamage( n_jugga_dmg, self.origin );
wait 0.5;
self.is_burning = undefined;
}
}
player_stop_burning()
{
self notify( "player_stop_burning" );
self endon( "player_stop_burning" );
self endon( "death_or_disconnect" );
self waittill( "zombified" );
self notify( "stop_flame_damage" );
maps\mp\_visionset_mgr::vsmgr_deactivate( "overlay", "zm_transit_burn", self );
}
zombie_burning_fx()
{
self endon( "death" );
self endon( "stop_flame_damage" );
while ( true )
{
if ( isdefined( level._effect ) && isdefined( level._effect["character_fire_death_torso"] ) )
{
if ( !self.isdog )
playfxontag( level._effect["character_fire_death_torso"], self, "J_SpineLower" );
}
if ( isdefined( level._effect ) && isdefined( level._effect["character_fire_death_sm"] ) )
{
wait 1;
tagarray = [];
if ( randomint( 2 ) == 0 )
{
tagarray[0] = "J_Elbow_LE";
tagarray[1] = "J_Elbow_RI";
tagarray[2] = "J_HEAD";
}
else
{
tagarray[0] = "J_Wrist_RI";
tagarray[1] = "J_Wrist_LE";
tagarray[2] = "J_HEAD";
}
tagarray = array_randomize( tagarray );
self thread network_safe_play_fx_on_tag( "flamethrower", 2, level._effect["character_fire_death_sm"], self, tagarray[0] );
}
wait 12;
}
}
zombie_burning_audio()
{
self playloopsound( "zmb_fire_loop" );
self waittill_any( "death", "stop_flame_damage" );
if ( isdefined( self ) && isalive( self ) )
self stoploopsound( 0.25 );
}
zombie_burning_dmg()
{
self endon( "death" );
self endon( "stop_flame_damage" );
damageradius = 25;
damage = 2;
while ( true )
{
eyeorigin = self geteye();
players = get_players();
for ( i = 0; i < players.size; i++ )
{
if ( is_player_valid( players[i], 1, 0 ) )
{
playereye = players[i] geteye();
if ( distancesquared( eyeorigin, playereye ) < damageradius * damageradius )
{
players[i] dodamage( damage, self.origin, self );
players[i] notify( "burned" );
}
}
}
wait 1.0;
}
}
promote_to_explosive()
{
self endon( "death" );
self thread zombie_burning_audio();
self thread zombie_burning_fx();
self thread explode_on_death();
self thread zombie_burning_dmg();
self thread on_fire_timeout();
}
explode_on_death()
{
self endon( "stop_flame_damage" );
self waittill( "death" );
if ( !isdefined( self ) )
return;
tag = "J_SpineLower";
if ( isdefined( self.animname ) && self.animname == "zombie_dog" )
tag = "tag_origin";
if ( is_mature() )
{
if ( isdefined( level._effect["zomb_gib"] ) )
playfx( level._effect["zomb_gib"], self gettagorigin( tag ) );
}
else if ( isdefined( level._effect["spawn_cloud"] ) )
playfx( level._effect["spawn_cloud"], self gettagorigin( tag ) );
self radiusdamage( self.origin, 128, 30, 15, undefined, "MOD_EXPLOSIVE" );
self ghost();
if ( isdefined( self.isdog ) && self.isdog )
self hide();
else
self delay_thread( 1, ::self_delete );
}
on_fire_timeout()
{
self endon( "death" );
wait 12;
if ( isdefined( self ) && isalive( self ) )
{
self.is_on_fire = 0;
self notify( "stop_flame_damage" );
}
}
should_do_flamethrower_attack()
{
assert( isdefined( self.favoriteenemy ) );
/#
if ( getdvarint( #"_id_E7121222" ) > 1 )
println( "\\n\\tMZ: Checking should flame\\n" );
#/
if ( isdefined( self.disable_complex_behaviors ) && self.disable_complex_behaviors )
{
/#
if ( getdvarint( #"_id_E7121222" ) > 1 )
println( "\\n\\t\\tMZ: Not doing flamethrower because doing force aggro\\n" );
#/
return false;
}
if ( isdefined( self.not_interruptable ) && self.not_interruptable )
{
/#
if ( getdvarint( #"_id_E7121222" ) > 1 )
println( "\\n\\t\\tMZ: Not doing flamethrower because another behavior has set not_interruptable\\n" );
#/
return false;
}
if ( !self mechz_check_in_arc( 26 ) )
{
/#
if ( getdvarint( #"_id_E7121222" ) > 1 )
println( "\\n\\t\\tMZ: Not doing flamethrower because target is not in front arc\\n" );
#/
return false;
}
if ( isdefined( self.last_flamethrower_time ) && gettime() - self.last_flamethrower_time < level.mechz_flamethrower_cooldown_time )
{
/#
if ( getdvarint( #"_id_E7121222" ) > 1 )
println( "\\n\\t\\tMZ: Not doing flamethrower because it is still on cooldown\\n" );
#/
return false;
}
n_dist_sq = distancesquared( self.origin, self.favoriteenemy.origin );
if ( n_dist_sq < 10000 || n_dist_sq > 50000 )
{
/#
if ( getdvarint( #"_id_E7121222" ) > 1 )
println( "\\n\\t\\tMZ: Not doing flamethrower because target is not in range\\n" );
#/
return false;
}
b_cansee = bullettracepassed( self.origin + vectorscale( ( 0, 0, 1 ), 36.0 ), self.favoriteenemy.origin + vectorscale( ( 0, 0, 1 ), 36.0 ), 0, undefined );
if ( !b_cansee )
{
/#
if ( getdvarint( #"_id_E7121222" ) > 1 )
println( "\\n\\t\\tMZ: Not doing flamethrower because cannot see target\\n" );
#/
return false;
}
return true;
}
#using_animtree("mechz_claw");
mechz_do_flamethrower_attack( tank_sweep )
{
self endon( "death" );
self endon( "kill_ft" );
/#
if ( getdvarint( #"_id_E7121222" ) > 0 )
println( "\\n\\tMZ: Doing Flamethrower Attack\\n" );
#/
self thread mechz_stop_basic_find_flesh();
self.ai_state = "flamethrower_attack";
self setgoalpos( self.origin );
self clearanim( %root, 0.2 );
self.last_flamethrower_time = gettime();
self thread mechz_kill_flamethrower_watcher();
if ( !isdefined( self.flamethrower_trigger ) )
self mechz_flamethrower_initial_setup();
n_nearby_enemies = 0;
a_players = getplayers();
foreach ( player in a_players )
{
if ( distance2dsquared( player.origin, self.favoriteenemy.origin ) < 10000 )
n_nearby_enemies++;
}
if ( isdefined( tank_sweep ) && tank_sweep )
{
self.doing_tank_sweep = 1;
self thread mechz_flamethrower_tank_sweep();
}
else if ( randomint( 100 ) < level.mechz_ft_sweep_chance && n_nearby_enemies > 1 )
{
self.doing_ft_sweep = 1;
self animscripted( self.origin, self.angles, "zm_flamethrower_sweep" );
self maps\mp\animscripts\zm_shared::donotetracks( "flamethrower_anim" );
}
else
{
self animscripted( self.origin, self.angles, "zm_flamethrower_aim_start" );
self thread mechz_flamethrower_aim();
self maps\mp\animscripts\zm_shared::donotetracks( "flamethrower_anim" );
}
self orientmode( "face default" );
if ( isdefined( self.doing_ft_sweep ) && self.doing_ft_sweep )
self.doing_ft_sweep = 0;
else
{
self.cant_melee = 1;
self waittill( "stop_ft" );
self mechz_flamethrower_cleanup();
wait 0.5;
self stopanimscripted();
return;
}
self mechz_flamethrower_cleanup();
}
mechz_kill_flamethrower_watcher()
{
self endon( "flamethrower_complete" );
self waittill_either( "kill_ft", "death" );
self mechz_flamethrower_cleanup();
}
mechz_flamethrower_cleanup()
{
self.fx_field = self.fx_field & ~64;
self setclientfield( "mechz_fx", self.fx_field );
self.firing = 0;
self.doing_tank_sweep = 0;
self.cant_melee = 0;
self notify( "flamethrower_complete" );
}

File diff suppressed because it is too large Load Diff