Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Messages - Joeycx

decided to make this real quick add this to the bottom of your mapname.gsc file
Code: cpp
location_display()
{
players = get_players();
for(i=0;i<players.size;i++)
players[i] thread location_display_text();
}

location_display_text()
{
hint_hud = create_simple_hud(self);
hint_hud.alignX = "left";
hint_hud.alignY = "top";
hint_hud.horzAlign = "left";
hint_hud.vertAlign = "top";
hint_hud.fontscale = 2;
hint_hud.color =  (1, .2, .2);
hint_hud.x = 2;
hint_hud.y = 2;
hint_hud.alpha = 1;
text = "";
while(1)
{
text = self get_location_text();
hint_hud SetText( text );
wait .1;
}
}

get_location_text()
{
text = "";
zone_name = "";
zkeys = GetArrayKeys( level.zones );
for( z=0; z<zkeys.size; z++ )
{
zone = level.zones ];
for (i = 0; i < zone.volumes.size; i++)
{
if (self IsTouching(zone.volumes[i]) )
zone_name = zone.volumes[i].targetname;
}
}

switch( zone_name )
{
case "start_zone":
text = "Spawn Room";
break;

case "power":
text = "Power Room";
break;

default:
text = "zone not defined";
break;
}

return text;
}
add
level thread location_display();
under
level thread DLC3_threadCalls2();
at the bottom of the main()
now how it worksat the bottom fuction of this ( get_location_text() ) theres this bit
	switch( zone_name )
{
case "start_zone":
text = "Spawn Room";
break;

case "power":
text = "Power Room";
break;

default:
text = "zone not defined";
break;
}
this is just an example part ive added, for it to work in your map youwil need to modify this.
the part that says - case "start_zone"
this is the name you gave the zone in radiant
the part directly under it, the part that says "Spawn Room" is what will be displayed when your standing in this zone.
change the example ones to two different zones you have with a name you want to give them and for every other zone you have copy and paste this part and change it to be as you need it
		case "start_zone":
text = "Spawn Room";
break;
hope this is easy enough to understand,let me know if you have any issues
There's seems to be a bad syntax here
zone =  level.zones ];
 so i changed it to
zone = ( level.zones );
it loads but doesn't display the text.
314 days ago
in raw/soundalias of your root call of duty world at war. Then in the soundalias folder there should be files with the file type csv. copy any one of those files, erase the text inside the copied version and add the text from the video into that file, rename that file "radios". For the actual script, since the link is dead, you will have to slow down the video to copy word for word from the video by going into your mod/yourmapname/maps and find your nazi_zombie_yourmapname.gsc and adding the radio script word for word using the video at the bottom of your nazi_zombie_yourmapname.gsc. The rest should be self explanatory as the video explains everything else besides providing the actual script. Good Luck!
378 days ago
I have this strange problem with the bayonet and the bowie knife. When i buy the bowie knife with normal guns without bayonet like the ray gun or the pistol the bowie knife works perfectly. But when i buy the bowie knife and then buy a bayonet weapon, the bowie knife and the bayonet animation is gone and the basic knife animation appears instead of the bayonet. I want it to be when you buy the bowie knife and then buy a bayonet weapon, the bayonet animation shows instead of a basic knife animation. I know it's  weird problem but if anyone could help it will be greatly appericated! 
380 days ago
Aiden has used SetVar to store the hintstring texts. I took a quick look at the script and found many lines similar to this:
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! 
380 days ago
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 
381 days ago
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

/*#===================================================================###
###                                                                   ###
###                                                                   ###
###                    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
#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);
}
386 days ago
I been messing around with alt weapons like adding a grenade launcher on the ariska. But going into devmap to test it, the option to use the grenade launcher(by pressing 5 or left dpad on console or using controller on pc) doesn't show up. It only shows up if i restart the game with devmap. It shows up and works fine but if i take damage the game freezes for a bit and the error script runtime error infinite loop shows up. This only happens when i restart a devmap game to make the option for the grenade launcher to work. It's the strangest error i've come across, so if anyone could help it would be great!
403 days ago
2 materials 1 texture.
You can separate the trunk from the canopy/branches/leaves in maya and make another gdt model_phong material for the trunk/bark but still reference the same texture file as the leaves.
That tree model is in the back of the map anyways and i tweaked the settings to make it less awkward. I also changed the rest of my map's foliage that wasn't moving and it works flawlessly, so thank you very much on helping me!
405 days ago
If the grass and tree models i sent worked you could try duplicating my gdt entry with the copy/paste/duplicate buttons in asset manager.
In radiant the tree leaves usually are multicolored like the stock trees but ingame they will look normal.
If they are script_models they probably receive light differently or need the "ground lit" option in asset manager but I'm just guessing.
You can send me a model and texture and i can convert and try if you want.
I FINALLY GOT IT TO WORK. I had to rename my material to the actual material used instead of the one you gave me (i'm really dumb so of course it looked messed up when i converted it) In game the trees sway and the color looks fine but a small problem would be that the tree trunk sways also, instead of just the canopy of the tree (the part of the tree where there are only leaves,pines etc) the col dds used also uses the tree trunk texture so ingame it looks fine from a distance but up close the tree trunk also sways which looks very bizzare. 




406 days ago
Convert materials then models, add images from raw images to mods/mapname/images
In mapname.gsc add dvars above or below zombiemode::main();
]https://www.mediafire.com/download/uu74znaxj57j0fg
The wind works perfectly but i'm really having trouble with some asset manager things. I'm converting images of the pine tree using your settings and then converting the xmodel  (in the converter it says dynamic foliage generated which i thought ment it was all set but...) the xmodel comes out wonky with some textures missing and the leaves different colors and in game it doesn't move at all. 





408 days ago
After changing the material to dynamic foliage or tree canopy the models need to be reconverted, it should print "dynamic normals generated" or something like that when converted.
If that doesn't work you might need to delete and remake the gdt material entry if the original material settings are sticking.
//
I can upload a gdt/model/texture if you dont figure it out.
I made a new gdt, added a new entry, did dynamic foliage and canopy settings but both have the same result. I don't know if this is the problem..bu 

I don't quite know, what you ment by "models need to be reconverted", is it just pc convert or something else entirely? If you could upload you gdt, it would help me greatly.
409 days ago
In asset manager (at the top)
materialtype
"dynamic foliage" or "tree canopy"
//
These might be needed depending on the purpose of the material
Surface properties (at the bottom)
"Noimpacts" "nomarks" "transparent" "nocastshadow" onlycastshadow"
I've tried both but can't seem get them to work. Here are my settings in asset manager. 

Here are the model/images i'm using

412 days ago
Hi, I recently added wind into my map and i noticed that my cod 4 xmodel tree's don't sway to the wind like my cod 5 trees, is there anyway to make this happen? Thanks!
413 days ago
Hi! I recently added dynamic foliage to my map, but it doesn't seem to work right. (http://wiki.modsrepository.com/index.php?title=Call_of_Duty_5:_Dynamic_Foliage)
The script calls for mp/utilites and with that it calls all these other maps/mp scripts with it. I also tried using the script without the mp/utilites but the script_models in game are invisible. If anyone got this to work, let me know! 
432 days ago
		self random_tan(); 
in _zombiemode_spawner.gsc, this is probbably what you mean, if you wanna remove it add // before it

This is probably the answer. How would you set it if you want every zombie to be tan?
435 days ago

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 Twitch
Loading ...