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
2023-12-16 21:11:47 -08:00

411 lines
11 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();
}
}