mirror of
https://github.com/JezuzLizard/BO2-Reimagined.git
synced 2025-06-10 15:17:57 -05:00
409 lines
13 KiB
Plaintext
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();
|
|
}
|
|
} |