1
0
mirror of https://github.com/JezuzLizard/BO2-Reimagined.git synced 2025-06-10 15:17:57 -05:00
Files
BO2-Reimagined/scripts/zm/replaced/_zm_equip_headchopper.gsc

409 lines
13 KiB
Plaintext

#include maps\mp\zombies\_zm_equip_headchopper;
#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\zombies\_zm_utility;
#include maps\mp\zombies\_zm_equipment;
#include maps\mp\zombies\_zm_spawner;
#include maps\mp\gametypes_zm\_weaponobjects;
#include maps\mp\zombies\_zm;
#include maps\mp\zombies\_zm_unitrigger;
#include maps\mp\zombies\_zm_power;
#include maps\mp\zombies\_zm_buildables;
#include maps\mp\animscripts\zm_death;
#include maps\mp\animscripts\zm_run;
#include maps\mp\zombies\_zm_audio;
#using_animtree("zombie_headchopper");
init_anim_slice_times()
{
level.headchopper_slice_times = [];
slice_times = getnotetracktimes( %o_zmb_chopper_slice_slow, "slice" );
retract_times = getnotetracktimes( %o_zmb_chopper_slice_slow, "retract" );
animlength = getanimlength( %o_zmb_chopper_slice_slow );
i = 0;
foreach ( frac in slice_times )
{
if ( i != 6 )
{
i++;
continue;
}
level.headchopper_slice_times[level.headchopper_slice_times.size] = animlength * frac;
i++;
}
i = 0;
foreach ( frac in retract_times )
{
if ( i == 0 || i == 6 )
{
i++;
continue;
}
level.headchopper_slice_times[level.headchopper_slice_times.size] = animlength * frac;
i++;
}
}
headchopperthink( weapon, electricradius, armed )
{
self endon( "death" );
self endon( "disconnect" );
self endon( "equip_headchopper_zm_taken" );
weapon endon( "death" );
radiussquared = electricradius * electricradius;
traceposition = weapon getcentroid() + anglestoforward( flat_angle( weapon.angles ) ) * -15;
trace = bullettrace( traceposition, traceposition + vectorscale( ( 0, 0, -1 ), 48.0 ), 1, weapon );
trigger_origin = weapon gettagorigin( "TAG_SAW" );
trigger = spawn( "trigger_box", trigger_origin, 1, 16, 128, 64 );
trigger.origin += anglestoup( weapon.angles ) * 32.0;
trigger.angles = weapon.angles;
trigger enablelinkto();
trigger linkto( weapon );
weapon.trigger = trigger;
weapon thread headchopperthinkcleanup( trigger );
direction_forward = anglestoforward( flat_angle( weapon.angles ) + vectorscale( ( -1, 0, 0 ), 60.0 ) );
direction_vector = vectorscale( direction_forward, 1024 );
direction_origin = weapon.origin + direction_vector;
home_angles = weapon.angles;
weapon.is_armed = 0;
self thread headchopper_fx( weapon );
self thread headchopper_animate( weapon, armed );
while ( !( isdefined( weapon.is_armed ) && weapon.is_armed ) )
wait 0.5;
weapon.chop_targets = [];
self thread targeting_thread( weapon, trigger );
while ( isdefined( weapon ) )
{
wait_for_targets( weapon );
if ( isdefined( weapon.chop_targets ) && weapon.chop_targets.size > 0 )
{
is_slicing = 1;
slice_count = 0;
weapon.headchopper_kills++;
while ( isdefined( is_slicing ) && is_slicing )
{
weapon notify( "chop", 1 );
weapon.is_armed = 0;
weapon.zombies_only = 1;
self headchopper_add_chop_ents( weapon, trigger );
foreach ( ent in weapon.chop_targets )
self thread headchopperattack( weapon, ent );
weapon.chop_targets = [];
weapon waittill_any( "slicing", "end" );
slice_count++;
is_slicing = weapon.is_slicing;
}
weapon notify( "slice_done" );
while ( !( isdefined( weapon.is_armed ) && weapon.is_armed ) )
wait 0.05;
if ( weapon.headchopper_kills >= 10 )
{
self thread headchopper_expired( weapon );
return;
}
}
else
wait 0.1;
}
}
targeting_thread( weapon, trigger )
{
self endon( "death" );
self endon( "disconnect" );
self endon( "equip_headchopper_zm_taken" );
weapon endon( "death" );
weapon.zombies_only = 1;
while ( isdefined( weapon ) )
{
if ( weapon.is_armed || isdefined( weapon.is_slicing ) && weapon.is_slicing )
{
if ( isdefined( weapon.is_slicing ) && weapon.is_slicing )
weapon waittill( "slice_done" );
self headchopper_add_chop_ents( weapon, trigger );
if ( !weapon.zombies_only )
weapon notify( "hi_priority_target" );
}
wait 0.05;
}
}
headchopper_add_chop_ents( weapon, trigger )
{
zombies = getaiarray( level.zombie_team );
foreach ( zombie in zombies )
{
if ( !isdefined( zombie ) || !isalive( zombie ) )
continue;
if ( isdefined( zombie.ignore_headchopper ) && zombie.ignore_headchopper )
continue;
if ( zombie istouching( trigger ) )
weapon headchopper_add_chop_ent( zombie );
}
players = get_players();
foreach ( player in players )
{
if ( is_player_valid( player ) && player istouching( trigger ) )
{
weapon headchopper_add_chop_ent( player );
weapon.zombies_only = 0;
}
}
}
wait_for_targets( weapon )
{
weapon endon( "hi_priority_target" );
while ( isdefined( weapon ) )
{
if ( isdefined( weapon.chop_targets ) && weapon.chop_targets.size > 0 )
{
return;
}
wait 0.05;
}
}
headchopperattack( weapon, ent )
{
self endon( "death" );
self endon( "disconnect" );
self endon( "equip_headchopper_zm_taken" );
weapon endon( "death" );
if ( !isdefined( ent ) || !isalive( ent ) )
return;
eye_position = ent geteye();
head_position = eye_position[2] + 13;
foot_position = ent.origin[2];
length_head_to_toe = abs( head_position - foot_position );
length_head_to_toe_25_percent = length_head_to_toe * 0.25;
is_headchop = weapon.origin[2] >= head_position - length_head_to_toe_25_percent;
is_torsochop = weapon.origin[2] >= foot_position + length_head_to_toe_25_percent;
is_footchop = abs( foot_position - weapon.origin[2] ) <= length_head_to_toe_25_percent;
trace_point = undefined;
if ( isdefined( is_headchop ) && is_headchop )
trace_point = eye_position;
else if ( isdefined( is_torsochop ) && is_torsochop )
trace_point = ent.origin + ( 0, 0, length_head_to_toe_25_percent * 2 );
else
trace_point = ent.origin + ( 0, 0, length_head_to_toe_25_percent );
fwdangles = anglestoup( weapon.angles );
tracefwd = bullettrace( weapon.origin + fwdangles * 5, trace_point, 0, weapon, 1, 1 );
if ( !isdefined( tracefwd ) || !isdefined( tracefwd["position"] ) || tracefwd["position"] != trace_point )
return;
if ( isplayer( ent ) )
{
if ( isdefined( is_headchop ) && is_headchop )
{
radiusdamage( ent.origin + (0, 0, 5), 10, 50, 50, weapon, "MOD_MELEE" );
}
else
{
radiusdamage( ent.origin + (0, 0, 5), 10, 25, 25, weapon, "MOD_MELEE" );
}
}
else
{
if ( !( isdefined( is_headchop ) && is_headchop ) || !( isdefined( is_headchop ) && is_headchop ) && !( isdefined( ent.has_legs ) && ent.has_legs ) )
{
headchop_height = 25;
if ( !( isdefined( ent.has_legs ) && ent.has_legs ) )
headchop_height = 35;
is_headchop = abs( eye_position[2] - weapon.origin[2] ) <= headchop_height;
}
if ( isdefined( is_headchop ) && is_headchop )
{
if ( !( isdefined( ent.no_gib ) && ent.no_gib ) )
ent maps\mp\zombies\_zm_spawner::zombie_head_gib();
ent dodamage( ent.health + 666, weapon.origin );
ent.headchopper_last_damage_time = gettime();
ent playsound( "zmb_exp_jib_headchopper_zombie" );
self thread headchopper_kill_vo( ent );
}
else if ( isdefined( is_torsochop ) && is_torsochop )
{
if ( ent.health <= 20 )
{
ent playsound( "zmb_exp_jib_headchopper_zombie" );
self thread headchopper_kill_vo( ent );
}
ent dodamage( 20, weapon.origin );
ent.headchopper_last_damage_time = gettime();
}
else if ( isdefined( is_footchop ) && is_footchop )
{
if ( !( isdefined( ent.no_gib ) && ent.no_gib ) )
{
ent.a.gib_ref = "no_legs";
ent thread maps\mp\animscripts\zm_death::do_gib();
ent.has_legs = 0;
ent allowedstances( "crouch" );
ent setphysparams( 15, 0, 24 );
ent allowpitchangle( 1 );
ent setpitchorient();
ent thread maps\mp\animscripts\zm_run::needsdelayedupdate();
if ( isdefined( ent.crawl_anim_override ) )
ent [[ ent.crawl_anim_override ]]();
}
if ( ent.health <= 10 )
{
ent playsound( "zmb_exp_jib_headchopper_zombie" );
self thread headchopper_kill_vo( ent );
}
ent dodamage( 10, weapon.origin );
ent.headchopper_last_damage_time = gettime();
}
}
}
setupwatchers()
{
self waittill( "weapon_watchers_created" );
watcher = maps\mp\gametypes_zm\_weaponobjects::getweaponobjectwatcher( "equip_headchopper" );
watcher.onspawnretrievetriggers = ::equipment_onspawnretrievableweaponobject;
}
equipment_onspawnretrievableweaponobject( watcher, player )
{
self.plant_parent = self;
iswallmount = isdefined( level.placeable_equipment_type[self.name] ) && level.placeable_equipment_type[self.name] == "wallmount";
if ( !isdefined( player.turret_placement ) || !player.turret_placement["result"] )
{
if ( iswallmount || !getdvarint( "tu11_zombie_turret_placement_ignores_bodies" ) )
{
self waittill( "stationary" );
waittillframeend;
if ( iswallmount )
{
if ( isdefined( player.planted_wallmount_on_a_zombie ) && player.planted_wallmount_on_a_zombie )
{
equip_name = self.name;
equipment_disappear_fx( self.origin, undefined, self.angles );
self delete();
player.do_not_display_equipment_pickup_hint = 1;
player maps\mp\zombies\_zm_equipment::equipment_take( equip_name );
player maps\mp\zombies\_zm_equipment::equipment_give( equip_name );
player.do_not_display_equipment_pickup_hint = undefined;
player.planted_wallmount_on_a_zombie = undefined;
return;
}
}
}
else
{
self.plant_parent = player;
self.origin = player.origin;
self.angles = player.angles;
wait_network_frame();
}
}
equipment = watcher.name + "_zm";
if ( isdefined( player.current_equipment ) && player.current_equipment == equipment )
player equipment_to_deployed( equipment );
if ( isdefined( level.zombie_equipment[equipment].place_fn ) )
{
if ( isdefined( player.turret_placement ) && player.turret_placement["result"] )
{
plant_origin = player.turret_placement["origin"];
plant_angles = player.turret_placement["angles"];
}
else if ( isdefined( level.placeable_equipment_type[self.name] ) && level.placeable_equipment_type[self.name] == "wallmount" )
{
plant_origin = self.origin;
plant_angles = self.angles;
}
else
{
plant_origin = self.origin;
plant_angles = self.angles;
}
if ( isdefined( level.check_force_deploy_origin ) )
{
if ( player [[ level.check_force_deploy_origin ]]( self, plant_origin, plant_angles ) )
{
plant_origin = player.origin;
plant_angles = player.angles;
self.plant_parent = player;
}
}
else if ( isdefined( level.check_force_deploy_z ) )
{
if ( player [[ level.check_force_deploy_z ]]( self, plant_origin, plant_angles ) )
plant_origin = ( plant_origin[0], plant_origin[1], player.origin[2] + 10 );
}
if ( isdefined( iswallmount ) && iswallmount )
self ghost();
replacement = player [[ level.zombie_equipment[equipment].place_fn ]]( plant_origin, plant_angles );
if ( isdefined( replacement ) )
{
replacement.owner = player;
replacement.original_owner = player;
replacement.name = self.name;
player notify( "equipment_placed", replacement, self.name );
if ( isdefined( level.equipment_planted ) )
player [[ level.equipment_planted ]]( replacement, equipment, self.plant_parent );
player maps\mp\zombies\_zm_buildables::track_buildables_planted( self );
}
if ( isdefined( self ) )
self delete();
}
}