diff --git a/Zombies Mods/Zombies++ v1.2/README.md b/Zombies Mods/Zombies++ v1.2/README.md index 4e25a74..85648b9 100644 --- a/Zombies Mods/Zombies++ v1.2/README.md +++ b/Zombies Mods/Zombies++ v1.2/README.md @@ -7,6 +7,7 @@ If you want to just run the mod, use the precompiled version of the files to sav ###### EDITING SOURCE CODE - Compile _**_clientids.gsc**_ as _**_clientids.gsc**_ and place it in the directory _**maps/mp/gametypes_zm/_clientids.gsc**_ - Compile _**_zm_powerups.gsc**_ as _**_zm_powerups.gsc**_ and place it in the directory _**maps/mp/zombies/_zm_powerups.gsc**_ +- Compile _**_zm_chugabud.gsc**_ as _**_zm_chugabud.gsc**_ and place it in the directory _**maps/mp/zombies/_zm_chugabud.gsc**_ - Make sure to replace your _**dedicated_zm.cfg**_ file with the one for Z++ ###### UPDATES V1.2 - _**_zm_powerups.gsc**_ now holds all functions for custom powerups diff --git a/Zombies Mods/Zombies++ v1.2/Source Code/_clientids.gsc b/Zombies Mods/Zombies++ v1.2/Source Code/_clientids.gsc index 5a85be0..836e7a4 100644 --- a/Zombies Mods/Zombies++ v1.2/Source Code/_clientids.gsc +++ b/Zombies Mods/Zombies++ v1.2/Source Code/_clientids.gsc @@ -17,6 +17,7 @@ init() level thread onPlayerConnect(); //on connect thread initServerDvars(); //initilize server dvars (credit JezuzLizard) thread startCustomPerkMachines(); //custom perk machines + level.afterlife_give_loadout = maps/mp/gametypes_zm/_clientids::give_afterlife_loadout; //override function that gives loadout back to the player. level.playerDamageStub = level.callbackplayerdamage; //damage callback for phd flopper level.callbackplayerdamage = ::phd_flopper_dmg_check; //more damage callback stuff. everybody do the flop //level.using_solo_revive = 0; //disables solo revive, fixing only 3 revives per game. @@ -36,6 +37,7 @@ onPlayerConnect() player thread doPHDdive(); player thread onPlayerSpawned(); player thread onPlayerDowned(); + player thread onPlayerRevived(); player thread spawnIfRoundOne(); //force spawns if round 1. no more spectating one player on round 1 } } @@ -107,19 +109,19 @@ onPlayerDowned() for(;;) { - self waittill( "player_downed" ); - self unsetperk( "specialty_additionalprimaryweapon" ); //removes the mulekick perk functionality + self waittill_any( "player_downed", "fake_death", "entering_last_stand"); + self unsetperk( "specialty_additionalprimaryweapon" ); //removes the mulekick perk functionality self unsetperk( "specialty_longersprint" ); //removes the staminup perk functionality self unsetperk( "specialty_deadshot" ); //removes the deadshot perk functionality self.hasPHD = undefined; //resets the flopper variable self.hasMuleKick = undefined; //resets the mule kick variable self.hasStaminUp = undefined; //resets the staminup variable self.hasDeadshot = undefined; //resets the deadshot variable - self.icon1 Destroy();self.icon1 = undefined; //deletes the perk icons and resets the variable - self.icon2 Destroy();self.icon2 = undefined; //deletes the perk icons and resets the variable - self.icon3 Destroy();self.icon3 = undefined; //deletes the perk icons and resets the variable - self.icon4 Destroy();self.icon4 = undefined; //deletes the perk icons and resets the variable - } + self.icon1 Destroy();self.icon1 = undefined; //deletes the perk icons and resets the variable + self.icon2 Destroy();self.icon2 = undefined; //deletes the perk icons and resets the variable + self.icon3 Destroy();self.icon3 = undefined; //deletes the perk icons and resets the variable + self.icon4 Destroy();self.icon4 = undefined; //deletes the perk icons and resets the variable + } } doPHDdive() //credit to extinct. just edited to add self.hasPHD variable @@ -270,18 +272,18 @@ setLowerMessage( ent, default_ref ) } drawshader( shader, x, y, width, height, color, alpha, sort ) -{ - hud = newclienthudelem( self ); - hud.elemtype = "icon"; - hud.color = color; - hud.alpha = alpha; - hud.sort = sort; - hud.children = []; - hud setparent( level.uiparent ); - hud setshader( shader, width, height ); - hud.x = x; - hud.y = y; - return hud; +{ + hud = newclienthudelem( self ); + hud.elemtype = "icon"; + hud.color = color; + hud.alpha = alpha; + hud.sort = sort; + hud.children = []; + hud setparent( level.uiparent ); + hud setshader( shader, width, height ); + hud.x = x; + hud.y = y; + return hud; } drawCustomPerkHUD(perk, x, color, perkname) //perk hud thinking or whatever. probably not the best method but whatever lol @@ -1155,3 +1157,219 @@ isTown() thread turn_tombstone_on(); } } +give_afterlife_loadout() +{ + + self takeallweapons(); + loadout = self.loadout; + primaries = self getweaponslistprimaries(); + if ( loadout.weapons.size > 1 || primaries.size > 1 ) + { + foreach ( weapon in primaries ) + { + self takeweapon( weapon ); + } + } + i = 0; + while ( i < loadout.weapons.size ) + { + + if ( !isDefined( loadout.weapons[ i ] ) ) + { + i++; + + continue; + } + if ( loadout.weapons[ i ][ "name" ] == "none" ) + { + i++; + + continue; + } + self maps/mp/zombies/_zm_weapons::weapondata_give( loadout.weapons[ i ] ); + i++; + } + self setspawnweapon( loadout.weapons[ loadout.current_weapon ] ); + self switchtoweaponimmediate( loadout.weapons[ loadout.current_weapon ] ); + if ( isDefined( self get_player_melee_weapon() ) ) + { + self giveweapon( self get_player_melee_weapon() ); + } + self maps/mp/zombies/_zm_equipment::equipment_give( self.loadout.equipment ); + if ( isDefined( loadout.hasclaymore ) && loadout.hasclaymore && !self hasweapon( "claymore_zm" ) ) + { + self giveweapon( "claymore_zm" ); + self set_player_placeable_mine( "claymore_zm" ); + self setactionslot( 4, "weapon", "claymore_zm" ); + self setweaponammoclip( "claymore_zm", loadout.claymoreclip ); + } + if ( isDefined( loadout.hasemp ) && loadout.hasemp ) + { + self giveweapon( "emp_grenade_zm" ); + self setweaponammoclip( "emp_grenade_zm", loadout.empclip ); + } + if ( isDefined( loadout.hastomahawk ) && loadout.hastomahawk ) + { + self giveweapon( self.current_tomahawk_weapon ); + self set_player_tactical_grenade( self.current_tomahawk_weapon ); + self setclientfieldtoplayer( "tomahawk_in_use", 1 ); + } + self.score = loadout.score; + perk_array = maps/mp/zombies/_zm_perks::get_perk_array( 1 ); + i = 0; + while ( i < perk_array.size ) + { + perk = perk_array[ i ]; + self unsetperk( perk ); + self set_perk_clientfield( perk, 0 ); + i++; + } + if (is_true(self.keep_perks)) + { + if(is_true(self.hadphd)) + { + self.hasphd = true; + self.hadphd = undefined; + self thread maps/mp/gametypes_zm/_clientids::drawCustomPerkHUD("specialty_doubletap_zombies", 0, (1, 0.25, 1)); + } + } + if ( isDefined( self.keep_perks ) && self.keep_perks && isDefined( loadout.perks ) && loadout.perks.size > 0 ) + { + i = 0; + while ( i < loadout.perks.size ) + { + if ( self hasperk( loadout.perks[ i ] ) ) + { + i++; + continue; + } + if ( loadout.perks[ i ] == "specialty_quickrevive" && flag( "solo_game" ) ) + { + level.solo_game_free_player_quickrevive = 1; + } + if ( loadout.perks[ i ] == "specialty_longersprint" ) + { + self setperk( "specialty_longersprint" ); //removes the staminup perk functionality + self.hasStaminUp = true; //resets the staminup variable + self thread maps/mp/gametypes_zm/_clientids::drawCustomPerkHUD("specialty_juggernaut_zombies", 0, (1, 1, 0)); + arrayremovevalue( loadout.perks, "specialty_longersprint" ); + + continue; + } + if ( loadout.perks[ i ] == "specialty_additionalprimaryweapon" ) + { + self setperk( "specialty_additionalprimaryweapon"); //removes the deadshot perk functionality + self.hasMuleKick = true; //resets the deadshot variable + self thread maps/mp/gametypes_zm/_clientids::drawCustomPerkHUD("specialty_fastreload_zombies", 0, (0, 0.7, 0)); + arrayremovevalue( loadout.perks, "specialty_additionalprimaryweapon" ); + continue; + } + if ( loadout.perks[ i ] == "specialty_finalstand" ) + { + i++; + continue; + } + maps/mp/zombies/_zm_perks::give_perk( loadout.perks[ i ] ); + i++; + wait 0.05; + } + } + self.keep_perks = undefined; + self set_player_lethal_grenade( self.loadout.lethal_grenade ); + if ( loadout.grenade > 0 ) + { + curgrenadecount = 0; + if ( self hasweapon( self get_player_lethal_grenade() ) ) + { + self getweaponammoclip( self get_player_lethal_grenade() ); + } + else + { + self giveweapon( self get_player_lethal_grenade() ); + } + self setweaponammoclip( self get_player_lethal_grenade(), loadout.grenade + curgrenadecount ); + } + +} +save_afterlife_loadout() //checked changed to match cerberus output +{ + primaries = self getweaponslistprimaries(); + currentweapon = self getcurrentweapon(); + self.loadout = spawnstruct(); + self.loadout.player = self; + self.loadout.weapons = []; + self.loadout.score = self.score; + self.loadout.current_weapon = -1; + index = 0; + foreach ( weapon in primaries ) + { + self.loadout.weapons[ index ] = maps/mp/zombies/_zm_weapons::get_player_weapondata( self, weapon ); + if ( weapon == currentweapon || self.loadout.weapons[ index ][ "alt_name" ] == currentweapon ) + { + self.loadout.current_weapon = index; + } + index++; + } + self.loadout.equipment = self get_player_equipment(); + if ( isDefined( self.loadout.equipment ) ) + { + self equipment_take( self.loadout.equipment ); + } + if ( self hasweapon( "claymore_zm" ) ) + { + self.loadout.hasclaymore = 1; + self.loadout.claymoreclip = self getweaponammoclip( "claymore_zm" ); + } + if ( self hasweapon( "emp_grenade_zm" ) ) + { + self.loadout.hasemp = 1; + self.loadout.empclip = self getweaponammoclip( "emp_grenade_zm" ); + } + if ( self hasweapon( "bouncing_tomahawk_zm" ) || self hasweapon( "upgraded_tomahawk_zm" ) ) + { + self.loadout.hastomahawk = 1; + self setclientfieldtoplayer( "tomahawk_in_use", 0 ); + } + self.loadout.perks = afterlife_save_perks( self ); + lethal_grenade = self get_player_lethal_grenade(); + if ( self hasweapon( lethal_grenade ) ) + { + self.loadout.grenade = self getweaponammoclip( lethal_grenade ); + } + else + { + self.loadout.grenade = 0; + } + self.loadout.lethal_grenade = lethal_grenade; + self set_player_lethal_grenade( undefined ); +} + +afterlife_save_perks( ent ) //checked changed to match cerberus output +{ + perk_array = ent get_perk_array( 1 ); + foreach ( perk in perk_array ) + { + ent unsetperk( perk ); + } + return perk_array; +} +onPlayerRevived() +{ + self endon("disconnect"); + level endon("end_game"); + + for(;;) + { + self waittill_any( "whos_who_self_revive","player_revived","fake_revive","do_revive_ended_normally", "al_t" ); + wait 1; + if(is_true(self.hadPHD)) + { + self setperk( "PHD_FLOPPER" ); //removes the staminup perk functionality + self.hasPHD = true; + self.hadPHD = undefined; + self thread drawCustomPerkHUD("specialty_doubletap_zombies", 0, (1, 0.25, 1)); + } + else + return; + } +} diff --git a/Zombies Mods/Zombies++ v1.2/Source Code/_zm_chugabud.gsc b/Zombies Mods/Zombies++ v1.2/Source Code/_zm_chugabud.gsc new file mode 100644 index 0000000..2046879 --- /dev/null +++ b/Zombies Mods/Zombies++ v1.2/Source Code/_zm_chugabud.gsc @@ -0,0 +1,830 @@ +#include maps/mp/_visionset_mgr; +#include maps/mp/zombies/_zm; +#include maps/mp/zombies/_zm_equipment; +#include maps/mp/zombies/_zm_weap_cymbal_monkey; +#include maps/mp/zombies/_zm_weapons; +#include maps/mp/zombies/_zm_clone; +#include maps/mp/zombies/_zm_chugabud; +#include maps/mp/zombies/_zm_laststand; +#include maps/mp/zombies/_zm_utility; +#include common_scripts/utility; +#include maps/mp/_utility; +#include maps/mp/zombies/_zm_perks; +#include maps/mp/gametypes_zm/_clientids; + +init() //checked matches cerberus output +{ + level.chugabud_laststand_func = ::chugabud_laststand; + level thread chugabud_hostmigration(); + level._effect[ "chugabud_revive_fx" ] = loadfx( "weapon/quantum_bomb/fx_player_position_effect" ); + level._effect[ "chugabud_bleedout_fx" ] = loadfx( "weapon/quantum_bomb/fx_player_position_effect" ); + add_custom_limited_weapon_check( ::is_weapon_available_in_chugabud_corpse ); +} + +chugabug_precache() //checked matches cerberus output +{ +} + +chugabud_player_init() //checked matches cerberus output +{ +} + +chugabud_laststand() //checked changed to match cerberus output +{ + self endon( "player_suicide" ); + self endon( "disconnect" ); + self endon( "chugabud_bleedout" ); + if(isDefined(self.hasPHD)) + self.hadPHD = true; + else + self.hadPHD = undefined; + self maps/mp/zombies/_zm_laststand::increment_downed_stat(); + self.ignore_insta_kill = 1; + self.health = self.maxhealth; + self maps/mp/zombies/_zm_chugabud::chugabud_save_loadout(); + self maps/mp/zombies/_zm_chugabud::chugabud_fake_death(); + wait 3; + if ( isDefined( self.insta_killed ) && self.insta_killed || isDefined( self.disable_chugabud_corpse ) ) + { + create_corpse = 0; + } + else + { + create_corpse = 1; + } + if ( create_corpse == 1 ) + { + if ( isDefined( level._chugabug_reject_corpse_override_func ) ) + { + reject_corpse = self [[ level._chugabug_reject_corpse_override_func ]]( self.origin ); + if ( reject_corpse ) + { + create_corpse = 0; + } + } + } + logline1 = "INFO: _zm_chugabud.gsc chugabud_laststand() create_corpse: " + create_corpse + "\n"; + logprint( logline1 ); + if ( create_corpse == 1 ) + { + self thread activate_chugabud_effects_and_audio(); + corpse = self chugabud_spawn_corpse(); + corpse thread chugabud_corpse_revive_icon( self ); + self.e_chugabud_corpse = corpse; + corpse thread chugabud_corpse_cleanup_on_spectator( self ); + if ( isDefined( level.whos_who_client_setup ) ) + { + corpse setclientfield( "clientfield_whos_who_clone_glow_shader", 1 ); + } + } + self chugabud_fake_revive(); + wait 0.1; + self.ignore_insta_kill = undefined; + self.disable_chugabud_corpse = undefined; + if ( create_corpse == 0 ) + { + self notify( "chugabud_effects_cleanup" ); + return; + } + bleedout_time = getDvarFloat( "player_lastStandBleedoutTime" ); + self thread chugabud_bleed_timeout( bleedout_time, corpse ); + self thread chugabud_handle_multiple_instances( corpse ); + corpse waittill( "player_revived", e_reviver ); + if ( isDefined( e_reviver ) && e_reviver == self ) + { + self notify( "whos_who_self_revive" ); + } + self perk_abort_drinking( 0.1 ); + self maps/mp/zombies/_zm_perks::perk_set_max_health_if_jugg( "health_reboot", 1, 0 ); + self setorigin( corpse.origin ); + self setplayerangles( corpse.angles ); + if ( self player_is_in_laststand() ) + { + self thread chugabud_laststand_cleanup( corpse, "player_revived" ); + self enableweaponcycling(); + self enableoffhandweapons(); + self auto_revive( self, 1 ); + return; + } + self chugabud_laststand_cleanup( corpse, undefined ); +} + +chugabud_laststand_cleanup( corpse, str_notify ) //checked matches cerberus output +{ + if ( isDefined( str_notify ) ) + { + self waittill( str_notify ); + } + self chugabud_give_loadout(); + self chugabud_corpse_cleanup( corpse, 1 ); +} + +chugabud_bleed_timeout( delay, corpse ) //checked changed to match cerberus output +{ + self endon( "player_suicide" ); + self endon( "disconnect" ); + corpse endon( "death" ); + wait delay; + if ( isDefined( corpse.revivetrigger ) ) + { + while ( corpse.revivetrigger.beingrevived ) + { + wait 0.01; + } + } + if ( isDefined( self.loadout.perks ) && flag( "solo_game" ) ) + { + for ( i = 0; i < self.loadout.perks.size; i++ ) + { + perk = self.loadout.perks[ i ]; + if ( perk == "specialty_quickrevive" ) + { + arrayremovevalue( self.loadout.perks, self.loadout.perks[ i ] ); + corpse notify( "player_revived" ); + return; + } + } + } + self chugabud_corpse_cleanup( corpse, 0 ); +} + +chugabud_corpse_cleanup( corpse, was_revived ) //checked matches cerberus output +{ + self notify( "chugabud_effects_cleanup" ); + if ( was_revived ) + { + playsoundatposition( "evt_ww_appear", corpse.origin ); + playfx( level._effect[ "chugabud_revive_fx" ], corpse.origin ); + } + else + { + playsoundatposition( "evt_ww_disappear", corpse.origin ); + playfx( level._effect[ "chugabud_bleedout_fx" ], 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; + } + self.loadout = undefined; + wait 0.1; + corpse delete(); + self.e_chugabud_corpse = undefined; +} + +chugabud_handle_multiple_instances( corpse ) //checked matches cerberus output +{ + corpse endon( "death" ); + self waittill( "perk_chugabud_activated" ); + self chugabud_corpse_cleanup( corpse, 0 ); +} + +chugabud_spawn_corpse() //checked matches cerberus output +{ + corpse = maps/mp/zombies/_zm_clone::spawn_player_clone( self, self.origin, undefined, self.whos_who_shader ); + corpse.angles = self.angles; + corpse maps/mp/zombies/_zm_clone::clone_give_weapon( "m1911_zm" ); + corpse maps/mp/zombies/_zm_clone::clone_animate( "laststand" ); + corpse.revive_hud = self chugabud_revive_hud_create(); + corpse thread maps/mp/zombies/_zm_laststand::revive_trigger_spawn(); + return corpse; +} + +chugabud_revive_hud_create() //checked matches cerberus output +{ + 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; +} + +chugabud_save_loadout() //checked changed to match cerberus output +{ + primaries = self getweaponslistprimaries(); + currentweapon = self getcurrentweapon(); + self.loadout = spawnstruct(); + self.loadout.player = self; + self.loadout.weapons = []; + self.loadout.score = self.score; + self.loadout.current_weapon = -1; + index = 0; + foreach ( weapon in primaries ) + { + logline1 = "weapon: " + weapon + "\n"; + logprint( logline1 ); + self.loadout.weapons[ index ] = maps/mp/zombies/_zm_weapons::get_player_weapondata( self, weapon ); + if ( weapon == currentweapon || self.loadout.weapons[ index ][ "alt_name" ] == currentweapon ) + { + self.loadout.current_weapon = index; + } + index++; + } + self.loadout.equipment = self get_player_equipment(); + if ( isDefined( self.loadout.equipment ) ) + { + self equipment_take( self.loadout.equipment ); + } + self.loadout save_weapons_for_chugabud( self ); + if ( self hasweapon( "claymore_zm" ) ) + { + self.loadout.hasclaymore = 1; + self.loadout.claymoreclip = self getweaponammoclip( "claymore_zm" ); + } + self.loadout.perks = chugabud_save_perks( self ); + self chugabud_save_grenades(); + if ( maps/mp/zombies/_zm_weap_cymbal_monkey::cymbal_monkey_exists() ) + { + self.loadout.zombie_cymbal_monkey_count = self getweaponammoclip( "cymbal_monkey_zm" ); + } +} + +chugabud_save_grenades() //checked matches cerberus output +{ + if ( self hasweapon( "emp_grenade_zm" ) ) + { + self.loadout.hasemp = 1; + self.loadout.empclip = self getweaponammoclip( "emp_grenade_zm" ); + } + lethal_grenade = self get_player_lethal_grenade(); + if ( self hasweapon( lethal_grenade ) ) + { + self.loadout.lethal_grenade = lethal_grenade; + self.loadout.lethal_grenade_count = self getweaponammoclip( lethal_grenade ); + } + else + { + self.loadout.lethal_grenade = undefined; + } +} + +chugabud_give_loadout() //checked partially changed to match cerberus output continues in for loops bad see the github for more info +{ + self takeallweapons(); + loadout = self.loadout; + primaries = self getweaponslistprimaries(); + if ( loadout.weapons.size > 1 || primaries.size > 1 ) + { + foreach ( weapon in primaries ) + { + self takeweapon( weapon ); + } + } + i = 0; + while ( i < loadout.weapons.size ) + { +// logline1 = "loadout.weapons[ " + i + " ][ name ] " + loadout.weapons[ i ][ "name" ] + "\n"; +// logprint( logline1 ); + if ( !isDefined( loadout.weapons[ i ] ) ) + { + i++; + continue; + } + if ( loadout.weapons[ i ][ "name" ] == "none" ) + { + i++; + continue; + } + self maps/mp/zombies/_zm_weapons::weapondata_give( loadout.weapons[ i ] ); + i++; + } + if ( loadout.current_weapon >= 0 && isDefined( loadout.weapons[ loadout.current_weapon ][ "name" ] ) ) + { + self switchtoweapon( loadout.weapons[ loadout.current_weapon ][ "name" ] ); + } + self giveweapon( "knife_zm" ); + self maps/mp/zombies/_zm_equipment::equipment_give( self.loadout.equipment ); + loadout restore_weapons_for_chugabud( self ); + self chugabud_restore_claymore(); + self.score = loadout.score; + self.pers[ "score" ] = loadout.score; + perk_array = maps/mp/zombies/_zm_perks::get_perk_array( 1 ); + for ( i = 0; i < perk_array.size; i++ ) + { + perk = perk_array[ i ]; + self unsetperk( perk ); + self.num_perks--; + self set_perk_clientfield( perk, 0 ); + } + if ( isDefined( loadout.perks ) && loadout.perks.size > 0 ) + { + + i = 0; + while ( i < loadout.perks.size ) + { + if ( self hasperk( loadout.perks[ i ] ) ) + { + i++; + continue; + } + if ( loadout.perks[ i ] == "specialty_quickrevive" && flag( "solo_game" ) ) + { + level.solo_game_free_player_quickrevive = 1; + } + if ( loadout.perks[ i ] == "specialty_longersprint" ) + { + self setperk( "specialty_longersprint" ); //gives the staminup perk functionality + self.hasStaminUp = true; //sets the staminup variable + self thread maps/mp/gametypes_zm/_clientids::drawCustomPerkHUD("specialty_juggernaut_zombies", 0, (1, 1, 0)); + arrayremovevalue( loadout.perks, "specialty_longersprint" ); + + continue; + } + if ( loadout.perks[ i ] == "specialty_deadshot" ) + { + self setperk( "specialty_deadshot"); //gives the deadshot perk functionality + self.hasDeadshot = true; //sets the deadshot variable + self thread maps/mp/gametypes_zm/_clientids::drawCustomPerkHUD("specialty_quickrevive_zombies", 0, (0.125, 0.125, 0.125)); + arrayremovevalue( loadout.perks, "specialty_deadshot" ); + continue; + } + if ( loadout.perks[ i ] == "specialty_finalstand" ) + { + i++; + continue; + } + maps/mp/zombies/_zm_perks::give_perk( loadout.perks[ i ] ); + i++; + } + } + self chugabud_restore_grenades(); + if ( maps/mp/zombies/_zm_weap_cymbal_monkey::cymbal_monkey_exists() ) + { + if ( loadout.zombie_cymbal_monkey_count ) + { + self maps/mp/zombies/_zm_weap_cymbal_monkey::player_give_cymbal_monkey(); + self setweaponammoclip( "cymbal_monkey_zm", loadout.zombie_cymbal_monkey_count ); + } + } +} + +chugabud_restore_grenades() //checked matches cerberus output +{ + if ( isDefined( self.loadout.hasemp ) && self.loadout.hasemp ) + { + self giveweapon( "emp_grenade_zm" ); + self setweaponammoclip( "emp_grenade_zm", self.loadout.empclip ); + } + if ( isDefined( self.loadout.lethal_grenade ) ) + { + self giveweapon( self.loadout.lethal_grenade ); + self setweaponammoclip( self.loadout.lethal_grenade, self.loadout.lethal_grenade_count ); + } +} + +chugabud_restore_claymore() //checked matches cerberus output +{ + if ( isDefined( self.loadout.hasclaymore ) && self.loadout.hasclaymore && !self hasweapon( "claymore_zm" ) ) + { + self giveweapon( "claymore_zm" ); + self set_player_placeable_mine( "claymore_zm" ); + self setactionslot( 4, "weapon", "claymore_zm" ); + self setweaponammoclip( "claymore_zm", self.loadout.claymoreclip ); + } +} + +chugabud_fake_death() //checked matches cerberus output +{ + level notify( "fake_death" ); + self notify( "fake_death" ); + self takeallweapons(); + self allowstand( 0 ); + self allowcrouch( 0 ); + self allowprone( 1 ); + self.ignoreme = 1; + self enableinvulnerability(); + wait 0.1; + self freezecontrols( 1 ); + wait 0.9; +} + +chugabud_fake_revive() //checked matches cerberus output +{ + level notify( "fake_revive" ); + self notify( "fake_revive" ); + playsoundatposition( "evt_ww_disappear", self.origin ); + playfx( level._effect[ "chugabud_revive_fx" ], self.origin ); + spawnpoint = chugabud_get_spawnpoint(); + if ( isDefined( level._chugabud_post_respawn_override_func ) ) + { + self [[ level._chugabud_post_respawn_override_func ]]( spawnpoint.origin ); + } + if ( isDefined( level.chugabud_force_corpse_position ) ) + { + if ( isDefined( self.e_chugabud_corpse ) ) + { + self.e_chugabud_corpse forceteleport( level.chugabud_force_corpse_position ); + } + level.chugabud_force_corpse_position = undefined; + } + if ( isDefined( level.chugabud_force_player_position ) ) + { + spawnpoint.origin = level.chugabud_force_player_position; + level.chugabud_force_player_position = undefined; + } + self setorigin( spawnpoint.origin ); + self setplayerangles( spawnpoint.angles ); + playsoundatposition( "evt_ww_appear", spawnpoint.origin ); + playfx( level._effect[ "chugabud_revive_fx" ], spawnpoint.origin ); + self allowstand( 1 ); + self allowcrouch( 1 ); + self allowprone( 1 ); + self.ignoreme = 0; + self setstance( "stand" ); + self freezecontrols( 0 ); + self giveweapon( "knife_zm" ); + self give_start_weapon( 1 ); + self.score = self.loadout.score; + self.pers[ "score" ] = self.loadout.score; + self giveweapon( "frag_grenade_zm" ); + self setweaponammoclip( "frag_grenade_zm", 2 ); + self chugabud_restore_claymore(); + wait 1; + self disableinvulnerability(); +} + +chugabud_get_spawnpoint() //checked partially changed to match cerberus output nested foreach is probably bad +{ + spawnpoint = undefined; + if ( get_chugabug_spawn_point_from_nodes( self.origin, 500, 700, 64, 1 ) ) + { + spawnpoint = level.chugabud_spawn_struct; + } + if ( !isDefined( spawnpoint ) ) + { + if ( get_chugabug_spawn_point_from_nodes( self.origin, 100, 400, 64, 1 ) ) + { + spawnpoint = level.chugabud_spawn_struct; + } + } + if ( !isDefined( spawnpoint ) ) + { + if ( get_chugabug_spawn_point_from_nodes( self.origin, 50, 400, 256, 0 ) ) + { + spawnpoint = level.chugabud_spawn_struct; + } + } + if ( !isDefined( spawnpoint ) ) + { + spawnpoint = maps/mp/zombies/_zm::check_for_valid_spawn_near_team( self, 1 ); + } + if ( !isDefined( spawnpoint ) ) + { + match_string = ""; + location = level.scr_zm_map_start_location; + if ( (location == "default" || location == "" ) && isdefined( level.default_start_location ) ) + { + location = level.default_start_location; + } + match_string = level.scr_zm_ui_gametype + "_" + location; + spawnpoints = []; + structs = getstructarray( "initial_spawn", "script_noteworthy" ); + if ( isdefined( structs ) ) + { + foreach ( struct in structs ) + { + if ( isdefined( struct.script_string ) ) + { + tokens = strtok( struct.script_string, " " ); + i = 0; + while ( i < tokens.size ) + { + if ( tokens[ i ] == match_string ) + { + spawnpoints[ spawnpoints.size ] = struct; + } + i++; + } + } + } + } + if ( !isDefined( spawnpoints ) || spawnpoints.size == 0 ) + { + spawnpoints = getstructarray( "initial_spawn_points", "targetname" ); + } + /* +/# + assert( isDefined( spawnpoints ), "Could not find initial spawn points!" ); +#/ + */ + spawnpoint = maps/mp/zombies/_zm::getfreespawnpoint( spawnpoints, self ); + } + return spawnpoint; +} + +get_chugabug_spawn_point_from_nodes( v_origin, min_radius, max_radius, max_height, ignore_targetted_nodes ) //checked partially changed to match cerberus output changed at own discretion +{ + if ( !isDefined( level.chugabud_spawn_struct ) ) + { + level.chugabud_spawn_struct = spawnstruct(); + } + found_node = undefined; + a_nodes = getnodesinradiussorted( v_origin, max_radius, min_radius, max_height, "pathnodes" ); + if ( isDefined( a_nodes ) && a_nodes.size > 0 ) + { + a_player_volumes = getentarray( "player_volume", "script_noteworthy" ); + index = a_nodes.size - 1; + i = index; + while ( i >= 0 ) + { + n_node = a_nodes[ i ]; + if ( ignore_targetted_nodes == 1 ) + { + if ( isDefined( n_node.target ) ) + { + i--; + continue; + } + } + if ( !positionwouldtelefrag( n_node.origin ) ) + { + if ( maps/mp/zombies/_zm_utility::check_point_in_enabled_zone( n_node.origin, 1, a_player_volumes ) ) + { + v_start = ( n_node.origin[ 0 ], n_node.origin[ 1 ], n_node.origin[ 2 ] + 30 ); + v_end = ( n_node.origin[ 0 ], n_node.origin[ 1 ], n_node.origin[ 2 ] - 30 ); + trace = bullettrace( v_start, v_end, 0, undefined ); + if ( trace[ "fraction" ] < 1 ) + { + override_abort = 0; + if ( isDefined( level._chugabud_reject_node_override_func ) ) + { + override_abort = [[ level._chugabud_reject_node_override_func ]]( v_origin, n_node ); + } + if ( !override_abort ) + { + found_node = n_node; + break; + } + } + } + } + i--; + } + } + if ( isDefined( found_node ) ) + { + level.chugabud_spawn_struct.origin = found_node.origin; + v_dir = vectornormalize( v_origin - level.chugabud_spawn_struct.origin ); + level.chugabud_spawn_struct.angles = vectorToAngles( v_dir ); + return 1; + } + return 0; +} + +force_corpse_respawn_position( forced_corpse_position ) //checked matches cerberus output +{ + level.chugabud_force_corpse_position = forced_corpse_position; +} + +force_player_respawn_position( forced_player_position ) //checked matches cerberus output +{ + level.chugabud_force_player_position = forced_player_position; +} + +save_weapons_for_chugabud( player ) //checked changed to match cerberus output +{ + self.chugabud_melee_weapons = []; + for ( i = 0; i < level._melee_weapons.size; i++ ) + { + self save_weapon_for_chugabud( player, level._melee_weapons[ i ].weapon_name ); + } +} + +save_weapon_for_chugabud( player, weapon_name ) //checked matches cerberus output +{ + if ( player hasweapon( weapon_name ) ) + { + self.chugabud_melee_weapons[ weapon_name ] = 1; + } +} + +restore_weapons_for_chugabud( player ) //checked changed to match cerberus output +{ + for ( i = 0; i < level._melee_weapons.size; i++ ) + { + self restore_weapon_for_chugabud( player, level._melee_weapons[ i ].weapon_name ); + } + self.chugabud_melee_weapons = undefined; +} + +restore_weapon_for_chugabud( player, weapon_name ) //checked changed to match cerberus output +{ + if ( !isDefined( weapon_name ) || !isDefined( self.chugabud_melee_weapons ) || !isDefined( self.chugabud_melee_weapons[ weapon_name ] ) ) + { + return; + } + if ( isDefined( self.chugabud_melee_weapons[ weapon_name ] ) && self.chugabud_melee_weapons[ weapon_name ] ) + { + player giveweapon( weapon_name ); + player set_player_melee_weapon( weapon_name ); + self.chugabud_melee_weapons[ weapon_name ] = 0; + } +} + +chugabud_save_perks( ent ) //checked changed to match cerberus output +{ + perk_array = ent get_perk_array( 1 ); + foreach ( perk in perk_array ) + { + ent unsetperk( perk ); + } + return perk_array; +} + +playchugabudtimeraudio() //checked matches cerberus output +{ + self endon( "chugabud_grabbed" ); + self endon( "chugabud_timedout" ); + player = self.player; + self thread playchugabudtimerout( player ); + while ( 1 ) + { + player playsoundtoplayer( "zmb_chugabud_timer_count", player ); + wait 1; + } +} + +playchugabudtimerout( player ) //checked matches cerberus output +{ + self endon( "chugabud_grabbed" ); + self waittill( "chugabud_timedout" ); + player playsoundtoplayer( "zmb_chugabud_timer_out", player ); +} + +chugabud_hostmigration() //checked changed to match cerberus output +{ + level endon( "end_game" ); + level notify( "chugabud_hostmigration" ); + level endon( "chugabud_hostmigration" ); + while ( 1 ) + { + level waittill( "host_migration_end" ); + chugabuds = getentarray( "player_chugabud_model", "script_noteworthy" ); + foreach ( model in chugabuds ) + { + playfxontag( level._effect[ "powerup_on" ], model, "tag_origin" ); + } + } +} + +player_revived_cleanup_chugabud_corpse() //checked matches cerberus output +{ +} + +player_has_chugabud_corpse() //checked matches cerberus output +{ + if ( isDefined( self.e_chugabud_corpse ) ) + { + return 1; + } + return 0; +} + +is_weapon_available_in_chugabud_corpse( weapon, player_to_check ) //checked partially changed to match cerberus output +{ + count = 0; + upgradedweapon = weapon; + if ( isDefined( level.zombie_weapons[ weapon ] ) && isDefined( level.zombie_weapons[ weapon ].upgrade_name ) ) + { + upgradedweapon = level.zombie_weapons[ weapon ].upgrade_name; + } + players = getplayers(); + if ( isDefined( players ) ) + { + player_index = 0; + while ( player_index < players.size ) + { + player = players[ player_index ]; + if ( isDefined( player_to_check ) && player != player_to_check ) + { + player_index++; + continue; + } + if ( player player_has_chugabud_corpse() ) + { + if ( isDefined( player.loadout ) && isDefined( player.loadout.weapons ) ) + { + for ( i = 0; i < player.loadout.weapons.size; i++ ) + { + chugabud_weapon = player.loadout.weapons[ i ]; + if ( isDefined( chugabud_weapon ) && chugabud_weapon[ "name" ] == weapon || chugabud_weapon[ "name" ] == upgradedweapon ) + { + count++; + } + } + } + } + player_index++; + } + } + return count; +} + +chugabud_corpse_cleanup_on_spectator( player ) //checked changed to match cerberus output +{ + self endon( "death" ); + player endon( "disconnect" ); + while ( 1 ) + { + if ( player.sessionstate == "spectator" ) + { + break; + } + wait 0.01; + } + player chugabud_corpse_cleanup( self, 0 ); +} + +chugabud_corpse_revive_icon( player ) //checked changed to match cerberus output +{ + self endon( "death" ); + height_offset = 30; + index = player.clientid; + hud_elem = newhudelem(); + self.revive_hud_elem = hud_elem; + hud_elem.x = self.origin[ 0 ]; + hud_elem.y = self.origin[ 1 ]; + hud_elem.z = self.origin[ 2 ] + height_offset; + hud_elem.alpha = 1; + hud_elem.archived = 1; + hud_elem setshader( "waypoint_revive", 5, 5 ); + hud_elem setwaypoint( 1 ); + hud_elem.hidewheninmenu = 1; + hud_elem.immunetodemogamehudsettings = 1; + while ( 1 ) + { + if ( !isDefined( self.revive_hud_elem ) ) + { + break; + } + hud_elem.x = self.origin[ 0 ]; + hud_elem.y = self.origin[ 1 ]; + hud_elem.z = self.origin[ 2 ] + height_offset; + wait 0.01; + } +} + +activate_chugabud_effects_and_audio() //checked matches cerberus output +{ + if ( isDefined( level.whos_who_client_setup ) ) + { + if ( !isDefined( self.whos_who_effects_active ) ) + { + if ( isDefined( level.chugabud_shellshock ) ) + { + self shellshock( "whoswho", 60 ); + } + if ( isDefined( level.vsmgr_prio_visionset_zm_whos_who ) ) + { + maps/mp/_visionset_mgr::vsmgr_activate( "visionset", "zm_whos_who", self ); + } + self setclientfieldtoplayer( "clientfield_whos_who_audio", 1 ); + self setclientfieldtoplayer( "clientfield_whos_who_filter", 1 ); + self.whos_who_effects_active = 1; + self thread deactivate_chugabud_effects_and_audio(); + } + } +} + +deactivate_chugabud_effects_and_audio() //checked matches cerberus output +{ + self waittill_any( "death", "chugabud_effects_cleanup", "spawned_player" ); + if ( isDefined( level.whos_who_client_setup ) ) + { + if ( isDefined( self.whos_who_effects_active ) && self.whos_who_effects_active == 1 ) + { + if ( isDefined( level.chugabud_shellshock ) ) + { + self stopshellshock(); + } + if ( isDefined( level.vsmgr_prio_visionset_zm_whos_who ) ) + { + maps/mp/_visionset_mgr::vsmgr_deactivate( "visionset", "zm_whos_who", self ); + } + self setclientfieldtoplayer( "clientfield_whos_who_audio", 0 ); + self setclientfieldtoplayer( "clientfield_whos_who_filter", 0 ); + } + self.whos_who_effects_active = undefined; + } +} + + + + + +