UGX-Mods Login

or login with an authentication provider below
Sign In with Google
Sign In with Twitter
Sign In with Discord
Sign In with Steam
Sign In with Facebook
Sign In with Twitch

Power text not updating (Solved)

broken avatar :(
Created 5 years ago
by Joeycx
0 Members and 1 Guest are viewing this topic.
2,458 views
broken avatar :(
×
broken avatar :(
Location: vn
Date Registered: 23 February 2015
Last active: 3 years ago
Posts
208
Respect
Forum Rank
Mr. Elemental
Primary Group
Member
×
Joeycx's Groups
Joeycx's Contact & Social Links
Hi, i recently came into a problem where turning on the power doesn't update the perk hinstrings from "needs power to be activated" to the hinstring used when the perk is powered on (like "3000 for speed cola") I'm using harrybo21's perks and this issue is also present when using aiden's kino teleporter (when the power is on the hintstring doesn't update from "needs power to be activated" to "press ___ to use teleporter but it is still usable) If you need me to post any scripts to help identify the problem, i will do so. Any help is appreciated as i'm trying to work out the kinks in my map, thanks :)

_zombiemode_perks.gsc

Code Snippet
Plaintext
/*#===================================================================###
###                                                                   ###
###                                                                   ###
###                    Harry Bo21s Perks v4.0.2                       ###
###         * Overwrites the original _zombiemode_perks.gsc           ###
###                                                                   ###
###                                                                   ###
###===================================================================#*/
/*=======================================================================

CREDITS

=========================================================================
ProRevenge - Heavy testing and input
StevieWonder87 - Heavy testing, input and FX - All the assets for Widows Wine
BluntStuffy - Input, scripting help, Anims and FX
RedSpace200 - Scripting help and Assets for Whos Who
thezombieproject - Testing and locating some errors
Smasher248 - Testing
JiffyNoodles - Testing
MZSlayer - Testing
AndyWhelen - Testing
HitmanVere - Testing, Vulture Aid Shaders for the fx, input and photoshop work
ProGamerzFTW - Testing and script support
Scobalula - Testing and script support
GerardS0406 - Testing
PCModder - Testing
IperBreach - Testing
TomBMX - Various Tools
Treyarch and Activision - For the concept and assets that were used
AllModz - Adivce and scripting help
Lilrifa - Black Ops 3 Models and scripting help
=======================================================================*/
#include maps\_utility;
#include common_scripts\utility;
#include maps\_zombiemode_utility;
#include maps\_harrybo21_utilities;
#include maps\_hud_util;
#include maps\_zombiemode_bo2_utility;
#using_animtree( "generic_human" );

init()
{
level.harrys_perks = true;
level thread harrybo21_perks_on_player_connect();
level thread harrybo21_perks_main();
level thread harrybo21_utilities_init();
}

harrybo21_perks_main()
{
level.DLC3.useElectricSwitch = true;
// ================================= USE PERKS =================================

// ================================= WAW PERKS =================================
set_zombie_var( "use_quick_revive", true ); // Use Quick Revive/Revive
set_zombie_var( "use_jugg", true ); // Use Juggernog
set_zombie_var( "use_double_tap_2", true ); // Use Double Tap 2.0
set_zombie_var( "use_speed_cola", true ); // Use Speed Cola

// ================================= BO1 PERKS =================================
set_zombie_var( "use_deadshot_daiquiri", true ); // Use Deadshot Daiquiri
set_zombie_var( "use_stamin_up", true ); // Use Stamin-up
set_zombie_var( "use_phd_flopper", true ); // Use P.H.D Flopper
set_zombie_var( "use_mule_kick", true ); // Use Mule Kick

// ================================= BO2 PERKS =================================
set_zombie_var( "use_tombstone_soda", false ); // Use Tombstone Soda
set_zombie_var( "use_whos_who", false ); // Use Whos Who
set_zombie_var( "use_electric_cherry", true ); // Use Electric Cherry
set_zombie_var( "use_vulture_aid", true ); // Use Vulture Aid Elixir
set_zombie_var( "use_wunderfizz", false ); // Use Wunderfizz

// ================================= BO3 PERKS =================================
set_zombie_var( "use_widows_wine", true ); // Use Widows Wine

// ================================= USE PERKS =================================

// ================================= PRECACHE MDOELS SHADERS AND WEAPON FILES =================================
PrecacheItem( "zombie_bo2_perk_bottles" );
PrecacheItem( "bo2_zm_knuckle_crack" );
PrecacheItem( "mustang_sally" );
PrecacheItem( "zombie_downed" );

if ( isDefined( level.zombie_vars ) && level.zombie_vars )
PrecacheModel( "bo2_ch_tombstone1" );

if ( isDefined( level.zombie_vars ) && level.zombie_vars )
{
PrecacheModel( "bo2_p6_zm_perk_vulture_ammo" );
PrecacheModel( "bo2_p6_zm_perk_vulture_points" );
PrecacheShader( "vending_vulture_glow_shader" );
}
if ( isDefined( level.zombie_vars ) && level.zombie_vars )
PrecacheShader( "vending_vulture_glow_shader" );

PrecacheModel( "bo2_p6_zm_buildable_pswitch_body" );
PrecacheModel( "bo2_p6_zm_buildable_pswitch_lever" );
PrecacheModel( "bo2_p6_zm_buildable_pswitch_hand" );
precachemodel( "projectile_usa_m9a1_riflegrenade" );

PrecacheShader( "bo2_waypoint_revive" );
// ================================= PRECACHE MDOELS SHADERS AND WEAPON FILES =================================

// ================================= PRECACHE FX =================================
if ( isDefined( level.zombie_vars ) && level.zombie_vars )
level._effect = loadfx( "explosions/default_explosion" );
if ( isDefined( level.zombie_vars ) && level.zombie_vars )
{
level._effect = loadfx( "harrys/fx_vulture_glow" );
level._effect = loadfx( "harrys/fx_vulture_mist" );
level._effect = loadfx( "harrys/fx_vulture_cherry" );
level._effect = loadfx( "harrys/fx_vulture_widow" );
level._effect = loadfx( "harrys/fx_vulture_deadshot" );
level._effect = loadfx( "harrys/fx_vulture_phd" );
level._effect = loadfx( "harrys/fx_vulture_tomb" );
level._effect = loadfx( "harrys/fx_vulture_whoswho" );
level._effect= loadfx( "harrys/fx_vulture_wunderfizz" );
level._effect = loadfx( "harrys/fx_vulture_double" );
level._effect = loadfx( "harrys/fx_vulture_mule" );
level._effect = loadfx( "harrys/fx_vulture_box" );
level._effect = loadfx( "harrys/fx_vulture_pap" );
level._effect = loadfx( "harrys/fx_vulture_revive" );
level._effect = loadfx( "harrys/fx_vulture_rifle" );
level._effect = loadfx( "harrys/fx_vulture_skull" );
level._effect = loadfx( "harrys/fx_vulture_stamin" );
level._effect = loadfx( "harrys/fx_vulture_vulture" );
level._effect = loadfx( "harrys/fx_vulture_speed" );
level._effect = loadfx( "harrys/fx_vulture_jugg" );
}
if ( isDefined( level.zombie_vars ) && level.zombie_vars )
{
level._effect = loadfx( "maps/zombie/fx_zombie_tesla_shock_eyes" );
level._effect = loadfx( "maps/zombie/fx_zombie_tesla_shock" );
level._effect = loadfx( "maps/zombie/fx_zombie_tesla_shock_secondary" );
level._effect = loadfx( "steviewonder87/cherry_1" );
level._effect = loadfx( "steviewonder87/cherry_2" );
level._effect = loadfx( "steviewonder87/cherry_3" );
level._effect = loadfx( "steviewonder87/cherry_4" );
}
if ( isDefined( level.zombie_vars ) && level.zombie_vars )
level._effect = loadfx( "harrys/fx_whos_who" );

level._effect = loadfx( "misc/fx_zombie_cola_revive_on" );
level._effect = loadfx( "misc/fx_zombie_cola_jugg_on" );
level._effect = loadfx( "misc/fx_zombie_cola_on" );
level._effect = loadfx( "misc/fx_zombie_cola_dtap_on" );
level._effect = loadfx ( "weapon/muzzleflashes/pistolflash_view" );
level._effect = loadfx ( "weapon/shellejects/pistol_view" );
level._effect = loadfx ( "explosions/grenadeExp_default" );
level._effect = loadfx ( "weapon/grenade/fx_trail_rifle_grenade" );
level._effect = loadfx ( "misc/fx_zombie_perk_lottery_4" );
// ================================= PRECACHE FX =================================

// ================================= SETUP =================================
level.wonderfizz_perks = ; // Array the wunderfizz perks are stored in
level.zombie_perks = ; // Array the perks are stored in
// ================================= SETUP =================================

// ================================= GENERAL SETTINGS ===============================
set_zombie_var( "use_power_switch", true ); // Decide if you want to have a power switch
set_zombie_var( "immune_to_powerdown", false ); // Decide if you want to use "depowered" perks like in tranzit
set_zombie_var( "vision_file", "zombie_asylum" ); // Change this to your vision file
set_zombie_var( "debug", false ); // Debug on/off
set_zombie_var( "start_pistol", "zombie_colt" ); // Need this to be a weapon in your mod, if you pap with just one gun, itll bug out if its not right
set_zombie_var( "start_grenade", "fraggrenade" ); // Need this to correct your inventory after downs
set_zombie_var( "last_stand_pistol", "mustang_sally" ); // Need this to be a weapon in your mod that you get during a solo down
set_zombie_var( "max_perks", 14 ); // Set to how many perks you want to initially limit the players to
set_zombie_var( "perk_jingle_wait_min", 320 ); // Minimum time to wait before trying to play a jingle again, ( checks are specfic to each machine )
set_zombie_var( "perk_jingle_wait_max", 2000 ); // Maximum time to wait before trying to play a jingle again, ( checks are specfic to each machine )
set_zombie_var( "use_power_off_functionality", false ); // Set this to true, if you want to be able to turn power off again. other wise, set to false
set_zombie_var( "use_d2p", true ); // Set this to true, if you want to use my crappy Dive To Prone
// ================================= GENERAL SETTINGS ===============================

// ================================= QUICK REVIVE =================================
if ( isDefined( level.zombie_vars ) && level.zombie_vars )
{
set_zombie_var( "revive_trigger_distance", 60 ); // Size of Revive trigger with Quick Revive
set_zombie_var( "solo_revive_time", 8 ); // Amount of time it takes to revive you on solo
set_zombie_var( "solo_revive_uses", 3 ); // Amount of time it takes to revive you on solo
}
// ================================= QUICK REVIVE =================================

// ================================= JUGGERNOG =================================
if ( isDefined( level.zombie_vars ) && level.zombie_vars )
{
set_zombie_var( "juggernog_health_normal", 100 ); // Max health with Juggernog
set_zombie_var( "juggernog_health_max", 250 ); // Max health with Juggernog
}
// ================================= JUGGERNOG =================================

// ================================= SPEED COLA =================================
if ( isDefined( level.zombie_vars ) && level.zombie_vars )
{
set_zombie_var( "speed_reload_rate_normal", 1 ); // Speed cola reload multiplier, 0.0 - 1.0;
set_zombie_var( "speed_reload_rate", .5 ); // Speed cola reload multiplier, 0.0 - 1.0;
}
// ================================= SPEED COLA =================================

// ================================= DOUBLE TAP 2.0 =================================
if ( isDefined( level.zombie_vars ) && level.zombie_vars )
{
set_zombie_var( "doubletap_fire_rate_normal", 1 ); // Double taps fire multiplier, 0.0 - 1.0;
set_zombie_var( "doubletap_fire_rate", .75 ); // Double taps fire multiplier, 0.0 - 1.0;
}
// ================================= DOUBLE TAP 2.0 =================================

// ================================= DEADSHOT DAIQUIRI =================================
if ( isDefined( level.zombie_vars ) && level.zombie_vars )
{
set_zombie_var( "deadshot_laser", 1 ); // use Deadshot Laser
set_zombie_var( "deadshot_laser_radius", .1 ); // Deadshot laser radius
set_zombie_var( "deadshot_light_radius", .4 ); // Deadshot laser light radius
set_zombie_var( "deadshot_spread_multiplier", .4225 ); // Deadshot hip fire reduction
set_zombie_var( "deadshot_point_reward", 80 ); // Deadshot headshot kill reward bonus amount
}
// ================================= DEADSHOT DAIQUIRI =================================

// ================================= STAMIN-UP =================================
if ( isDefined( level.zombie_vars ) && level.zombie_vars )
{
set_zombie_var( "staminup_sprint_scale", 1.17 ); // Staminup run speed scale
set_zombie_var( "staminup_sprint_max_duration", 8 ); // Staminup max sprint duration
}
// ================================= STAMIN-UP =================================

// ================================= PHD-FLOPPER =================================
if ( isDefined( level.zombie_vars ) && level.zombie_vars )
{
set_zombie_var( "phd_max_damage", 1700 ); // PHD nuke effects max damage
set_zombie_var( "phd_max_range", 256 ); // PHD nuke effects max range
set_zombie_var( "phd_drop_requirement", 20 ); // Minimum distance you must fall for Dive to Nuke
}
// ================================= PHD-FLOPPER =================================

// ================================= MULE KICK =================================
if ( isDefined( level.zombie_vars ) && level.zombie_vars )
{
set_zombie_var( "use_mule_kick_hud", true ); // Use custom Mule Kick hud indicator
set_zombie_var( "mule_kick_max_weapons", 3 ); // Max amount of weapons with Mule Kick
}
// ================================= MULE KICK =================================

// ================================= ELECTRIC CHERRY =================================
if ( isDefined( level.zombie_vars ) && level.zombie_vars )
{
set_zombie_var( "electric_cherry_max_damage", 1054 ); // Electric Cherry max damage
set_zombie_var( "electric_cherry_boss_damage", 500 ); // Electric Cherry max damage
set_zombie_var( "electric_cherry_max_range", 148 ); // Electric Cherry max range
set_zombie_var( "electric_cherry_points", 40 ); // Electric Cherry Points given for a kill
}
// ================================= ELECTRIC CHERRY =================================

// ================================= VULTURE AID =================================
if ( isDefined( level.zombie_vars ) && level.zombie_vars )
{
set_zombie_var( "vulture_drop_chance", 65 ); // Chance of a zombie dropping anything at all
set_zombie_var( "vulture_ammo_chance", 33 ); // Chance of zombie being a zombie that drops ammo default = 33% ( 1 in 3 )
set_zombie_var( "vulture_points_chance", 33 ); // Chance of zombie being a zombie that drops points default = 33% ( 1 in 3 )
set_zombie_var( "vulture_stink_chance", 13 ); // Chance of zombie being a stink zombie default = 33% ( 1 in 3 )
set_zombie_var( "vulture_drops_max", 20 ); // Max amount of vulture drops that can be around per player at once
set_zombie_var( "vulture_max_stink_zombies", 3 ); // Max amount of mist zombies that can be around at once
set_zombie_var( "vulture_on_dogs", true ); // Vulture Aid drops and mist work on dogs
set_zombie_var( "vulture_mist_time", 25 ) ; // Length of vulture mist effect before dispersing

level.vulture_huds = ;
level.vulture_huds = "vulture_widow_shader";
level.vulture_huds = "vulture_cherry_shader";
level.vulture_huds = "vulture_deadshot_shader";
level.vulture_huds = "vulture_phd_shader";
level.vulture_huds = "vulture_tomb_shader";
level.vulture_huds = "vulture_whoswho_shader";
level.vulture_huds = "vulture_mule_shader";
level.vulture_huds = "vulture_dt_shader";
level.vulture_huds = "vulture_revive_shader";
level.vulture_huds = "vulture_stamin_shader";
level.vulture_huds = "vulture_vulture_shader";
level.vulture_huds = "vulture_speed_shader";
level.vulture_huds = "vulture_jugg_shader";
level.vulture_huds = "vulture_pap_shader";
level.vulture_huds = "vulture_skull_shader";
level.vulture_huds = "vulture_rifle_shader";
level.vulture_huds = "vulture_wunderfizz_shader";
level.vulture_huds = "vulture_box_shader";
}
// ================================= VULTURE AID =================================

// ================================= TOMBSTONE SODA =================================
if ( isDefined( level.zombie_vars ) && level.zombie_vars )
set_zombie_var( "tombstone_enable_solo_version", true ); // Turns on my solo version of Tombstone, as well as the co-op only version

// ================================= TOMBSTONE SODA =================================

// ================================= WHOS WHO ======================================
if ( isDefined( level.zombie_vars ) && level.zombie_vars )
set_zombie_var( "whos_who_bleedout_time", getDvarFloat( "player_lastStandBleedoutTime" ) ); // Bleedout time for Whos Who

// ================================= WHOS WHO ======================================

// ================================= WIDOWS WINE ======================================
if ( isDefined( level.zombie_vars ) && level.zombie_vars )
{
precacheModel( "t7_ww_powerup" );
precacheModel( "t7_ww_grenade_proj" );
precacheShader( "vending_widows_grenade_indicator" );
precacheItem( "bo3_zm_widows_grenade" );

level._effect = loadfx ( "harrys/fx_widows_wine_explode" );
level._effect = loadfx ( "harrys/fx_widows_wine_zombie" );
level._effect = loadfx( "misc/fx_zombie_powerup_on_solo" );
level._effect = loadfx( "misc/fx_zombie_powerup_grab_solo" );
level._effect = loadfx( "misc/fx_zombie_powerup_wave_solo" );

set_zombie_var( "widows_wine_drop_chance", 22 ); // Chance of a zombie dropping anything at all
// set_zombie_var( "default_grenade", "fraggrenade" ); // Your maps default grenade that you start with - required
set_zombie_var( "widows_wine_max_range", 128 ); // Widows wine explode max range
set_zombie_var( "widows_wine_max_damage", 3 ); // Widows wine exlosion and after effect damage - percentage of total health
set_zombie_var( "widows_wine_max_melee_damage", 300 ); // Widows wine melee damage addition
}
// ================================= WIDOWS WINE ======================================

// ================================= PACK A PUNCH ===============================
level maps\_zombiemode_pack_a_punch::harrybo21_perks_upgrade_init(); // To remove this, just comment it out - or just dont place one
// ================================= PACK A PUNCH ===============================

// ================================= WUNDERFIZZ ===============================
if ( isDefined( level.zombie_vars ) && level.zombie_vars )
level thread maps\_zombiemode_wunderfizz::harrybo21_perks_init_wonderfizz(); // To remove this, just comment it out - or just dont place one
// ================================= WUNDERFIZZ ===============================

level thread harrybo21_perks_init(); // Start logic

registerClientSys( "zombiemode_perks" );

level thread harrybo21_vulture_chest_watcher();

level thread harrybo21_perks_kill_d2p();
}

harrybo21_perks_kill_d2p()
{
wait 1;
if ( isDefined( level.zombie_vars ) && level.zombie_vars )
return;

players = get_players();
for ( i = 0; i < players.size; i++ )
players notify( "kill_d2p" );
}

// DONE =============================
harrybo21_weapons_inventory_reset()
{
self takeAllWeapons();
wait 1;
self.inventory = ;
self.inventory = level.zombie_vars;
self.inventory = "none";
self.action_inventory = ;
self.action_inventory = "none";
self setactionslot( 0, "", undefined );
self.action_inventory = "none";
self setactionslot( 1, "", undefined );
self.action_inventory = "none";
self setactionslot( 2, "", undefined );
self.action_inventory = "none";
self setactionslot( 3, "", undefined );
self.grenade = level.zombie_vars;
self.alt_grenade = undefined;

self giveWeapon( level.zombie_vars );
self set_player_current_grenade( level.zombie_vars, 0 );
self switchToWeapon( level.zombie_vars );
}

// DONE =============================
debug_weapons()
{
while( 1 )
{
if ( !isDefined( self.inventory ) || self.inventory.size < 1 )
{
wait .1;
continue;
}
for ( i = 0; i < self.inventory.size; i++ )
iPrintLnBold( i + " : " + self.inventory );

for ( i = 0; i < self.action_inventory.size; i++ )
iPrintLnBold( i + " : " + self.action_inventory );

wait 1;
}
}

// DONE =============================
harrybo21_perks_set_dvars()
{
self setClientDvar( "revive_trigger_radius", level.zombie_vars );
self setClientDvar( "perk_weapReloadMultiplier", level.zombie_vars );
self setClientDvar( "perk_weapRateMultiplier", level.zombie_vars );
self setClientDvar( "cg_laserForceOn", "0" );
}

// DONE =============================
harrybo21_perks_player_debug()
{
self.score = 500000;
self.max_perks = 14;
}

harrybo21_perks_on_player_connect()
{
flag_wait( "all_players_connected" );
players = get_players();
for ( i = 0; i < players.size; i++ )
{
players thread harrybo21_perks_on_player_spawned();
players thread harrybo21_perks_setup_player(); 

if ( isDefined( level.zombie_vars ) && level.zombie_vars )
players thread harrybo21_perks_widows_wine_watch_for_throw();
}
}

// DONE =============================
harrybo21_perks_on_player_spawned()
{
for( ;; )
{
self waittill( "spawned_player" );
self harrybo21_perks_reset_player();
self harrybo21_weapons_inventory_reset();
}
}

// DONE =============================
harrybo21_perks_game_type()
{
flag_wait( "all_players_connected" );
// wait_network_frame();

players = get_players();
for ( i = 0; i < players.size; i++ )
players harrybo21_perks_set_dvars();

if ( players.size < 2 )
level thread harrybo21_perks_solo_game();
else
level thread harrybo21_perks_co_op_game();

if ( !level.zombie_vars )
level thread harrybo21_perks_power_on();
}

// REVIEW =============================
harrybo21_perks_solo_game()
{
// If its a solo game, make your changes here ==============================================================================
level.zombie_perks.perk_hint = "Press & hold ^6&&1^7 to buy Revive [Cost: 500]";
level.zombie_perks.perk_cost = 500;
level thread harrybo21_perks_limit_perk_usage( "specialty_quickrevive", level.zombie_vars );
level thread harrybo21_perks_ignore_power( "specialty_quickrevive" );
if ( !isDefined( level.zombie_vars ) || !level.zombie_vars )
{
level thread harrybo21_perks_remove_perk( "specialty_reconnaissance" );
// if ( isDefined( level.has_wunderfizz ) && level.has_wunderfizz )
// maps\_zombiemode_wunderfizz::harrybo21_perks_wonderfizz_remove( "specialty_reconnaissance" );

}
}

// DONE =============================
harrybo21_perks_co_op_game()
{
// If its a co-op game, make your changes here ==============================================================================
}

// DONE =============================
harrybo21_perks_mustang_trail( model1, model2 )
{
wait .05;
PlayFXOnTag( level._effect, model1, "tag_origin" );
PlayFXOnTag( level._effect, model2, "tag_origin" );
}

// DONE =============================
harrybo21_perks_mustang_fired()
{
self endon ( "disconnect" );
while( 1 )
{
self waittill( "grenade_fire", grenade, weapname );
if ( !issubstr( weapname, "mustang_sally" ) )
continue;

self thread mustang_thread( grenade, weapname );
}
}

mustang_thread( grenade, weapname )
{
model1 = spawn( "script_model" , grenade.origin + ( anglesToRight( grenade.angles ) * -10 ) );
model1 setModel( "projectile_usa_m9a1_riflegrenade" );
model1.angles = grenade.angles;
model1 linkTo( grenade, "tag_origin", anglesToRight( grenade.angles ) * -10 );

model2 = spawn( "script_model" , grenade.origin + ( anglesToRight( grenade.angles ) * 10 ) );
model2 setModel( "projectile_usa_m9a1_riflegrenade" );
model2.angles = grenade.angles;
model2 linkTo( grenade, "tag_origin", anglesToRight( grenade.angles ) * 10 );

self thread harrybo21_perks_mustang_trail( model1, model2 );

self waittill( "projectile_impact", weapname, point, radius );
PlayFX( level._effect, point + ( anglesToRight( grenade.angles ) * -10 ) );
playsoundatposition ( "rifle_grenade_explode", point + ( anglesToRight( grenade.angles ) * -10 ) );
PlayFX( level._effect, point + ( anglesToRight( grenade.angles ) * 10 ) );
playsoundatposition ( "rifle_grenade_explode", point + ( anglesToRight( grenade.angles ) * 10 ) );
model1 delete();
model1 destroy();
model1 = undefined;
model2 delete();
model2 destroy();
model2 = undefined;
}

// REVIEW ==================================
harrybo21_perks_spawn_dw_world_model()
{
self.dual_model = false;
while( 1 )
{
self waittill( "weapon_change_complete" );
current_weapon = self getCurrentWeapon();
if (  current_weapon == "mustang_sally" )
{
if ( self.dual_model )
continue;

self.dual_model = true;
self attach( GetWeaponModel( "mustang_sally" ), "tag_weapon_left" );
}
else
{
if ( !self.dual_model )
continue;

self.dual_model = false;
self detach( GetWeaponModel( "mustang_sally" ), "tag_weapon_left" );
}
wait .1;
}
}

// REVIEW ==================================
harrybo21_perks_init() // Add / Remove perks here by commenting them out
{
level.primaryProgressBarWidth = level.primaryProgressBarWidth;
level.primaryProgressBarHeight = level.primaryProgressBarHeight + 5;

level.power_on = false;
level.is_swapping = false;
harrybo21_perks_power_thread();

if ( isDefined( level.zombie_vars ) && level.zombie_vars )
harrybo21_perks_add_perk( "specialty_quickrevive", 1500, "bo3_revive_off", "bo3_revive_on" , "vending_quickrevive_shader", level._effect, "Quick Revive", ::harrybo21_perks_revive, "_perk_revive_d_", 0, "mx_revive_jingle", "mx_revive_sting" );
else
harrybo21_perks_remove_unused_machines( "specialty_quickrevive" );

if ( isDefined( level.zombie_vars ) && level.zombie_vars )
harrybo21_perks_add_perk( "specialty_armorvest", 2500, "bo3_juggernog_off", "bo3_juggernog_on" , "vending_juggernaut_shader", level._effect, "Juggernog", ::harrybo21_perks_juggernog, "_perk_jugga_d_", 2, "mx_jugger_jingle", "mx_jugger_sting" );
else
harrybo21_perks_remove_unused_machines( "specialty_armorvest" );

if ( isDefined( level.zombie_vars ) && level.zombie_vars )
harrybo21_perks_add_perk( "specialty_rof", 2000, "bo3_doubletap2_off", "bo3_doubletap2_on" , "vending_doubletap_shader", level._effect, "Double Tap 2.0", ::harrybo21_perks_doubletap, "_perk_doubletap_d_", 1, "mx_doubletap_jingle", "mx_doubletap_sting" );
else
harrybo21_perks_remove_unused_machines( "specialty_rof" );

if ( isDefined( level.zombie_vars ) && level.zombie_vars )
harrybo21_perks_add_perk( "specialty_fastreload", 2500, "bo3_speed_off", "bo3_speed_on" , "vending_fastreload_shader", level._effect, "Speed Cola", ::harrybo21_perks_speed, "_perk_speed_d_", 3, "mx_speed_jingle", "mx_speed_sting" );
else
harrybo21_perks_remove_unused_machines( "specialty_fastreload" );

if ( isDefined( level.zombie_vars ) && level.zombie_vars )
harrybo21_perks_add_perk( "specialty_bulletaccuracy", 1000, "bo3_deadshot_off", "bo3_deadshot_on" , "vending_deadshot_shader", level._effect, "Deadshot Daiquiri", ::harrybo21_perks_deadshot, "_perk_deadshot_d_", 4, "mx_deadshot_jingle", "mx_deadshot_sting" );
else
harrybo21_perks_remove_unused_machines( "specialty_bulletaccuracy" );

if ( isDefined( level.zombie_vars ) && level.zombie_vars )
harrybo21_perks_add_perk( "specialty_longersprint", 2000, "bo3_staminup_off", "bo3_staminup_on" , "vending_staminup_shader", level._effect, "Stamin-Up", ::harrybo21_perks_staminup, "_perk_stamine_d_", 5, "mx_marathon_jingle", "mx_marathon_sting" );
else
harrybo21_perks_remove_unused_machines( "specialty_longersprint" );

if ( isDefined( level.zombie_vars ) && level.zombie_vars )
harrybo21_perks_add_perk( "specialty_detectexplosive", 2500, "bo3_flopper_off", "bo3_flopper_on" , "vending_phd_shader", level._effect, "PHD Flopper", ::harrybo21_perks_phd, "_perk_phdflopper_d_", 6, "mx_nuke_jingle", "mx_nuke_sting" );
else
harrybo21_perks_remove_unused_machines( "specialty_detectexplosive" );

if ( isDefined( level.zombie_vars ) && level.zombie_vars )
harrybo21_perks_add_perk( "specialty_extraammo", 3000, "bo3_mulekick_off", "bo3_mulekick_on" , "vending_mule_kick_shader", level._effect, "Mule Kick", ::harrybo21_perks_mulekick, "_perk_mule_d_", 7, "mx_mule_kick_jingle", "mx_mule_kick_sting" );
else
harrybo21_perks_remove_unused_machines( "specialty_extraammo" );

if ( isDefined( level.zombie_vars ) && level.zombie_vars )
harrybo21_perks_add_perk( "specialty_boost", 2000, "bo2_p6_zm_vending_electric_cherry", "bo2_p6_zm_vending_electric_cherry_on" , "vending_electric_cherry_shader", level._effect, "Electric Cherry", ::harrybo21_perks_electric_cherry, undefined, 8, "mx_electric_cherry_jingle", "mx_electric_cherry_jingle" );
else
harrybo21_perks_remove_unused_machines( "specialty_boost" );

if ( isDefined( level.zombie_vars ) && level.zombie_vars )
harrybo21_perks_add_perk( "specialty_reconnaissance", 2000, "bo2_zombie_vending_tombstone", "bo2_zombie_vending_tombstone_on" , "vending_tombstone_shader", level._effect, "Tombstone Soda", ::harrybo21_perks_tombstone, undefined, 9, "mx_tombstone_jingle", "mx_tombstone_sting" );
else
harrybo21_perks_remove_unused_machines( "specialty_reconnaissance" );

if ( isDefined( level.zombie_vars ) && level.zombie_vars )
harrybo21_perks_add_perk( "specialty_shades", 2000, "bo2_p6_zm_vending_chugabud", "bo2_p6_zm_vending_chugabud_on" , "vending_whoswho_shader", level._effect, "Who's Who", ::harrybo21_perks_whos_who, undefined, 11, "mx_whos_who_jingle", "mx_whos_who_sting" );
else
harrybo21_perks_remove_unused_machines( "specialty_shades" );

if ( isDefined( level.zombie_vars ) && level.zombie_vars )
harrybo21_perks_add_perk( "specialty_ordinance", 3000, "bo2_zombie_vending_vultureaid", "bo2_zombie_vending_vultureaid_on" , "vending_vulture_shader", level._effect, "Vulture Aid", ::harrybo21_perks_vulture, undefined, 10, "mx_vulture_jingle", "mx_vulture_sting" );
else
harrybo21_perks_remove_unused_machines( "specialty_ordinance" );

if ( isDefined( level.zombie_vars ) && level.zombie_vars )
harrybo21_perks_add_perk( "specialty_specialgrenade", 3000, "t7_ww_off", "t7_ww_on" , "vending_widows_shader", level._effect, "Widows Wine", ::harrybo21_perks_widows_wine, undefined, 12, "mx_widows_jingle", "mx_widows_sting" );
else
harrybo21_perks_remove_unused_machines( "specialty_specialgrenade" );

harrybo21_perks_machines_init();
level thread harrybo21_perks_game_type();
level thread harrybo21_perks_zombie_watch_for_spawn();
level thread harrybo21_perks_swapping_perk_watch_for_reset();
wait 1;
level.overridePlayerDamage = ::harrybo21_perks_player_damage_override;
}

// DONE =============================
harrybo21_perks_remove_unused_machines( perk )
{
machines = harrybo21_perks_get_machines_for_perk( perk );
if ( !isDefined( machines ) || machines.size < 1 )
return;

for ( i = 0; i < machines.size; i++ )
machines thread harrybo21_perks_remove_perk_machine();

}

// REVIEW BOSSES =============================
harrybo21_perks_zombie_watch_for_spawn()
{
while( 1 )
{
zombies = getAiSpeciesArray( "axis", "all" );
if ( isDefined( zombies ) && zombies.size > 0 )
{
for( i = 0; i < zombies.size; i++ )
{
if( !isDefined( zombies.spawn_functions_ran ) || !zombies.spawn_functions_ran )
{
zombies.spawn_functions_ran = 1;
zombies thread harrybo21_perks_vulture_zombie_function();
zombies thread harrybo21_perks_doubletap_watcher();
zombies thread harrybo21_perks_widows_watcher();
}
}
}
zombies = undefined;
wait .1;
}
}

// DONE =============================
harrybo21_perks_reset_player()
{
self harrybo21_perks_remove_all();
self.perk_inventory = ;
self.perk_hud = ;
self.muleAmmo = undefined;
self.lost_mule_guns = undefined;
self.mule_kick_switch_back = undefined;
self.immune_to_powerdown = level.zombie_vars;
setClientSysState( "lsm", "0", self );
self stopLoopSound();
self VisionSetNaked( level.zombie_vars );
}

// DONE =============================
harrybo21_perks_setup_player()
{
self harrybo21_perks_remove_all();
self harrybo21_perks_reset_player();

self.max_perks = level.zombie_vars;
// self thread harrybo21_perks_down_watcher();
self thread harrybo21_perks_mule_kick_weapon_change_watcher();
self thread harrybo21_perks_mustang_fired();
if ( isDefined( level.zombie_vars ) && level.zombie_vars )
self harrybo21_perks_player_debug();

}

// REVIEW =============================
harrybo21_perks_turn_power_on_stock()
{
flag_wait( "electricity_on" );
wait 2;
if ( isDefined( level.power_on ) && level.power_on )
return;

harrybo21_perks_power_on();
if ( level.zombie_vars )
level thread harrybo21_perks_enable_switch_to_turn_off_power();

}

// DONE =============================
harrybo21_perks_power_thread()
{
panels = getEntArray( "harrybo21_power_panels", "script_noteworthy" );
if ( !isDefined( panels ) || panels.size < 1 )
return;
for ( i = 0; i < panels.size; i++ )
{
panels setModel( "bo2_p6_zm_buildable_pswitch_body" );
}

trigs = getEntArray( "harrybo21_power_trigger", "script_noteworthy" );
if ( !isDefined( trigs ) || trigs.size < 1 || !isDefined( level.power_on ) )
{
level.zombie_vars = false;
return;
}
for ( i = 0; i < trigs.size; i++ )
{
trigs.handle = getEnt( trigs.targetname, "target" );
trigs.handle setModel( "bo2_p6_zm_buildable_pswitch_lever" );
trigs.handle notsolid();
trigs.hand = getEnt( trigs.handle.targetname, "target" );
trigs.hand setModel( "bo2_p6_zm_buildable_pswitch_hand" );
trigs.hand notsolid();
trigs.hand LinkTo( trigs.handle );
trigs SetCursorHint( "HINT_NOICON" );
if ( !level.power_on )
trigs thread harrybo21_perks_enable_switch_to_turn_on_power();
else if ( level.zombie_vars )
trigs thread harrybo21_perks_enable_switch_to_turn_off_power();

}
}

// DONE =============================
harrybo21_perks_enable_switch_to_turn_off_power()
{
self.active = true;
self sethintstring( "Press & hold ^6&&1^7 to deactivate power" );
self waittill( "trigger" );
self playsound( "switch_flip" );
self.active = false;
self sethintstring( "" );
self.handle rotateroll( 90, .3 );
trigs = getEntArray( "harrybo21_power_trigger", "script_noteworthy" );

if ( level.power_on )
level thread harrybo21_perks_power_off();

wait 5;
self thread harrybo21_perks_enable_switch_to_turn_on_power();
}

// DONE =============================
harrybo21_perks_enable_switch_to_turn_on_power()
{
self.active = false;
self sethintstring( "Press & hold ^6&&1^7 to activate power" );
self waittill( "trigger" );
self playsound( "switch_flip" );
self.active = true;
self sethintstring( "" );
self.handle rotateroll( -90, .3 );
trigs = getEntArray( "harrybo21_power_trigger", "script_noteworthy" );
count = undefined;
if ( isDefined( trigs ) && trigs.size > 0 )
{
count = 0;
for ( i = 0; i < trigs.size; i++ )
{
if ( trigs.active )
count++;

}
}
if ( !isDefined( count ) || count == trigs.size )
level thread harrybo21_perks_power_on();

wait 5;
if ( level.zombie_vars )
self thread harrybo21_perks_enable_switch_to_turn_off_power();
}

// DONE =============================
harrybo21_perks_power_on()
{
level.power_on = true;
flag_set( "electricity_on" );
        clientnotify ( "pl1" );
exploder(600);
vending_machines = harrybo21_perks_get_machines();
for ( i = 0; i < vending_machines.size; i++ )
{
if ( !isDefined( vending_machines.ignore_power ) || !vending_machines.ignore_power )
vending_machines notify( "activate_machine" );

}
vending_machines = GetEntArray( "harrybo21_upgrade", "script_noteworthy" );
for ( i = 0; i < vending_machines.size; i++ )
{
if ( !isDefined( vending_machines.ignore_power ) || !vending_machines.ignore_power )
vending_machines notify( "activate_machine" );

}
vending_machines = maps\_zombiemode_wunderfizz::harrybo21_perks_wonderfizz_get_machines();
for ( i = 0; i < vending_machines.size; i++ )
{
if ( !isDefined( vending_machines.ignore_power ) || !vending_machines.ignore_power )
vending_machines notify( "activate_machine" );

}
wait .1;
players = get_players();
for ( i = 0; i < players.size; i++ )
{
if ( players.immune_to_powerdown )
continue;

players harrybo21_perks_power_on_owned_perks();
}
           
       
}

// DONE =============================
harrybo21_perks_power_off()
{
level.power_on = false;
vending_machines = harrybo21_perks_get_machines();
for ( i = 0; i < vending_machines.size; i++ )
{
if ( !isDefined( vending_machines.ignore_power ) || !vending_machines.ignore_power )
vending_machines notify( "deactivate_machine" );

}
vending_machines = GetEntArray( "harrybo21_upgrade", "script_noteworthy" );
for ( i = 0; i < vending_machines.size; i++ )
{
if ( !isDefined( vending_machines.ignore_power ) || !vending_machines.ignore_power )
vending_machines notify( "deactivate_machine" );
}
/*
vending_machines = maps\_zombiemode_wunderfizz::harrybo21_perks_wonderfizz_get_machines();
for ( i = 0; i < vending_machines.size; i++ )
{
if ( !isDefined( vending_machines.ignore_power ) || !vending_machines.ignore_power )
vending_machines notify( "deactivate_machine" );
}
*/
wait .1;
players = get_players();
for ( i = 0; i < players.size; i++ )
{
if ( players.immune_to_powerdown )
continue;

players harrybo21_perks_power_off_owned_perks();
}
}

// DONE =============================
harrybo21_perks_power_off_owned_perks()
{
if ( self.immune_to_powerdown  || !isDefined( self.perk_inventory ) || self.perk_inventory.size < 1 )
return;

for ( i = 0; i < self.perk_inventory.size; i++ )
{
if ( harrybo21_perks_is_machine_for_perk_active( self.perk_inventory ) )
continue;

self harrybo21_perks_hud_fade_power_off( self.perk_inventory );
self unSetPerk( self.perk_inventory );
if ( isDefined( level.zombie_perks ].perk_function ) )
self thread [[ level.zombie_perks[ self.perk_inventory[ i ] ].perk_function ]]( false );

if ( self.perk_inventory == "specialty_extraammo" )
self harrybo21_perks_mule_kick_take_extras();
}
}

// DONE =============================
harrybo21_perks_power_on_owned_perks()
{
if ( !isDefined( self.perk_inventory ) || self.perk_inventory.size < 1 )
return;

for ( i = 0; i < self.perk_inventory.size; i++ )
{
self harrybo21_perks_hud_fade_power_on( self.perk_inventory );
self setPerk( self.perk_inventory );
if ( isDefined( level.zombie_perks ].perk_function ) )
self [[ level.zombie_perks[ self.perk_inventory[ i ] ].perk_function ]]( true );

if ( self.perk_inventory == "specialty_extraammo" )
self harrybo21_perks_mule_kick_return_extras();
}
}

// DONE =============================
harrybo21_perks_get_machines_for_perk( perk )
{
new_array = ;
machines = harrybo21_perks_get_machines();
if ( !isDefined( machines ) || machines.size < 1 )
return undefined;

for ( i = 0; i < machines.size; i++ )
{
if ( isDefined( machines.script_string ) && machines.script_string == perk )
new_array = machines;

}
if ( new_array.size > 0 )
return new_array;

return undefined;
}

// DONE =============================
harrybo21_perks_is_machine_for_perk_active( perk )
{
if ( isDefined( level.zombie_perks.ignore_power ) && level.zombie_perks.ignore_power )
return true;

perk_machines = harrybo21_perks_get_machines_for_perk( perk );
if ( !isDefined( perk_machines ) || perk_machines.size < 1 )
return false;

for ( i = 0; i < perk_machines.size; i++ )
{
if ( isDefined( perk_machines.active ) && perk_machines.active )
return true;

}
return false;
}

// DONE =============================
harrybo21_perks_get_machine_trigger( machine )
{
trig = getEntArray( "harrybo21_perk_trigger", "targetname" );
for ( t = 0; t < trig.size; t++ )
{
if ( machine.targetname == trig.target )
return trig;

}
return undefined;
}

// DONE =============================
harrybo21_perks_get_machine_clip( machine )
{
clips = getEntArray( "harrybo21_perk_clip", "script_noteworthy" );
for ( t = 0; t < clips.size; t++ )
{
if ( machine.targetname == clips.target )
return clips;

}
return undefined;
}

// DONE =============================
harrybo21_perks_get_machines()
{
return GetEntArray( "harrybo21_vending", "script_noteworthy" );
}

// DONE =============================
harrybo21_perks_machines_init()
{
vending_machines = harrybo21_perks_get_machines();
for ( i = 0; i < vending_machines.size; i++ )
{
if ( isDefined( vending_machines.script_string ) )
vending_machines harrybo21_perks_machine_initialize();
else
vending_machines thread harrybo21_perks_machine_random_spawn();
}
}

// DONE =============================
harrybo21_perks_machine_random_spawn()
{
self setModel( "tag_origin" );
trig = harrybo21_perks_get_machine_trigger( self );
trig setHintString( "" );
trig SetCursorHint( "HINT_NOICON" );
triggers = getEntArray( "harrybo21_random_vending", "script_noteworthy" );
if ( !isDefined( triggers ) || triggers.size < 1 )
return;

trigger = undefined;
for ( i = 0; i < triggers.size; i++ )
{
if ( triggers.target == self.targetname )
{
trigger = triggers;
break;
}
}
if ( !isDefined( trigger ) )
return;

while( isDefined( trigger ) )
{
trigger waittill( "trigger", user );
if ( !isPlayer( user ) || !level.power_on )
{
wait .1;
continue;
}
playsoundatposition( "rando_start", self.origin );
playsoundatposition( "rando_perk", self.origin );
level thread play_sound_2D( "perk_lottery" );
playfxontag( level._effect, self, "tag_origin" );
self thread harrybo21_perks_randomize_machine();
self moveZ( 30, 4, 3 );
self vibrate( ( 0, -100, 0 ) , 0.3, 0.4, 5 );
wait 4;

self.script_string = harrybo21_perks_randomize_decide_final(); // keys;

self harrybo21_perks_machine_initialize();

self notify( "stop_randomize" );
self moveZ( -30, 1, 1 );
wait 1;
if ( isDefined( level.zombie_perks.ignore_power ) && level.zombie_perks.ignore_power )
{
self.ignore_power = true;
self notify( "activate_machine" );
}
else if ( isDefined( level.power_on ) && level.power_on )
self notify( "activate_machine" );
break;
}
trigger delete();
trigger = undefined;

harrybo21_perks_vulture_waypoint_functionality();
}

// DONE =============================
harrybo21_perks_randomize_decide_final()
{
perks = harrybo21_perks_get_unplaced();

if ( !isDefined( perks ) )
perks = level.zombie_perks;

keys = getArrayKeys( perks );
keys = array_randomize( keys );

return keys;
}

// DONE =============================
harrybo21_perks_get_unplaced()
{
array = ;
keys = getArrayKeys( level.zombie_perks );
for ( i = 0; i < keys.size; i++ )
{
if ( isDefined( level.zombie_perks ].removed ) && level.zombie_perks ].removed )
continue;

machines = harrybo21_perks_get_machines_for_perk( keys );
if ( !isDefined( machines ) || machines.size < 1 )
{
array ] = keys;
continue;
}
}
if ( array.size > 0 )
return array;
else
return undefined;
}

// DONE =============================
harrybo21_perks_randomize_machine()
{
self endon( "stop_randomize" );
wait_time = .01;
last_key = undefined;
while( 1 )
{
perks = harrybo21_perks_get_unplaced();
if ( !isDefined( perks ) )
perks = level.zombie_perks;

keys = getArrayKeys( perks );
keys = array_randomize( keys );

key_use = 0;
if ( isDefined( last_key ) && last_key == keys && keys.size > 1 )
key_use = 1;

self setModel( level.zombie_perks ].perk_model );
last_key = keys;
wait wait_time;
wait_time += .01;
}
}

// DONE =============================
harrybo21_perks_machine_initialize()
{
self.active = false;
self setModel( level.zombie_perks.perk_model );
self.clip = harrybo21_perks_get_machine_clip( self );
self.trig = harrybo21_perks_get_machine_trigger( self );
self.trig SetHintString( &"ZOMBIE_FLAMES_UNAVAILABLE" );
self.trig SetCursorHint( "HINT_NOICON" );
self.trig thread harrybo21_perks_trigger_watcher( self );
self thread harryb21_perks_trigger_visible_watcher( self );
self thread harrybo21_perks_play_jingle();
self thread harrybo21_perks_machines_power_watcher();
self thread harrybo21_perks_check_for_change();

secondary_power = getEntArray( "harrybo21_secondary_power_trigger", "script_noteworthy" );
for ( i = 0; i < secondary_power.size; i++ )
{
if ( isDefined( secondary_power.target ) && secondary_power.target == self.targetname )
{
secondary_power.handle = getEnt( secondary_power.targetname, "target" );
secondary_power.handle setModel( "bo2_p6_zm_buildable_pswitch_lever" );
secondary_power.handle notsolid();
secondary_power.hand = getEnt( secondary_power.handle.targetname, "target" );
secondary_power.hand setModel( "bo2_p6_zm_buildable_pswitch_hand" );
secondary_power.hand notsolid();
secondary_power.hand LinkTo( secondary_power.handle );
secondary_power SetCursorHint( "HINT_NOICON" );
if ( isDefined( level.power_on ) && level.power_on )
{
secondary_power sethintstring( "Press & hold ^6&&1^7 to deactivate switch" );
secondary_power.active = true;
}
else
{
secondary_power sethintstring( "Press & hold ^6&&1^7 to activate switch" );
secondary_power.active = false;
}
self.secondary_power = secondary_power;
self.secondary_power thread harrybo21_perks_secondary_power( self );

break;
}
}

target_by = getEntArray( "harrybo21_swapping_vending", "script_noteworthy" );
for ( i = 0; i < target_by.size; i++ )
{
if ( isDefined( target_by.target ) && target_by.target == self.targetname )
{
if ( !isDefined( level.swap_machines ) )
level.swap_machines = ;

level.swap_machines = self;
self.swapping_machine = true;
self thread harrybo21_perks_spawn_swapping_perk_machine();
break;
}
}
}

// DONE =============================
harrybo21_perks_secondary_power( machine )
{
while( 1 )
{
hint = undefined;
self waittill( "trigger" );
self playsound( "switch_flip" );
self sethintstring( "" );
self.handle rotateroll( -90, .3 );
if ( isDefined( self.active ) && self.active )
{
hint = "Press & hold ^6&&1^7 to activate switch";
self.active = false;
if ( machine.active )
machine notify( "deactivate_machine" );
}
else
{
hint = "Press & hold ^6&&1^7 to deactivate switch";
self.active = true;
if ( isDefined( level.power_on ) && level.power_on )
{
if ( !machine.active )
machine notify( "activate_machine" );

}
}
wait 5;
self sethintstring( hint );
hint = undefined;
self waittill( "trigger" );
self playsound( "switch_flip" );
self sethintstring( "" );
self.handle rotateroll( 90, .3 );
if ( isDefined( self.active ) && self.active )
{
hint = "Press & hold ^6&&1^7 to activate switch";
self.active = false;
if ( machine.active )
machine notify( "deactivate_machine" );

}
else
{
hint = "Press & hold ^6&&1^7 to deactivate switch";
self.active = true;
if ( isDefined( level.power_on ) && level.power_on )
{
if ( !machine.active )
machine notify( "activate_machine" );
}
}
wait 5;
self sethintstring( hint );
}
}

// DONE =============================
harrybo21_perks_spawn_swapping_perk_machine()
{
wait .5;
triggers = getEntArray( "harrybo21_swapping_vending", "script_noteworthy" );
for ( i = 0; i < triggers.size; i++ )
{
if ( triggers.target == self.targetname )
{
triggers.is_swapping = true;
self thread harrybo21_perks_swapping_perk_randomize();
playsoundatposition( "rando_start", self.origin );
playsoundatposition( "rando_perk", self.origin );
level thread play_sound_2D( "perk_lottery" );
wait 3;

self notify( "perk_swap_done" );
self setModel( level.zombie_perks.perk_model );
if ( isDefined( self.active ) && self.active )
self setModel( level.zombie_perks.perk_model_on );

wait 1;
triggers thread harrybo21_perks_swapping_perk_machine_thread( self );
self.is_swapping = undefined;
break;
}
}
for ( i = 0; i < triggers.size; i++ )
{
triggers.is_swapping = undefined;
}

harrybo21_perks_vulture_waypoint_functionality(); // SHOW WHEN SPAWNED
}

// DONE =============================
harrybo21_perks_swapping_perk_watch_for_reset()
{
while( 1 )
{
level waittill( "between_round_over" );
triggers = getEntArray( "harrybo21_swapping_vending", "script_noteworthy" );
if ( !isDefined( triggers ) || triggers.size < 1 )
continue;

level.round_swapped = false;
}
}

// DONE =============================
harrybo21_perks_swapping_perk_machine_thread( machine )
{
while( 1 )
{
array = undefined;
self waittill( "trigger", user );
if ( ( isDefined( self.is_swapping ) && self.is_swapping ) || !isPlayer( user ) || !level.power_on || level.round_swapped )
{
wait .1;
continue;
}

triggers = getEntArray( "harrybo21_swapping_vending", "script_noteworthy" );
for ( i = 0; i < triggers.size; i++ )
{
triggers.is_swapping = true;
ent = getEnt( triggers.target, "targetname" );
ent.is_swapping = true;
if ( !isDefined( array ) )
array = ;

ent.light_location delete();
array = ent.script_string;
ent thread harrybo21_perks_swapping_perk_randomize();
}

harrybo21_perks_vulture_waypoint_functionality();

level.round_swapped = true;
level.is_swapping = true;
wait 4;
level.is_swapping = false;
for ( i = 0; i < triggers.size; i++ )
{
ent = getEnt( triggers.target, "targetname" );
ent notify( "perk_swap_done" );
}
if ( array.size > 1 )
{
new_array = ;
for ( i = 1; i < array.size; i++ )
new_array = array;

new_array = array;
}
else
new_array = array;

for ( i = 0; i < triggers.size; i++ )
{
ent = getEnt( triggers.target, "targetname" );
ent.script_string = new_array;
ent setModel( level.zombie_perks.perk_model );
ent.is_swapping = undefined;
if ( isDefined( ent.active ) && ent.active )
{
ent.light_location = spawn( "script_model", ent.origin + ( anglesToForward( ent.angles + ( 0, 90, 0 ) ) * -0 ) );
ent.light_location.angles = ( ent.angles + ( 0, 0, 0 ) );
ent.light_location setModel( "tag_origin" );
ent.trig SetHintString( level.zombie_perks.perk_hint );
PlayFxOnTag( level.zombie_perks.perk_light, ent.light_location, "tag_origin" );
ent setModel( level.zombie_perks.perk_model_on );
}
}
for ( i = 0; i < triggers.size; i++ )
triggers.is_swapping = undefined;

harrybo21_perks_vulture_waypoint_functionality();

}
}

// DONE =============================
harrybo21_perks_swapping_perk_randomize()
{
self endon( "perk_swap_done" );
self.is_swapping = true;
self hide();
self.origin = self.origin + ( 0, 0, 200 );
wait .1;
self show();
self moveZ( -200, 4, 3, 1 );
self playSound( "perk_lottery" );
playfxontag( level._effect, self, "tag_origin" );

wait_time = .01;
last_key = undefined;
while( 1 )
{
array = ;
triggers = getEntArray( "harrybo21_swapping_vending", "script_noteworthy" );
for ( i = 0; i < triggers.size; i++ )
{
ent = getEnt( triggers.target, "targetname" );
array = ent.script_string;
}
array = array_randomize( array );

key_use = 0;
if ( isDefined( last_key ) && last_key == array && array.size > 1 )
key_use = 1;

self setModel( level.zombie_perks ].perk_model );
last_key = array;
wait wait_time;
wait_time += .01;
}
}

// DONE =============================
harrybo21_perks_machines_power_watcher()
{
while( 1 )
{
while( 1 )
{
self waittill( "activate_machine" );
if ( isDefined( self.active ) && self.active )
continue;

if ( isDefined( self.secondary_power ) && !self.secondary_power.active )
continue;

break;
}
self thread harrybo21_perks_activate_machine();
while( 1 )
{
self waittill( "deactivate_machine" );
if ( isDefined( self.active ) && !self.active )
continue;

break;
}
self thread harrybo21_perks_deactivate_machine();
}
}

// REVIEW =============================
harrybo21_perks_check_for_change()
{
self endon( "machine_removed" );
change_collected = false;
while( 1 )
{
players = get_players();
for ( i = 0; i < players.size; i++ )
{
if ( distance( players.origin, self.origin ) < 64 && players getStance() != "prone" && !players maps\_laststand::player_is_in_laststand() ) // && !players.being_revived )
{
self playsound ( "perks_rattle" );
while( 1 )
{
if ( distance( players.origin, self.origin ) >= 64 || players maps\_laststand::player_is_in_laststand() )
break;

if ( players getStance() == "prone" && !change_collected )
{
players maps\_zombiemode_score::add_to_player_score( 20 );
play_sound_at_pos( "purchase", players.origin );
change_collected = true;
}
wait .1;
}
}
}
wait .1;
}
}

// DONE =============================
harrybo21_perks_ignore_power( perk )
{
level.zombie_perks.ignore_power = true;
vending_machines = harrybo21_perks_get_machines();
for ( i = 0; i < vending_machines.size; i++ )
{
if ( isDefined( vending_machines.script_string ) && vending_machines.script_string == perk )
{
vending_machines.ignore_power = true;
vending_machines thread harrybo21_perks_activate_machine();
}
}
}

// DONE =============================
harrybo21_perks_add_perk( perk_name, perk_cost, perk_model, perk_model_on, perk_shader, perk_light, perk_hint, perk_function, perk_quote, perk_bottle, perk_jingle, perk_sting )
{
if ( isDefined ( level.zombie_perks ) )
return;

PrecacheModel( perk_model );
PrecacheModel( perk_model_on );
PrecacheShader( perk_shader );

struct = SpawnStruct();
struct.perk_name = perk_name;
struct.perk_hint = "Press & hold ^6&&1^7 to buy " + perk_hint + " [Cost: " + perk_cost + "]";
struct.perk_model = perk_model;
struct.perk_model_on = perk_model_on;
struct.perk_shader = perk_shader;
struct.perk_quote = perk_quote;
struct.perk_function = perk_function;
struct.perk_light = perk_light;
struct.perk_bottle = perk_bottle;
struct.perk_jingle = perk_jingle;
struct.perk_sting = perk_sting;
struct.perk_cost = perk_cost;

level.wonderfizz_perks = perk_name;

level.zombie_perks = struct;
}

// DONE =============================
harrybo21_perks_remove_perk( perk_name )
{
vending_machines = harrybo21_perks_get_machines();
for ( i = 0; i < vending_machines.size; i++ )
{
if ( vending_machines.script_string == perk_name )
{
vending_machines setmodel( level.zombie_perks.perk_model_on );
vending_machines thread harrybo21_perks_remove_perk_machine();
}
}
}

// DONE =============================
harrybo21_perks_limit_perk_usage( perk, limit )
{
for ( i = 0; i < limit; i++ )
level waittill( perk + "_drank" );

vending_machines = harrybo21_perks_get_machines();
for ( i = 0; i < vending_machines.size; i++ )
{
if ( isDefined( vending_machines.script_string ) && vending_machines.script_string == perk )
vending_machines thread harrybo21_perks_remove_perk_machine();

}
level.zombie_perks.script_string ].removed = true;
}

// DONE =============================
harrybo21_perks_limit_machine_usage( limit )
{
count = limit;
while( count > 0 )
{
self waittill( "machine_used" );
count--;
}
self thread harrybo21_perks_remove_perk_machine();
}

// DONE =============================
harrybo21_perks_remove_perk_machine()
{
wait 2;
self playSound( "ann_vox_laugh_l" );
self.active = false;
harrybo21_perks_vulture_waypoint_functionality();
self vibrate( ( 0, -100, 0 ) , 0.3, 0.4, 3 );
wait 3;
self moveZ( 40, 4, 3 );
wait 3;
playfx( level._effect, self.origin );
self.clip delete();
self.trig delete();
if ( isDefined( self.light_location ) )
self.light_location delete();

self notify( "machine_removed" );
self delete();
}

// DONE =============================
harrybo21_perks_activate_machine()
{
while ( isDefined( self.swapping_machine ) && self.swapping_machine && isDefined( level.is_swapping ) && level.is_swapping )
wait .1;

self endon( "machine_removed" );
self.active = true;
self setmodel( level.zombie_perks.perk_model_on );
self vibrate( ( 0, -100, 0 ) , 0.3, 0.4, 3 );
self playsound( "perks_power_on" );

self.light_location = spawn( "script_model", self.origin + ( anglesToForward( self.angles + ( 0, 90, 0 ) ) * -0 ) );
self.light_location.angles = ( self.angles + ( 0, 0, 0 ) );
self.light_location setModel( "tag_origin" );
self.light_location playLoopSound( "perks_machine_loop" );
PlayFxOnTag( level.zombie_perks.perk_light, self.light_location, "tag_origin" );

self.trig SetHintString( level.zombie_perks.perk_hint );
harrybo21_perks_vulture_waypoint_functionality();
self notify( "machine_activated" );
}

// DONE =============================
harrybo21_perks_deactivate_machine()
{
self.active = false;
self setmodel( level.zombie_perks.perk_model );
self.light_location stopLoopSound( "perks_machine_loop" );
self.light_location delete();
self.trig SetHintString( &"ZOMBIE_FLAMES_UNAVAILABLE" );
harrybo21_perks_vulture_waypoint_functionality();
self notify( "machine_turned_off" );
}

// DONE =============================
harryb21_perks_trigger_visible_watcher( machine )
{
self endon( "machine_removed" );
while( 1 )
{
players = get_players();
for ( i = 0; i < players.size; i++ )
{
if ( ( isDefined( self.swapping_machine ) && isDefined( level.is_swapping ) && level.is_swapping ) || ( isDefined( players.is_drinking ) && players.is_drinking ) || players hasPerk( machine.script_string )  || players maps\_laststand::player_is_in_laststand()
|| players.perk_inventory.size >= players.max_perks || ( isDefined( players.last_stand ) && players.last_stand ) || players isThrowingGrenade() || players isSwitchingWeapons() )
self.trig SetInvisibleToPlayer( players, true );
else
self.trig SetInvisibleToPlayer( players, false );
}
wait .1;
}
}

// DONE =============================
harrybo21_perks_trigger_watcher( machine )
{
machine endon( "machine_removed" );
machine waittill( "machine_activated" );
while( 1 )
{
player = undefined;
self waittill( "trigger", player );

if ( !machine.active || ( isDefined( player.is_drinking ) && player.is_drinking ) || player hasPerk( machine.script_string ) || player maps\_laststand::player_is_in_laststand()
|| player.perk_inventory.size >= player.max_perks || player isThrowingGrenade() || player isSwitchingWeapons() )
{
wait .1;
continue;
}
if ( player.score < level.zombie_perks.perk_cost  )
{
machine playsound( "deny" );
player thread harry_powerup_quotes( "nomoney_generic_d_" );
continue;
}

player.is_drinking = 1;
player maps\_zombiemode_score::minus_to_player_score( level.zombie_perks.perk_cost );
playsoundatposition( "bottle_dispense3d", machine.origin );
player thread harrybo21_perks_bottle_drink( machine.script_string );
machine playSound( level.zombie_perks.perk_sting, "sound_done", true );
machine notify( machine.script_string + "_drank" );
level notify( machine.script_string + "_drank" );
machine notify( "machine_used" );
}
}

// DONE =============================
harrybo21_perks_bottle_drink( perk )
{
while ( self isSwitchingWeapons() )
wait .1;

index = level.zombie_perks.perk_bottle;
gun = undefined;
self _disableOffhandWeapons();
self DisableWeaponCycling();
self AllowLean( false );
self AllowAds( false );
self AllowSprint( false );
self AllowProne( false );
self AllowMelee( false );
if ( level.zombie_vars && self hasPerk( "specialty_bulletaccuracy" ) )
self setClientDvar( "cg_laserForceOn", 0 );

if( self GetStance() == "prone" )
self SetStance( "crouch" );

gun = self GetCurrentWeapon();
self GiveWeapon( "zombie_bo2_perk_bottles", index );
self SwitchToWeapon( "zombie_bo2_perk_bottles" );
self waittill_any( "fake_death", "death", "player_downed", "weapon_change_complete" );

self TakeWeapon( "zombie_bo2_perk_bottles" );

self SwitchToWeapon( gun );

self thread harrybo21_perks_give( perk );

while ( self isSwitchingWeapons() )
wait .1;

self _enableOffhandWeapons();
self EnableWeaponCycling();
self AllowLean( true );
self AllowAds( true );
self AllowSprint( true );
self AllowProne( true );
self AllowMelee( true );
self waittill_any( "fake_death", "death", "player_downed", "weapon_change_complete" );
self.is_drinking = undefined;
if ( level.zombie_vars && self hasPerk( "specialty_bulletaccuracy" ) )
self setClientDvar( "cg_laserForceOn", 1 );

self thread harrybo21_vending_play_quote( perk );

self notify( "machine_used" );
}

// REVIEW =============================
harrybo21_perks_give( perk )
{
if ( self maps\_laststand::player_is_in_laststand() )
return;

// self thread harry_powerup_quotes( level.zombie_perks.perk_quote );
self harrybo21_perks_give_perk( perk );
self setblur( 4, .1 );
wait .1;
self setblur( 0, .1 );
}

// DONE =============================
harrybo21_perks_give_perk( perk )
{
self notify( "obtained_" + perk );
if ( self hasPerk( perk ) )
return;

self.perk_inventory = perk;
self thread harrybo21_perks_hud_set( perk );
if ( !self.immune_to_powerdown && isDefined( level.power_on ) && !level.power_on && !harrybo21_perks_is_machine_for_perk_active( perk ) )
return;

self setPerk( perk );
if ( isDefined( level.zombie_perks.perk_function ) )
self thread [[ level.zombie_perks[ perk ].perk_function ]]( true );
}

// DONE =============================
harrybo21_perks_take_perk( perk )
{
for ( i = 0; i < self.perk_inventory.size; i++ )
{
if ( self.perk_inventory == perk )
self.perk_inventory = array_remove( self.perk_inventory, self.perk_inventory );

}
self unSetPerk( perk );
self harrybo21_perks_hud_remove( perk );
if ( isDefined( level.zombie_perks.perk_function ) )
self thread [[ level.zombie_perks[ perk ].perk_function ]]( false );
}

// DONE =============================
harrybo21_perks_hud_set( perk )
{
if ( !isDefined( self.perk_hud ) )
self.perk_hud = ;

hud = NewClientHudElem( self );
hud.perk = perk;
hud.foreground = true;
hud.sort = 1;
hud.hidewheninmenu = false;
hud.alignX = "left";
hud.alignY = "bottom";
hud.horzAlign = "left";
hud.vertAlign = "bottom";
hud.x = self.perk_hud.size * 30;
hud.y = hud.y - 70;
// hud.x = 0; // For vertical shaders
// hud.y = 0 - 70 - ( self.perk_hud.size * 30 ); // For vertical shaders
hud.alpha = 0;
hud SetShader( level.zombie_perks.perk_shader , 48, 48 );
hud scaleOverTime( .5, 24, 24 );
hud fadeOverTime( .5 );
hud.alpha = 1;
self.perk_hud = hud;
}

// DONE =============================
harrybo21_perks_hud_fade_power_off( perk )
{
if ( !isDefined( self.perk_hud ) || self.perk_hud.size < 1 )
return;

for ( i = 0; i < self.perk_hud.size; i++ )
{
if ( self.perk_hud.perk != perk )
continue;

self.perk_hud fadeOverTime( .5 );
self.perk_hud.alpha = .25;

}
}

// DONE =============================
harrybo21_perks_hud_fade_power_on( perk )
{
if ( !isDefined( self.perk_hud ) || self.perk_hud.size < 1 )
return;

for ( i = 0; i < self.perk_hud.size; i++ )
{
if ( self.perk_hud.perk != perk )
continue;

self.perk_hud fadeOverTime( .5 );
self.perk_hud.alpha = 1;

}
}

// DONE =============================
harrybo21_perks_hud_remove( perk )
{
new_array = ;
for ( i = 0; i < self.perk_hud.size; i++ )
{
if ( self.perk_hud.perk == perk )
self.perk_hud thread maps\_harrybo21_utilities::harry_fade_hud( .5, 0 );
else
new_array = self.perk_hud;

}
self.perk_hud = new_array;
for ( i = 0; i < self.perk_hud.size; i++ )
self.perk_hud maps\_harrybo21_utilities::harry_move_hud( .5, 0 + ( i * 30 ), self.perk_hud.y );

}

// DONE =============================
harrybo21_perks_get_hud_index( perk )
{
for ( i = 0; i < self.perk_hud.size; i++ )
{
if ( self.perk_hud.perk == perk )
return i;

}
return undefined;
}

// DONE =============================
harrybo21_perks_remove_all()
{
if ( !isDefined( self.perk_inventory ) || self.perk_inventory.size < 1 )
return;

take = ;
for( p = 0; p < self.perk_inventory.size; p++ )
take = self.perk_inventory;


for( p = 0; p < take.size; p++ )
self harrybo21_perks_take_perk( take );
}

// REVIEW =============================
harrybo21_perks_play_jingle()
{
self endon( "machine_turned_off" );
while( 1 )
{
wait randomInt( level.zombie_vars, level.zombie_vars );
if ( isDefined( level.perk_jingle_playing ) || !self.active )
{
wait 1;
continue;
}
if ( randomInt( 100 ) > 15 )
{
if ( isDefined( level.zombie_perks.perk_jingle ) )
{
self playsound( level.zombie_perks.perk_jingle, "sound_done", true );
self waittill( "sound_done" );
}
else
{
wait( randomfloatrange( 7, 18 ) );
playsoundatposition ( "broken_random_jingle", self.origin );
playsoundatposition ( "electrical_surge", self.origin );
}
}
}
}

// REVIEW =============================
harrybo21_vending_play_quote( type )
{
/*
self endon("death");
self endon("disconnect");

index = maps\_zombiemode_weapons::get_player_index( self );
sound = undefined;

if( isdefined( level.player_is_speaking ) && level.player_is_speaking )
return;

player_index = "vox_plr_" + index + "_";

switch( type )
{
case "specialty_armorvest":
sound_to_play = "perk_jugga_d_0";
break;
case "specialty_fastreload":
sound_to_play = "perk_speed_d_0";
break;
case "specialty_quickrevive":
sound_to_play = "perk_revive_d_0";
break;
case "specialty_rof":
sound_to_play = "perk_tap_d_0";
break;
case "specialty_detectexplosive":
sound_to_play = "perk_phdflopper_d_0";
break;
case "specialty_extraammo":
sound_to_play = "perk_mule_d_0";
break;
case "specialty_longersprint":
sound_to_play = "perk_stamine_d_0";
break;
case "specialty_bulletaccuracy":
sound_to_play = "perk_deadshot_d_0";
break;
case "specialty_upgrade":
rand = randomInt( 5 );
sound_to_play = "pap_arm_d_" + rand;
break;
case "nomoney":
rand = randomInt( 5 );
sound_to_play = "nomoney_generic_d_" + rand;
break;
default:
return;
}

wait 1;
self playSound( player_index + sound_to_play, "sound_done" );
self waittill( "sound_done" );
level.player_is_speaking = undefined;
*/
}

// REVIEW =============================
harrybo21_perks_fake_death()
{
level notify( "fake_death" );
self notify( "fake_death" );

self setClientDvar( "has_retriever", 0 );
self setClientDvar( "retriever_charged", 0 );
self.ignoreme = true;
self EnableInvulnerability();
self SetStance( "prone" );
self AllowStand( false );
self AllowCrouch( false );
self AllowSprint( false );
self AllowProne( true );
self harrybo21_perks_remove_all();
self setactionslot( 1, "", undefined );
self setactionslot( 2, "", undefined );
self setactionslot( 3, "", undefined );
self setactionslot( 4, "", undefined );
self takeallweapons();
if ( !is_coop() )
{
self giveWeapon( level.zombie_vars );
self SwitchToWeapon( level.zombie_vars );
self giveWeapon( "bo2_zm_frag_grenade" );
self setWeaponAmmoClip( "bo2_zm_frag_grenade", 2 );
}
else
{
self giveWeapon( level.zombie_vars );
self SwitchToWeapon( level.zombie_vars );
self giveWeapon( "bo2_zm_frag_grenade" );
self setWeaponAmmoClip( "bo2_zm_frag_grenade", 2 );
}
self VisionSetNaked( "laststand" );
}

// REVIEW =============================
harrybo21_perks_player_damage_override( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, modelIndex, psOffsetTime )
{
if( sMeansOfDeath == "MOD_FALLING" )
{
sMeansOfDeath = "MOD_EXPLOSIVE";
}

if( isDefined( eAttacker ) )
{
if( isDefined( self.ignoreAttacker ) && self.ignoreAttacker == eAttacker )
{
return;
}

if( isDefined( eAttacker.is_zombie ) && eAttacker.is_zombie )
{
self.ignoreAttacker = eAttacker;
self thread maps\_zombiemode::remove_ignore_attacker();
}

if( isDefined( eAttacker.damage_mult ) )
{
iDamage *= eAttacker.damage_mult;
}
eAttacker notify( "hit_player" );
}
finalDamage = iDamage;
self.loadout = self harrybo21_collect_loadout();
if( sMeansOfDeath == "MOD_PROJECTILE" || sMeansOfDeath == "MOD_PROJECTILE_SPLASH" || sMeansOfDeath == "MOD_GRENADE" || sMeansOfDeath == "MOD_GRENADE_SPLASH" )
{
if( self.health > 75 )
{
finalDamage = 75;
self maps\_callbackglobal::finishPlayerDamageWrapper( eInflictor, eAttacker, finalDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, modelIndex, psOffsetTime );
return;
}
}

if( iDamage < self.health )
{
if ( IsDefined( eAttacker ) )
eAttacker.sound_damage_player = self;

self maps\_callbackglobal::finishPlayerDamageWrapper( eInflictor, eAttacker, finalDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, modelIndex, psOffsetTime );
return;
}
if( level.intermission )
{
level waittill( "forever" );
}

players = get_players();
count = 0;
for( i = 0; i < players.size; i++ )
{
if( players[i] == self || players[i].is_zombie || players[i] maps\_laststand::player_is_in_laststand() || players[i].sessionstate == "spectator" )
count++;

}

if( count < players.size )
{
self maps\_callbackglobal::finishPlayerDamageWrapper( eInflictor, eAttacker, finalDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, modelIndex, psOffsetTime );
return;
}
perk_stands = undefined;
if ( self hasPerk( "specialty_shades" ) )
{
perk_stands = "specialty_shades";
}
else if ( self hasPerk( "specialty_reconnaissance" ) )
{
perk_stands = "specialty_reconnaissance";
}
else if ( self hasPerk( "specialty_quickrevive" ) && !is_coop() )
{
perk_stands = "specialty_quickrevive";
}
self.intermission = true;
self maps\_laststand::PlayerLastStand( eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime );

self harrybo21_perks_fake_death();

self.revived = undefined;

if ( isDefined( perk_stands ) && perk_stands == "specialty_shades" )
self harrybo21_perks_whos_who_laststand();
else if ( isDefined( perk_stands ) && perk_stands == "specialty_reconnaissance" )
self harrybo21_perks_tombstone_activate();
else if ( isDefined( perk_stands ) && perk_stands == "specialty_quickrevive" )
self harrybo21_perks_revive_auto_revive();

// self harrybo21_perks_remove_all();

if( count == players.size )
{
if ( count == 1 )
{
if ( !isDefined( players.revived ) || ( isDefined( players.revived ) && !players.revived ) )
{
level notify( "end_game" );
harrybo21_perks_end_game_hands();
}
}
else
{
level notify( "end_game" );
harrybo21_perks_end_game_hands();
}
}
else
self maps\_callbackglobal::finishPlayerDamageWrapper( eInflictor, eAttacker, finalDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, modelIndex, psOffsetTime );

}

// REVIEW =============================
harrybo21_perks_player_revive()
{
self notify ( "player_revived", self );
self reviveplayer();

self harrybo21_return_loadout( self.loadout, self.loadout.perk_inventory );

self thread maps\_laststand::say_revived_vo();
self.revivetrigger delete();
self.revivetrigger = undefined;
self.health = self.maxhealth;
self AllowStand( true );
self AllowCrouch( true );
self AllowProne( true );
self AllowSprint( true );
self SetStance( "stand" );
self DisableInvulnerability();
self EnableWeaponCycling();
self _enableOffhandWeapons();
self freezecontrols( false );
self.being_revived = false;
self.ignoreme = false;
self.revived = true;
wait .1;
if ( isDefined( self.whos_who_active ) )
self VisionSetNaked( "zombie_whos_who", 1 );
else
{
self VisionSetNaked( level.zombie_vars, 1 );
setClientSysState( "lsm", "0", self );
}

if ( self hasPerk( "specialty_armorvest" ) )
{
self.maxhealth = level.zombie_vars;
self.health = level.zombie_vars;
}
else
{
self.maxhealth = level.zombie_vars;
self.health = level.zombie_vars;
}
self.intermission = false;
}

// REVIEW =============================
harrybo21_perks_player_fake_revive()
{
self reviveplayer();
self AllowStand( true );
self AllowCrouch( true );
self AllowProne( true );
self AllowSprint( true );
self SetStance( "stand" );
self DisableInvulnerability();
self EnableWeaponCycling();
self _enableOffhandWeapons();
self freezecontrols( false );
self.revivetrigger delete();
self.health = self.maxhealth;
self.revivetrigger = undefined;
self.being_revived = false;
self.ignoreme = false;
self.revived = true;
self stopLoopSound();
self VisionSetNaked( level.zombie_vars, 1 );
setClientSysState( "lsm", "0", self );
if ( self hasPerk( "specialty_armorvest" ) )
{
self.maxhealth = level.zombie_vars;
self.health = level.zombie_vars;
}
else
{
self.maxhealth = level.zombie_vars;
self.health = level.zombie_vars;
}
self.intermission = false;
}

// REVIEW =============================
harrybo21_perks_end_game_hands()
{
players = get_players();
for ( i = 0; i < players.size; i++ )
{
players takeallweapons();
players giveWeapon( "zombie_downed" );
players SwitchToWeapon( "zombie_downed" );
players VisionSetNaked( level.zombie_vars, 1 );
players SetStance( "prone" );
players EnableInvulnerability();
players.ignoreme = true;
players DisableWeaponCycling();
players _disableOffhandWeapons();
players freezecontrols( true );
}
}

// DONE =============================
harrybo21_perks_is_perk_in_game( perk )
{
keys = getArrayKeys( level.zombie_perks );
if ( !isDefined( keys ) || keys.size < 1 )
return false;

for ( i = 0; i < keys.size; i++ )
{
if ( keys == perk )
return true;

}
return false;
}

harrybo21_perks_do_gib( plr )
{
chance = 58;
if ( level.round_number > 15 )
chance = 38;
if ( level.round_number > 24 )
chance = 10;

shouldGib = randomIntRange( 0,100 ) < chance;
gibType = strtok( "legs:head:arm",":" );
 
if( ( isdefined( self.boss ) && self.boss ) || self.animname == "jnaut_melee" || self.animname == "jnaut_gunner" || ( isDefined( self.boss_mech ) && self.boss_mech ) || ( isDefined( self.animname ) && self.animname == "boss_zombie" ) || ( isDefined( self.animname ) && self.animname == "sonic_zombie" ) )
return;
 
if ( shouldGib && !isdefined( self.boss ) )
{
switch( gibType )
{
case "legs":
{
self thread maps\_zombiemode_spawner::make_crawler();
break;
}
case "head":
{
self thread maps\_zombiemode_spawner::zombie_head_gib( plr );
break;
}
case "arm":
{
refs = ;
refs = "guts";
refs = "right_arm";
refs = "left_arm";
self.a.gib_ref = animscripts\death::get_random( refs );
break;
}
}
self thread animscripts\death::do_gib();
}
}

// Perks Functionality ==============================================================================================

// Speed Functionality ( "specialty_quickrevive" ) ==============================================================================================

harrybo21_perks_revive( give )
{
self endon( "disconnect" );
if ( isDefined( give ) && give )
{
// what to do when perk is given
}
else
{
// what to do when perk is lost
self notify( "lost_specialty_quickrevive" );
}
}

harrybo21_perks_revive_laststand_check()
{
if ( isDefined( self.revive_last_stand ) && self.revive_last_stand )
return true;
else
return false;
}

harrybo21_perks_revive_auto_revive()
{

// self thread maps\_laststand::laststand_give_grenade();

self.revive_hud setText( &"GAME_PLAYER_IS_REVIVING_YOU", self );
self thread maps\_laststand::revive_hud_show_n_fade( level.zombie_vars );

if( !isdefined( self.reviveProgressBar ) )
self.reviveProgressBar = self createPrimaryProgressBar();

self.reviveProgressBar updateBar( 0.01, 1 / level.zombie_vars );

wait level.zombie_vars;

if( isdefined( self.reviveProgressBar ) )
self.reviveProgressBar destroyElem();

self harrybo21_perks_player_revive();

self.revives++;
self.stats = self.revives;
}

// Jugg Functionality ( "specialty_armorvest" ) ==============================================================================================

harrybo21_perks_juggernog( give )
{
self endon( "disconnect" );
if ( isDefined( give ) && give )
{
self.maxhealth = level.zombie_vars;
self.health = level.zombie_vars;
}
else
{
self.maxhealth = level.zombie_vars;
self.health = level.zombie_vars;
self notify( "lost_specialty_armorvest" );
}
}

// Speed Functionality ( "specialty_fastreload" ) ==============================================================================================

harrybo21_perks_speed( give )
{
self endon( "disconnect" );
if ( isDefined( give ) && give )
{
}
else
{
self notify( "lost_specialty_fastreload" );
}
}

// Double Tap 2.0 Functionality ( "specialty_rof" ) ==============================================================================================

harrybo21_perks_doubletap( give )
{
self endon( "disconnect" );
if ( isDefined( give ) && give )
{
}
else
{
self.attacker.doubletap_hit = undefined;
self notify( "lost_specialty_rof" );
}
}

harrybo21_perks_doubletap_damage( amount, origin, attacker, location, direction_vec, point, type )
{
self endon( "death" );
self.damageLocation = location;
wait_network_frame();
setPlayerIgnoreRadiusDamage( true );
self.attacker radiusDamage( self.origin, 1, amount, amount, self.attacker, self.damagemod );
setPlayerIgnoreRadiusDamage( false );
// self doDamage( amount, origin, attacker );
self.damageLocation = location;
// iPrintLn( location );
wait_network_frame();
}

harrybo21_perks_doubletap_watcher()
{
self endon( "death" );
while( 1 )
{
self waittill( "damage", amount, attacker, direction_vec, point, type );

if ( type == "MOD_PISTOL_BULLET" || type == "MOD_RIFLE_BULLET" || ( isDefined( self.damageWeapon ) && WeaponClass( self.damageWeapon ) == "spread" ) )
{
if( isDefined( attacker ) && isplayer( attacker ) && isAlive( attacker ) )
{
if( attacker hasPerk( "specialty_rof" )  )
self harrybo21_perks_doubletap_damage( amount, self.origin, attacker, self.damageLocation );
if ( ( self.damageLocation == "head" || self.damageLocation == "helmet" ) && attacker hasPerk( "specialty_bulletaccuracy" )  )
self harrybo21_perks_deadshot_damage( amount, attacker, type, self.damageLocation );

}
}
wait_network_frame();
}
}

// Deadshot Functionality ( "specialty_bulletaccuracy" ) ==============================================================================================

harrybo21_perks_deadshot( give )
{
self endon( "disconnect" );
if ( isDefined( give ) && give )
{
self setClientDvar( "cg_laserForceOn", level.zombie_vars );
self setClientDvar( "cg_laserRadius", level.zombie_vars );
self setClientDvar( "cg_laserLightRadius", 0.4, level.zombie_vars );
self setClientDvar( "perk_weapSpreadMultiplier", level.zombie_vars );
}
else
{
self.attacker.deadshot_hit = undefined;
self setClientDvar( "cg_laserForceOn", 0 );
self setClientDvar( "perk_weapSpreadMultiplier", 0.65 );
self notify( "lost_specialty_bulletaccuracy" );
}
}

harrybo21_perks_deadshot_damage( amount, origin, attacker, location )
{
self endon( "death" );
self.deadshot_hit = true;
new_damage = amount / 4;
if ( attacker hasPerk( "specialty_rof" ) )
new_damage = new_damage * 2;

if ( new_damage > self.health )
{
score = level.zombie_vars;
if ( isDefined( level.zombie_vars["zombie_powerup_point_doubler_on"] ) && level.zombie_vars["zombie_powerup_point_doubler_on"] )
score = score * 2;

attacker maps\_zombiemode_score::add_to_player_score( score );
}
self.damageLocation = location;
wait_network_frame();
self.attacker radiusDamage( self.origin, 1, amount, amount, self.attacker, self.damagemod );
// self doDamage( new_damage, origin, attacker );
wait_network_frame();
self.deadshot_hit = undefined;
}

// Stamin-Up Functionality ( "specialty_longersprint" ) ==============================================================================================

harrybo21_perks_staminup( give )
{
self endon( "disconnect" );
if ( isDefined( give ) && give )
{
self setmovespeedscale( level.zombie_vars );
self setClientDvar( "player_sprintTime" , level.zombie_vars );
}
else
{
self setmovespeedscale( 1 );
self setClientDvar( "player_sprintTime" , 4 );
self notify( "lost_specialty_longersprint" );
}
}

// PHD Functionality ( "specialty_detectexplosive" ) ==============================================================================================

harrybo21_perks_phd( give )
{
self endon( "disconnect" );
if ( isDefined( give ) && give )
{
self thread harrybo21_perks_phd_watcher();
}
else
{
self notify( "phd_lost" );
self notify( "lost_specialty_detectexplosive" );
}
}

harrybo21_perks_phd_watcher()
{
self endon( "disconnect" );
self endon( "phd_lost" );
while( 1 )
{
self waittill( "do_nuke" );

PlayFxOnTag( level._effect, self, "tag_origin" );
self playSound( "phd_explode" );

ai = GetAiSpeciesArray( "axis", "all" );
for( i = 0; i < ai.size; i++ )
{
if ( distance( self.origin, ai.origin ) > level.zombie_vars )
continue;

ai.damagemod = "MOD_EXPLOSIVE";
fraction = level.zombie_vars / distance( self.origin, ai.origin );
damage = level.zombie_vars - fraction;

if( ( isdefined( ai.boss ) && ai.boss ) || ( isDefined( ai.boss_mech ) && ai.boss_mech ) || ( isDefined( ai.animname ) && ( ai.animname == "boss_zombie" || ai.animname == "sonic_zombie" || ai.animname == "napalm_zombie" ) ) )
continue;

if ( isDefined( level.zombie_vars ) && level.zombie_vars )
damage = ai.health + 666;
if ( damage < ai.health )
ai thread harrybo21_perks_do_gib();

ai DoDamage( damage , ai.origin, self );
}
wait .1;
}
}

// Mule Kick Functionality ( "specialty_extraammo" ) ==============================================================================================

harrybo21_perks_mulekick( give )
{
self endon( "disconnect" );
if ( isDefined( give ) && give )
{
for ( i = 2; i < level.zombie_vars; i++ )
{
// if ( !isDefined( self.inventory ) )
self.inventory = "none";
self.double_pap_inventory = 0;
}
wait .5;
self harrybo21_perks_mule_kick_hud_effect();
}
else
{
self notify( "lost_specialty_extraammo" );
}
}

harrybo21_perks_mule_kick_take_extras()
{
self.lost_mule_guns = ;
self.muleAmmo = ;
if ( !isDefined( self.inventory ) || self.inventory.size < 3 )
return;

current_weapon = self getCurrentWeapon();
self.mule_kick_switch_back = current_weapon;
for ( i = 2; i < self.inventory.size; i++ )
{
self.lost_mule_guns = self.inventory;
self.muleAmmo ] = self GetWeaponAmmoClip( self.inventory );
self.muleAmmo ] = self GetWeaponAmmoStock( self.inventory );

self takeWeapon( self.inventory );
if ( current_weapon == self.inventory )
self switchToWeapon( self.inventory );

}
new_inventory = ;
for ( i = 0; i < 2; i++ )
{
new_inventory = self.inventory;
}
self.inventory = new_inventory;
}

harrybo21_perks_mule_kick_return_extras()
{
if ( !isDefined( self.lost_mule_guns ) || self.lost_mule_guns.size < 1 )
return;

current_weapon = self getCurrentWeapon();
for ( i = 0; i < self.lost_mule_guns.size; i++ )
{
self.inventory = self.lost_mule_guns;
self giveWeapon( self.lost_mule_guns );
self SetWeaponAmmoClip( self.lost_mule_guns, self.muleAmmo ] );
if ( WeaponType( self.lost_mule_guns ) != "grenade" )
self SetWeaponAmmoStock( self.lost_mule_guns, self.muleAmmo ] );

}
if ( current_weapon != self.mule_kick_switch_back )
self switchToWeapon( self.mule_kick_switch_back );

self.muleAmmo = undefined;
self.lost_mule_guns = undefined;
self.mule_kick_switch_back = undefined;
}

harrybo21_perks_mule_kick_weapon_change_watcher()
{
while( 1 )
{
self waittill( "weapon_change" );
if ( !self hasPerk( "specialty_extraammo" ) )
continue;

wait .1;
current_weapon = self getCurrentWeapon();
if ( self harrybo21_get_weapon_index( current_weapon ) > 1 )
self harrybo21_perks_mule_kick_hud_effect();

}
}

harrybo21_perks_mule_kick_hud_effect()
{
perk_index = self harrybo21_perks_get_hud_index( "specialty_extraammo" );
if ( !isDefined( perk_index ) )
return;

self endon( "disconnect" );
self endon( "lost_specialty_extraammo" );
self endon( "death" );
self.mule_glow_hud = NewClientHudElem( self );
self.mule_glow_hud.foreground = true;
self.mule_glow_hud.sort = 1;
self.mule_glow_hud.hidewheninmenu = false;
self.mule_glow_hud.alignX = "left";
self.mule_glow_hud.alignY = "bottom";
self.mule_glow_hud.horzAlign = "left";
self.mule_glow_hud.vertAlign = "bottom";
self.mule_glow_hud.x = ( perk_index * 30 ) - 12;
self.mule_glow_hud.y = self.mule_glow_hud.y - 70 + 12;
self.mule_glow_hud SetShader( "vending_vulture_glow_shader" , 48, 48 );
self.mule_glow_hud.alpha = 0;

self.mule_glow_hud harry_blink_hud( .5 );
}

harrybo21_perks_mule_kick_hud( gun_name )
{
self endon( "disconnect" );
if ( !level.zombie_vars )
return;

self thread harrybo21_perks_mule_kick_hud_effect();
}

// Electric Cherry Functionality ( "specialty_boost" ) ==============================================================================================

harrybo21_perks_electric_cherry( give )
{
self endon( "disconnect" );
if ( give )
{
self.consecutive_electric_cherry_attacks = 0;
self thread harrybo21_perks_cherry_perk_watcher();
}
else
{
self notify( "cherry_lost" );
self thread harrybo21_perks_cherry_laststand();
self notify( "lost_specialty_boost" );
}
}

harrybo21_perks_cherry_perk_watcher()
{
self endon( "disconnect" );
self endon( "cherry_lost" );
while( 1 )
{
self waittill( "reload_start" );
if ( self getCurrentWeapon() == "zombie_shield" )
continue;

self thread harrybo21_perks_run_cherry_reload();
self playSound( "cherry_alert" );
weapon = self GetCurrentWeapon();
clip = self GetCurrentWeaponClipAmmo();
while( 1 )
{
if( weapon != self GetCurrentWeapon() || clip != self GetCurrentWeaponClipAmmo() )
{
self notify( "reload_complete" );
break;
}
wait .1;
}
}
}

harrybo21_perks_cherry_laststand()
{
self endon( "disconnect" );
self endon( "cherry_down_over" );

fx = spawn( "script_model", self.origin + ( 0, 0, 5 ) );
fx setmodel( "tag_origin" );
fx thread harrybo21_perks_play_cherry_fx( 1, self );
fx playsound( "cherry_reload_charge" );

wait .05;

ai = GetAiSpeciesArray( "axis", "all" );
ai = get_array_of_closest( self.origin, ai, undefined, undefined, 500 );
for( i = 0; i < ai.size; i++ )
{
if ( distance( self.origin, ai.origin ) > level.zombie_vars )
continue;

if( ( isdefined( ai.boss ) && ai.boss ) || ( isDefined( ai.boss_mech ) && ai.boss_mech ) || ( isDefined( ai.animname ) && ( ai.animname == "boss_zombie" || ai.animname == "sonic_zombie" || ai.animname == "napalm_zombie" ) ) )
{
ai doDamage( level.zombie_vars, self.origin, self );
continue;
}

if ( ai.health <= level.zombie_vars )
{
if( ai.has_legs )
ai.deathanim = random( level._zombie_tesla_death.animname ] );
else
ai.deathanim = random( level._zombie_tesla_crawl_death.animname ] );

self.score += level.zombie_vars;
self maps\_zombiemode_score::set_player_score_hud();

ai harrybo21_perks_cherry_death_fx();
}
else
{
ai thread harrybo21_perks_cherry_stunned();
}
ai DoDamage( level.zombie_vars , ai.origin );
}
self notify( "cherry_down_over" );
}

harrybo21_perks_run_cherry_reload()
{
self endon( "disconnect" );

current_weapon = self GetCurrentWeapon();
clip = WeaponClipSize( current_weapon );
remaining = self GetCurrentWeaponClipAmmo();

if( clip <= 0 )
return;

switch( self.consecutive_electric_cherry_attacks )
{
case 2:
{
n_zombie_limit = 8;
break;
}
case 3:
{
n_zombie_limit = 4;
break;
}
case 4:
{
n_zombie_limit = 2;
break;
}
default:
{
n_zombie_limit = undefined;
break;
}
}

fraction = remaining / clip;

stock_ammo = self GetWeaponAmmoStock( current_weapon );

if ( stock_ammo < clip )
fraction = stock_ammo / clip;

range = level.zombie_vars * ( 1 - fraction );
perk_dmg = level.zombie_vars * ( 1 - fraction );

if ( range < 64 )
range = 64;

fx = spawn( "script_model", self.origin + ( 0, 0, 5 ) );
fx setmodel( "tag_origin" );
// fx thread harrybo21_perks_follow_angles( self );
fx linkTo( self, "tag_origin", ( 0, 0, 0 ), ( 270, 0, 0 ) );
fx thread harrybo21_perks_play_cherry_fx( ( 1 - fraction ), self );
fx playsound( "cherry_reload_charge" );

ai = GetAiSpeciesArray( "axis", "all" );
ai = get_array_of_closest( self.origin, ai );
n_zombies_hit = 0;
for( i = 0; i < ai.size; i++ )
{
if ( distance( self.origin, ai.origin ) > range )
continue;
if ( isDefined( n_zombie_limit ) && n_zombies_hit > n_zombie_limit )
break;
if( ( isdefined( ai.boss ) && ai.boss ) || ( isDefined( ai.boss_mech ) && ai.boss_mech ) || ( isDefined( ai.animname ) && ( ai.animname == "boss_zombie" || ai.animname == "sonic_zombie" || ai.animname == "napalm_zombie" ) ) )
{
ai doDamage( level.zombie_vars * ( 1 - fraction ), self.origin, self );
continue;
}
if ( isDefined( level.zombie_vars["zombie_powerup_insta_kill_on"] ) && level.zombie_vars["zombie_powerup_insta_kill_on"] )
perk_dmg = ai.health + 666;

if ( ai.health <= perk_dmg )
{
if( ai.has_legs )
ai.deathanim = random( level._zombie_tesla_death.animname ] );
else
ai.deathanim = random( level._zombie_tesla_crawl_death.animname ] );

score = level.zombie_vars;
if ( level.zombie_vars["zombie_powerup_point_doubler_on"] )
score = score * 2;

self.score += score;
self maps\_zombiemode_score::set_player_score_hud();

ai harrybo21_perks_cherry_death_fx();
}
else
{
ai thread harrybo21_perks_cherry_stunned();
}
n_zombies_hit++;
ai DoDamage( perk_dmg , ai.origin );
}
self thread harrybo21_perks_cherry_cooldown_timer( self getCurrentWeapon() );
}

harrybo21_perks_play_cherry_fx( fraction, player )
{
self endon( "disconnect" );

self endon( "cherry_player_fx_over" );
if ( fraction >= 0.67 )
shock_fx = "cherry_shock_3";
else if ( fraction >= 0.33 && fraction < 0.67 )
shock_fx = "cherry_shock_2";
else
shock_fx = "cherry_shock_1";

PlayFxOnTag( level._effect, self, "tag_origin" );
wait 2;
self delete();
self notify( "cherry_player_fx_over" );
}

harrybo21_perks_cherry_stunned()
{
self thread harrybo21_perks_cherry_shock_fx();
if ( !self enemy_is_dog() )
self.cherry_stunned = true;

}

harrybo21_perks_cherry_cooldown_timer( str_current_weapon )
{
self notify( "electric_cherry_cooldown_started" );
self endon( "electric_cherry_cooldown_started" );
self endon( "cherry_lost" );
self endon( "death" );
self endon( "disconnect" );
self waittill( "reload_complete" );
n_cooldown_time = 3;
wait n_cooldown_time;
self.consecutive_electric_cherry_attacks = 0;
}

harrybo21_perks_cherry_shock_fx()
{
self endon( "death" );
tag = "J_SpineUpper";
fx = "tesla_shock_secondary";
if ( self enemy_is_dog() )
{
tag = "J_Spine1";
}
self playSound( "imp_tesla" );
PlayFxOnTag( level._effect, self, tag );
}

harrybo21_perks_cherry_death_fx()
{
self endon( "death" );
tag = "J_SpineUpper";
fx = "tesla_shock";
if ( self enemy_is_dog() )
{
tag = "J_Spine1";
}
PlayFxOnTag( level._effect, self, tag );
self playsound( "imp_tesla" );

if ( !self enemy_is_dog() )
{
PlayFxOnTag( level._effect, self, "J_Eyeball_LE" );
}
}

// Tombstone Functionality ( "specialty_reconnaissance" ) ==============================================================================================

harrybo21_perks_tombstone( give )
{
self endon( "disconnect" );
if ( isDefined( give ) && give )
{
// self thread harrybo21_perks_tombstone_watcher();
}
// NO LOSE FUNCTION FOR A REASON
}

harrybo21_perks_tombstone_spawn( owner )
{
tombstone = spawn( "script_model" , self.origin + ( 0, 0, 35 ) );
tombstone setModel( "bo2_ch_tombstone1" );
tombstone thread harrybo21_wobble_object();
tombstone.tombstone_stuff = self.loadout;
playfxontag ( level._effect, tombstone, "tag_origin" );
tombstone thread harrybo21_perks_tombstone_thread( owner );
tombstone thread harrybo21_perks_tombstone_timeout( owner );
return tombstone;
}

harrybo21_perks_tombstone_activate()
{
tombstone = harrybo21_perks_tombstone_spawn( self );
self harrybo21_perks_remove_all();
players = get_players();
if ( !is_coop() )
{
spawn_point = harrybo21_get_respawn_not_in_sight_of_object( self );
self linkTo( spawn_point );
self setorigin( spawn_point.origin );
self setplayerangles( spawn_point.angles );
playsoundatposition( "evt_ww_appear", spawn_point.origin );

self takeAllWeapons();
self.inventory = ;
self.inventory = level.zombie_vars;
self.inventory = level.zombie_vars;
self giveWeapon( level.zombie_vars );
self SwitchToWeapon( level.zombie_vars );
self.inventory = ;
self.inventory = level.zombie_vars;
self.inventory = "none";
self.revived = true;

self harrybo21_perks_player_fake_revive();
self unlink();
self stopLoopSound();
self VisionSetNaked( level.zombie_vars, 1 );
setClientSysState( "lsm", "0", self );
}
else
{
self thread harrybo21_perks_tombstone_suicide();
}
self.tombstone_last_stand = undefined;
}

harrybo21_perks_tombstone_cleanup()
{
self waittill_any( "disconnect", "player_died", "player_revived", "tombstone_grabbed" );

self.tombstoneProgressBar destroy();
self.tombstoneProgressBar delete();
self.tombstoneProgressBar = undefined;
self.tombstone_hud destroy();
self.tombstone_hud delete();
self.tombstone_hud = undefined;
}

harrybo21_perks_tombstone_suicide()
{
self endon( "death" );
self endon( "disconnect" );
self endon( "zombified" );
self endon( "player_revived" );
self endon( "tombstone_grabbed" );
self.tombstone_hud = newclienthudelem( self );
self.tombstone_hud.horzAlign = "center";
self.tombstone_hud.vertAlign = "middle";
self.tombstone_hud.alignX = "center";
self.tombstone_hud.alignY = "middle";
self.tombstone_hud.y += 70;
self.tombstone_hud.foreground = 1;
self.tombstone_hud.fontscale = 1.2;
self.tombstone_hud.alpha = 1;
self thread harrybo21_perks_tombstone_cleanup();
while( 1 )
{
self.tombstone_hud SetText( "Press ^6[{+activate}]^7 [Please don't feed the zombies]" );

time = 0;
self.tombstoneProgressBar = self createPrimaryProgressBar();
while( self UseButtonPressed() && time < 1 )
{
self.tombstoneProgressBar updateBar( 1 - time );
self.tombstone_hud SetText( "Don't feed the zombies" );
time += .1;
wait .1;
}

self.tombstoneProgressBar destroyElem();
if ( time >= 1 )
{
while( isDefined( self.revivetrigger ) && self.revivetrigger.beingRevived )
wait .1;

self VisionSetNaked( level.zombie_vars, 0 );
setClientSysState("lsm", "0", self); // Notify client last stand ended.
self notify( "end_bleedout" );
self [[ level.player_becomes_zombie ]]();
break;
}

wait .1;
}
}

harrybo21_perks_tombstone_thread( player )
{
self endon( "delete" );
self endon( "tombstone_timedout" );
while( 1 )
{
if ( distance( player.origin, self.origin ) < 64 && !player maps\_laststand::player_is_in_laststand() && player.sessionstate != "spectator" )
break;

wait .01;
}
playfx( level._effect, self.origin );
playsoundatposition( "powerup_grabbed", self.origin );
self stoploopsound( 1 );

discard_perks = ;
if ( !is_coop() )
discard_perks = "specialty_quickrevive";

discard_perks = "specialty_shades";
discard_perks = "specialty_reconnaissance";

player harrybo21_return_loadout( self.tombstone_stuff, discard_perks );
player notify( "tombstone_grabbed" );
self delete();
}

harrybo21_perks_tombstone_timeout( player )
{
player endon( "disconnect" );
self endon( "tombstone_grabbed" );
self endon( "tombstone_timedout" );
player waittill( "spawned_player" );
player waittill_any( "fake_death", "death", "player_downed", "specialty_reconnaissance_drank" );
self delete();
self notify( "tombstone_timedout" );
}

// Whos Who Functionality ( "specialty_shades" ) ==============================================================================================

harrybo21_perks_whos_who( give )
{
self endon( "disconnect" );
if ( give )
{
self notify( "perk_chugabud_activated" );
}
else
{
self notify( "whos_who_over" );
}
}

harrybo21_perks_whos_who_laststand_check()
{
if ( isDefined( self.whos_who_active ) && self.whos_who_active )
return true;
else
return false;

}

harrybo21_perks_whos_who_laststand()
{
self endon( "player_suicide" );
self endon( "disconnect" );
self notify ("end_bleedout");
origin = self.origin;

players = get_players();

self.whos_who_active = true;
self freezecontrols( true );

self takeAllWeapons();
self giveWeapon( "zombie_downed" );
self SwitchToWeapon( "zombie_downed" );
self waittill( "weapon_change_complete" );

auto_revive = false;
if ( !is_coop() && self hasPerk( "specialty_quickrevive" ) )
auto_revive = true;

self harrybo21_perks_remove_all();
self giveWeapon( level.zombie_vars );
self SwitchToWeapon( level.zombie_vars );
self takeWeapon( "zombie_downed" );

self.inventory = ;
self.inventory = level.zombie_vars;
self.inventory = "none";
self harrybo21_perks_whos_who_fake_revive();

corpse = self harrybo21_perks_whos_who_spawn_corpse( origin );
corpse thread harrybo21_perks_whos_who_corpse_revive_icon( self, corpse );
corpse thread harrybo21_perks_whos_who_corpse_cleanup_on_spectator( self );
self thread harrybo21_perks_whos_who_handle_multiple_instances( corpse );

// self VisionSetNaked( "zombie_whos_who", 1 );
self VisionSetNaked( "r_poisonFX_debug_enable", 1 );
self setClientDvar( "r_poisonFX_debug_enable", 1 );
self setClientDvar( "r_poisonFX_pulse", 2 );
self setClientDvar( "r_poisonFX_warpy", 0.3 );

self thread harrybo21_perks_whos_who_bleed_timeout( level.zombie_vars, corpse );

corpse waittill( "player_revived", e_reviver );
self setClientDvar( "r_poisonFX_debug_enable", 0 );

if ( auto_revive )
e_reviver = self;

if ( self maps\_laststand::player_is_in_laststand() )
{
self thread harrybo21_perks_whos_who_laststand_cleanup( corpse, "player_revived" );
self enableweaponcycling();
self _enableoffhandweapons();
return;
}
self harrybo21_perks_whos_who_laststand_cleanup( corpse, e_reviver );
self.revived = true;
wait 1;
}

harrybo21_perks_whos_who_handle_multiple_instances( corpse )
{
corpse endon( "death" );
self waittill( "perk_chugabud_activated" );
self harrybo21_perks_whos_who_corpse_cleanup( corpse, 0 );
}

harrybo21_perks_whos_who_laststand_cleanup( corpse, str_notify )
{
if ( isDefined( str_notify ) )
self waittill( str_notify );

self harrybo21_perks_whos_who_corpse_cleanup( corpse, str_notify );

}

harrybo21_perks_whos_who_revive_check()
{
if ( isDefined( self.loadout.perk_inventory ) && self.loadout.perk_inventory.size > 0 )
{
for ( i = 0; i < self.loadout.perk_inventory.size; i++ )
{
if ( self.loadout.perk_inventory == "specialty_quickrevive" )
return true;
}
}
return false;
}

harrybo21_perks_whos_who_bleed_timeout( delay, corpse )
{
self endon( "player_suicide" );
self endon( "disconnect" );
corpse endon( "death" );
wait delay;
while ( isDefined( corpse.revivetrigger ) )
{
if ( corpse.revivetrigger.beingrevived )
{
wait .01;
continue;
}
break;
}
corpse notify( "player_revived" );
}

harrybo21_perks_whos_who_corpse_cleanup( corpse, was_revived )
{
self notify( "chugabud_effects_cleanup" );
self stopLoopSound( 1 );
if ( isDefined( was_revived ) && was_revived )
{
discard_perks = ;
// if ( !is_coop() )
// discard_perks = "specialty_quickrevive";

discard_perks = "specialty_shades";
self harrybo21_perks_remove_all();
self setorigin( corpse.origin );
self setplayerangles( corpse.angles );
wait .1;
self VisionSetNaked( level.zombie_vars, 1 );
self harrybo21_return_loadout( corpse.loadout, discard_perks );
playsoundatposition( "evt_ww_appear", corpse.origin );
playfx( level._effect, corpse.origin );
}
else
{
playsoundatposition( "evt_ww_disappear", corpse.origin );
playfx( level._effect, corpse.origin );
self notify( "chugabud_bleedout" );
}
if ( isDefined( corpse.revivetrigger ) )
{
corpse notify( "stop_revive_trigger" );
corpse.revivetrigger delete();
corpse.revivetrigger = undefined;
}
if ( isDefined( corpse.revive_hud_elem ) )
{
corpse.revive_hud_elem destroy();
corpse.revive_hud_elem = undefined;
}
corpse delete();
if ( !self maps\_laststand::player_is_in_laststand() )
{
setClientSysState( "lsm", "0", self );
self stopLoopSound();
self VisionSetNaked( level.zombie_vars );
}
self.e_chugabud_corpse = undefined;
self.whos_who_active = undefined;
}

harrybo21_perks_whos_who_fake_revive()
{
playsoundatposition( "evt_ww_disappear", self.origin );

spawn_point = harrybo21_get_respawn_not_in_sight_of_object( self );

self linkTo( spawn_point );
self setorigin( spawn_point.origin );
self setplayerangles( spawn_point.angles );
playsoundatposition( "evt_ww_appear", spawn_point.origin );
playfx( level._effect, spawn_point.origin );
self unlink();
self harrybo21_perks_player_fake_revive();
self playloopSound( "evt_ww_loop", 1 );
}

harrybo21_perks_whos_who_spawn_corpse( origin )
{
corpse = harrybo21_perks_whos_who_spawn_player_clone( self, origin, undefined, self.whos_who_shader );
corpse UseAnimTree( #animtree );
corpse.angles = self.angles;
corpse setAnim( %pb_laststand_idle );
corpse.revive_hud = self harrybo21_perks_whos_who_revive_hud_create();
corpse maps\_laststand::revive_trigger_spawn();
corpse.loadout = self.loadout;
self.e_chugabud_corpse = corpse;

return corpse;
}

harrybo21_perks_whos_who_corpse_cleanup_on_spectator( player )
{
self endon( "death" );
player endon( "disconnect" );
while ( 1 )
{
if ( player.sessionstate == "spectator" )
{
break;
}
else
{
wait 0.01;
}
}
setClientSysState( "lsm", "0", player ); // Notify client last stand ended.
player stopLoopSound();
player VisionSetNaked( level.zombie_vars );
player harrybo21_perks_whos_who_corpse_cleanup( self, 0 );
}

harrybo21_perks_whos_who_revive_colour_change_thread( player, corpse )
{
player endon( "death" );
self endon( "delete" );
player endon( "chugabud_bleedout" );
self endon( "colour_change_complete" );
bleed_out_time = GetDvarFloat( "player_lastStandBleedoutTime" );
remaining_bleed_out_time = GetDvarFloat( "player_lastStandBleedoutTime" );

while( 1 )
{
fraction = remaining_bleed_out_time / bleed_out_time;

self.color = ( 1, fraction, 0 );
if ( isDefined( corpse.revivetrigger.beingRevived ) && corpse.revivetrigger.beingRevived )
self.color = ( 1, 1, 1 );

remaining_bleed_out_time -= .1;
wait .1;
}
self notify( "colour_change_complete" );
}

harrybo21_perks_whos_who_corpse_revive_icon( player, corpse )
{
self endon( "death" );
height_offset = 30;
hud_elem = newHudElem();
self.revive_hud_elem = hud_elem;
hud_elem.x = self.origin;
hud_elem.y = self.origin;
hud_elem.z = self.origin + height_offset;
hud_elem.color = ( 1, 1, 0 );
hud_elem setWaypoint( false, "bo2_waypoint_revive" );
hud_elem.hidewheninmenu = 1;
hud_elem.immunetodemogamehudsettings = 1;
hud_elem thread harrybo21_perks_whos_who_revive_colour_change_thread( player, corpse );
}

harrybo21_perks_whos_who_revive_hud_create()
{
self.revive_hud = newclienthudelem( self );
self.revive_hud.alignx = "center";
self.revive_hud.aligny = "middle";
self.revive_hud.horzalign = "center";
self.revive_hud.vertalign = "bottom";
self.revive_hud.y = -50;
self.revive_hud.foreground = 1;
self.revive_hud.font = "default";
self.revive_hud.fontscale = 1.5;
self.revive_hud.alpha = 0;
self.revive_hud.color = ( 1, 1, 1 );
self.revive_hud settext( "" );
return self.revive_hud;
}

harrybo21_perks_whos_who_spawn_player_clone( player, origin, forceweapon, forcemodel )
{
if ( !isDefined( origin ) )
{
origin = player.origin;
}
primaryweapons = player getweaponslistprimaries();
if ( isDefined( forceweapon ) )
{
weapon = forceweapon;
}
else if ( primaryweapons.size )
{
weapon = primaryweapons;
}
else
{
weapon = player getcurrentweapon();
}
weaponmodel = getweaponmodel( weapon );
clone = spawn( "script_model", origin );
clone.isactor = 0;
if ( isDefined( forcemodel ) )
{
clone setmodel( forcemodel );
}
else
{
clone setmodel( self.model );
if ( isDefined( player.headmodel ) )
{
clone.headmodel = player.headmodel;
clone attach( clone.headmodel, "", 1 );
}
}
if ( weaponmodel != "" && weaponmodel != "none" )
{
clone attach( weaponmodel, "tag_weapon_right" );
}
clone.team = player.team;
clone.is_inert = 1;
clone.zombie_move_speed = "walk";
clone.script_noteworthy = "corpse_clone";
return clone;
}

// Vulture Functionality ( "specialty_ordinance" ) ==============================================================================================

harrybo21_perks_player_has_vulture()
{
players = get_players();
for( i = 0; i < players.size; i++ )
{
if( players hasPerk( "specialty_ordinance" ) )
return true;

}
return false;
}

harrybo21_vulture_chest_watcher()
{
while( 1 )
{
level waittill( "weapon_fly_away_end" );
harrybo21_perks_vulture_waypoint_functionality();
}
}

harrybo21_vulture_change_hud_fx( new_fx )
{
players = get_players();
for ( p = 0; p < players.size; p++ )
SetClientSysState( "zombiemode_perks", "change_fx," + self.targetname + "," + new_fx, players );
}

play_fx_to_client( name, effect, origin, angles )
{
if ( !isDefined( angles ) )
angles = ( 0, 0, 0 );

SetClientSysState( "zombiemode_perks", "harry_fx_spawn," + name + "," + effect + "," + int( origin ) + "," + int( origin ) + "," + int( origin ) + "," + int( angles ) + "," + int( angles ) + "," + int( angles ), self );
}
stop_fx_to_client( name )
{
SetClientSysState( "zombiemode_perks", "harry_fx_kill," + name, self );
}

play_fx_to_all_clients( name, effect, origin, angles )
{
if ( !isDefined( angles ) )
angles = ( 0, 0, 0 );

players = get_players();
for ( i = 0; i < players.size; i++ )
{
SetClientSysState( "zombiemode_perks", "harry_fx_spawn," + name + "," + effect + "," + int( origin ) + "," + int( origin ) + "," + int( origin ) + "," + int( angles ) + "," + int( angles ) + "," + int( angles ), players );
}
}
stop_fx_to_all_clients( name )
{
players = get_players();
for ( i = 0; i < players.size; i++ )
{
SetClientSysState( "zombiemode_perks", "harry_fx_kill," + name, players );
}
}

harrybo21_perks_vulture_waypoint_functionality()
{
players = get_players();
for ( p = 0; p < players.size; p++ )
{
machines = getEntArray( "harrybo21_vending", "script_noteworthy" );
if ( isDefined( machines ) && machines.size > 0 )
{
for ( i = 0; i < machines.size; i++ )
{
if ( players hasPerk( "specialty_ordinance" ) && ( isDefined( machines.active ) && machines.active ) ) // && ( !isDefined( machines.is_swapping ) || ( isDefined( machines.is_swapping ) && !machines.is_swapping ) ) )
{
if ( isDefined( machines.is_swapping ) && machines.is_swapping )
players stop_fx_to_client( machines.targetname );
else
players play_fx_to_client( machines.targetname, level.vulture_huds.script_string ], machines.origin + ( 0, 0, 50 ), ( 0, 0, 0 ) );
}
else
players stop_fx_to_client( machines.targetname );

}
}
harrybo21_mystery_box = getEntArray( "harrybo21_mystery_box", "script_noteworthy" );
if ( isDefined( harrybo21_mystery_box ) && harrybo21_mystery_box.size > 0 )
{
for ( i = 0; i < harrybo21_mystery_box.size; i++ )
{
if ( players hasPerk( "specialty_ordinance" ) && ( isDefined( harrybo21_mystery_box.active ) && harrybo21_mystery_box.active ) ) // && ( !isDefined( machines.is_swapping ) || ( isDefined( machines.is_swapping ) && !machines.is_swapping ) ) )
{
players play_fx_to_client( harrybo21_mystery_box.targetname, "vulture_box_shader", harrybo21_mystery_box.origin, ( 0, 0, 0 ) );
}
else
players stop_fx_to_client( harrybo21_mystery_box.targetname );
}
}
mystery_box = level.chests;
if ( isDefined( mystery_box ) && mystery_box.size > 0 )
{
for ( i = 0; i < mystery_box.size; i++ )
{
lid = getEnt( mystery_box.target, "targetname" );
if ( players hasPerk( "specialty_ordinance" ) )
{
if ( level.chest_index == i )
{
players play_fx_to_client( lid.targetname, "vulture_box_shader", lid.origin + ( 0, 0, 50 ), ( 0, 0, 0 ) );
}
else
players stop_fx_to_client( lid.targetname );
}
else
players stop_fx_to_client( lid.targetname );
}
}

harrybo21_upgrade = getEntArray( "harrybo21_upgrade", "script_noteworthy" );
if ( isDefined( harrybo21_upgrade ) && harrybo21_upgrade.size > 0 )
{
for ( i = 0; i < harrybo21_upgrade.size; i++ )
{
if ( players hasPerk( "specialty_ordinance" ) && ( isDefined( harrybo21_upgrade.active ) && harrybo21_upgrade.active ) )
{
players play_fx_to_client( harrybo21_upgrade.targetname, "vulture_pap_shader", harrybo21_upgrade.origin + ( 0, 0, 50 ), ( 0, 0, 0 ) );
}
else
players stop_fx_to_client( harrybo21_upgrade.targetname );
}
}
harrybo21_vending_wonderfizz = getEntArray( "harrybo21_vending_wonderfizz", "script_noteworthy" );
if ( isDefined( harrybo21_vending_wonderfizz ) && harrybo21_vending_wonderfizz.size > 0 )
{
for ( i = 0; i < harrybo21_vending_wonderfizz.size; i++ )
{
if ( players hasPerk( "specialty_ordinance" ) && ( isDefined( harrybo21_vending_wonderfizz.active ) && harrybo21_vending_wonderfizz.active ) )
{
players play_fx_to_client( harrybo21_vending_wonderfizz.targetname, "vulture_wunderfizz_shader", harrybo21_vending_wonderfizz.origin + ( 0, 0, 50 ), ( 0, 0, 0 ) );
}
else
players stop_fx_to_client( harrybo21_vending_wonderfizz.targetname );
}
}
harrybo21_wallbuys = getStructArray( "vulture_hud_weapon", "script_noteworthy" );
if ( !isDefined( harrybo21_wallbuys ) || harrybo21_wallbuys.size < 1 )
return;

for ( i = 0; i < harrybo21_wallbuys.size; i++ )
{
if ( players hasPerk( "specialty_ordinance" ) )
{
players play_fx_to_client( harrybo21_wallbuys.targetname, "vulture_rifle_shader", harrybo21_wallbuys.origin, ( 0, 0, 0 ) );
}
else
players stop_fx_to_client( harrybo21_wallbuys.targetname );
}
}
}

harrybo21_perks_vulture( give )
{
self endon( "disconnect" );
if ( give )
{
harrybo21_perks_vulture_waypoint_functionality();
self.touching_mist = undefined;
self.vulture_level = 0;
self.vulture_drops = 0;
self thread harrybo21_perks_vulture_hud_mist_effect();
self thread harrybo21_perks_vulture_mist_watcher();
}
else
{
harrybo21_perks_vulture_waypoint_functionality();
self notify( "vulture_over" );
self.vulture_level = 0;
self setblur( 0, 1 );
self.vulture_drops = undefined;
self.vulture_glow_hud destroy();
self.vulture_glow_hud = undefined;
self notify( "lost_specialty_ordinance" );
}
}

harrybo21_perks_vulture_lose_watcher( player )
{
self endon( "delete" );
player endon( "disconnect" );
player waittill( "vulture_over" );
self delete();
}

harrybo21_perks_vulture_should_do_drop()
{
n_roll = randomint( 100 );
b_should_drop = n_roll > ( 100 - level.zombie_vars );
return b_should_drop;
}

harrybo21_perks_vulture_zombie_function()
{
if( ( isdefined( self.boss ) && self.boss ) || ( isDefined( self.boss_mech ) && self.boss_mech ) || ( isDefined( self.animname ) && ( self.animname == "boss_zombie" || self.animname == "sonic_zombie" || self.animname == "napalm_zombie" ) ) )
return;
if ( self enemy_is_dog() && !level.zombie_vars )
return;

if ( !harrybo21_perks_vulture_should_do_drop() )
return;

n_total_weight = level.zombie_vars + level.zombie_vars + level.zombie_vars;
n_cutoff_ammo = level.zombie_vars;
n_cutoff_points = level.zombie_vars + level.zombie_vars;
n_roll = randomint( n_total_weight );
if ( n_roll < n_cutoff_ammo )
str_bonus = "ammo";
else if ( n_roll > n_cutoff_ammo && n_roll < n_cutoff_points )
str_bonus = "points";
else
str_bonus = "stink";

if ( str_bonus == "stink" )
self thread harrybo21_perks_vulture_zombie_mist_watcher();
if ( str_bonus == "points" )
self thread harrybo21_perks_vulture_zombie_drop( "points" );
if ( str_bonus == "ammo" )
self thread harrybo21_perks_vulture_zombie_drop( "ammo" );

}

harrybo21_perks_vulture_zombie_drop( type )
{
self endon( "cancel" );
self waittill( "death" );
if( ( isdefined( self.boss ) && self.boss ) || ( isDefined( self.boss_mech ) && self.boss_mech ) || ( isDefined( self.animname ) && ( self.animname == "boss_zombie" || self.animname == "sonic_zombie" || self.animname == "napalm_zombie" ) ) )
return;
if( isDefined( self.attacker ) && isPlayer( self.attacker ) && self.attacker hasPerk( "specialty_ordinance" ) && harry_in_playable_area_check( self.origin ) )
{
player_drops = harrybo21_perks_vulture_get_drops( self.attacker.playername );
if ( player_drops.size > level.zombie_vars )
self notify( "cancel" );

self.drop_model = spawn( "script_model", self.origin + ( 0, 0, 16 ) );
self.drop_model.targetname = self.attacker.playername + "_vulture_drop";
players = get_players();
for( i = 0; i < players.size; i++ )
self.drop_model SetInvisibleToPlayer( players );

self.drop_model SetVisibleToPlayer( self.attacker );

if ( isDefined( self.drop_model ) )
{
self.drop_model playSound( "vulture_drop" );
self.drop_model playloopSound( "vulture_loop", 1 );
switch( type )
{
case "points":
{
self.drop_model setModel( "bo2_p6_zm_perk_vulture_points" );
self.drop_model thread vulture_points_watcher( self.attacker );
break;
}
case "ammo":
{
self.drop_model setModel( "bo2_p6_zm_perk_vulture_ammo" );
self.drop_model thread vulture_ammo_watcher( self.attacker );
break;
}
}

self.drop_model thread harrybo21_perks_vulture_lose_watcher( self.attacker );
self.drop_model thread harrybo21_perks_vulture_timeout( self.attacker );
self.drop_model thread harrybo21_perks_vulture_dissapear_on_death( self.attacker );
playfxontag( level._effect["vulture_glow"], self.drop_model, "tag_origin" );
}
}
}

vulture_ammo_watcher( owner )
{
self endon( "timeout" );
self endon( "delete" );
while( 1 )
{
if ( distance( owner.origin, self.origin ) < 48 )
{
owner playSound( "vulture_pickup" );

current_weapon = owner getCurrentWeapon();

current_ammo = owner getWeaponAmmoStock( current_weapon );
weapon_max = weaponMaxAmmo( current_weapon );
clip = WeaponClipSize( current_weapon );
clip_add = int( clip / 10 );
if ( clip_add < 1 )
clip_add = 1;

new_ammo = current_ammo + clip_add;
if ( new_ammo > weapon_max )
new_ammo = weapon_max;

owner SetWeaponAmmoStock( current_weapon, new_ammo );

self notify( "grabbed" );
self delete();
break;
}
wait .1;
}
}

vulture_points_watcher( owner )
{
self endon( "timeout" );
self endon( "delete" );
while( 1 )
{
if ( distance( owner.origin, self.origin ) < 48 )
{
owner playSound( "vulture_pickup" );
owner playSound( "vulture_money" );

score = 10;
rand = randomInt( 2 );
if ( rand == 1 )
score = 20;

if ( isDefined( level.zombie_vars ) && level.zombie_vars )
score = score * 2;

owner.score += score;
owner maps\_zombiemode_score::set_player_score_hud();

self notify( "grabbed" );
self delete();
break;
}
wait .1;
}
}

harrybo21_perks_vulture_dissapear_on_death( player )
{
self endon( "delete" );
self endon( "timedout" );
self endon( "grabbed" );
while( 1 )
{
player waittill( "vulture_lost" );
self delete();
}
}

harrybo21_perks_vulture_timeout( player )
{
self endon ( "delete" );

wait 10;

for ( i = 0; i < 40; i++ )
{
if ( i % 2 )
{
self hide();
}
else
{
self show();
}

if ( i < 15 )
{
wait .5;
}
else if ( i < 25 )
{
wait .25;
}
else
{
wait .1;
}
}
self notify( "timeout" );
self delete();
}

harrybo21_perks_vulture_get_drops( playername )
{
return getEntArray( playername + "_vulture_drop", "targetname" );
}

harrybo21_perks_vulture_zombie_mist_watcher()
{
vulture_mists = harrybo21_perks_vulture_get_mists();
if ( vulture_mists.size >= level.zombie_vars )
return;

vulture_mist = spawn( "script_model", self.origin + ( 0, 0, 16 ), 1, 1, 1 );
vulture_mist.linked = true;
vulture_mist playloopSound( "vulture_mist_loop", 1 );
vulture_mist.targetname = "vulture_mist";
vulture_mist.angles = self.angles;
vulture_mist setmodel( "tag_origin" );

vulture_mist linkTo( self, "tag_origin" );
vulture_mist thread harrybo21_perks_vulture_mist_fx( "tag_origin", level._effect );

self waittill( "death" );
vulture_mist.linked = false;
if ( !harrybo21_perks_vulture_can_drop( vulture_mist ) )
{
vulture_mist stoploopsound( 2 );
vulture_mist stopsounds( 2 );
vulture_mist notify( "stop_vulture_fx" );
wait 2;
vulture_mist delete();
vulture_mist = undefined;
return;
}

vulture_mist unlink();
wait level.zombie_vars;
vulture_mist stoploopsound( 2 );
vulture_mist stopsounds( 2 );
vulture_mist notify( "stop_vulture_fx" );
wait 20;
vulture_mist delete();
vulture_mist = undefined;
}

harrybo21_perks_vulture_get_mists()
{
return getEntArray( "vulture_mist", "targetname" );
}

harrybo21_perks_vulture_mist_watcher()
{
self endon( "disconnect" );
self endon( "player_downed" );
self endon( "fake_death" );
touched = false;
while( 1 )
{
touching = false;
vulture_mists = harrybo21_perks_vulture_get_mists();
for ( i = 0; i < vulture_mists.size; i++ )
{
if ( self hasPerk( "specialty_ordinance" ) && distance( vulture_mists.origin, self.origin ) < 48 && !vulture_mists.linked )
{
touching = true;
if ( !touched )
{
self playSound( "vulture_mist_start" );
touched = true;
}

if ( self.vulture_level + .1 < 1 )
self.vulture_level += .1;
else
self.vulture_level = 1;

self setblur( self.vulture_level, .01 );
break;
}
}

if ( touching )
{
if ( ( !isDefined( self.vulture_mist ) || !self.vulture_mist ) && self.vulture_level >= 1 )
{
self.vulture_mist = true;
self.ignoreme = true;
}
wait .25;
continue;
}
else
{
if ( touched )
{
self playSound( "vulture_mist_stop" );
touched = false;
}
}
if ( self.vulture_level - .1 >= 0 )
{
self.vulture_level -= .1;
self setblur( self.vulture_level, .01 );
}
else
self.vulture_level = 0;

if ( !self maps\_laststand::player_is_in_laststand() && !self.last_stand && ( isDefined( self.vulture_mist ) && self.vulture_mist ) && self.vulture_level <= 0 )
{
self.vulture_mist = false;
self.ignoreme = false;
}

wait .25;
}
}

harrybo21_perks_vulture_hud_mist_effect()
{
self endon( "disconnect" );
self endon( "player_downed" );
self endon( "fake_death" );
colour = 0;
self.vulture_glow_hud = NewClientHudElem( self );
self.vulture_glow_hud.foreground = true;
self.vulture_glow_hud.sort = 1;
self.vulture_glow_hud.hidewheninmenu = false;
self.vulture_glow_hud.alignX = "left";
self.vulture_glow_hud.alignY = "bottom";
self.vulture_glow_hud.horzAlign = "left";
self.vulture_glow_hud.vertAlign = "bottom";
self.vulture_glow_hud.x = 0;
self.vulture_glow_hud.y = 0;
self.vulture_glow_hud.alpha = 0;
self.vulture_glow_hud SetShader( "vending_vulture_glow_shader" , 48, 48 );
self.vulture_glow_hud.alpha = 0;
glow = true;
while( 1 )
{
for ( i = 0; i < self.perk_hud.size; i++ )
{
if ( self.perk_hud.perk == "specialty_ordinance" )
{
self.vulture_glow_hud.x = self.perk_hud.x - 12;
self.vulture_glow_hud.y = self.perk_hud.y + 12;
self.vulture_glow_hud.alpha = self.vulture_level;
}
}

wait .1;
}
}

harrybo21_perks_vulture_mist_fx( tag, fx )
{
self endon( "stop_vulture_fx" );

while( 1 )
{
playfxontag( fx, self, tag );
players = get_players();
for( i = 0; i < players.size; i++ )
{
if( players hasPerk( "specialty_ordinance" ) )
self SetVisibleToPlayer( players );
else
self SetInvisibleToPlayer( players );

}
wait randomfloatrange( 0.1, 0.2 );
}
}

harrybo21_perks_vulture_can_drop( object )
{
playable_area = getEntArray( "playable_area", "targetname" );
for ( i = 0; i < playable_area.size; i++ )
{
if ( object isTouching( playable_area ) )
{
return true;
}
}
return false;
}

// Widows Wine Functionality ( "specialty_specialgrenade" ) ==============================================================================================

harrybo21_perks_widows_wine( give )
{
self endon( "disconnect" );
if ( give )
{
self.previous_grenade = self harrybo21_get_grenade();
ammo = 0;
if ( isDefined( self.previous_grenade ) )
ammo = self getWeaponAmmoClip( self.previous_grenade );
else
self.previous_grenade = level.zombie_vars;

self harrybo21_set_grenade( "bo3_zm_widows_grenade", ammo );
}
else
{
ammo = self getWeaponAmmoClip( "bo3_zm_widows_grenade" );
if ( !isDefined( ammo ) )
ammo = 0;

self harrybo21_set_grenade( self.previous_grenade, ammo );
}
}

harrybo21_perks_widows_wine_watch_for_throw()
{
while( 1 )
{
self waittill( "grenade_fire", grenade, weapname );
if ( weapname != "bo3_zm_widows_grenade" )
continue;

self thread harrybo21_perks_widows_wine_thrown( grenade );
}
}

harrybo21_perks_widows_wine_hud_watcher()
{
huds = ;
players = get_players();
for ( i = 0; i < players.size; i++ )
{
hud_elem = NewClientHudElem( players );
hud_elem.x = self.origin;
hud_elem.y = self.origin;
hud_elem.z = self.origin;
hud_elem setWaypoint( false, "vending_widows_grenade_indicator" );
hud_elem.hidewheninmenu = 1;
hud_elem.immunetodemogamehudsettings = 1;
huds = hud_elem;
}

while( isDefined( self ) )
{
for ( i = 0; i < players.size; i++ )
{
distance_to_grenade = distance( players.origin, self.origin ) / ( level.zombie_vars * 3 );
if ( distance_to_grenade > 1 )
distance_to_grenade = 1;
if ( distance_to_grenade < 0 )
distance_to_grenade = 0;

huds.alpha = 1 - distance_to_grenade;
}
wait .05;
}
for ( i = 0; i < huds.size; i++ )
{
huds destroy();
huds delete();
}
huds = undefined;
}

harrybo21_perks_widows_wine_thrown( grenade )
{
self endon( "delete" );
self endon( "destroy" );
self endon( "detonate" );
grenade waittill_not_moving();

fake_model = spawn( "script_model", grenade.origin );
fake_model setModel( "t7_ww_grenade_proj" );
fake_model.angles = grenade.angles;
grenade delete();

fake_model.owner = self;
wait 1;
fake_model thread harrybo21_perks_widows_wine_explode( self );
fake_model delete();
}

harrybo21_perks_widows_wine_explode( owner )
{
origin = self.origin;
earthquake ( 0.8, 0.6, origin, level.zombie_vars );
self playSound( "grenade_explode" );

playsoundatposition ( "mx_widows_explode", origin );
playFX( level._effect, origin );

ai = GetAiSpeciesArray( "axis", "all" );
ai = get_array_of_closest( origin, ai );
n_zombies_hit = 0;
for( i = 0; i < ai.size; i++ )
{
if ( distance( origin, ai.origin ) > level.zombie_vars )
continue;

if ( isDefined( ai.widow_stunned ) && ai.widow_stunned )
continue;

if( ( isdefined( ai.boss ) && ai.boss ) || ( isDefined( ai.boss_mech ) && ai.boss_mech ) || ( isDefined( ai.animname ) && ( ai.animname == "boss_zombie" || ai.animname == "sonic_zombie" || ai.animname == "napalm_zombie" ) ) )
continue;

if ( ai enemy_is_dog() )
{
ai doDamage( ai.health + 666, self.origin, owner );
continue;
}

ai thread harrybo21_perks_do_gib( owner );
ai thread harrybo21_perks_widows_wine_should_do_drop( owner );
ai thread harrybo21_perks_widows_wine_stunned();
ai thread harrybo21_perks_widows_wine_damage_over_time( owner );
ai thread harrybo21_perks_widows_wine_infected_fx( owner );
ai doDamage( ( self.maxHealth / level.zombie_vars ) / 20, self.origin, self );
}
}

harrybo21_perks_widows_wine_should_do_drop( owner )
{
self endon( "delete" );
self waittill( "death" );

if ( isDefined( level.zombie_vars ) && level.zombie_vars >= 1 )
return;
if( ( isdefined( self.boss ) && self.boss ) || ( isDefined( self.boss_mech ) && self.boss_mech ) || ( isDefined( self.animname ) && ( self.animname == "boss_zombie" || self.animname == "sonic_zombie" || self.animname == "napalm_zombie" ) ) )
return;

n_roll = randomint( 100 );
b_should_drop = n_roll > ( 100 - level.zombie_vars );
if ( !b_should_drop )
return;
if ( owner maps\_laststand::player_is_in_laststand() || !isAlive( owner ) )
return;
if ( !harry_in_playable_area_check( self.origin + ( 0, 0, 40 ) ) )
return;

widows_model = spawn( "script_model", self.origin + ( 0, 0, 40 ) );
effect = spawn( "script_model", widows_model.origin );
effect setModel( "tag_origin" );
playfxontag( level._effect, effect, "tag_origin" );
widows_model.owner = owner;
widows_model setModel( "t7_ww_powerup" );
widows_model PlayLoopSound( "spawn_powerup_loop" );
widows_model thread harrybo21_perks_widows_wine_wobble();
widows_model thread harrybo21_perks_widows_wine_timeout( effect );
widows_model thread harrybo21_perks_widows_wine_grab_powerup( effect );
widows_model thread harrybo21_perks_widows_wine_check_for_down_or_disconnect( owner );
}

harrybo21_perks_widows_wine_wobble()
{
self endon ( "widows_grabbed" );
self endon ( "widows_timedout" );

playsoundatposition( "spawn_powerup", self.origin );

while ( isdefined( self ) )
{
waittime = randomfloatrange( 2.5, 5 );
yaw = RandomInt( 360 );
if( yaw > 300 )
yaw = 300;
if( yaw < 60 )
yaw = 60;

yaw = self.angles + yaw;
self rotateto ( ( -60 + randomint( 120 ), yaw, -45 + randomint( 90 ) ), waittime, waittime * 0.5, waittime * 0.5 );
wait randomfloat ( waittime - 0.1 );
}
}

harrybo21_perks_widows_wine_hide()
{
players = get_players();
for( i = 0; i < players.size; i++ )
self SetInvisibleToPlayer( players );

}

harrybo21_perks_widows_wine_show()
{
players = get_players();
for( i = 0; i < players.size; i++ )
self SetInvisibleToPlayer( players );

self SetVisibleToPlayer( self.owner );
}

harrybo21_perks_widows_wine_check_for_down_or_disconnect( owner )
{
self endon( "widows_timedout" );
self endon( "widows_grabbed" );
owner waittill_any( "death", "fake_death", "player_downed", "disconnect" );
self notify( "widows_timedout" );
}

harrybo21_perks_widows_wine_timeout( effect )
{
self endon ( "widows_grabbed" );
wait 1;
for ( i = 0; i < 8; i++ )
{
if ( i % 2 )
self harrybo21_perks_widows_wine_hide();
else
self harrybo21_perks_widows_wine_show();

wait .5;
}

self notify ( "widows_timedout" );
effect delete();
self delete();
}

harrybo21_perks_widows_wine_grab_powerup( effect )
{
self endon( "widows_timedout" );
wait .5;
while ( isDefined( self ) )
{
if ( distance ( self.owner.origin, self.origin ) < 64 )
{
playfx ( level._effect, self.origin );
playfx ( level._effect, self.origin );
playsoundatposition( "powerup_grabbed", self.origin );
self stoploopsound();

clip_ammo = self.owner GetWeaponAmmoClip( "bo3_zm_widows_grenade" );
if ( !isDefined( clip_ammo ) )
clip_ammo = 0;

clip_ammo += 1;
if ( clip_ammo > 4 )
clip_ammo = 4;

self.owner setWeaponAmmoClip( "bo3_zm_widows_grenade", clip_ammo );
self notify ( "widows_grabbed" );
break;
}
wait .1;
}
effect delete();
self delete();
}

harrybo21_perks_widows_wine_infected_fx()
{
self endon( "delete" );
self endon( "widows_effects_over" );
self playLoopSound( "ww_lp" );
while( 1 )
{
spot = self getTagOrigin( "j_spinelower" );
playFX( level._effect, spot );
wait .5;
}
}

harrybo21_perks_widows_wine_explode_on_melee()
{
if ( isDefined( self.widows_exploded ) )
return false;

clip_ammo = self GetWeaponAmmoClip( "bo3_zm_widows_grenade" );
if ( !self hasPerk( "specialty_specialgrenade" ) || clip_ammo < 1 )
return false;

if ( !isDefined( clip_ammo ) )
clip_ammo = 0;

clip_ammo--;
if ( clip_ammo < 0 )
clip_ammo = 0;

self setWeaponAmmoClip( "bo3_zm_widows_grenade", clip_ammo );
self.widows_exploded = 1;
self thread harrybo21_perks_widows_wine_explode( self );
self thread harrybo21_perks_widows_wine_cooldown_timer();
self EnableInvulnerability();
    wait .25;
    self DisableInvulnerability();
return true;
}

harrybo21_perks_widows_wine_cooldown_timer()
{
wait 2;
self.widows_exploded = undefined;
}

harrybo21_perks_widows_wine_damage_over_time( attacker )
{
self endon( "death" );
self endon( "widows_effects_over" );

dmg = ( self.maxHealth / level.zombie_vars ) / 20;

if( !isAlive( self ) )
return;

if( !isPlayer( attacker ) )
attacker = undefined;

while( 1 )
{
wait 1 ;

if( isDefined( attacker ) )
self doDamage( dmg, self.origin, attacker );
else
self doDamage( dmg, self.origin );

}
}

harrybo21_perks_widows_wine_stunned()
{
self endon( "death" );
self endon( "delete" );
if ( isDefined( self.widow_stunned ) )
return;

self.widow_stunned = 1;
count = 1;
while( 1 )
{
count -= 0.05;
self.melee_anim_rate = count;
self.moveplaybackrate = count;
self.animplaybackrate = count;
self.traverseplaybackrate = count;

if ( count <= 0.15 )
break;

wait 0.05;
}
wait 20;
while( 1 )
{
count += 0.05;
self.melee_anim_rate = count;
self.moveplaybackrate = count;
self.animplaybackrate = count;
self.traverseplaybackrate = count;

if ( count >= 1 )
break;

wait .05;
}
self notify( "widows_effects_over" );
self stopLoopSound( "ww_lp" );
self playSound( "ww_lp_end" );
self.widow_stunned = undefined;
}

harrybo21_perks_widows_watcher()
{
self endon( "death" );
while( 1 )
{
self waittill( "damage", amount, attacker, direction_vec, point, type );

if( ( isdefined( self.boss ) && self.boss ) || self.animname == "jnaut_melee" || self.animname == "jnaut_gunner" || ( isDefined( self.boss_mech ) && self.boss_mech )|| ( isDefined( self.animname ) && self.animname == "boss_zombie" ) )
return;

if ( type == "MOD_MELEE" )
{
self.widows_hit = true;
if( isDefined( attacker ) && isplayer( attacker ) && isAlive( attacker ) )
{
if( attacker hasPerk( "specialty_specialgrenade" )  )
{
self harrybo21_perks_widows_damage( level.zombie_vars, self.origin, attacker, self.damageLocation );
if ( isAlive( self ) )
{
if ( isDefined( self.widow_stunned ) && self.widow_stunned )
continue;

self thread harrybo21_perks_widows_wine_should_do_drop( attacker );
self thread harrybo21_perks_widows_wine_stunned();
self thread harrybo21_perks_widows_wine_damage_over_time( self );
self thread harrybo21_perks_widows_wine_infected_fx( self );
}
}
}
}
wait_network_frame();
}
}

harrybo21_perks_widows_damage( amount, origin, attacker, location )
{
self endon( "death" );
self.damageLocation = location;
setPlayerIgnoreRadiusDamage( true );
attacker radiusDamage( self.origin, 1, amount, amount, attacker, "MOD_MELEE" );
setPlayerIgnoreRadiusDamage( false );
self.damageLocation = location;
wait_network_frame();
}

// Stock functions called from other scripts ==============================================================================================

perk_think( perk )
{
self harrybo21_perks_give_perk( perk );
}

play_no_money_perk_dialog()
{
index = maps\_zombiemode_weapons::get_player_index( self );
player_index = "plr_" + index + "_";
if( !IsDefined ( self.vox_nomoney_perk ) )
{
num_variants = maps\_zombiemode_spawner::get_number_variants( player_index + "vox_nomoney_perk" );
self.vox_nomoney_perk = ;
for( i = 0; i < num_variants; i++ )
self.vox_nomoney_perk[self.vox_nomoney_perk.size] = "vox_nomoney_perk_" + i;

self.vox_nomoney_perk_available = self.vox_nomoney_perk;
}
sound_to_play = random( self.vox_nomoney_perk_available );

self.vox_nomoney_perk_available = array_remove( self.vox_nomoney_perk_available, sound_to_play );

if ( self.vox_nomoney_perk_available.size < 1 )
self.vox_nomoney_perk_available = self.vox_nomoney_perk;

self maps\_zombiemode_spawner::do_player_playdialog(player_index, sound_to_play, 0.25 );
}
_kinostyle_teleporter.gsc
Code Snippet
Plaintext
#include common_scripts\utility; 
#include maps\_utility;
#include maps\_zombiemode_utility;

init()
{
addItems();

level.kts["teleporter_trigger"] SetCursorHint("HINT_NOICON");
level.kts["mainframe_trigger"] SetCursorHint("HINT_NOICON");
level.kts["teleporter_trigger"] SetHintString(level.kts["hint_electricity"]);
level.kts["mainframe_trigger"] SetHintString(level.kts["hint_electricity"]);

flag_wait("electricity_on");

thread teleport_room_fx();
thread main();
}
addItems()
{
// Create Kino Teleporting System array
level.kts = ;
// Set variables needed for the teleporting system (using the setVar function)

// DO NOT EDIT THESE
setVar("teleporter_trigger", getEnt("kino_teleporter_trigger","targetname"));
setVar("mainframe_trigger", getEnt("kino_mainframe_trigger","targetname"));
setVar("teleporter_fxspot", getEnt("kino_teleporter_fxspot","targetname"));
setVar("mainframe_fxspot", getEnt("kino_mainframe_fxspot","targetname"));
setVar("zombie_goto", getEnt("kino_teleporter_zombiegoto","targetname"));
setVar("mainframe_spawn", getEntArray("kino_mainframe_spawn","targetname"));
setVar("pap_room_spawn", getEntArray("kino_paproom_spawn","targetname"));
setVar("transfer_room_structs", getEntArray("kino_image_room","targetname"));
level.paping = false;
level.disable_pap = true;
level.kts["zombie_goto"] create_zombie_point_of_interest( 1536, 96, 10000, true );
level.kts["zombie_goto"].attract_to_origin = false;

// You MUST change this to be correct
setVar("room_is_pap", true); // If the room you go to when teleporting does NOT have the pack-a-punch in it, set this to false

// You CAN edit these
setVar("teleporter_cooldown_time", 60); // After a teleport, this is how long a wait until you can use it again
setVar("teleport_lag", 1); // When you go to teleport, this is how long it will wait until it actually teleports
setVar("pap_room_time", 45); // This is how long you are in the pack-a-punch room
setVar("wait_for_pap", true); // If false, you can be teleported out of the room even if there is a gun in the slot of the pap machine
setVar("teleport_cost", 500); // This is the amount of money it costs to teleport

// Hintstrings
setVar("hint_electricity", "You need to activate the power before using the teleporter");
setVar("hint_startup_t", "Press &&1 to initiate link to mainframe");
setVar("hint_startup_m", "Waiting for initial link to mainframe");
setVar("hint_link", "Press &&1 to link pad to mainframe");
setVar("hint_teleport_free", "Press &&1 to teleport"); // The non-free teleport hint is hardcoded below
setVar("hint_teleporting", "Teleporting in progress");
setVar("hint_cooldown", "The teleporter is cooling down");


if(!level.kts["room_is_pap"])
level.disable_pap = false;
}
setVar(var, value)
{
// Sets the value on the array
level.kts[var] = value;
}

// --------
// - Main -
// --------

main()
{
while(1)
{
level.kts["teleporter_trigger"] SetHintString(level.kts["hint_startup_t"]);
level.kts["mainframe_trigger"] SetHintString(level.kts["hint_startup_m"]);

level.kts["teleporter_trigger"] waittill("trigger");

level.kts["teleporter_trigger"] disable_trigger();
level.kts["mainframe_trigger"] SetHintString(level.kts["hint_link"]);

level.kts["mainframe_trigger"] waittill("trigger");

if(level.kts["teleport_cost"] == 0)
level.kts["teleporter_trigger"] SetHintString(level.kts["hint_teleport_free"]);
else
level.kts["teleporter_trigger"] SetHintString("Press &&1 to teleport [Cost: " + level.kts["teleport_cost"] + "]");
level.kts["teleporter_trigger"] enable_trigger();
level.kts["mainframe_trigger"] disable_trigger();

while(1)
{
level.kts["teleporter_trigger"] waittill("trigger", who);
if(level.kts["teleport_cost"] == 0)
break;

if(who.score < level.kts["teleport_cost"])
{
who playsound("deny");
continue;
}
who playsound("pa_buzz");
who maps\_zombiemode_score::minus_to_player_score( level.kts["teleport_cost"] );
break;
}

level.kts["teleporter_trigger"] SetHintString(level.kts["hint_teleporting"]);
level.kts["mainframe_trigger"] SetHintString(level.kts["hint_teleporting"]);
level.kts["mainframe_trigger"] enable_trigger();

level.kts["teleporter_trigger"] do_teleport();

level.kts["teleporter_trigger"] SetHintString(level.kts["hint_cooldown"]);
level.kts["mainframe_trigger"] SetHintString(level.kts["hint_cooldown"]);

wait level.kts["teleporter_cooldown_time"];
}
}
do_teleport()
{
// start fps fx
self thread teleport_pad_player_fx();

// Activate the TP zombie kill effect
self thread teleport_nuke( 20, 300, false); // Max 20 zombies and range 300

// 3rd Person Beam
level.kts["teleporter_fxspot"] thread pad_explosion();

// Teleport the players
self teleport_players();
}
teleport_players()
{
wait level.kts["teleport_lag"];
self notify( "fx_done" );
players_in = ;
attract = false;
players = GetPlayers();
for ( i = 0; i < players.size; i++ )
{
if( self player_is_near_pad( players[i] ) )
{
players_in[players_in.size] = players[i];
players[i] SetTransported( 2 );
players[i] SetStance( "stand" );
players[i] disableOffhandWeapons();
players[i] disableweapons();
image_room = getent( "teleport_room_" + i, "script_noteworthy" );
players[i].teleport_origin = spawn( "script_origin", players[i].origin );
players[i].teleport_origin.angles = players[i].angles;
players[i] linkto( players[i].teleport_origin );
players[i].teleport_origin.origin = image_room.origin + (0,70,-60); // 0, -70, -60
players[i].teleport_origin.angles = image_room.angles + (0,180,0);
setClientSysState("levelNotify", "t2d", players[i]);
players[i] FreezeControls( true );
wait_network_frame();
}
}
if(players_in.size == players.size)
{
attract = true;
level.kts["zombie_goto"].attract_to_origin = true;
}
wait 2;
for ( i = 0; i <players_in.size; i++ )
{
players_in[i].teleport_origin delete();
players_in[i].teleport_origin = undefined;
players_in[i] SetTransported( 0 );
players_in[i] FreezeControls( false );
players_in[i] enableOffhandWeapons();
players_in[i] enableweapons();
players_in[i] setOrigin(level.kts["pap_room_spawn"][i].origin);
}
if(level.kts["room_is_pap"])
level.disable_pap = false;
wait(level.kts["pap_room_time"] - 2);
if(level.kts["room_is_pap"] && level.kts["wait_for_pap"])
{
while(level.paping)
{
wait 0.5;
}
}

for ( i = 0; i <players_in.size; i++ )
players_in[i] SetTransported( 2 );
if(level.kts["room_is_pap"])
level.disable_pap = true;
level.kts["mainframe_fxspot"] thread do_mainframe_explode();
wait 2;
for ( i = 0; i <players_in.size; i++ )
{
players_in[i] SetTransported( 2 );
players_in[i] SetStance( "stand" );
players_in[i] disableOffhandWeapons();
players_in[i] disableweapons();
image_room = getent( "teleport_room_" + i, "script_noteworthy" );
players_in[i].teleport_origin = spawn( "script_origin", players_in[i].origin );
players_in[i].teleport_origin.angles = players_in[i].angles;
players_in[i] linkto( players_in[i].teleport_origin );
players_in[i].teleport_origin.origin = image_room.origin + (0,70,-60);
players_in[i].teleport_origin.angles = image_room.angles + (0,180,0);
players_in[i] FreezeControls( true );
setClientSysState("levelNotify", "t2d", players_in[i]);
wait_network_frame();
}
wait 2;
for ( i = 0; i <players_in.size; i++ )
{
players_in[i].teleport_origin delete();
players_in[i].teleport_origin = undefined;
players_in[i] SetTransported( 0 );
players_in[i] FreezeControls( false );
players_in[i] enableOffhandWeapons();
players_in[i] enableweapons();
players_in[i] setOrigin(level.kts["mainframe_spawn"][i].origin);
}
if(attract)
{
level.kts["zombie_goto"].attract_to_origin = false;
}
}

// -------
// Effects
// -------

teleport_room_fx()
{
points = level.kts["transfer_room_structs"];
for(i=0;i<points.size;i++)
{
points[i].struct = Spawn( "script_model", points[i].origin );
points[i].struct SetModel( "tag_origin_animate" );
points[i].struct.angles = points[i].angles;
PlayFxOnTag( level._effect["zombie_flashback_american"], points[i].struct, "tag_origin" );
}
}
teleport_pad_player_fx()
{
self endon( "fx_done" );

while ( 1 )
{
players = getplayers();
for ( i = 0; i < players.size; i++ )
{
if ( isdefined( players[i] ) )
{
if ( self player_is_near_pad( players[i] ) )
{
players[i] SetTransported( 2 );
}
else
{
players[i] SetTransported( 0 );
}
}
}
wait ( .05 );
}
}
player_is_near_pad( player )
{
radius = 88;
scale_factor = 2;

dist = Distance2D( player.origin, self.origin );
dist_touching = radius * scale_factor;

if ( dist < dist_touching )
{
return true;
}

return false;
}
teleport_nuke( max_zombies, range, end_after_one )
{
self endon( "fx_done" );
if(!isDefined(end_after_one))
end_after_one = false;
while(1)
{
zombies = getaispeciesarray("axis");

zombies = get_array_of_closest( self.origin, zombies, undefined, max_zombies, range );

for (i = 0; i < zombies.size; i++)
{
wait (randomfloatrange(0.2, 0.3));
if( !IsDefined( zombies[i] ) )
{
continue;
}

if( is_magic_bullet_shield_enabled( zombies[i] ) )
{
continue;
}

if( !( zombies[i] enemy_is_dog() ) )
{
zombies[i] maps\_zombiemode_spawner::zombie_head_gib();
}

zombies[i] dodamage( 10000, zombies[i].origin );
playsoundatposition( "nuked", zombies[i].origin );
}
if(end_after_one)
return;
wait 0.01;
}
}
pad_explosion()
{
self thread pad_explosion_sound();
playfx(level._effect["transporter_pad_start"], self.origin);
wait level.kts["teleport_lag"];
playfx(level._effect["transporter_beam"], self.origin);
}
pad_explosion_sound()
{
count = 0;
while(1)
{
count ++;
if(count == 5)
return;
sound = "top_spark" + count + "_warmup";
playsoundatposition(sound, self.origin);
wait 0.1;
if(count == 4)
return;
}
}
do_mainframe_explode()
{
playfx(level._effect["zombie_mainframe_beam_start"], self.origin);
wait 4;
earthquake(0.3, 2, self.origin, 1024);
playfx(level._effect["zombie_mainframe_beam"], self.origin);
self thread teleport_nuke( 20, 300, true);
}
Last Edit: November 03, 2018, 05:55:39 pm by Joeycx
broken avatar :(
×
broken avatar :(
Location: fi
Date Registered: 2 January 2015
Last active: 3 years ago
Posts
125
Respect
Forum Rank
Pack-a-Puncher
Primary Group
Member
My Contact & Social Links
More
Signature
Beginner mapper trying to make something for the community to enjoy
×
ihmiskeho's Groups
ihmiskeho's Contact & Social Linksihmiskeho
This is most likely not a script error. WaW has a limit to hintstrings (48 I believe). After you hit the limit the hintstrings stop updating.

Luckily there's a workaround for this issue, which can be found here: https://confluence.ugx-mods.com/display/UGXMODS/Hintstrings+not+updating

You should be able to find everything you need there.
Last Edit: October 28, 2018, 02:42:06 pm by ihmiskeho
broken avatar :(
×
broken avatar :(
Location: vn
Date Registered: 23 February 2015
Last active: 3 years ago
Posts
208
Respect
Forum Rank
Mr. Elemental
Primary Group
Member
×
Joeycx's Groups
Joeycx's Contact & Social Links
This is most likely not a script error. WaW has a limit to hintstrings (48 I believe). After you hit the limit the hintstrings stop updating.

Luckily there's a workaround for this issue, which can be found here: https://confluence.ugx-mods.com/display/UGXMODS/Hintstrings+not+updating

You should be able to find everything you need there.
 Works perfectly, But the teleporter text is still stuck on "power is required" text, because the teleporter text doesn't use _setHintString but uses setvar so i'm currently stuck on that lol 
broken avatar :(
×
broken avatar :(
Location: fi
Date Registered: 2 January 2015
Last active: 3 years ago
Posts
125
Respect
Forum Rank
Pack-a-Puncher
Primary Group
Member
My Contact & Social Links
More
×
ihmiskeho's Groups
ihmiskeho's Contact & Social Linksihmiskeho
Works perfectly, But the teleporter text is still stuck on "power is required" text, because the teleporter text doesn't use _setHintString but uses setvar so i'm currently stuck on that lol
Aiden has used SetVar to store the hintstring texts. I took a quick look at the script and found many lines similar to this:
Code Snippet
Plaintext
level.kts["teleporter_trigger"] SetHintString(level.kts["hint_electricity"]);
You should be able to replace SetHintString with _SetHintString.
Replace all SetHintStrings in the file with _SetHintString.
broken avatar :(
×
broken avatar :(
Location: vn
Date Registered: 23 February 2015
Last active: 3 years ago
Posts
208
Respect
Forum Rank
Mr. Elemental
Primary Group
Member
×
Joeycx's Groups
Joeycx's Contact & Social Links
Aiden has used SetVar to store the hintstring texts. I took a quick look at the script and found many lines similar to this:
Code Snippet
Plaintext
level.kts["teleporter_trigger"] SetHintString(level.kts["hint_electricity"]);
You should be able to replace SetHintString with _SetHintString.
Replace all SetHintStrings in the file with _SetHintString.
Problem solved! Thank you so much! 

 
Loading ...