diff --git a/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/gametypes_zm/_zm_gametype.gsc b/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/gametypes_zm/_zm_gametype.gsc new file mode 100644 index 0000000..b87c304 --- /dev/null +++ b/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/gametypes_zm/_zm_gametype.gsc @@ -0,0 +1,2076 @@ +#include maps/mp/zombies/_zm_spawner; +#include maps/mp/zombies/_zm_game_module; +#include maps/mp/zombies/_zm_pers_upgrades_functions; +#include maps/mp/zombies/_zm_blockers; +#include maps/mp/gametypes_zm/_spawning; +#include maps/mp/zombies/_zm_stats; +#include maps/mp/gametypes_zm/_hud; +#include maps/mp/zombies/_zm_audio_announcer; +#include maps/mp/zombies/_zm_audio; +#include maps/mp/zombies/_zm_laststand; +#include maps/mp/gametypes_zm/_globallogic_ui; +#include maps/mp/gametypes_zm/_hud_message; +#include maps/mp/gametypes_zm/_globallogic_score; +#include maps/mp/gametypes_zm/_globallogic_defaults; +#include maps/mp/gametypes_zm/_gameobjects; +#include maps/mp/gametypes_zm/_weapons; +#include maps/mp/gametypes_zm/_callbacksetup; +#include maps/mp/zombies/_zm_utility; +#include common_scripts/utility; +#include maps/mp/gametypes_zm/_hud_util; +#include maps/mp/_utility; + +main() +{ + //the bare minimum for a zombies game + maps/mp/gametypes_zm/_globallogic::init(); + maps/mp/gametypes_zm/_callbacksetup::setupcallbacks(); + globallogic_setupdefault_zombiecallbacks(); + menu_init(); + //controls several gamemode specific variables non essential + registerroundlimit( 1, 1 ); + registertimelimit( 0, 0 ); + registerscorelimit( 0, 0 ); + registerroundwinlimit( 0, 0 ); + registernumlives( 1, 1 ); + maps/mp/gametypes_zm/_weapons::registergrenadelauncherduddvar( level.gametype, 10, 0, 1440 ); + maps/mp/gametypes_zm/_weapons::registerthrowngrenadeduddvar( level.gametype, 0, 0, 1440 ); + maps/mp/gametypes_zm/_weapons::registerkillstreakdelay( level.gametype, 0, 0, 1440 ); + maps/mp/gametypes_zm/_globallogic::registerfriendlyfiredelay( level.gametype, 15, 0, 1440 ); + + //determines many aspects of the game non essential + level.takelivesondeath = 1; + level.teambased = 1; + level.disableprematchmessages = 1; + level.disablemomentum = 1; + level.overrideteamscore = 0; + level.overrideplayerscore = 0; + level.displayhalftimetext = 0; + level.displayroundendtext = 0; + level.allowannouncer = 0; + level.endgameonscorelimit = 0; + level.endgameontimelimit = 0; + level.resetplayerscoreeveryround = 1; + level.doprematch = 0; + level.nopersistence = 1; + level.scoreroundbased = 0; + level.forceautoassign = 1; + level.dontshowendreason = 1; + level.forceallallies = 0; + level.allow_teamchange = 0; + + //non essential dvars + setdvar( "scr_disable_team_selection", 1 ); + makedvarserverinfo( "scr_disable_team_selection", 1 ); + setmatchflag( "hud_zombie", 1 ); + setdvar( "scr_disable_weapondrop", 1 ); + setdvar( "scr_xpscale", 0 ); + + //all working except onspawnplayerunified + level.onstartgametype = ::onstartgametype; + level.onspawnplayer = ::blank; + + //causes the server to crash when someone joins + level.onspawnplayerunified = ::onspawnplayerunified; + level.onroundendgame = ::onroundendgame; + level.mayspawn = ::mayspawn; + set_game_var( "ZM_roundLimit", 1 ); + set_game_var( "ZM_scoreLimit", 1 ); + set_game_var( "_team1_num", 0 ); + set_game_var( "_team2_num", 0 ); + + //all working non essential + map_name = level.script; + mode = getDvar( "ui_gametype" ); + if ( isDefined( mode ) && mode == "" && isDefined( level.default_game_mode ) ) + { + mode = level.default_game_mode; + } + set_gamemode_var_once( "mode", mode ); + set_game_var_once( "side_selection", 1 ); + location = getDvar( "ui_zm_mapstartlocation" ); + if ( location == "" && isDefined( level.default_start_location ) ) + { + location = level.default_start_location; + } + set_gamemode_var_once( "location", location ); + set_gamemode_var_once( "randomize_mode", getDvarInt( "zm_rand_mode" ) ); + set_gamemode_var_once( "randomize_location", getDvarInt( "zm_rand_loc" ) ); + + //non essential vars + set_gamemode_var_once( "team_1_score", 0 ); + set_gamemode_var_once( "team_2_score", 0 ); + set_gamemode_var_once( "current_round", 0 ); + set_gamemode_var_once( "rules_read", 0 ); + set_game_var_once( "switchedsides", 0 ); + gametype = getDvar( "ui_gametype" ); + game[ "dialog" ][ "gametype" ] = gametype + "_start"; + game[ "dialog" ][ "gametype_hardcore" ] = gametype + "_start"; + game[ "dialog" ][ "offense_obj" ] = "generic_boost"; + game[ "dialog" ][ "defense_obj" ] = "generic_boost"; + set_gamemode_var( "pre_init_zombie_spawn_func", undefined ); + set_gamemode_var( "post_init_zombie_spawn_func", undefined ); + set_gamemode_var( "match_end_notify", undefined ); + set_gamemode_var( "match_end_func", undefined ); + setscoreboardcolumns( "score", "kills", "downs", "revives", "headshots" ); + + //causes no crashes probably fine + onplayerconnect_callback( ::onplayerconnect_check_for_hotjoin ); +} + +game_objects_allowed( mode, location ) +{ + allowed[ 0 ] = mode; + entities = getentarray(); + _a153 = entities; + _k153 = getFirstArrayKey( _a153 ); + while ( isDefined( _k153 ) ) + { + entity = _a153[ _k153 ]; + if ( isDefined( entity.script_gameobjectname ) ) + { + isallowed = maps/mp/gametypes_zm/_gameobjects::entity_is_allowed( entity, allowed ); + isvalidlocation = maps/mp/gametypes_zm/_gameobjects::location_is_allowed( entity, location ); + if ( !isallowed || !isvalidlocation && !is_classic() ) + { + if ( isDefined( entity.spawnflags ) && entity.spawnflags == 1 ) + { + if ( isDefined( entity.classname ) && entity.classname != "trigger_multiple" ) + { + entity connectpaths(); + } + } + entity delete(); + break; + } + else + { + if ( isDefined( entity.script_vector ) ) + { + entity moveto( entity.origin + entity.script_vector, 0,05 ); + entity waittill( "movedone" ); + if ( isDefined( entity.spawnflags ) && entity.spawnflags == 1 ) + { + entity disconnectpaths(); + } + break; + } + else + { + if ( isDefined( entity.spawnflags ) && entity.spawnflags == 1 ) + { + if ( isDefined( entity.classname ) && entity.classname != "trigger_multiple" ) + { + entity connectpaths(); + } + } + } + } + } + _k153 = getNextArrayKey( _a153, _k153 ); + } +} + +post_init_gametype() +{ + if ( isDefined( level.gamemode_map_postinit ) ) + { + if ( isDefined( level.gamemode_map_postinit[ level.scr_zm_ui_gametype ] ) ) + { + [[ level.gamemode_map_postinit[ level.scr_zm_ui_gametype ] ]](); + } + } +} + +post_gametype_main( mode ) +{ + set_game_var( "ZM_roundWinLimit", get_game_var( "ZM_roundLimit" ) * 0.5 ); + level.roundlimit = get_game_var( "ZM_roundLimit" ); + if ( isDefined( level.gamemode_map_preinit ) ) + { + if ( isDefined( level.gamemode_map_preinit[ mode ] ) ) + { + [[ level.gamemode_map_preinit[ mode ] ]](); + } + } +} + +globallogic_setupdefault_zombiecallbacks() +{ + level.spawnplayer = maps/mp/gametypes_zm/_globallogic_spawn::spawnplayer; + level.spawnplayerprediction = maps/mp/gametypes_zm/_globallogic_spawn::spawnplayerprediction; + level.spawnclient = maps/mp/gametypes_zm/_globallogic_spawn::spawnclient; + level.spawnspectator = maps/mp/gametypes_zm/_globallogic_spawn::spawnspectator; + level.spawnintermission = maps/mp/gametypes_zm/_globallogic_spawn::spawnintermission; + level.onplayerscore = ::blank; + level.onteamscore = ::blank; + + //doesn't exist in any dump or any other script no idea what its trying to override to + //level.wavespawntimer = ::wavespawntimer; + level.onspawnplayer = ::blank; + level.onspawnplayerunified = ::blank; + level.onspawnspectator = ::onspawnspectator; + level.onspawnintermission = ::onspawnintermission; + level.onrespawndelay = ::blank; + level.onforfeit = ::blank; + level.ontimelimit = ::blank; + level.onscorelimit = ::blank; + level.ondeadevent = ::ondeadevent; + level.ononeleftevent = ::blank; + level.giveteamscore = ::blank; + level.giveplayerscore = ::blank; + level.gettimelimit = maps/mp/gametypes_zm/_globallogic_defaults::default_gettimelimit; + level.getteamkillpenalty = ::blank; + level.getteamkillscore = ::blank; + level.iskillboosting = ::blank; + level._setteamscore = maps/mp/gametypes_zm/_globallogic_score::_setteamscore; + level._setplayerscore = ::blank; + level._getteamscore = ::blank; + level._getplayerscore = ::blank; + level.onprecachegametype = ::blank; + level.onstartgametype = ::blank; + level.onplayerconnect = ::blank; + level.onplayerdisconnect = ::onplayerdisconnect; + level.onplayerdamage = ::blank; + level.onplayerkilled = ::blank; + level.onplayerkilledextraunthreadedcbs = []; + level.onteamoutcomenotify = maps/mp/gametypes_zm/_hud_message::teamoutcomenotifyzombie; + level.onoutcomenotify = ::blank; + level.onteamwageroutcomenotify = ::blank; + level.onwageroutcomenotify = ::blank; + level.onendgame = ::onendgame; + level.onroundendgame = ::blank; + level.onmedalawarded = ::blank; + level.autoassign = maps/mp/gametypes_zm/_globallogic_ui::menuautoassign; + level.spectator = maps/mp/gametypes_zm/_globallogic_ui::menuspectator; + level.class = maps/mp/gametypes_zm/_globallogic_ui::menuclass; + level.allies = ::menuallieszombies; + level.teammenu = maps/mp/gametypes_zm/_globallogic_ui::menuteam; + level.callbackactorkilled = ::blank; + level.callbackvehicledamage = ::blank; +} + +setup_standard_objects( location ) +{ + structs = getstructarray( "game_mode_object" ); + _a290 = structs; + _k290 = getFirstArrayKey( _a290 ); + while ( isDefined( _k290 ) ) + { + struct = _a290[ _k290 ]; + if ( isDefined( struct.script_noteworthy ) && struct.script_noteworthy != location ) + { + } + else + { + if ( isDefined( struct.script_string ) ) + { + keep = 0; + tokens = strtok( struct.script_string, " " ); + _a300 = tokens; + _k300 = getFirstArrayKey( _a300 ); + while ( isDefined( _k300 ) ) + { + token = _a300[ _k300 ]; + if ( token == level.scr_zm_ui_gametype && token != "zstandard" ) + { + keep = 1; + } + else + { + if ( token == "zstandard" ) + { + keep = 1; + } + } + _k300 = getNextArrayKey( _a300, _k300 ); + } + if ( !keep ) + { + break; + } + } + else + { + barricade = spawn( "script_model", struct.origin ); + barricade.angles = struct.angles; + barricade setmodel( struct.script_parameters ); + } + } + _k290 = getNextArrayKey( _a290, _k290 ); + } + objects = getentarray(); + _a322 = objects; + _k322 = getFirstArrayKey( _a322 ); + while ( isDefined( _k322 ) ) + { + object = _a322[ _k322 ]; + if ( !object is_survival_object() ) + { + } + else + { + if ( isDefined( object.spawnflags ) && object.spawnflags == 1 && object.classname != "trigger_multiple" ) + { + object connectpaths(); + } + object delete(); + } + _k322 = getNextArrayKey( _a322, _k322 ); + } + if ( isDefined( level._classic_setup_func ) ) + { + [[ level._classic_setup_func ]](); + } +} + +is_survival_object() +{ + if ( !isDefined( self.script_parameters ) ) + { + return 0; + } + tokens = strtok( self.script_parameters, " " ); + remove = 0; + _a352 = tokens; + _k352 = getFirstArrayKey( _a352 ); + while ( isDefined( _k352 ) ) + { + token = _a352[ _k352 ]; + if ( token == "survival_remove" ) + { + remove = 1; + } + _k352 = getNextArrayKey( _a352, _k352 ); + } + return remove; +} + +game_module_player_damage_callback( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime ) +{ + self.last_damage_from_zombie_or_player = 0; + if ( isDefined( eattacker ) ) + { + if ( isplayer( eattacker ) && eattacker == self ) + { + return; + } + if ( isDefined( eattacker.is_zombie ) || eattacker.is_zombie && isplayer( eattacker ) ) + { + self.last_damage_from_zombie_or_player = 1; + } + } + if ( isDefined( self._being_shellshocked ) || self._being_shellshocked && self maps/mp/zombies/_zm_laststand::player_is_in_laststand() ) + { + return; + } + if ( isplayer( eattacker ) && isDefined( eattacker._encounters_team ) && eattacker._encounters_team != self._encounters_team ) + { + if ( isDefined( self.hasriotshield ) && self.hasriotshield && isDefined( vdir ) ) + { + if ( isDefined( self.hasriotshieldequipped ) && self.hasriotshieldequipped ) + { + if ( self maps/mp/zombies/_zm::player_shield_facing_attacker( vdir, 0.2 ) && isDefined( self.player_shield_apply_damage ) ) + { + return; + } + } + else + { + if ( !isDefined( self.riotshieldentity ) ) + { + if ( !self maps/mp/zombies/_zm::player_shield_facing_attacker( vdir, -0.2 ) && isDefined( self.player_shield_apply_damage ) ) + { + return; + } + } + } + } + if ( isDefined( level._game_module_player_damage_grief_callback ) ) + { + self [[ level._game_module_player_damage_grief_callback ]]( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime ); + } + if ( isDefined( level._effect[ "butterflies" ] ) ) + { + if ( isDefined( sweapon ) && weapontype( sweapon ) == "grenade" ) + { + playfx( level._effect[ "butterflies" ], self.origin + vectorScale( ( 1, 1, 1 ), 40 ) ); + } + else + { + playfx( level._effect[ "butterflies" ], vpoint, vdir ); + } + } + self thread do_game_mode_shellshock(); + self playsound( "zmb_player_hit_ding" ); + } +} + +do_game_mode_shellshock() +{ + self endon( "disconnect" ); + self._being_shellshocked = 1; + self shellshock( "grief_stab_zm", 0.75 ); + wait 0.75; + self._being_shellshocked = 0; +} + +add_map_gamemode( mode, preinit_func, precache_func, main_func ) +{ + if ( !isDefined( level.gamemode_map_location_init ) ) + { + level.gamemode_map_location_init = []; + } + if ( !isDefined( level.gamemode_map_location_main ) ) + { + level.gamemode_map_location_main = []; + } + if ( !isDefined( level.gamemode_map_preinit ) ) + { + level.gamemode_map_preinit = []; + } + if ( !isDefined( level.gamemode_map_postinit ) ) + { + level.gamemode_map_postinit = []; + } + if ( !isDefined( level.gamemode_map_precache ) ) + { + level.gamemode_map_precache = []; + } + if ( !isDefined( level.gamemode_map_main ) ) + { + level.gamemode_map_main = []; + } + level.gamemode_map_preinit[ mode ] = preinit_func; + level.gamemode_map_main[ mode ] = main_func; + level.gamemode_map_precache[ mode ] = precache_func; + level.gamemode_map_location_precache[ mode ] = []; + level.gamemode_map_location_main[ mode ] = []; +} + +add_map_location_gamemode( mode, location, precache_func, main_func ) +{ + if ( !isDefined( level.gamemode_map_location_precache[ mode ] ) ) + { + /* +/# + println( "*** ERROR : " + mode + " has not been added to the map using add_map_gamemode." ); +#/ + */ + return; + } + level.gamemode_map_location_precache[ mode ][ location ] = precache_func; + level.gamemode_map_location_main[ mode ][ location ] = main_func; +} + +rungametypeprecache( gamemode ) +{ + if ( !isDefined( level.gamemode_map_location_main ) || !isDefined( level.gamemode_map_location_main[ gamemode ] ) ) + { + return; + } + if ( isDefined( level.gamemode_map_precache ) ) + { + if ( isDefined( level.gamemode_map_precache[ gamemode ] ) ) + { + [[ level.gamemode_map_precache[ gamemode ] ]](); + } + } + if ( isDefined( level.gamemode_map_location_precache ) ) + { + if ( isDefined( level.gamemode_map_location_precache[ gamemode ] ) ) + { + loc = getDvar( "ui_zm_mapstartlocation" ); + if ( loc == "" && isDefined( level.default_start_location ) ) + { + loc = level.default_start_location; + } + if ( isDefined( level.gamemode_map_location_precache[ gamemode ][ loc ] ) ) + { + [[ level.gamemode_map_location_precache[ gamemode ][ loc ] ]](); + } + } + } + if ( isDefined( level.precachecustomcharacters ) ) + { + self [[ level.precachecustomcharacters ]](); + } +} + +rungametypemain( gamemode, mode_main_func, use_round_logic ) +{ + if ( !isDefined( level.gamemode_map_location_main ) || !isDefined( level.gamemode_map_location_main[ gamemode ] ) ) + { + return; + } + level thread game_objects_allowed( get_gamemode_var( "mode" ), get_gamemode_var( "location" ) ); + if ( isDefined( level.gamemode_map_main ) ) + { + if ( isDefined( level.gamemode_map_main[ gamemode ] ) ) + { + level thread [[ level.gamemode_map_main[ gamemode ] ]](); + } + } + if ( isDefined( level.gamemode_map_location_main ) ) + { + if ( isDefined( level.gamemode_map_location_main[ gamemode ] ) ) + { + loc = getDvar( "ui_zm_mapstartlocation" ); + if ( loc == "" && isDefined( level.default_start_location ) ) + { + loc = level.default_start_location; + } + if ( isDefined( level.gamemode_map_location_main[ gamemode ][ loc ] ) ) + { + level thread [[ level.gamemode_map_location_main[ gamemode ][ loc ] ]](); + } + } + } + if ( isDefined( mode_main_func ) ) + { + if ( isDefined( use_round_logic ) && use_round_logic ) + { + level thread round_logic( mode_main_func ); + } + else + { + level thread non_round_logic( mode_main_func ); + } + } + level thread game_end_func(); +} + + +round_logic( mode_logic_func ) +{ + level.skit_vox_override = 1; + if ( isDefined( level.flag[ "start_zombie_round_logic" ] ) ) + { + flag_wait( "start_zombie_round_logic" ); + } + flag_wait( "start_encounters_match_logic" ); + if ( !isDefined( game[ "gamemode_match" ][ "rounds" ] ) ) + { + game[ "gamemode_match" ][ "rounds" ] = []; + } + set_gamemode_var_once( "current_round", 0 ); + set_gamemode_var_once( "team_1_score", 0 ); + set_gamemode_var_once( "team_2_score", 0 ); + if ( isDefined( is_encounter() ) && is_encounter() ) + { + [[ level._setteamscore ]]( "allies", get_gamemode_var( "team_2_score" ) ); + [[ level._setteamscore ]]( "axis", get_gamemode_var( "team_1_score" ) ); + } + flag_set( "pregame" ); + waittillframeend; + level.gameended = 0; + cur_round = get_gamemode_var( "current_round" ); + set_gamemode_var( "current_round", cur_round + 1 ); + game[ "gamemode_match" ][ "rounds" ][ cur_round ] = spawnstruct(); + game[ "gamemode_match" ][ "rounds" ][ cur_round ].mode = getDvar( "ui_gametype" ); + level thread [[ mode_logic_func ]](); + flag_wait( "start_encounters_match_logic" ); + level.gamestarttime = getTime(); + level.gamelengthtime = undefined; + level notify( "clear_hud_elems" ); + level waittill( "game_module_ended", winner ); + game[ "gamemode_match" ][ "rounds" ][ cur_round ].winner = winner; + level thread kill_all_zombies(); + level.gameendtime = getTime(); + level.gamelengthtime = level.gameendtime - level.gamestarttime; + level.gameended = 1; + if ( winner == "A" ) + { + score = get_gamemode_var( "team_1_score" ); + set_gamemode_var( "team_1_score", score + 1 ); + } + else + { + score = get_gamemode_var( "team_2_score" ); + set_gamemode_var( "team_2_score", score + 1 ); + } + if ( isDefined( is_encounter() ) && is_encounter() ) + { + [[ level._setteamscore ]]( "allies", get_gamemode_var( "team_2_score" ) ); + [[ level._setteamscore ]]( "axis", get_gamemode_var( "team_1_score" ) ); + if ( get_gamemode_var( "team_1_score" ) == get_gamemode_var( "team_2_score" ) ) + { + level thread maps/mp/zombies/_zm_audio::zmbvoxcrowdonteam( "win" ); + level thread maps/mp/zombies/_zm_audio_announcer::announceroundwinner( "tied" ); + } + else + { + level thread maps/mp/zombies/_zm_audio::zmbvoxcrowdonteam( "win", winner, "lose" ); + level thread maps/mp/zombies/_zm_audio_announcer::announceroundwinner( winner ); + } + } + level thread delete_corpses(); + level delay_thread( 5, ::revive_laststand_players ); + level notify( "clear_hud_elems" ); + while ( startnextzmround( winner ) ) + { + level clientnotify( "gme" ); + while ( 1 ) + { + wait 1; + } + } + level.match_is_ending = 1; + if ( isDefined( is_encounter() ) && is_encounter() ) + { + matchwonteam = ""; + if ( get_gamemode_var( "team_1_score" ) > get_gamemode_var( "team_2_score" ) ) + { + matchwonteam = "A"; + } + else + { + matchwonteam = "B"; + } + level thread maps/mp/zombies/_zm_audio::zmbvoxcrowdonteam( "win", matchwonteam, "lose" ); + level thread maps/mp/zombies/_zm_audio_announcer::announcematchwinner( matchwonteam ); + level create_final_score(); + track_encounters_win_stats( matchwonteam ); + } + maps/mp/zombies/_zm::intermission(); + level.can_revive_game_module = undefined; + level notify( "end_game" ); +} + +end_rounds_early( winner ) +{ + level.forcedend = 1; + cur_round = get_gamemode_var( "current_round" ); + set_gamemode_var( "ZM_roundLimit", cur_round ); + if ( isDefined( winner ) ) + { + level notify( "game_module_ended" ); + } + else + { + level notify( "end_game" ); + } +} + + +checkzmroundswitch() +{ + if ( !isDefined( level.zm_roundswitch ) || !level.zm_roundswitch ) + { + return 0; + } + + return 1; + return 0; +} + +create_hud_scoreboard( duration, fade ) +{ + level endon( "end_game" ); + level thread module_hud_full_screen_overlay(); + level thread module_hud_team_1_score( duration, fade ); + level thread module_hud_team_2_score( duration, fade ); + level thread module_hud_round_num( duration, fade ); + respawn_spectators_and_freeze_players(); + waittill_any_or_timeout( duration, "clear_hud_elems" ); +} + +respawn_spectators_and_freeze_players() +{ + players = get_players(); + _a785 = players; + _k785 = getFirstArrayKey( _a785 ); + while ( isDefined( _k785 ) ) + { + player = _a785[ _k785 ]; + if ( player.sessionstate == "spectator" ) + { + if ( isDefined( player.spectate_hud ) ) + { + player.spectate_hud destroy(); + } + player [[ level.spawnplayer ]](); + } + player freeze_player_controls( 1 ); + _k785 = getNextArrayKey( _a785, _k785 ); + } +} + +module_hud_team_1_score( duration, fade ) +{ + level._encounters_score_1 = newhudelem(); + level._encounters_score_1.x = 0; + level._encounters_score_1.y = 260; + level._encounters_score_1.alignx = "center"; + level._encounters_score_1.horzalign = "center"; + level._encounters_score_1.vertalign = "top"; + level._encounters_score_1.font = "default"; + level._encounters_score_1.fontscale = 2.3; + level._encounters_score_1.color = ( 1, 1, 1 ); + level._encounters_score_1.foreground = 1; + level._encounters_score_1 settext( "Team CIA: " + get_gamemode_var( "team_1_score" ) ); + level._encounters_score_1.alpha = 0; + level._encounters_score_1.sort = 11; + level._encounters_score_1 fadeovertime( fade ); + level._encounters_score_1.alpha = 1; + level waittill_any_or_timeout( duration, "clear_hud_elems" ); + level._encounters_score_1 fadeovertime( fade ); + level._encounters_score_1.alpha = 0; + wait fade; + level._encounters_score_1 destroy(); +} + +module_hud_team_2_score( duration, fade ) +{ + level._encounters_score_2 = newhudelem(); + level._encounters_score_2.x = 0; + level._encounters_score_2.y = 290; + level._encounters_score_2.alignx = "center"; + level._encounters_score_2.horzalign = "center"; + level._encounters_score_2.vertalign = "top"; + level._encounters_score_2.font = "default"; + level._encounters_score_2.fontscale = 2.3; + level._encounters_score_2.color = ( 1, 1, 1 ); + level._encounters_score_2.foreground = 1; + level._encounters_score_2 settext( "Team CDC: " + get_gamemode_var( "team_2_score" ) ); + level._encounters_score_2.alpha = 0; + level._encounters_score_2.sort = 12; + level._encounters_score_2 fadeovertime( fade ); + level._encounters_score_2.alpha = 1; + level waittill_any_or_timeout( duration, "clear_hud_elems" ); + level._encounters_score_2 fadeovertime( fade ); + level._encounters_score_2.alpha = 0; + wait fade; + level._encounters_score_2 destroy(); +} + +module_hud_round_num( duration, fade ) +{ + level._encounters_round_num = newhudelem(); + level._encounters_round_num.x = 0; + level._encounters_round_num.y = 60; + level._encounters_round_num.alignx = "center"; + level._encounters_round_num.horzalign = "center"; + level._encounters_round_num.vertalign = "top"; + level._encounters_round_num.font = "default"; + level._encounters_round_num.fontscale = 2.3; + level._encounters_round_num.color = ( 1, 1, 1 ); + level._encounters_round_num.foreground = 1; + level._encounters_round_num settext( "Round: ^5" + get_gamemode_var( "current_round" ) + 1 + " / " + get_game_var( "ZM_roundLimit" ) ); + level._encounters_round_num.alpha = 0; + level._encounters_round_num.sort = 13; + level._encounters_round_num fadeovertime( fade ); + level._encounters_round_num.alpha = 1; + level waittill_any_or_timeout( duration, "clear_hud_elems" ); + level._encounters_round_num fadeovertime( fade ); + level._encounters_round_num.alpha = 0; + wait fade; + level._encounters_round_num destroy(); +} + +createtimer() +{ + flag_waitopen( "pregame" ); + elem = newhudelem(); + elem.hidewheninmenu = 1; + elem.horzalign = "center"; + elem.vertalign = "top"; + elem.alignx = "center"; + elem.aligny = "middle"; + elem.x = 0; + elem.y = 0; + elem.foreground = 1; + elem.font = "default"; + elem.fontscale = 1.5; + elem.color = ( 1, 1, 1 ); + elem.alpha = 2; + elem thread maps/mp/gametypes_zm/_hud::fontpulseinit(); + if ( isDefined( level.timercountdown ) && level.timercountdown ) + { + elem settenthstimer( level.timelimit * 60 ); + } + else + { + elem settenthstimerup( 0.1 ); + } + level.game_module_timer = elem; + level waittill( "game_module_ended" ); + elem destroy(); +} + +revive_laststand_players() +{ + if ( isDefined( level.match_is_ending ) && level.match_is_ending ) + { + return; + } + players = get_players(); + _a917 = players; + _k917 = getFirstArrayKey( _a917 ); + while ( isDefined( _k917 ) ) + { + player = _a917[ _k917 ]; + if ( player maps/mp/zombies/_zm_laststand::player_is_in_laststand() ) + { + player thread maps/mp/zombies/_zm_laststand::auto_revive( player ); + } + _k917 = getNextArrayKey( _a917, _k917 ); + } +} + +team_icon_winner( elem ) +{ + og_x = elem.x; + og_y = elem.y; + elem.sort = 1; + elem scaleovertime( 0.75, 150, 150 ); + elem moveovertime( 0.75 ); + elem.horzalign = "center"; + elem.vertalign = "middle"; + elem.x = 0; + elem.y = 0; + elem.alpha = 0.7; + wait 0.75; +} + +delete_corpses() +{ + corpses = getcorpsearray(); + x = 0; + while ( x < corpses.size ) + { + corpses[ x ] delete(); + x++; + } +} + +track_encounters_win_stats( matchwonteam ) +{ + players = get_players(); + i = 0; + while ( i < players.size ) + { + if ( players[ i ]._encounters_team == matchwonteam ) + { + players[ i ] maps/mp/zombies/_zm_stats::increment_client_stat( "wins" ); + players[ i ] maps/mp/zombies/_zm_stats::add_client_stat( "losses", -1 ); + players[ i ] adddstat( "skill_rating", 1 ); + players[ i ] setdstat( "skill_variance", 1 ); + if ( gamemodeismode( level.gamemode_public_match ) ) + { + players[ i ] maps/mp/zombies/_zm_stats::add_location_gametype_stat( level.scr_zm_map_start_location, level.scr_zm_ui_gametype, "wins", 1 ); + players[ i ] maps/mp/zombies/_zm_stats::add_location_gametype_stat( level.scr_zm_map_start_location, level.scr_zm_ui_gametype, "losses", -1 ); + } + } + else + { + players[ i ] setdstat( "skill_rating", 0 ); + players[ i ] setdstat( "skill_variance", 1 ); + } + players[ i ] updatestatratio( "wlratio", "wins", "losses" ); + i++; + } +} + +non_round_logic( mode_logic_func ) +{ + level thread [[ mode_logic_func ]](); +} + +game_end_func() +{ + if ( !isDefined( get_gamemode_var( "match_end_notify" ) ) && !isDefined( get_gamemode_var( "match_end_func" ) ) ) + { + return; + } + level waittill( get_gamemode_var( "match_end_notify" ), winning_team ); + level thread [[ get_gamemode_var( "match_end_func" ) ]]( winning_team ); +} + +setup_classic_gametype() +{ + ents = getentarray(); + _a1004 = ents; + _k1004 = getFirstArrayKey( _a1004 ); + while ( isDefined( _k1004 ) ) + { + ent = _a1004[ _k1004 ]; + if ( isDefined( ent.script_parameters ) ) + { + parameters = strtok( ent.script_parameters, " " ); + should_remove = 0; + _a1010 = parameters; + _k1010 = getFirstArrayKey( _a1010 ); + while ( isDefined( _k1010 ) ) + { + parm = _a1010[ _k1010 ]; + if ( parm == "survival_remove" ) + { + should_remove = 1; + } + _k1010 = getNextArrayKey( _a1010, _k1010 ); + } + if ( should_remove ) + { + ent delete(); + } + } + _k1004 = getNextArrayKey( _a1004, _k1004 ); + } + structs = getstructarray( "game_mode_object" ); + _a1040 = structs; + _k1040 = getFirstArrayKey( _a1040 ); + while ( isDefined( _k1040 ) ) + { + struct = _a1040[ _k1040 ]; + if ( !isDefined( struct.script_string ) ) + { + } + else tokens = strtok( struct.script_string, " " ); + spawn_object = 0; + _a1048 = tokens; + _k1048 = getFirstArrayKey( _a1048 ); + while ( isDefined( _k1048 ) ) + { + parm = _a1048[ _k1048 ]; + if ( parm == "survival" ) + { + spawn_object = 1; + } + _k1048 = getNextArrayKey( _a1048, _k1048 ); + } + if ( !spawn_object ) + { + } + else + { + barricade = spawn( "script_model", struct.origin ); + barricade.angles = struct.angles; + barricade setmodel( struct.script_parameters ); + } + _k1040 = getNextArrayKey( _a1040, _k1040 ); + } + unlink_meat_traversal_nodes(); +} + +zclassic_main() +{ + level thread setup_classic_gametype(); + level thread maps/mp/zombies/_zm::round_start(); +} + +unlink_meat_traversal_nodes() +{ + meat_town_nodes = getnodearray( "meat_town_barrier_traversals", "targetname" ); + meat_tunnel_nodes = getnodearray( "meat_tunnel_barrier_traversals", "targetname" ); + meat_farm_nodes = getnodearray( "meat_farm_barrier_traversals", "targetname" ); + nodes = arraycombine( meat_town_nodes, meat_tunnel_nodes, 1, 0 ); + traversal_nodes = arraycombine( nodes, meat_farm_nodes, 1, 0 ); + _a1086 = traversal_nodes; + _k1086 = getFirstArrayKey( _a1086 ); + while ( isDefined( _k1086 ) ) + { + node = _a1086[ _k1086 ]; + end_node = getnode( node.target, "targetname" ); + unlink_nodes( node, end_node ); + _k1086 = getNextArrayKey( _a1086, _k1086 ); + } +} + +canplayersuicide() +{ + return self hasperk( "specialty_scavenger" ); +} + +onplayerdisconnect() +{ + if ( isDefined( level.game_mode_custom_onplayerdisconnect ) ) + { + level [[ level.game_mode_custom_onplayerdisconnect ]]( self ); + } + level thread maps/mp/zombies/_zm::check_quickrevive_for_hotjoin( 1 ); + self maps/mp/zombies/_zm_laststand::add_weighted_down(); + level maps/mp/zombies/_zm::checkforalldead( self ); +} + +ondeadevent( team ) +{ + thread maps/mp/gametypes_zm/_globallogic::endgame( level.zombie_team, "" ); +} + +onspawnintermission() +{ + spawnpointname = "info_intermission"; + spawnpoints = getentarray( spawnpointname, "classname" ); + if ( spawnpoints.size < 1 ) + { + /* +/# + println( "NO " + spawnpointname + " SPAWNPOINTS IN MAP" ); +#/ + */ + return; + } + spawnpoint = spawnpoints[ randomint( spawnpoints.size ) ]; + if ( isDefined( spawnpoint ) ) + { + self spawn( spawnpoint.origin, spawnpoint.angles ); + } +} + +onspawnspectator( origin, angles ) +{ +} + +mayspawn() +{ + if ( isDefined( level.custommayspawnlogic ) ) + { + return self [[ level.custommayspawnlogic ]](); + } + if ( self.pers[ "lives" ] == 0 ) + { + level notify( "player_eliminated" ); + self notify( "player_eliminated" ); + return 0; + } + return 1; +} + +onstartgametype() +{ + setclientnamemode( "auto_change" ); + level.displayroundendtext = 0; + maps/mp/gametypes_zm/_spawning::create_map_placed_influencers(); + if ( !isoneround() ) + { + level.displayroundendtext = 1; + if ( isscoreroundbased() ) + { + maps/mp/gametypes_zm/_globallogic_score::resetteamscores(); + } + } +} + +module_hud_full_screen_overlay() +{ + fadetoblack = newhudelem(); + fadetoblack.x = 0; + fadetoblack.y = 0; + fadetoblack.horzalign = "fullscreen"; + fadetoblack.vertalign = "fullscreen"; + fadetoblack setshader( "black", 640, 480 ); + fadetoblack.color = ( 1, 1, 1 ); + fadetoblack.alpha = 1; + fadetoblack.foreground = 1; + fadetoblack.sort = 0; + if ( is_encounter() || getDvar( "ui_gametype" ) == "zcleansed" ) + { + level waittill_any_or_timeout( 25, "start_fullscreen_fade_out" ); + } + else + { + level waittill_any_or_timeout( 25, "start_zombie_round_logic" ); + } + fadetoblack fadeovertime( 2 ); + fadetoblack.alpha = 0; + wait 2.1; + fadetoblack destroy(); +} + +create_final_score() +{ + level endon( "end_game" ); + level thread module_hud_team_winer_score(); + wait 2; +} + +module_hud_team_winer_score() +{ + players = get_players(); + i = 0; + while ( i < players.size ) + { + players[ i ] thread create_module_hud_team_winer_score(); + if ( isDefined( players[ i ]._team_hud ) && isDefined( players[ i ]._team_hud[ "team" ] ) ) + { + players[ i ] thread team_icon_winner( players[ i ]._team_hud[ "team" ] ); + } + if ( isDefined( level.lock_player_on_team_score ) && level.lock_player_on_team_score ) + { + players[ i ] freezecontrols( 1 ); + players[ i ] takeallweapons(); + players[ i ] setclientuivisibilityflag( "hud_visible", 0 ); + players[ i ].sessionstate = "spectator"; + players[ i ].spectatorclient = -1; + players[ i ].maxhealth = players[ i ].health; + players[ i ].shellshocked = 0; + players[ i ].inwater = 0; + players[ i ].friendlydamage = undefined; + players[ i ].hasspawned = 1; + players[ i ].spawntime = getTime(); + players[ i ].afk = 0; + players[ i ] detachall(); + } + i++; + } + level thread maps/mp/zombies/_zm_audio::change_zombie_music( "match_over" ); +} + +create_module_hud_team_winer_score() +{ + self._team_winer_score = newclienthudelem( self ); + self._team_winer_score.x = 0; + self._team_winer_score.y = 70; + self._team_winer_score.alignx = "center"; + self._team_winer_score.horzalign = "center"; + self._team_winer_score.vertalign = "middle"; + self._team_winer_score.font = "default"; + self._team_winer_score.fontscale = 15; + self._team_winer_score.color = ( 1, 1, 1 ); + self._team_winer_score.foreground = 1; + if ( self._encounters_team == "B" && get_gamemode_var( "team_2_score" ) > get_gamemode_var( "team_1_score" ) ) + { + self._team_winer_score settext( &"ZOMBIE_MATCH_WON" ); + } + else + { + if ( self._encounters_team == "B" && get_gamemode_var( "team_2_score" ) < get_gamemode_var( "team_1_score" ) ) + { + self._team_winer_score.color = ( 1, 1, 1 ); + self._team_winer_score settext( &"ZOMBIE_MATCH_LOST" ); + } + } + if ( self._encounters_team == "A" && get_gamemode_var( "team_1_score" ) > get_gamemode_var( "team_2_score" ) ) + { + self._team_winer_score settext( &"ZOMBIE_MATCH_WON" ); + } + else + { + if ( self._encounters_team == "A" && get_gamemode_var( "team_1_score" ) < get_gamemode_var( "team_2_score" ) ) + { + self._team_winer_score.color = ( 1, 1, 1 ); + self._team_winer_score settext( &"ZOMBIE_MATCH_LOST" ); + } + } + self._team_winer_score.alpha = 0; + self._team_winer_score.sort = 12; + self._team_winer_score fadeovertime( 0.25 ); + self._team_winer_score.alpha = 1; + wait 2; + self._team_winer_score fadeovertime( 0.25 ); + self._team_winer_score.alpha = 0; + wait 0.25; + self._team_winer_score destroy(); +} + +displayroundend( round_winner ) +{ + players = get_players(); + _a1336 = players; + _k1336 = getFirstArrayKey( _a1336 ); + while ( isDefined( _k1336 ) ) + { + player = _a1336[ _k1336 ]; + player thread module_hud_round_end( round_winner ); + if ( isDefined( player._team_hud ) && isDefined( player._team_hud[ "team" ] ) ) + { + player thread team_icon_winner( player._team_hud[ "team" ] ); + } + player freeze_player_controls( 1 ); + _k1336 = getNextArrayKey( _a1336, _k1336 ); + } + level thread maps/mp/zombies/_zm_audio::change_zombie_music( "round_end" ); + level thread maps/mp/zombies/_zm_audio::zmbvoxcrowdonteam( "clap" ); + level thread play_sound_2d( "zmb_air_horn" ); + wait 2; +} + +module_hud_round_end( round_winner ) +{ + self endon( "disconnect" ); + self._team_winner_round = newclienthudelem( self ); + self._team_winner_round.x = 0; + self._team_winner_round.y = 50; + self._team_winner_round.alignx = "center"; + self._team_winner_round.horzalign = "center"; + self._team_winner_round.vertalign = "middle"; + self._team_winner_round.font = "default"; + self._team_winner_round.fontscale = 15; + self._team_winner_round.color = ( 1, 1, 1 ); + self._team_winner_round.foreground = 1; + if ( self._encounters_team == round_winner ) + { + self._team_winner_round.color = ( 1, 1, 1 ); + self._team_winner_round settext( "YOU WIN" ); + } + else + { + self._team_winner_round.color = ( 1, 1, 1 ); + self._team_winner_round settext( "YOU LOSE" ); + } + self._team_winner_round.alpha = 0; + self._team_winner_round.sort = 12; + self._team_winner_round fadeovertime( 0.25 ); + self._team_winner_round.alpha = 1; + wait 1.5; + self._team_winner_round fadeovertime( 0.25 ); + self._team_winner_round.alpha = 0; + wait 0.25; + self._team_winner_round destroy(); +} + +displayroundswitch() +{ + level._round_changing_sides = newhudelem(); + level._round_changing_sides.x = 0; + level._round_changing_sides.y = 60; + level._round_changing_sides.alignx = "center"; + level._round_changing_sides.horzalign = "center"; + level._round_changing_sides.vertalign = "middle"; + level._round_changing_sides.font = "default"; + level._round_changing_sides.fontscale = 2.3; + level._round_changing_sides.color = ( 1, 1, 1 ); + level._round_changing_sides.foreground = 1; + level._round_changing_sides.sort = 12; + fadetoblack = newhudelem(); + fadetoblack.x = 0; + fadetoblack.y = 0; + fadetoblack.horzalign = "fullscreen"; + fadetoblack.vertalign = "fullscreen"; + fadetoblack setshader( "black", 640, 480 ); + fadetoblack.color = ( 1, 1, 1 ); + fadetoblack.alpha = 1; + level thread maps/mp/zombies/_zm_audio_announcer::leaderdialog( "side_switch" ); + level._round_changing_sides settext( "CHANGING SIDES" ); + level._round_changing_sides fadeovertime( 0.25 ); + level._round_changing_sides.alpha = 1; + wait 1; + fadetoblack fadeovertime( 1 ); + level._round_changing_sides fadeovertime( 0.25 ); + level._round_changing_sides.alpha = 0; + fadetoblack.alpha = 0; + wait 0.25; + level._round_changing_sides destroy(); + fadetoblack destroy(); +} + +module_hud_create_team_name() +{ + if ( !is_encounter() ) + { + return; + } + if ( !isDefined( self._team_hud ) ) + { + self._team_hud = []; + } + if ( isDefined( self._team_hud[ "team" ] ) ) + { + self._team_hud[ "team" ] destroy(); + } + elem = newclienthudelem( self ); + elem.hidewheninmenu = 1; + elem.alignx = "center"; + elem.aligny = "middle"; + elem.horzalign = "center"; + elem.vertalign = "middle"; + elem.x = 0; + elem.y = 0; + if ( isDefined( level.game_module_team_name_override_og_x ) ) + { + elem.og_x = level.game_module_team_name_override_og_x; + } + else + { + elem.og_x = 85; + } + elem.og_y = -40; + elem.foreground = 1; + elem.font = "default"; + elem.color = ( 1, 1, 1 ); + elem.sort = 1; + elem.alpha = 0.7; + elem setshader( game[ "icons" ][ self.team ], 150, 150 ); + self._team_hud[ "team" ] = elem; +} + +nextzmhud( winner ) +{ + displayroundend( winner ); + create_hud_scoreboard( 1, 0.25 ); + if ( checkzmroundswitch() ) + { + displayroundswitch(); + } +} + +startnextzmround( winner ) +{ + if ( !isonezmround() ) + { + if ( !waslastzmround() ) + { + nextzmhud( winner ); + setmatchtalkflag( "DeadChatWithDead", level.voip.deadchatwithdead ); + setmatchtalkflag( "DeadChatWithTeam", level.voip.deadchatwithteam ); + setmatchtalkflag( "DeadHearTeamLiving", level.voip.deadhearteamliving ); + setmatchtalkflag( "DeadHearAllLiving", level.voip.deadhearallliving ); + setmatchtalkflag( "EveryoneHearsEveryone", level.voip.everyonehearseveryone ); + setmatchtalkflag( "DeadHearKiller", level.voip.deadhearkiller ); + setmatchtalkflag( "KillersHearVictim", level.voip.killershearvictim ); + game[ "state" ] = "playing"; + level.allowbattlechatter = getgametypesetting( "allowBattleChatter" ); + if ( isDefined( level.zm_switchsides_on_roundswitch ) && level.zm_switchsides_on_roundswitch ) + { + set_game_var( "switchedsides", !get_game_var( "switchedsides" ) ); + } + map_restart( 1 ); + return 1; + } + } + return 0; +} + +start_round() +{ + flag_clear( "start_encounters_match_logic" ); + if ( !isDefined( level._module_round_hud ) ) + { + level._module_round_hud = newhudelem(); + level._module_round_hud.x = 0; + level._module_round_hud.y = 70; + level._module_round_hud.alignx = "center"; + level._module_round_hud.horzalign = "center"; + level._module_round_hud.vertalign = "middle"; + level._module_round_hud.font = "default"; + level._module_round_hud.fontscale = 2.3; + level._module_round_hud.color = ( 1, 1, 1 ); + level._module_round_hud.foreground = 1; + level._module_round_hud.sort = 0; + } + players = get_players(); + i = 0; + while ( i < players.size ) + { + players[ i ] freeze_player_controls( 1 ); + i++; + } + level._module_round_hud.alpha = 1; + label = &"Next Round Starting In ^2"; + level._module_round_hud.label = label; + level._module_round_hud settimer( 3 ); + level thread maps/mp/zombies/_zm_audio_announcer::leaderdialog( "countdown" ); + level thread maps/mp/zombies/_zm_audio::zmbvoxcrowdonteam( "clap" ); + level thread maps/mp/zombies/_zm_audio::change_zombie_music( "round_start" ); + level notify( "start_fullscreen_fade_out" ); + wait 2; + level._module_round_hud fadeovertime( 1 ); + level._module_round_hud.alpha = 0; + wait 1; + level thread play_sound_2d( "zmb_air_horn" ); + players = get_players(); + i = 0; + while ( i < players.size ) + { + players[ i ] freeze_player_controls( 0 ); + players[ i ] sprintuprequired(); + i++; + } + flag_set( "start_encounters_match_logic" ); + flag_clear( "pregame" ); + level._module_round_hud destroy(); +} + +isonezmround() +{ + if ( get_game_var( "ZM_roundLimit" ) == 1 ) + { + return 1; + } + return 0; +} + +waslastzmround() +{ + if ( isDefined( level.forcedend ) && level.forcedend ) + { + return 1; + } + if ( !hitzmroundlimit() || hitzmscorelimit() && hitzmroundwinlimit() ) + { + return 1; + } + return 0; +} + +hitzmroundlimit() +{ + if ( get_game_var( "ZM_roundLimit" ) <= 0 ) + { + return 0; + } + return getzmroundsplayed() >= get_game_var( "ZM_roundLimit" ); +} + +hitzmroundwinlimit() +{ + if ( !isDefined( get_game_var( "ZM_roundWinLimit" ) ) || get_game_var( "ZM_roundWinLimit" ) <= 0 ) + { + return 0; + } + if ( get_gamemode_var( "team_1_score" ) >= get_game_var( "ZM_roundWinLimit" ) || get_gamemode_var( "team_2_score" ) >= get_game_var( "ZM_roundWinLimit" ) ) + { + return 1; + } + if ( get_gamemode_var( "team_1_score" ) >= get_game_var( "ZM_roundWinLimit" ) || get_gamemode_var( "team_2_score" ) >= get_game_var( "ZM_roundWinLimit" ) ) + { + if ( get_gamemode_var( "team_1_score" ) != get_gamemode_var( "team_2_score" ) ) + { + return 1; + } + } + return 0; +} + +hitzmscorelimit() +{ + if ( get_game_var( "ZM_scoreLimit" ) <= 0 ) + { + return 0; + } + if ( is_encounter() ) + { + if ( get_gamemode_var( "team_1_score" ) >= get_game_var( "ZM_scoreLimit" ) || get_gamemode_var( "team_2_score" ) >= get_game_var( "ZM_scoreLimit" ) ) + { + return 1; + } + } + return 0; +} + +getzmroundsplayed() +{ + return get_gamemode_var( "current_round" ); +} + +onspawnplayerunified() +{ + onspawnplayer( 0 ); +} + +onspawnplayer( predictedspawn ) +{ + if ( !isDefined( predictedspawn ) ) + { + predictedspawn = 0; + } + pixbeginevent( "ZSURVIVAL:onSpawnPlayer" ); + self.usingobj = undefined; + self.is_zombie = 0; + if ( isDefined( level.custom_spawnplayer ) && isDefined( self.player_initialized ) && self.player_initialized ) + { + self [[ level.custom_spawnplayer ]](); + return; + } + if ( isDefined( level.customspawnlogic ) ) + { + + + spawnpoint = self [[ level.customspawnlogic ]]( predictedspawn ); + if ( predictedspawn ) + { + return; + } + } + else + { + + } + + if ( flag( "begin_spawning" ) ) + { + 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," "); + foreach(token in tokens) + { + if(token == match_string ) + { + spawnPoints[spawnPoints.size] = struct; + } + } + } + + } + } + */ + if ( !isDefined( spawnpoints ) || spawnpoints.size == 0 ) + { + spawnpoints = getstructarray( "initial_spawn_points", "targetname" ); + } + + + spawnpoint = maps/mp/zombies/_zm::getfreespawnpoint( spawnpoints, self ); + } + if ( predictedspawn ) + { + self predictspawnpoint( spawnpoint.origin, spawnpoint.angles ); + return; + } + else + { + self spawn( spawnpoint.origin, spawnpoint.angles, "zsurvival" ); + } + self.entity_num = self getentitynumber(); + self thread maps/mp/zombies/_zm::onplayerspawned(); + self thread maps/mp/zombies/_zm::player_revive_monitor(); + self freezecontrols( 1 ); + self.spectator_respawn = spawnpoint; + self.score = self maps/mp/gametypes_zm/_globallogic_score::getpersstat( "score" ); + self.pers[ "participation" ] = 0; + + self.score_total = self.score; + self.old_score = self.score; + self.player_initialized = 0; + self.zombification_time = 0; + self.enabletext = 1; + self thread maps/mp/zombies/_zm_blockers::rebuild_barrier_reward_reset(); + if ( isDefined( level.host_ended_game ) && !level.host_ended_game ) + { + self freeze_player_controls( 0 ); + self enableweapons(); + } + if ( isDefined( level.game_mode_spawn_player_logic ) ) + { + spawn_in_spectate = [[ level.game_mode_spawn_player_logic ]](); + if ( spawn_in_spectate ) + { + self delay_thread( 0.05, maps/mp/zombies/_zm::spawnspectator ); + } + } + pixendevent(); +} + + +get_player_spawns_for_gametype() +{ + 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; + player_spawns = []; + structs = getstructarray( "player_respawn_point", "targetname" ); + _a1869 = structs; + _k1869 = getFirstArrayKey( _a1869 ); + while ( isDefined( _k1869 ) ) + { + struct = _a1869[ _k1869 ]; + if ( isDefined( struct.script_string ) ) + { + tokens = strtok( struct.script_string, " " ); + _a1874 = tokens; + _k1874 = getFirstArrayKey( _a1874 ); + while ( isDefined( _k1874 ) ) + { + token = _a1874[ _k1874 ]; + if ( token == match_string ) + { + player_spawns[ player_spawns.size ] = struct; + } + _k1874 = getNextArrayKey( _a1874, _k1874 ); + } + } + else player_spawns[ player_spawns.size ] = struct; + _k1869 = getNextArrayKey( _a1869, _k1869 ); + } + return player_spawns; +} + +onendgame( winningteam ) +{ +} + +onroundendgame( roundwinner ) +{ + if ( game[ "roundswon" ][ "allies" ] == game[ "roundswon" ][ "axis" ] ) + { + winner = "tie"; + } + else if ( game[ "roundswon" ][ "axis" ] > game[ "roundswon" ][ "allies" ] ) + { + winner = "axis"; + } + else + { + winner = "allies"; + } + return winner; +} + +menu_init() +{ + game[ "menu_team" ] = "team_marinesopfor"; + game[ "menu_changeclass_allies" ] = "changeclass"; + game[ "menu_initteam_allies" ] = "initteam_marines"; + game[ "menu_changeclass_axis" ] = "changeclass"; + game[ "menu_initteam_axis" ] = "initteam_opfor"; + game[ "menu_class" ] = "class"; + game[ "menu_changeclass" ] = "changeclass"; + game[ "menu_changeclass_offline" ] = "changeclass"; + game[ "menu_wager_side_bet" ] = "sidebet"; + game[ "menu_wager_side_bet_player" ] = "sidebet_player"; + game[ "menu_changeclass_wager" ] = "changeclass_wager"; + game[ "menu_changeclass_custom" ] = "changeclass_custom"; + game[ "menu_changeclass_barebones" ] = "changeclass_barebones"; + game[ "menu_controls" ] = "ingame_controls"; + game[ "menu_options" ] = "ingame_options"; + game[ "menu_leavegame" ] = "popup_leavegame"; + game[ "menu_restartgamepopup" ] = "restartgamepopup"; + precachemenu( game[ "menu_controls" ] ); + precachemenu( game[ "menu_options" ] ); + precachemenu( game[ "menu_leavegame" ] ); + precachemenu( game[ "menu_restartgamepopup" ] ); + precachemenu( "scoreboard" ); + precachemenu( game[ "menu_team" ] ); + precachemenu( game[ "menu_changeclass_allies" ] ); + precachemenu( game[ "menu_initteam_allies" ] ); + precachemenu( game[ "menu_changeclass_axis" ] ); + precachemenu( game[ "menu_class" ] ); + precachemenu( game[ "menu_changeclass" ] ); + precachemenu( game[ "menu_initteam_axis" ] ); + precachemenu( game[ "menu_changeclass_offline" ] ); + precachemenu( game[ "menu_changeclass_wager" ] ); + precachemenu( game[ "menu_changeclass_custom" ] ); + precachemenu( game[ "menu_changeclass_barebones" ] ); + precachemenu( game[ "menu_wager_side_bet" ] ); + precachemenu( game[ "menu_wager_side_bet_player" ] ); + precachestring( &"MP_HOST_ENDED_GAME" ); + precachestring( &"MP_HOST_ENDGAME_RESPONSE" ); + level thread menu_onplayerconnect(); +} + +menu_onplayerconnect() +{ + for ( ;; ) + { + level waittill( "connecting", player ); + player thread menu_onmenuresponse(); + } +} + +menu_onmenuresponse() +{ + self endon( "disconnect" ); + for ( ;; ) + { + self waittill( "menuresponse", menu, response ); + if ( response == "back" ) + { + self closemenu(); + self closeingamemenu(); + if ( level.console ) + { + if ( game[ "menu_changeclass" ] != menu && game[ "menu_changeclass_offline" ] != menu || menu == game[ "menu_team" ] && menu == game[ "menu_controls" ] ) + { + if ( self.pers[ "team" ] == "allies" ) + { + self openmenu( game[ "menu_class" ] ); + } + if ( self.pers[ "team" ] == "axis" ) + { + self openmenu( game[ "menu_class" ] ); + } + } + } + continue; + } + else if ( response == "changeteam" && level.allow_teamchange == "1" ) + { + self closemenu(); + self closeingamemenu(); + self openmenu( game[ "menu_team" ] ); + } + if ( response == "changeclass_marines" ) + { + self closemenu(); + self closeingamemenu(); + self openmenu( game[ "menu_changeclass_allies" ] ); + continue; + } + else if ( response == "changeclass_opfor" ) + { + self closemenu(); + self closeingamemenu(); + self openmenu( game[ "menu_changeclass_axis" ] ); + continue; + } + else if ( response == "changeclass_wager" ) + { + self closemenu(); + self closeingamemenu(); + self openmenu( game[ "menu_changeclass_wager" ] ); + continue; + } + else if ( response == "changeclass_custom" ) + { + self closemenu(); + self closeingamemenu(); + self openmenu( game[ "menu_changeclass_custom" ] ); + continue; + } + else if ( response == "changeclass_barebones" ) + { + self closemenu(); + self closeingamemenu(); + self openmenu( game[ "menu_changeclass_barebones" ] ); + continue; + } + else if ( response == "changeclass_marines_splitscreen" ) + { + self openmenu( "changeclass_marines_splitscreen" ); + } + if ( response == "changeclass_opfor_splitscreen" ) + { + self openmenu( "changeclass_opfor_splitscreen" ); + } + if ( response == "endgame" ) + { + if ( self issplitscreen() ) + { + level.skipvote = 1; + if ( isDefined( level.gameended ) && !level.gameended ) + { + self maps/mp/zombies/_zm_laststand::add_weighted_down(); + self maps/mp/zombies/_zm_stats::increment_client_stat( "deaths" ); + self maps/mp/zombies/_zm_stats::increment_player_stat( "deaths" ); + self maps/mp/zombies/_zm_pers_upgrades_functions::pers_upgrade_jugg_player_death_stat(); + level.host_ended_game = 1; + maps/mp/zombies/_zm_game_module::freeze_players( 1 ); + level notify( "end_game" ); + } + } + continue; + } + else if ( response == "restart_level_zm" ) + { + self maps/mp/zombies/_zm_laststand::add_weighted_down(); + self maps/mp/zombies/_zm_stats::increment_client_stat( "deaths" ); + self maps/mp/zombies/_zm_stats::increment_player_stat( "deaths" ); + self maps/mp/zombies/_zm_pers_upgrades_functions::pers_upgrade_jugg_player_death_stat(); + missionfailed(); + } + if ( response == "killserverpc" ) + { + level thread maps/mp/gametypes_zm/_globallogic::killserverpc(); + continue; + } + else if ( response == "endround" ) + { + if ( isDefined( level.gameended ) && !level.gameended ) + { + self maps/mp/gametypes_zm/_globallogic::gamehistoryplayerquit(); + self maps/mp/zombies/_zm_laststand::add_weighted_down(); + self closemenu(); + self closeingamemenu(); + level.host_ended_game = 1; + maps/mp/zombies/_zm_game_module::freeze_players( 1 ); + level notify( "end_game" ); + } + else + { + self closemenu(); + self closeingamemenu(); + self iprintln( &"MP_HOST_ENDGAME_RESPONSE" ); + } + continue; + } + else if ( menu == game[ "menu_team" ] && level.allow_teamchange == "1" ) + { + switch( response ) + { + case "allies": + self [[ level.allies ]](); + break; + case "axis": + self [[ level.teammenu ]]( response ); + break; + case "autoassign": + self [[ level.autoassign ]]( 1 ); + break; + case "spectator": + self [[ level.spectator ]](); + break; + } + continue; + } + else + { + if ( game[ "menu_changeclass" ] != menu && game[ "menu_changeclass_offline" ] != menu && game[ "menu_changeclass_wager" ] != menu || menu == game[ "menu_changeclass_custom" ] && menu == game[ "menu_changeclass_barebones" ] ) + { + self closemenu(); + self closeingamemenu(); + if ( level.rankedmatch && issubstr( response, "custom" ) ) + { + } + self.selectedclass = 1; + self [[ level.class ]]( response ); + } + } + } +} + + +menuallieszombies() +{ + self maps/mp/gametypes_zm/_globallogic_ui::closemenus(); + if ( !level.console && level.allow_teamchange == "0" && isDefined( self.hasdonecombat ) && self.hasdonecombat ) + { + return; + } + if ( self.pers[ "team" ] != "allies" ) + { + if ( level.ingraceperiod || !isDefined( self.hasdonecombat ) && !self.hasdonecombat ) + { + self.hasspawned = 0; + } + if ( self.sessionstate == "playing" ) + { + self.switching_teams = 1; + self.joining_team = "allies"; + self.leaving_team = self.pers[ "team" ]; + self suicide(); + } + self.pers[ "team" ] = "allies"; + self.team = "allies"; + self.class = undefined; + self updateobjectivetext(); + if ( level.teambased ) + { + self.sessionteam = "allies"; + } + else + { + self.sessionteam = "none"; + self.ffateam = "allies"; + } + self setclientscriptmainmenu( game[ "menu_class" ] ); + self notify( "joined_team" ); + level notify( "joined_team" ); + self notify( "end_respawn" ); + } +} + + +custom_spawn_init_func() +{ + array_thread( level.zombie_spawners, ::add_spawn_function, maps/mp/zombies/_zm_spawner::zombie_spawn_init ); + array_thread( level.zombie_spawners, ::add_spawn_function, level._zombies_round_spawn_failsafe ); +} + +kill_all_zombies() +{ + ai = getaiarray( level.zombie_team ); + _a2225 = ai; + _k2225 = getFirstArrayKey( _a2225 ); + while ( isDefined( _k2225 ) ) + { + zombie = _a2225[ _k2225 ]; + if ( isDefined( zombie ) ) + { + zombie dodamage( zombie.maxhealth * 2, zombie.origin, zombie, zombie, "none", "MOD_SUICIDE" ); + wait 0.05; + } + _k2225 = getNextArrayKey( _a2225, _k2225 ); + } +} + +init() +{ + + flag_init( "pregame" ); + flag_set( "pregame" ); + level thread onplayerconnect(); +} + +onplayerconnect() +{ + for ( ;; ) + { + level waittill( "connected", player ); + player thread onplayerspawned(); + if ( isDefined( level.game_module_onplayerconnect ) ) + { + player [[ level.game_module_onplayerconnect ]](); + } + } +} + +onplayerspawned() +{ + level endon( "end_game" ); + self endon( "disconnect" ); + for ( ;; ) + { + self waittill_either( "spawned_player", "fake_spawned_player" ); + if ( isDefined( level.match_is_ending ) && level.match_is_ending ) + { + return; + } + if ( self maps/mp/zombies/_zm_laststand::player_is_in_laststand() ) + { + self thread maps/mp/zombies/_zm_laststand::auto_revive( self ); + } + if ( isDefined( level.custom_player_fake_death_cleanup ) ) + { + self [[ level.custom_player_fake_death_cleanup ]](); + } + self setstance( "stand" ); + self.zmbdialogqueue = []; + self.zmbdialogactive = 0; + self.zmbdialoggroups = []; + self.zmbdialoggroup = ""; + if ( is_encounter() ) + { + if ( self.team == "axis" ) + { + self.characterindex = 0; + self._encounters_team = "A"; + self._team_name = &"ZOMBIE_RACE_TEAM_1"; + break; + } + else + { + self.characterindex = 1; + self._encounters_team = "B"; + self._team_name = &"ZOMBIE_RACE_TEAM_2"; + } + } + self takeallweapons(); + if ( isDefined( level.givecustomcharacters ) ) + { + self [[ level.givecustomcharacters ]](); + } + self giveweapon( "knife_zm" ); + if ( isDefined( level.onplayerspawned_restore_previous_weapons ) && isDefined( level.isresetting_grief ) && level.isresetting_grief ) + { + weapons_restored = self [[ level.onplayerspawned_restore_previous_weapons ]](); + } + if ( isDefined( weapons_restored ) && !weapons_restored ) + { + self give_start_weapon( 1 ); + } + weapons_restored = 0; + if ( isDefined( level._team_loadout ) ) + { + self giveweapon( level._team_loadout ); + self switchtoweapon( level._team_loadout ); + } + if ( isDefined( level.gamemode_post_spawn_logic ) ) + { + self [[ level.gamemode_post_spawn_logic ]](); + } + } +} + +wait_for_players() +{ + level endon( "end_race" ); + if ( getDvarInt( "party_playerCount" ) == 1 ) + { + flag_wait( "start_zombie_round_logic" ); + return; + } + while ( !flag_exists( "start_zombie_round_logic" ) ) + { + wait 0.05; + } + while ( !flag( "start_zombie_round_logic" ) && isDefined( level._module_connect_hud ) ) + { + level._module_connect_hud.alpha = 0; + level._module_connect_hud.sort = 12; + level._module_connect_hud fadeovertime( 1 ); + level._module_connect_hud.alpha = 1; + wait 1.5; + level._module_connect_hud fadeovertime( 1 ); + level._module_connect_hud.alpha = 0; + wait 1.5; + } + if ( isDefined( level._module_connect_hud ) ) + { + level._module_connect_hud destroy(); + } +} + +onplayerconnect_check_for_hotjoin() +{ +/* +/# + if ( getDvarInt( #"EA6D219A" ) > 0 ) + { + return; +#/ + } +*/ + map_logic_exists = level flag_exists( "start_zombie_round_logic" ); + map_logic_started = flag( "start_zombie_round_logic" ); + if ( map_logic_exists && map_logic_started ) + { + self thread hide_gump_loading_for_hotjoiners(); + } +} + +hide_gump_loading_for_hotjoiners() +{ + self endon( "disconnect" ); + self.rebuild_barrier_reward = 1; + self.is_hotjoining = 1; + num = self getsnapshotackindex(); + while ( num == self getsnapshotackindex() ) + { + wait 0.25; + } + wait 0.5; + self maps/mp/zombies/_zm::spawnspectator(); + self.is_hotjoining = 0; + self.is_hotjoin = 1; + if ( is_true( level.intermission ) || is_true( level.host_ended_game ) ) + { + setclientsysstate( "levelNotify", "zi", self ); + self setclientthirdperson( 0 ); + self resetfov(); + self.health = 100; + self thread [[ level.custom_intermission ]](); + } +} + +blank() +{ + //empty function +} + + diff --git a/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/zombies/_zm.gsc b/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/zombies/_zm.gsc index 027c6e5..e1a91bc 100644 --- a/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/zombies/_zm.gsc +++ b/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/zombies/_zm.gsc @@ -21,11 +21,12 @@ init() { - //level.player_out_of_playable_area_monitor = 1; - //level.player_too_many_weapons_monitor = 1; - //level.player_too_many_weapons_monitor_func = ::player_too_many_weapons_monitor; - //level.player_too_many_players_check = 1; - //level.player_too_many_players_check_func = ::player_too_many_players_check; + + level.player_out_of_playable_area_monitor = 1; + level.player_too_many_weapons_monitor = 1; + level.player_too_many_weapons_monitor_func = ::player_too_many_weapons_monitor; + level.player_too_many_players_check = 1; + level.player_too_many_players_check_func = ::player_too_many_players_check; level._use_choke_weapon_hints = 1; level._use_choke_blockers = 1; level.passed_introscreen = 0; @@ -120,11 +121,8 @@ init() } register_offhand_weapons_for_level_defaults(); level thread drive_client_connected_notifies(); - /* -/# - maps/mp/zombies/_zm_devgui::init(); -#/ - */ + + //not the cause of the minidump maps/mp/zombies/_zm_zonemgr::init(); maps/mp/zombies/_zm_unitrigger::init(); maps/mp/zombies/_zm_audio::init(); @@ -136,15 +134,24 @@ init() maps/mp/zombies/_zm_laststand::init(); maps/mp/zombies/_zm_magicbox::init(); maps/mp/zombies/_zm_perks::init(); - maps/mp/zombies/_zm_playerhealth::init(); + + //causes the server to minidump + //maps/mp/zombies/_zm_playerhealth::init(); + + //ok maps/mp/zombies/_zm_power::init(); maps/mp/zombies/_zm_powerups::init(); maps/mp/zombies/_zm_score::init(); maps/mp/zombies/_zm_spawner::init(); maps/mp/zombies/_zm_gump::init(); - maps/mp/zombies/_zm_timer::init(); + + //causes the server to minidump + //maps/mp/zombies/_zm_timer::init(); + + //ok maps/mp/zombies/_zm_traps::init(); maps/mp/zombies/_zm_weapons::init(); + init_function_overrides(); level thread last_stand_pistol_rank_init(); level thread maps/mp/zombies/_zm_tombstone::init(); @@ -177,6 +184,7 @@ init() level thread onallplayersready(); level thread startunitriggers(); level thread maps/mp/gametypes_zm/_zm_gametype::post_init_gametype(); + } post_main() @@ -1450,7 +1458,7 @@ onplayerspawned() self.zmbdialogactive = 0; self.zmbdialoggroups = []; self.zmbdialoggroup = ""; - /* + if ( isDefined( level.player_out_of_playable_area_monitor ) && level.player_out_of_playable_area_monitor ) { self thread player_out_of_playable_area_monitor(); @@ -1463,7 +1471,6 @@ onplayerspawned() { level thread [[ level.player_too_many_players_check_func ]](); } - */ self.disabled_perks = []; if ( isDefined( self.player_initialized ) ) { @@ -1586,7 +1593,7 @@ in_enabled_playable_area() } return 0; } -/* + get_player_out_of_playable_area_monitor_wait_time() { @@ -1599,8 +1606,7 @@ get_player_out_of_playable_area_monitor_wait_time() return 3; } -*/ -/* + player_out_of_playable_area_monitor() { self notify( "stop_player_out_of_playable_area_monitor" ); @@ -1638,7 +1644,7 @@ player_out_of_playable_area_monitor() wait get_player_out_of_playable_area_monitor_wait_time(); #/ } - + */ self maps/mp/zombies/_zm_stats::increment_map_cheat_stat( "cheat_out_of_playable" ); self maps/mp/zombies/_zm_stats::increment_client_stat( "cheat_out_of_playable", 0 ); self maps/mp/zombies/_zm_stats::increment_client_stat( "cheat_total", 0 ); @@ -1743,7 +1749,7 @@ player_too_many_weapons_monitor() wait get_player_too_many_weapons_monitor_wait_time(); #/ } - + */ weapon_limit = get_player_weapon_limit( self ); primaryweapons = self getweaponslistprimaries(); if ( primaryweapons.size > weapon_limit ) @@ -1775,7 +1781,7 @@ player_too_many_weapons_monitor() wait get_player_too_many_weapons_monitor_wait_time(); } } -*/ + player_monitor_travel_dist() { self endon( "disconnect" ); @@ -6067,7 +6073,7 @@ update_quick_revive( solo_mode ) level.quick_revive_machine thread maps/mp/zombies/_zm_perks::reenable_quickrevive( clip, solo_mode ); } -/* + player_too_many_players_check() { max_players = 4; @@ -6081,6 +6087,7 @@ player_too_many_players_check() level notify( "end_game" ); } } -*/ + + diff --git a/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/zombies/_zm_perks.gsc b/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/zombies/_zm_perks.gsc index 5b846fc..105c5cf 100644 --- a/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/zombies/_zm_perks.gsc +++ b/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/zombies/_zm_perks.gsc @@ -26,12 +26,9 @@ init() { return; } - if ( getDvarIntDefault( "_zm_perks_return_early", "0" ) == "1" ) - { - return; - } initialize_custom_perk_arrays(); perk_machine_spawn_init(); + vending_weapon_upgrade_trigger = []; vending_triggers = getentarray( "zombie_vending", "targetname" ); i = 0; @@ -75,6 +72,7 @@ init() set_zombie_var( "zombie_perk_juggernaut_health_upgrade", 190 ); array_thread( vending_triggers, ::vending_trigger_think ); array_thread( vending_triggers, ::electric_perks_dialog ); + if ( isDefined( level.zombiemode_using_doubletap_perk ) && level.zombiemode_using_doubletap_perk ) { level thread turn_doubletap_on(); @@ -137,6 +135,7 @@ init() [[ level.quantum_bomb_register_result_func ]]( "give_nearest_perk", ::quantum_bomb_give_nearest_perk_result, 10, ::quantum_bomb_give_nearest_perk_validation ); } level thread perk_hostmigration(); + } default_vending_precaching() @@ -3091,19 +3090,19 @@ perk_machine_spawn_init() { match_string = ""; location = level.scr_zm_map_start_location; - if ( location != "default" && location == "" && isDefined( level.default_start_location ) ) + if(location == "default" || location == "" && isdefined(level.default_start_location)) { location = level.default_start_location; } - match_string = ( level.scr_zm_ui_gametype + "_perks_" ) + location; + match_string = level.scr_zm_ui_gametype + "_perks_" + location; pos = []; - if ( isDefined( level.override_perk_targetname ) ) + if(isdefined(level.override_perk_targetname)) { - structs = getstructarray( level.override_perk_targetname, "targetname" ); + structs = getstructarray(level.override_perk_targetname, "targetname"); } else { - structs = getstructarray( "zm_perk_machine", "targetname" ); + structs = getstructarray("zm_perk_machine", "targetname"); } _a3578 = structs; _k3578 = getFirstArrayKey( _a3578 ); @@ -3128,60 +3127,59 @@ perk_machine_spawn_init() else pos[ pos.size ] = struct; _k3578 = getNextArrayKey( _a3578, _k3578 ); } - if ( !isDefined( pos ) || pos.size == 0 ) + if(!isdefined(pos) || pos.size == 0) { return; } - precachemodel( "zm_collision_perks1" ); - i = 0; - while ( i < pos.size ) + precachemodel("zm_collision_perks1"); + for(i = 0; i < pos.size; i++) { - perk = pos[ i ].script_noteworthy; - if ( isDefined( perk ) && isDefined( pos[ i ].model ) ) + perk = pos[i].script_noteworthy; + if(isdefined(perk) && isdefined(pos[i].model)) { - use_trigger = spawn( "trigger_radius_use", pos[ i ].origin + vectorScale( ( 0, -1, 0 ), 30 ), 0, 40, 70 ); + use_trigger = spawn("trigger_radius_use", pos[i].origin + VectorScale( 0, 0, 1, 30), 0, 40, 70); use_trigger.targetname = "zombie_vending"; use_trigger.script_noteworthy = perk; use_trigger triggerignoreteam(); - perk_machine = spawn( "script_model", pos[ i ].origin ); - perk_machine.angles = pos[ i ].angles; - perk_machine setmodel( pos[ i ].model ); - if ( isDefined( level._no_vending_machine_bump_trigs ) && level._no_vending_machine_bump_trigs ) + perk_machine = spawn("script_model", pos[i].origin); + perk_machine.angles = pos[i].angles; + perk_machine setmodel(pos[i].model); + if(isdefined(level._no_vending_machine_bump_trigs) && level._no_vending_machine_bump_trigs) { bump_trigger = undefined; } else { - bump_trigger = spawn( "trigger_radius", pos[ i ].origin, 0, 35, 64 ); + bump_trigger = spawn("trigger_radius", pos[i].origin, 0, 35, 64); bump_trigger.script_activated = 1; bump_trigger.script_sound = "zmb_perks_bump_bottle"; bump_trigger.targetname = "audio_bump_trigger"; - if ( perk != "specialty_weapupgrade" ) + if(perk != "specialty_weapupgrade") { bump_trigger thread thread_bump_trigger(); } } - collision = spawn( "script_model", pos[ i ].origin, 1 ); - collision.angles = pos[ i ].angles; - collision setmodel( "zm_collision_perks1" ); + collision = spawn("script_model", pos[i].origin, 1); + collision.angles = pos[i].angles; + collision setmodel("zm_collision_perks1"); collision.script_noteworthy = "clip"; collision disconnectpaths(); use_trigger.clip = collision; use_trigger.machine = perk_machine; use_trigger.bump = bump_trigger; - if ( isDefined( pos[ i ].blocker_model ) ) + if(isdefined(pos[i].blocker_model)) { - use_trigger.blocker_model = pos[ i ].blocker_model; + use_trigger.blocker_model = pos[i].blocker_model; } - if ( isDefined( pos[ i ].script_int ) ) + if(isdefined(pos[i].script_int)) { - perk_machine.script_int = pos[ i ].script_int; + perk_machine.script_int = pos[i].script_int; } - if ( isDefined( pos[ i ].turn_on_notify ) ) + if(isdefined(pos[i].turn_on_notify)) { - perk_machine.turn_on_notify = pos[ i ].turn_on_notify; + perk_machine.turn_on_notify = pos[i].turn_on_notify; } - switch( perk ) + switch(perk) { case "specialty_quickrevive": case "specialty_quickrevive_upgrade": @@ -3191,7 +3189,7 @@ perk_machine_spawn_init() use_trigger.target = "vending_revive"; perk_machine.script_string = "revive_perk"; perk_machine.targetname = "vending_revive"; - if ( isDefined( bump_trigger ) ) + if(isdefined(bump_trigger)) { bump_trigger.script_string = "revive_perk"; } @@ -3204,7 +3202,7 @@ perk_machine_spawn_init() use_trigger.target = "vending_sleight"; perk_machine.script_string = "speedcola_perk"; perk_machine.targetname = "vending_sleight"; - if ( isDefined( bump_trigger ) ) + if(isdefined(bump_trigger)) { bump_trigger.script_string = "speedcola_perk"; } @@ -3217,7 +3215,7 @@ perk_machine_spawn_init() use_trigger.target = "vending_marathon"; perk_machine.script_string = "marathon_perk"; perk_machine.targetname = "vending_marathon"; - if ( isDefined( bump_trigger ) ) + if(isdefined(bump_trigger)) { bump_trigger.script_string = "marathon_perk"; } @@ -3231,7 +3229,7 @@ perk_machine_spawn_init() use_trigger.target = "vending_jugg"; perk_machine.script_string = "jugg_perk"; perk_machine.targetname = "vending_jugg"; - if ( isDefined( bump_trigger ) ) + if(isdefined(bump_trigger)) { bump_trigger.script_string = "jugg_perk"; } @@ -3244,7 +3242,7 @@ perk_machine_spawn_init() use_trigger.target = "vending_tombstone"; perk_machine.script_string = "tombstone_perk"; perk_machine.targetname = "vending_tombstone"; - if ( isDefined( bump_trigger ) ) + if(isdefined(bump_trigger)) { bump_trigger.script_string = "tombstone_perk"; } @@ -3257,7 +3255,7 @@ perk_machine_spawn_init() use_trigger.target = "vending_doubletap"; perk_machine.script_string = "tap_perk"; perk_machine.targetname = "vending_doubletap"; - if ( isDefined( bump_trigger ) ) + if(isdefined(bump_trigger)) { bump_trigger.script_string = "tap_perk"; } @@ -3270,7 +3268,7 @@ perk_machine_spawn_init() use_trigger.target = "vending_chugabud"; perk_machine.script_string = "tap_perk"; perk_machine.targetname = "vending_chugabud"; - if ( isDefined( bump_trigger ) ) + if(isdefined(bump_trigger)) { bump_trigger.script_string = "tap_perk"; } @@ -3283,7 +3281,7 @@ perk_machine_spawn_init() use_trigger.target = "vending_additionalprimaryweapon"; perk_machine.script_string = "tap_perk"; perk_machine.targetname = "vending_additionalprimaryweapon"; - if ( isDefined( bump_trigger ) ) + if(isdefined(bump_trigger)) { bump_trigger.script_string = "tap_perk"; } @@ -3294,16 +3292,16 @@ perk_machine_spawn_init() use_trigger.script_label = "mus_perks_packa_sting"; use_trigger.longjinglewait = 1; perk_machine.targetname = "vending_packapunch"; - flag_pos = getstruct( pos[ i ].target, "targetname" ); - if ( isDefined( flag_pos ) ) + flag_pos = getstruct(pos[i].target, "targetname"); + if(isdefined(flag_pos)) { - perk_machine_flag = spawn( "script_model", flag_pos.origin ); + perk_machine_flag = spawn("script_model", flag_pos.origin); perk_machine_flag.angles = flag_pos.angles; - perk_machine_flag setmodel( flag_pos.model ); + perk_machine_flag setmodel(flag_pos.model); perk_machine_flag.targetname = "pack_flag"; perk_machine.target = "pack_flag"; } - if ( isDefined( bump_trigger ) ) + if(isdefined(bump_trigger)) { bump_trigger.script_string = "perks_rattle"; } @@ -3316,30 +3314,29 @@ perk_machine_spawn_init() use_trigger.target = "vending_deadshot"; perk_machine.script_string = "deadshot_vending"; perk_machine.targetname = "vending_deadshot_model"; - if ( isDefined( bump_trigger ) ) + if(isdefined(bump_trigger)) { bump_trigger.script_string = "deadshot_vending"; } break; - default: + case default: use_trigger.script_sound = "mus_perks_speed_jingle"; use_trigger.script_string = "speedcola_perk"; use_trigger.script_label = "mus_perks_speed_sting"; use_trigger.target = "vending_sleight"; perk_machine.script_string = "speedcola_perk"; perk_machine.targetname = "vending_sleight"; - if ( isDefined( bump_trigger ) ) + if(isdefined(bump_trigger)) { bump_trigger.script_string = "speedcola_perk"; } break; } - if ( isDefined( level._custom_perks[ perk ] ) && isDefined( level._custom_perks[ perk ].perk_machine_set_kvps ) ) + if(isdefined(level._custom_perks[perk]) && isdefined(level._custom_perks[perk].perk_machine_set_kvps)) { - [[ level._custom_perks[ perk ].perk_machine_set_kvps ]]( use_trigger, perk_machine, bump_trigger, collision ); + [[level._custom_perks[perk].perk_machine_set_kvps]](use_trigger, perk_machine, bump_trigger, collision); } } - i++; } } @@ -4163,3 +4160,4 @@ _register_undefined_perk( str_perk ) } } + diff --git a/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/zombies/_zm_powerups.gsc b/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/zombies/_zm_powerups.gsc new file mode 100644 index 0000000..0c23f2c --- /dev/null +++ b/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/zombies/_zm_powerups.gsc @@ -0,0 +1,2965 @@ +#include maps/mp/zombies/_zm_melee_weapon; +#include maps/mp/zombies/_zm_weapons; +#include maps/mp/zombies/_zm_perks; +#include maps/mp/gametypes_zm/_hud_util; +#include maps/mp/zombies/_zm_pers_upgrades_functions; +#include maps/mp/zombies/_zm_spawner; +#include maps/mp/animscripts/zm_death; +#include maps/mp/zombies/_zm_score; +#include maps/mp/zombies/_zm_powerups; +#include maps/mp/zombies/_zm_blockers; +#include maps/mp/zombies/_zm_audio_announcer; +#include maps/mp/zombies/_zm_stats; +#include maps/mp/zombies/_zm_pers_upgrades; +#include maps/mp/zombies/_zm_laststand; +#include maps/mp/_demo; +#include maps/mp/zombies/_zm_magicbox; +#include maps/mp/zombies/_zm_audio; +#include maps/mp/zombies/_zm_net; +#include maps/mp/zombies/_zm_utility; +#include maps/mp/_utility; +#include common_scripts/utility; + +init() +{ + precacheshader( "specialty_doublepoints_zombies" ); + precacheshader( "specialty_instakill_zombies" ); + precacheshader( "specialty_firesale_zombies" ); + precacheshader( "zom_icon_bonfire" ); + precacheshader( "zom_icon_minigun" ); + precacheshader( "black" ); + set_zombie_var( "zombie_insta_kill", 0, undefined, undefined, 1 ); + set_zombie_var( "zombie_point_scalar", 1, undefined, undefined, 1 ); + set_zombie_var( "zombie_drop_item", 0 ); + set_zombie_var( "zombie_timer_offset", 350 ); + set_zombie_var( "zombie_timer_offset_interval", 30 ); + set_zombie_var( "zombie_powerup_fire_sale_on", 0 ); + set_zombie_var( "zombie_powerup_fire_sale_time", 30 ); + set_zombie_var( "zombie_powerup_bonfire_sale_on", 0 ); + set_zombie_var( "zombie_powerup_bonfire_sale_time", 30 ); + set_zombie_var( "zombie_powerup_insta_kill_on", 0, undefined, undefined, 1 ); + set_zombie_var( "zombie_powerup_insta_kill_time", 30, undefined, undefined, 1 ); + set_zombie_var( "zombie_powerup_point_doubler_on", 0, undefined, undefined, 1 ); + set_zombie_var( "zombie_powerup_point_doubler_time", 30, undefined, undefined, 1 ); + set_zombie_var( "zombie_powerup_drop_increment", 2000 ); + set_zombie_var( "zombie_powerup_drop_max_per_round", 4 ); + onplayerconnect_callback( ::init_player_zombie_vars ); + level._effect[ "powerup_on" ] = loadfx( "misc/fx_zombie_powerup_on" ); + level._effect[ "powerup_off" ] = loadfx( "misc/fx_zombie_powerup_off" ); + level._effect[ "powerup_grabbed" ] = loadfx( "misc/fx_zombie_powerup_grab" ); + level._effect[ "powerup_grabbed_wave" ] = loadfx( "misc/fx_zombie_powerup_wave" ); + if ( isDefined( level.using_zombie_powerups ) && level.using_zombie_powerups ) + { + level._effect[ "powerup_on_red" ] = loadfx( "misc/fx_zombie_powerup_on_red" ); + level._effect[ "powerup_grabbed_red" ] = loadfx( "misc/fx_zombie_powerup_red_grab" ); + level._effect[ "powerup_grabbed_wave_red" ] = loadfx( "misc/fx_zombie_powerup_red_wave" ); + } + level._effect[ "powerup_on_solo" ] = loadfx( "misc/fx_zombie_powerup_solo_on" ); + level._effect[ "powerup_grabbed_solo" ] = loadfx( "misc/fx_zombie_powerup_solo_grab" ); + level._effect[ "powerup_grabbed_wave_solo" ] = loadfx( "misc/fx_zombie_powerup_solo_wave" ); + level._effect[ "powerup_on_caution" ] = loadfx( "misc/fx_zombie_powerup_caution_on" ); + level._effect[ "powerup_grabbed_caution" ] = loadfx( "misc/fx_zombie_powerup_caution_grab" ); + level._effect[ "powerup_grabbed_wave_caution" ] = loadfx( "misc/fx_zombie_powerup_caution_wave" ); + init_powerups(); + if ( !level.enable_magic ) + { + return; + } + thread watch_for_drop(); + thread setup_firesale_audio(); + thread setup_bonfiresale_audio(); + level.use_new_carpenter_func = ::start_carpenter_new; + level.board_repair_distance_squared = 562500; +} + +init_powerups() +{ + flag_init( "zombie_drop_powerups" ); + if ( isDefined( level.enable_magic ) && level.enable_magic ) + { + flag_set( "zombie_drop_powerups" ); + } + if ( !isDefined( level.active_powerups ) ) + { + level.active_powerups = []; + } + if ( !isDefined( level.zombie_powerup_array ) ) + { + level.zombie_powerup_array = []; + } + if ( !isDefined( level.zombie_special_drop_array ) ) + { + level.zombie_special_drop_array = []; + } + add_zombie_powerup( "nuke", "zombie_bomb", &"ZOMBIE_POWERUP_NUKE", ::func_should_always_drop, 0, 0, 0, "misc/fx_zombie_mini_nuke_hotness" ); + add_zombie_powerup( "insta_kill", "zombie_skull", &"ZOMBIE_POWERUP_INSTA_KILL", ::func_should_always_drop, 0, 0, 0, undefined, "powerup_instant_kill", "zombie_powerup_insta_kill_time", "zombie_powerup_insta_kill_on" ); + add_zombie_powerup( "full_ammo", "zombie_ammocan", &"ZOMBIE_POWERUP_MAX_AMMO", ::func_should_always_drop, 0, 0, 0 ); + add_zombie_powerup( "double_points", "zombie_x2_icon", &"ZOMBIE_POWERUP_DOUBLE_POINTS", ::func_should_always_drop, 0, 0, 0, undefined, "powerup_double_points", "zombie_powerup_point_doubler_time", "zombie_powerup_point_doubler_on" ); + add_zombie_powerup( "carpenter", "zombie_carpenter", &"ZOMBIE_POWERUP_MAX_AMMO", ::func_should_drop_carpenter, 0, 0, 0 ); + add_zombie_powerup( "fire_sale", "zombie_firesale", &"ZOMBIE_POWERUP_MAX_AMMO", ::func_should_drop_fire_sale, 0, 0, 0, undefined, "powerup_fire_sale", "zombie_powerup_fire_sale_time", "zombie_powerup_fire_sale_on" ); + add_zombie_powerup( "bonfire_sale", "zombie_pickup_bonfire", &"ZOMBIE_POWERUP_MAX_AMMO", ::func_should_never_drop, 0, 0, 0, undefined, "powerup_bon_fire", "zombie_powerup_bonfire_sale_time", "zombie_powerup_bonfire_sale_on" ); + add_zombie_powerup( "minigun", "zombie_pickup_minigun", &"ZOMBIE_POWERUP_MINIGUN", ::func_should_drop_minigun, 1, 0, 0, undefined, "powerup_mini_gun", "zombie_powerup_minigun_time", "zombie_powerup_minigun_on" ); + add_zombie_powerup( "free_perk", "zombie_pickup_perk_bottle", &"ZOMBIE_POWERUP_FREE_PERK", ::func_should_never_drop, 0, 0, 0 ); + add_zombie_powerup( "tesla", "zombie_pickup_minigun", &"ZOMBIE_POWERUP_MINIGUN", ::func_should_never_drop, 1, 0, 0, undefined, "powerup_tesla", "zombie_powerup_tesla_time", "zombie_powerup_tesla_on" ); + add_zombie_powerup( "random_weapon", "zombie_pickup_minigun", &"ZOMBIE_POWERUP_MAX_AMMO", ::func_should_never_drop, 1, 0, 0 ); + add_zombie_powerup( "bonus_points_player", "zombie_z_money_icon", &"ZOMBIE_POWERUP_BONUS_POINTS", ::func_should_never_drop, 1, 0, 0 ); + add_zombie_powerup( "bonus_points_team", "zombie_z_money_icon", &"ZOMBIE_POWERUP_BONUS_POINTS", ::func_should_never_drop, 0, 0, 0 ); + add_zombie_powerup( "lose_points_team", "zombie_z_money_icon", &"ZOMBIE_POWERUP_LOSE_POINTS", ::func_should_never_drop, 0, 0, 1 ); + add_zombie_powerup( "lose_perk", "zombie_pickup_perk_bottle", &"ZOMBIE_POWERUP_MAX_AMMO", ::func_should_never_drop, 0, 0, 1 ); + add_zombie_powerup( "empty_clip", "zombie_ammocan", &"ZOMBIE_POWERUP_MAX_AMMO", ::func_should_never_drop, 0, 0, 1 ); + add_zombie_powerup( "insta_kill_ug", "zombie_skull", &"ZOMBIE_POWERUP_INSTA_KILL", ::func_should_never_drop, 1, 0, 0, undefined, "powerup_instant_kill_ug", "zombie_powerup_insta_kill_ug_time", "zombie_powerup_insta_kill_ug_on", 5000 ); + if ( isDefined( level.level_specific_init_powerups ) ) + { + [[ level.level_specific_init_powerups ]](); + } + randomize_powerups(); + level.zombie_powerup_index = 0; + randomize_powerups(); + level.rare_powerups_active = 0; + level.firesale_vox_firstime = 0; + level thread powerup_hud_monitor(); + if ( isDefined( level.quantum_bomb_register_result_func ) ) + { + [[ level.quantum_bomb_register_result_func ]]( "random_powerup", ::quantum_bomb_random_powerup_result, 5, level.quantum_bomb_in_playable_area_validation_func ); + [[ level.quantum_bomb_register_result_func ]]( "random_zombie_grab_powerup", ::quantum_bomb_random_zombie_grab_powerup_result, 5, level.quantum_bomb_in_playable_area_validation_func ); + [[ level.quantum_bomb_register_result_func ]]( "random_weapon_powerup", ::quantum_bomb_random_weapon_powerup_result, 60, level.quantum_bomb_in_playable_area_validation_func ); + [[ level.quantum_bomb_register_result_func ]]( "random_bonus_or_lose_points_powerup", ::quantum_bomb_random_bonus_or_lose_points_powerup_result, 25, level.quantum_bomb_in_playable_area_validation_func ); + } + registerclientfield( "scriptmover", "powerup_fx", 1000, 3, "int" ); +} + +init_player_zombie_vars() +{ + self.zombie_vars[ "zombie_powerup_minigun_on" ] = 0; + self.zombie_vars[ "zombie_powerup_minigun_time" ] = 0; + self.zombie_vars[ "zombie_powerup_tesla_on" ] = 0; + self.zombie_vars[ "zombie_powerup_tesla_time" ] = 0; + self.zombie_vars[ "zombie_powerup_insta_kill_ug_on" ] = 0; + self.zombie_vars[ "zombie_powerup_insta_kill_ug_time" ] = 18; +} + +set_weapon_ignore_max_ammo( str_weapon ) +{ + if ( !isDefined( level.zombie_weapons_no_max_ammo ) ) + { + level.zombie_weapons_no_max_ammo = []; + } + level.zombie_weapons_no_max_ammo[ str_weapon ] = 1; +} + +powerup_hud_monitor() +{ + flag_wait( "start_zombie_round_logic" ); + if ( isDefined( level.current_game_module ) && level.current_game_module == 2 ) + { + return; + } + flashing_timers = []; + flashing_values = []; + flashing_timer = 10; + flashing_delta_time = 0; + flashing_is_on = 0; + flashing_value = 3; + flashing_min_timer = 0.15; + while ( flashing_timer >= flashing_min_timer ) + { + if ( flashing_timer < 5 ) + { + flashing_delta_time = 0.1; + } + else + { + flashing_delta_time = 0.2; + } + if ( flashing_is_on ) + { + flashing_timer = flashing_timer - flashing_delta_time - 0.05; + flashing_value = 2; + } + else + { + flashing_timer -= flashing_delta_time; + flashing_value = 3; + } + flashing_timers[ flashing_timers.size ] = flashing_timer; + flashing_values[ flashing_values.size ] = flashing_value; + flashing_is_on = !flashing_is_on; + } + client_fields = []; + powerup_keys = getarraykeys( level.zombie_powerups ); + powerup_key_index = 0; + while ( powerup_key_index < powerup_keys.size ) + { + if ( isDefined( level.zombie_powerups[ powerup_keys[ powerup_key_index ] ].client_field_name ) ) + { + powerup_name = powerup_keys[ powerup_key_index ]; + client_fields[ powerup_name ] = spawnstruct(); + client_fields[ powerup_name ].client_field_name = level.zombie_powerups[ powerup_name ].client_field_name; + client_fields[ powerup_name ].solo = level.zombie_powerups[ powerup_name ].solo; + client_fields[ powerup_name ].time_name = level.zombie_powerups[ powerup_name ].time_name; + client_fields[ powerup_name ].on_name = level.zombie_powerups[ powerup_name ].on_name; + } + powerup_key_index++; + } + if ( getDvar( "_zm_powerupsReturnEarly" ) ) + { + return; + } + client_field_keys = getarraykeys( client_fields ); + + while ( 1 ) + { + wait 0.05; + waittillframeend; + players = get_players(); + playerindex = 0; + while ( playerindex < players.size ) + { + client_field_key_index = 0; + while ( client_field_key_index < client_field_keys.size ) + { + player = players[ playerindex ]; + if ( isDefined( level.powerup_player_valid ) ) + { + if ( !( [[ level.powerup_player_valid ]]( player ) ) ) + { + client_field_key_index++; + continue; + } + } + client_field_name_array = client_field_keys[client_field_key_index]; + client_field_name = client_fields[client_field_name_array].client_field_name; + time_name = client_fields[client_field_name_array].time_name; + on_name = client_fields[client_field_name_array].on_name; + powerup_timer = undefined; + powerup_on = undefined; + if ( client_fields[ client_field_keys[ client_field_key_index ] ].solo ) + { + if ( isDefined( player._show_solo_hud ) && player._show_solo_hud == 1 ) + { + powerup_timer = player.zombie_vars[ time_name ]; + powerup_on = player.zombie_vars[ on_name ]; + } + } + else if ( isDefined( level.zombie_vars[ player.team ][ time_name ] ) ) + { + powerup_timer = level.zombie_vars[ player.team ][ time_name ]; + powerup_on = level.zombie_vars[ player.team ][ on_name ]; + } + else + { + if ( isDefined( level.zombie_vars[ time_name ] ) ) + { + powerup_timer = level.zombie_vars[ time_name ]; + powerup_on = level.zombie_vars[ on_name ]; + } + } + if ( isDefined( powerup_timer ) && isDefined( powerup_on ) ) + { + player set_clientfield_powerups( client_field_name, powerup_timer, powerup_on, flashing_timers, flashing_values ); + client_field_key_index++; + continue; + } + else + { + player setclientfieldtoplayer( client_field_name, 0 ); + } + client_field_key_index++; + } + playerindex++; + } + } +} + +set_clientfield_powerups( clientfield_name, powerup_timer, powerup_on, flashing_timers, flashing_values ) +{ + if ( powerup_on ) + { + if ( powerup_timer < 10 ) + { + flashing_value = 3; + i = flashing_timers.size - 1; + while ( i > 0 ) + { + if ( powerup_timer < flashing_timers[ i ] ) + { + flashing_value = flashing_values[ i ]; + break; + } + else + { + i--; + + } + } + self setclientfieldtoplayer( clientfield_name, flashing_value ); + } + else + { + self setclientfieldtoplayer( clientfield_name, 1 ); + } + } + else + { + self setclientfieldtoplayer( clientfield_name, 0 ); + } +} + +randomize_powerups() +{ + level.zombie_powerup_array = array_randomize( level.zombie_powerup_array ); +} + +get_next_powerup() +{ + powerup = level.zombie_powerup_array[ level.zombie_powerup_index ]; + level.zombie_powerup_index++; + if ( level.zombie_powerup_index >= level.zombie_powerup_array.size ) + { + level.zombie_powerup_index = 0; + randomize_powerups(); + } + return powerup; +} + +get_valid_powerup() +{ + if ( isDefined( level.zombie_powerup_boss ) ) + { + i = level.zombie_powerup_boss; + level.zombie_powerup_boss = undefined; + return level.zombie_powerup_array[ i ]; + } + if ( isDefined( level.zombie_powerup_ape ) ) + { + powerup = level.zombie_powerup_ape; + level.zombie_powerup_ape = undefined; + return powerup; + } + powerup = get_next_powerup(); + while ( 1 ) + { + while ( !( [[ level.zombie_powerups[ powerup ].func_should_drop_with_regular_powerups ]]() ) ) + { + powerup = get_next_powerup(); + } + return powerup; + } +} + +minigun_no_drop() +{ + players = get_players(); + i = 0; + while ( i < players.size ) + { + if ( players[ i ].zombie_vars[ "zombie_powerup_minigun_on" ] == 1 ) + { + return 1; + } + i++; + } + if ( !flag( "power_on" ) ) + { + if ( flag( "solo_game" ) ) + { + if ( level.solo_lives_given == 0 ) + { + return 1; + } + } + else + { + return 1; + } + } + return 0; +} + +get_num_window_destroyed() +{ + num = 0; + i = 0; + while ( i < level.exterior_goals.size ) + { + if ( all_chunks_destroyed( level.exterior_goals[ i ], level.exterior_goals[ i ].barrier_chunks ) ) + { + num += 1; + } + i++; + } + return num; +} + +watch_for_drop() +{ + flag_wait( "start_zombie_round_logic" ); + flag_wait( "begin_spawning" ); + players = get_players(); + score_to_drop = ( players.size * level.zombie_vars[ "zombie_score_start_" + players.size + "p" ] ) + level.zombie_vars[ "zombie_powerup_drop_increment" ]; + while ( 1 ) + { + flag_wait( "zombie_drop_powerups" ); + players = get_players(); + curr_total_score = 0; + i = 0; + while ( i < players.size ) + { + if ( isDefined( players[ i ].score_total ) ) + { + curr_total_score += players[ i ].score_total; + } + i++; + } + if ( curr_total_score > score_to_drop ) + { + level.zombie_vars[ "zombie_powerup_drop_increment" ] *= 1.14; + score_to_drop = curr_total_score + level.zombie_vars[ "zombie_powerup_drop_increment" ]; + level.zombie_vars[ "zombie_drop_item" ] = 1; + } + wait 0.5; + } + +} + +add_zombie_powerup( powerup_name, model_name, hint, func_should_drop_with_regular_powerups, solo, caution, zombie_grabbable, fx, client_field_name, time_name, on_name, clientfield_version ) +{ + if ( !isDefined( clientfield_version ) ) + { + clientfield_version = 1; + } + if ( isDefined( level.zombie_include_powerups ) && !isDefined( level.zombie_include_powerups[ powerup_name ] ) ) + { + return; + } + precachemodel( model_name ); + precachestring( hint ); + struct = spawnstruct(); + if ( !isDefined( level.zombie_powerups ) ) + { + level.zombie_powerups = []; + } + struct.powerup_name = powerup_name; + struct.model_name = model_name; + struct.weapon_classname = "script_model"; + struct.hint = hint; + struct.func_should_drop_with_regular_powerups = func_should_drop_with_regular_powerups; + struct.solo = solo; + struct.caution = caution; + struct.zombie_grabbable = zombie_grabbable; + if ( isDefined( fx ) ) + { + struct.fx = loadfx( fx ); + } + level.zombie_powerups[ powerup_name ] = struct; + level.zombie_powerup_array[ level.zombie_powerup_array.size ] = powerup_name; + add_zombie_special_drop( powerup_name ); + if ( !level.createfx_enabled ) + { + if ( isDefined( client_field_name ) ) + { + registerclientfield( "toplayer", client_field_name, clientfield_version, 2, "int" ); + struct.client_field_name = client_field_name; + struct.time_name = time_name; + struct.on_name = on_name; + } + } +} + +powerup_set_can_pick_up_in_last_stand( powerup_name, b_can_pick_up ) +{ + level.zombie_powerups[ powerup_name ].can_pick_up_in_last_stand = b_can_pick_up; +} + +add_zombie_special_drop( powerup_name ) +{ + level.zombie_special_drop_array[ level.zombie_special_drop_array.size ] = powerup_name; +} + +include_zombie_powerup( powerup_name ) +{ + if ( !isDefined( level.zombie_include_powerups ) ) + { + level.zombie_include_powerups = []; + } + level.zombie_include_powerups[ powerup_name ] = 1; +} + +powerup_round_start() +{ + level.powerup_drop_count = 0; +} + +powerup_drop( drop_point ) +{ + if ( level.powerup_drop_count >= level.zombie_vars[ "zombie_powerup_drop_max_per_round" ] ) + { + return; + } + if ( !isDefined( level.zombie_include_powerups ) || level.zombie_include_powerups.size == 0 ) + { + return; + } + rand_drop = randomint( 100 ); + if ( rand_drop > 2 ) + { + if ( !level.zombie_vars[ "zombie_drop_item" ] ) + { + return; + } + debug = "score"; + } + else + { + debug = "random"; + } + playable_area = getentarray( "player_volume", "script_noteworthy" ); + level.powerup_drop_count++; + powerup = maps/mp/zombies/_zm_net::network_safe_spawn( "powerup", 1, "script_model", drop_point + vectorScale( ( 0, 0, 0 ), 40 ) ); + valid_drop = 0; + i = 0; + while ( i < playable_area.size ) + { + if ( powerup istouching( playable_area[ i ] ) ) + { + valid_drop = 1; + } + i++; + } + if ( valid_drop && level.rare_powerups_active ) + { + pos = ( drop_point[ 0 ], drop_point[ 1 ], drop_point[ 2 ] + 42 ); + if ( check_for_rare_drop_override( pos ) ) + { + level.zombie_vars[ "zombie_drop_item" ] = 0; + valid_drop = 0; + } + } + if ( !valid_drop ) + { + level.powerup_drop_count--; + + powerup delete(); + return; + } + powerup powerup_setup(); + print_powerup_drop( powerup.powerup_name, debug ); + powerup thread powerup_timeout(); + powerup thread powerup_wobble(); + powerup thread powerup_grab(); + powerup thread powerup_move(); + powerup thread powerup_emp(); + level.zombie_vars[ "zombie_drop_item" ] = 0; + level notify( "powerup_dropped" ); +} + +specific_powerup_drop( powerup_name, drop_spot, powerup_team, powerup_location ) +{ + powerup = maps/mp/zombies/_zm_net::network_safe_spawn( "powerup", 1, "script_model", drop_spot + vectorScale( ( 0, 0, 0 ), 40 ) ); + level notify( "powerup_dropped" ); + if ( isDefined( powerup ) ) + { + powerup powerup_setup( powerup_name, powerup_team, powerup_location ); + powerup thread powerup_timeout(); + powerup thread powerup_wobble(); + powerup thread powerup_grab( powerup_team ); + powerup thread powerup_move(); + powerup thread powerup_emp(); + return powerup; + } +} + +quantum_bomb_random_powerup_result( position ) +{ + if ( !isDefined( level.zombie_include_powerups ) || !level.zombie_include_powerups.size ) + { + return; + } + keys = getarraykeys( level.zombie_include_powerups ); + while ( keys.size ) + { + index = randomint( keys.size ); + if ( !level.zombie_powerups[ keys[ index ] ].zombie_grabbable ) + { + skip = 0; + switch( keys[ index ] ) + { + case "bonus_points_player": + case "bonus_points_team": + case "random_weapon": + skip = 1; + break; + case "fire_sale": + case "full_ammo": + case "insta_kill": + case "minigun": + if ( randomint( 4 ) ) + { + skip = 1; + } + break; + case "bonfire_sale": + case "free_perk": + case "tesla": + if ( randomint( 20 ) ) + { + skip = 1; + } + break; + default: + } + while ( skip ) + { + arrayremovevalue( keys, keys[ index ] ); + } + self thread maps/mp/zombies/_zm_audio::create_and_play_dialog( "kill", "quant_good" ); + [[ level.quantum_bomb_play_player_effect_at_position_func ]]( position ); + level specific_powerup_drop( keys[ index ], position ); + return; + continue; + } + else + { + arrayremovevalue( keys, keys[ index ] ); + } + } +} + +quantum_bomb_random_zombie_grab_powerup_result( position ) +{ + if ( !isDefined( level.zombie_include_powerups ) || !level.zombie_include_powerups.size ) + { + return; + } + keys = getarraykeys( level.zombie_include_powerups ); + while ( keys.size ) + { + index = randomint( keys.size ); + if ( level.zombie_powerups[ keys[ index ] ].zombie_grabbable ) + { + self thread maps/mp/zombies/_zm_audio::create_and_play_dialog( "kill", "quant_bad" ); + [[ level.quantum_bomb_play_player_effect_at_position_func ]]( position ); + level specific_powerup_drop( keys[ index ], position ); + return; + continue; + } + else + { + arrayremovevalue( keys, keys[ index ] ); + } + } +} + +quantum_bomb_random_weapon_powerup_result( position ) +{ + self thread maps/mp/zombies/_zm_audio::create_and_play_dialog( "kill", "quant_good" ); + [[ level.quantum_bomb_play_player_effect_at_position_func ]]( position ); + level specific_powerup_drop( "random_weapon", position ); +} + +quantum_bomb_random_bonus_or_lose_points_powerup_result( position ) +{ + rand = randomint( 10 ); + powerup = "bonus_points_team"; + switch( rand ) + { + case 0: + case 1: + powerup = "lose_points_team"; + if ( isDefined( level.zombie_include_powerups[ powerup ] ) ) + { + self thread maps/mp/zombies/_zm_audio::create_and_play_dialog( "kill", "quant_bad" ); + break; + } + case 2: + case 3: + case 4: + powerup = "bonus_points_player"; + if ( isDefined( level.zombie_include_powerups[ powerup ] ) ) + { + break; + } + default: + powerup = "bonus_points_team"; + break; + } + [[ level.quantum_bomb_play_player_effect_at_position_func ]]( position ); + level specific_powerup_drop( powerup, position ); +} + +special_powerup_drop( drop_point ) +{ + if ( !isDefined( level.zombie_include_powerups ) || level.zombie_include_powerups.size == 0 ) + { + return; + } + powerup = spawn( "script_model", drop_point + vectorScale( ( 0, 0, 0 ), 40 ) ); + playable_area = getentarray( "player_volume", "script_noteworthy" ); + valid_drop = 0; + i = 0; + while ( i < playable_area.size ) + { + if ( powerup istouching( playable_area[ i ] ) ) + { + valid_drop = 1; + break; + } + else + { + i++; + } + } + if ( !valid_drop ) + { + powerup delete(); + return; + } + powerup special_drop_setup(); +} + +cleanup_random_weapon_list() +{ + self waittill( "death" ); + arrayremovevalue( level.random_weapon_powerups, self ); +} + +powerup_setup( powerup_override, powerup_team, powerup_location ) +{ + powerup = undefined; + if ( !isDefined( powerup_override ) ) + { + powerup = get_valid_powerup(); + } + else + { + powerup = powerup_override; + if ( powerup == "tesla" && tesla_powerup_active() ) + { + powerup = "minigun"; + } + } + struct = level.zombie_powerups[ powerup ]; + if ( powerup == "random_weapon" ) + { + players = get_players(); + self.weapon = maps/mp/zombies/_zm_magicbox::treasure_chest_chooseweightedrandomweapon( players[ 0 ] ); + self.base_weapon = self.weapon; + if ( !isDefined( level.random_weapon_powerups ) ) + { + level.random_weapon_powerups = []; + } + level.random_weapon_powerups[ level.random_weapon_powerups.size ] = self; + self thread cleanup_random_weapon_list(); + if ( isDefined( level.zombie_weapons[ self.weapon ].upgrade_name ) && !randomint( 4 ) ) + { + self.weapon = level.zombie_weapons[ self.weapon ].upgrade_name; + } + self setmodel( getweaponmodel( self.weapon ) ); + self useweaponhidetags( self.weapon ); + offsetdw = vectorScale( ( 0, 0, 0 ), 3 ); + self.worldgundw = undefined; + if ( maps/mp/zombies/_zm_magicbox::weapon_is_dual_wield( self.weapon ) ) + { + self.worldgundw = spawn( "script_model", self.origin + offsetdw ); + self.worldgundw.angles = self.angles; + self.worldgundw setmodel( maps/mp/zombies/_zm_magicbox::get_left_hand_weapon_model_name( self.weapon ) ); + self.worldgundw useweaponhidetags( self.weapon ); + self.worldgundw linkto( self, "tag_weapon", offsetdw, ( 0, 0, 0 ) ); + } + } + else + { + self setmodel( struct.model_name ); + } + maps/mp/_demo::bookmark( "zm_powerup_dropped", getTime(), undefined, undefined, 1 ); + playsoundatposition( "zmb_spawn_powerup", self.origin ); + if ( isDefined( powerup_team ) ) + { + self.powerup_team = powerup_team; + } + if ( isDefined( powerup_location ) ) + { + self.powerup_location = powerup_location; + } + self.powerup_name = struct.powerup_name; + self.hint = struct.hint; + self.solo = struct.solo; + self.caution = struct.caution; + self.zombie_grabbable = struct.zombie_grabbable; + self.func_should_drop_with_regular_powerups = struct.func_should_drop_with_regular_powerups; + if ( isDefined( struct.fx ) ) + { + self.fx = struct.fx; + } + if ( isDefined( struct.can_pick_up_in_last_stand ) ) + { + self.can_pick_up_in_last_stand = struct.can_pick_up_in_last_stand; + } + self playloopsound( "zmb_spawn_powerup_loop" ); + level.active_powerups[ level.active_powerups.size ] = self; +} + +special_drop_setup() +{ + powerup = undefined; + is_powerup = 1; + if ( level.round_number <= 10 ) + { + powerup = get_valid_powerup(); + } + else + { + powerup = level.zombie_special_drop_array[ randomint( level.zombie_special_drop_array.size ) ]; + if ( level.round_number > 15 && randomint( 100 ) < ( ( level.round_number - 15 ) * 5 ) ) + { + powerup = "nothing"; + } + } + switch( powerup ) + { + case "all_revive": + case "bonfire_sale": + case "bonus_points_player": + case "bonus_points_team": + case "carpenter": + case "double_points": + case "empty_clip": + case "fire_sale": + case "free_perk": + case "insta_kill": + case "lose_perk": + case "lose_points_team": + case "minigun": + case "nuke": + case "random_weapon": + case "tesla": + case "zombie_blood": + break; + case "full_ammo": + if ( level.round_number > 10 && randomint( 100 ) < ( ( level.round_number - 10 ) * 5 ) ) + { + powerup = level.zombie_powerup_array[ randomint( level.zombie_powerup_array.size ) ]; + } + break; + case "dog": + if ( level.round_number >= 15 ) + { + is_powerup = 0; + dog_spawners = getentarray( "special_dog_spawner", "targetname" ); + thread play_sound_2d( "sam_nospawn" ); + } + else + { + powerup = get_valid_powerup(); + } + break; + default: + if ( isDefined( level._zombiemode_special_drop_setup ) ) + { + is_powerup = [[ level._zombiemode_special_drop_setup ]]( powerup ); + } + else + { + is_powerup = 0; + playfx( level._effect[ "lightning_dog_spawn" ], self.origin ); + playsoundatposition( "pre_spawn", self.origin ); + wait 1.5; + playsoundatposition( "zmb_bolt", self.origin ); + earthquake( 0.5, 0.75, self.origin, 1000 ); + playrumbleonposition( "explosion_generic", self.origin ); + playsoundatposition( "spawn", self.origin ); + wait 1; + thread play_sound_2d( "sam_nospawn" ); + self delete(); + } + } + if ( is_powerup ) + { + playfx( level._effect[ "lightning_dog_spawn" ], self.origin ); + playsoundatposition( "pre_spawn", self.origin ); + wait 1.5; + playsoundatposition( "zmb_bolt", self.origin ); + earthquake( 0.5, 0.75, self.origin, 1000 ); + playrumbleonposition( "explosion_generic", self.origin ); + playsoundatposition( "spawn", self.origin ); + self powerup_setup( powerup ); + self thread powerup_timeout(); + self thread powerup_wobble(); + self thread powerup_grab(); + self thread powerup_move(); + self thread powerup_emp(); + } +} + +powerup_zombie_grab_trigger_cleanup( trigger ) +{ + self waittill_any( "powerup_timedout", "powerup_grabbed", "hacked" ); + trigger delete(); +} + +powerup_zombie_grab( powerup_team ) +{ + self endon( "powerup_timedout" ); + self endon( "powerup_grabbed" ); + self endon( "hacked" ); + zombie_grab_trigger = spawn( "trigger_radius", self.origin - vectorScale( ( 0, 0, 0 ), 40 ), 4, 32, 72 ); + zombie_grab_trigger enablelinkto(); + zombie_grab_trigger linkto( self ); + zombie_grab_trigger setteamfortrigger( level.zombie_team ); + self thread powerup_zombie_grab_trigger_cleanup( zombie_grab_trigger ); + poi_dist = 300; + if ( isDefined( level._zombie_grabbable_poi_distance_override ) ) + { + poi_dist = level._zombie_grabbable_poi_distance_override; + } + zombie_grab_trigger create_zombie_point_of_interest( poi_dist, 2, 0, 1, undefined, undefined, powerup_team ); + while ( isDefined( self ) ) + { + zombie_grab_trigger waittill( "trigger", who ); + if ( isDefined( level._powerup_grab_check ) ) + { + while ( !( self [[ level._powerup_grab_check ]]( who ) ) ) + { + continue; + } + } + else if ( !isDefined( who ) || !isai( who ) ) + { + continue; + } + playfx( level._effect[ "powerup_grabbed_red" ], self.origin ); + playfx( level._effect[ "powerup_grabbed_wave_red" ], self.origin ); + switch( self.powerup_name ) + { + case "lose_points_team": + level thread lose_points_team_powerup( self ); + players = get_players(); + players[ randomintrange( 0, players.size ) ] thread powerup_vo( "lose_points" ); + break; + case "lose_perk": + level thread lose_perk_powerup( self ); + break; + case "empty_clip": + level thread empty_clip_powerup( self ); + break; + default: + if ( isDefined( level._zombiemode_powerup_zombie_grab ) ) + { + level thread [[ level._zombiemode_powerup_zombie_grab ]]( self ); + } + if ( isDefined( level._game_mode_powerup_zombie_grab ) ) + { + level thread [[ level._game_mode_powerup_zombie_grab ]]( self, who ); + } + else + { + } + break; + } + level thread maps/mp/zombies/_zm_audio::do_announcer_playvox( "powerup", self.powerup_name ); + wait 0.1; + playsoundatposition( "zmb_powerup_grabbed", self.origin ); + self stoploopsound(); + self powerup_delete(); + self notify( "powerup_grabbed" ); + } +} + +powerup_grab(powerup_team) +{ + if ( isdefined( self ) && self.zombie_grabbable ) + { + self thread powerup_zombie_grab(powerup_team); + return; + } + + self endon ("powerup_timedout"); + self endon ("powerup_grabbed"); + + range_squared = 64 * 64; + while (isdefined(self)) + { + players = GET_PLAYERS(); + + for (i = 0; i < players.size; i++) + { + // Don't let them grab the minigun, tesla, or random weapon if they're downed or reviving + // due to weapon switching issues. + if ( self.powerup_name != "minigun" && self.powerup_name != "tesla" && self.powerup_name != "random_weapon" && self.powerup_name == "meat_stink" || players[ i ] maps/mp/zombies/_zm_laststand::player_is_in_laststand() && players[ i ] usebuttonpressed() && players[ i ] in_revive_trigger() ) + { + continue; + } + + if ( DistanceSquared( players[i].origin, self.origin ) < range_squared ) + { + if( IsDefined( level.zombie_powerup_grab_func ) ) + { + level thread [[level.zombie_powerup_grab_func]](); + } + else + { + switch (self.powerup_name) + { + case "nuke": + level thread nuke_powerup( self, players[i].team ); + + //chrisp - adding powerup VO sounds + players[i] thread powerup_vo("nuke"); + zombies = getaiarray( level.zombie_team ); + //players[i].zombie_nuked = get_array_of_closest( self.origin, zombies ); + players[i].zombie_nuked = ArraySort( zombies, self.origin ); + players[i] notify("nuke_triggered"); + + break; + case "full_ammo": + level thread full_ammo_powerup( self ,players[i] ); + players[i] thread powerup_vo("full_ammo"); + break; + case "double_points": + level thread double_points_powerup( self, players[i] ); + players[i] thread powerup_vo("double_points"); + break; + case "insta_kill": + level thread insta_kill_powerup( self,players[i] ); + players[i] thread powerup_vo("insta_kill"); + break; + case "carpenter": + if(isDefined(level.use_new_carpenter_func)) + { + level thread [[level.use_new_carpenter_func]](self.origin); + } + else + { + level thread start_carpenter( self.origin ); + } + players[i] thread powerup_vo("carpenter"); + break; + + case "fire_sale": + level thread start_fire_sale( self ); + players[i] thread powerup_vo("firesale"); + break; + + case "bonfire_sale": + level thread start_bonfire_sale( self ); + players[i] thread powerup_vo("firesale"); + break; + + case "minigun": + level thread minigun_weapon_powerup( players[i] ); + players[i] thread powerup_vo( "minigun" ); + break; + + case "free_perk": + level thread free_perk_powerup( self ); + //players[i] thread powerup_vo( "insta_kill" ); + break; + + case "tesla": + level thread tesla_weapon_powerup( players[i] ); + players[i] thread powerup_vo( "tesla" ); // TODO: Audio should uncomment this once the sounds have been set up + break; + + case "random_weapon": + if ( !level random_weapon_powerup( self, players[i] ) ) + { + continue; + } + // players[i] thread powerup_vo( "random_weapon" ); // TODO: Audio should uncomment this once the sounds have been set up + break; + + case "bonus_points_player": + level thread bonus_points_player_powerup( self, players[i] ); + players[i] thread powerup_vo( "bonus_points_solo" ); // TODO: Audio should uncomment this once the sounds have been set up + break; + + case "bonus_points_team": + level thread bonus_points_team_powerup( self ); + players[i] thread powerup_vo( "bonus_points_team" ); // TODO: Audio should uncomment this once the sounds have been set up + break; + + case "teller_withdrawl": + level thread teller_withdrawl(self ,players[i]); + //TODO - play some sound/vo stuff here? + break; + + default: + // RAVEN BEGIN bhackbarth: callback for level specific powerups + if ( IsDefined( level._zombiemode_powerup_grab ) ) + { + level thread [[ level._zombiemode_powerup_grab ]]( self, players[i] ); + } + // RAVEN END + else + { + } + + break; + + } + } + + maps\mp\_demo::bookmark( "zm_player_powerup_grabbed", gettime(), players[i] ); + + if( should_award_stat ( self.powerup_name )) //don't do this for things that aren't really a powerup + { + //track # of picked up powerups/drops for the player + players[i] maps\mp\zombies\_zm_stats::increment_client_stat( "drops" ); + players[i] maps\mp\zombies\_zm_stats::increment_client_stat( self.powerup_name + "_pickedup" ); + } + + if ( self.solo ) + { + playfx( level._effect["powerup_grabbed_solo"], self.origin ); + playfx( level._effect["powerup_grabbed_wave_solo"], self.origin ); + } + else if ( self.caution ) + { + playfx( level._effect["powerup_grabbed_caution"], self.origin ); + playfx( level._effect["powerup_grabbed_wave_caution"], self.origin ); + } + else + { + playfx( level._effect["powerup_grabbed"], self.origin ); + playfx( level._effect["powerup_grabbed_wave"], self.origin ); + } + + if ( is_true( self.stolen ) ) + { + level notify( "monkey_see_monkey_dont_achieved" ); + } + + // RAVEN BEGIN bhackbarth: since there is a wait here, flag the powerup as being taken + self.claimed = true; + self.power_up_grab_player = players[i]; //Player who grabbed the power up + // RAVEN END + + wait( 0.1 ); + + playsoundatposition("zmb_powerup_grabbed", self.origin); + self stoploopsound(); + self hide(); + + //Preventing the line from playing AGAIN if fire sale becomes active before it runs out + if( self.powerup_name != "fire_sale" ) + { + if( isdefined( self.power_up_grab_player ) ) + { + if(isDefined(level.powerup_intro_vox)) + { + level thread [[level.powerup_intro_vox]](self); + } + else + { + if(isDefined(level.powerup_vo_available) ) + { + can_say_vo = [[level.powerup_vo_available]](); + if(!can_say_vo) + { + self powerup_delete(); + self notify ("powerup_grabbed"); + return; + } + } + level thread maps\mp\zombies\_zm_audio_announcer::leaderDialog( self.powerup_name, self.power_up_grab_player.pers["team"] ); + self powerup_delete(); + self notify ("powerup_grabbed"); + } + } + } + } + } + wait 0.1; + } +} + +start_fire_sale( item ) +{ + if ( level.zombie_vars[ "zombie_powerup_fire_sale_time" ] > 0 && is_true( level.zombie_vars[ "zombie_powerup_fire_sale_on" ] ) ) + { + level.zombie_vars[ "zombie_powerup_fire_sale_time" ] += 30; + return; + } + level notify( "powerup fire sale" ); + level endon( "powerup fire sale" ); + level thread maps/mp/zombies/_zm_audio_announcer::leaderdialog( "fire_sale" ); + level.zombie_vars[ "zombie_powerup_fire_sale_on" ] = 1; + level thread toggle_fire_sale_on(); + level.zombie_vars[ "zombie_powerup_fire_sale_time" ] = 30; + while ( level.zombie_vars[ "zombie_powerup_fire_sale_time" ] > 0 ) + { + wait 0.05; + level.zombie_vars[ "zombie_powerup_fire_sale_time" ] -= 0.05; + } + level.zombie_vars[ "zombie_powerup_fire_sale_on" ] = 0; + level notify( "fire_sale_off" ); +} + +start_bonfire_sale( item ) +{ + level notify( "powerup bonfire sale" ); + level endon( "powerup bonfire sale" ); + temp_ent = spawn( "script_origin", ( 0, 0, 0 ) ); + temp_ent playloopsound( "zmb_double_point_loop" ); + level.zombie_vars[ "zombie_powerup_bonfire_sale_on" ] = 1; + level thread toggle_bonfire_sale_on(); + level.zombie_vars[ "zombie_powerup_bonfire_sale_time" ] = 30; + while ( level.zombie_vars[ "zombie_powerup_bonfire_sale_time" ] > 0 ) + { + wait 0.05; + level.zombie_vars[ "zombie_powerup_bonfire_sale_time" ] -= 0.05; + } + level.zombie_vars[ "zombie_powerup_bonfire_sale_on" ] = 0; + level notify( "bonfire_sale_off" ); + players = get_players(); + i = 0; + while ( i < players.size ) + { + players[ i ] playsound( "zmb_points_loop_off" ); + i++; + } + temp_ent delete(); +} + +start_carpenter( origin ) +{ + window_boards = getstructarray( "exterior_goal", "targetname" ); + total = level.exterior_goals.size; + carp_ent = spawn( "script_origin", ( 0, 0, 0 ) ); + carp_ent playloopsound( "evt_carpenter" ); + while ( 1 ) + { + windows = get_closest_window_repair( window_boards, origin ); + if ( !isDefined( windows ) ) + { + carp_ent stoploopsound( 1 ); + carp_ent playsoundwithnotify( "evt_carpenter_end", "sound_done" ); + carp_ent waittill( "sound_done" ); + break; + } + else arrayremovevalue( window_boards, windows ); + while ( 1 ) + { + if ( all_chunks_intact( windows, windows.barrier_chunks ) ) + { + break; + } + else chunk = get_random_destroyed_chunk( windows, windows.barrier_chunks ); + if ( !isDefined( chunk ) ) + { + break; + } + else + { + windows thread maps/mp/zombies/_zm_blockers::replace_chunk( windows, chunk, undefined, maps/mp/zombies/_zm_powerups::is_carpenter_boards_upgraded(), 1 ); + if ( isDefined( windows.clip ) ) + { + windows.clip enable_trigger(); + windows.clip disconnectpaths(); + } + else + { + blocker_disconnect_paths( windows.neg_start, windows.neg_end ); + } + wait_network_frame(); + wait 0.05; + } + } + wait_network_frame(); + } + players = get_players(); + i = 0; + while ( i < players.size ) + { + players[ i ] maps/mp/zombies/_zm_score::player_add_points( "carpenter_powerup", 200 ); + i++; + } + carp_ent delete(); +} + +get_closest_window_repair( windows, origin ) +{ + current_window = undefined; + shortest_distance = undefined; + i = 0; + while ( i < windows.size ) + { + if ( all_chunks_intact( windows, windows[ i ].barrier_chunks ) ) + { + i++; + continue; + } + else if ( !isDefined( current_window ) ) + { + current_window = windows[ i ]; + shortest_distance = distancesquared( current_window.origin, origin ); + i++; + continue; + } + else + { + if ( distancesquared( windows[ i ].origin, origin ) < shortest_distance ) + { + current_window = windows[ i ]; + shortest_distance = distancesquared( windows[ i ].origin, origin ); + } + } + i++; + } + return current_window; +} + +powerup_vo( type ) +{ + self endon( "death" ); + self endon( "disconnect" ); + if ( isDefined( level.powerup_vo_available ) ) + { + if ( !( [[ level.powerup_vo_available ]]() ) ) + { + return; + } + } + wait randomfloatrange( 2, 2.5 ); + if ( type == "tesla" ) + { + self maps/mp/zombies/_zm_audio::create_and_play_dialog( "weapon_pickup", type ); + } + else + { + self maps/mp/zombies/_zm_audio::create_and_play_dialog( "powerup", type ); + } + if ( isDefined( level.custom_powerup_vo_response ) ) + { + level [[ level.custom_powerup_vo_response ]]( self, type ); + } +} + +powerup_wobble_fx() +{ + self endon( "death" ); + if ( !isDefined( self ) ) + { + return; + } + if ( isDefined( level.powerup_fx_func ) ) + { + self thread [[ level.powerup_fx_func ]](); + return; + } + if ( self.solo ) + { + self setclientfield( "powerup_fx", 2 ); + } + else if ( self.caution ) + { + self setclientfield( "powerup_fx", 4 ); + } + else if ( self.zombie_grabbable ) + { + self setclientfield( "powerup_fx", 3 ); + } + else + { + self setclientfield( "powerup_fx", 1 ); + } +} + +powerup_wobble() +{ + self endon( "powerup_grabbed" ); + self endon( "powerup_timedout" ); + self thread powerup_wobble_fx(); + while ( isDefined( self ) ) + { + waittime = randomfloatrange( 2.5, 5 ); + yaw = randomint( 360 ); + if ( yaw > 300 ) + { + yaw = 300; + } + else + { + if ( yaw < 60 ) + { + yaw = 60; + } + } + yaw = self.angles[ 1 ] + yaw; + new_angles = ( -60 + randomint( 120 ), yaw, -45 + randomint( 90 ) ); + self rotateto( new_angles, waittime, waittime * 0.5, waittime * 0.5 ); + if ( isDefined( self.worldgundw ) ) + { + self.worldgundw rotateto( new_angles, waittime, waittime * 0.5, waittime * 0.5 ); + } + wait randomfloat( waittime - 0,1 ); + } +} + +powerup_timeout() +{ + if ( isDefined( level._powerup_timeout_override ) && !isDefined( self.powerup_team ) ) + { + self thread [[ level._powerup_timeout_override ]](); + return; + } + self endon( "powerup_grabbed" ); + self endon( "death" ); + self endon( "powerup_reset" ); + self show(); + wait_time = 15; + if ( isDefined( level._powerup_timeout_custom_time ) ) + { + time = [[ level._powerup_timeout_custom_time ]]( self ); + if ( time == 0 ) + { + return; + } + wait_time = time; + } + wait wait_time; + i = 0; + while ( i < 40 ) + { + if ( i % 2 ) + { + self ghost(); + if ( isDefined( self.worldgundw ) ) + { + self.worldgundw ghost(); + } + } + else + { + self show(); + if ( isDefined( self.worldgundw ) ) + { + self.worldgundw show(); + } + } + if ( i < 15 ) + { + wait 0.5; + i++; + continue; + } + else if ( i < 25 ) + { + wait 0.25; + i++; + continue; + } + else + { + wait 0.1; + } + i++; + } + self notify( "powerup_timedout" ); + self powerup_delete(); +} + +powerup_delete() +{ + arrayremovevalue( level.active_powerups, self, 0 ); + if ( isDefined( self.worldgundw ) ) + { + self.worldgundw delete(); + } + self delete(); +} + +powerup_delete_delayed( time ) +{ + if ( isDefined( time ) ) + { + wait time; + } + else + { + wait 0.01; + } + self powerup_delete(); +} + +nuke_powerup( drop_item, player_team ) +{ + location = drop_item.origin; + playfx( drop_item.fx, location ); + level thread nuke_flash( player_team ); + wait 0.5; + zombies = getaiarray( level.zombie_team ); + zombies = arraysort( zombies, location ); + zombies_nuked = []; + i = 0; + while ( i < zombies.size ) + { + if ( isDefined( zombies[ i ].ignore_nuke ) && zombies[ i ].ignore_nuke ) + { + i++; + continue; + } + else + { + if ( isDefined( zombies[ i ].marked_for_death ) && zombies[ i ].marked_for_death ) + { + i++; + continue; + } + else + { + if ( isDefined( zombies[ i ].nuke_damage_func ) ) + { + zombies[ i ] thread [[ zombies[ i ].nuke_damage_func ]](); + i++; + continue; + } + else if ( is_magic_bullet_shield_enabled( zombies[ i ] ) ) + { + i++; + continue; + } + else + { + zombies[ i ].marked_for_death = 1; + zombies[ i ].nuked = 1; + zombies_nuked[ zombies_nuked.size ] = zombies[ i ]; + } + } + } + i++; + } + i = 0; + while ( i < zombies_nuked.size ) + { + wait randomfloatrange( 0.1, 0.7 ); + if ( !isDefined( zombies_nuked[ i ] ) ) + { + i++; + continue; + } + else if ( is_magic_bullet_shield_enabled( zombies_nuked[ i ] ) ) + { + i++; + continue; + } + else + { + if ( i < 5 && !zombies_nuked[ i ].isdog ) + { + zombies_nuked[ i ] thread maps/mp/animscripts/zm_death::flame_death_fx(); + } + if ( !zombies_nuked[ i ].isdog ) + { + if ( isDefined( zombies_nuked[ i ].no_gib ) && !zombies_nuked[ i ].no_gib ) + { + zombies_nuked[ i ] maps/mp/zombies/_zm_spawner::zombie_head_gib(); + } + zombies_nuked[ i ] playsound( "evt_nuked" ); + } + zombies_nuked[ i ] dodamage( zombies_nuked[ i ].health + 666, zombies_nuked[ i ].origin ); + } + i++; + } + players = get_players( player_team ); + i = 0; + while ( i < players.size ) + { + players[ i ] maps/mp/zombies/_zm_score::player_add_points( "nuke_powerup", 400 ); + i++; + } +} + +nuke_flash( team ) +{ + if ( isDefined( team ) ) + { + get_players()[ 0 ] playsoundtoteam( "evt_nuke_flash", team ); + } + else + { + get_players()[ 0 ] playsound( "evt_nuke_flash" ); + } + fadetowhite = newhudelem(); + fadetowhite.x = 0; + fadetowhite.y = 0; + fadetowhite.alpha = 0; + fadetowhite.horzalign = "fullscreen"; + fadetowhite.vertalign = "fullscreen"; + fadetowhite.foreground = 1; + fadetowhite setshader( "white", 640, 480 ); + fadetowhite fadeovertime( 0,2 ); + fadetowhite.alpha = 0.8; + wait 0.5; + fadetowhite fadeovertime( 1 ); + fadetowhite.alpha = 0; + wait 1.1; + fadetowhite destroy(); +} + +double_points_powerup( drop_item, player ) +{ + level notify( "powerup points scaled_" + player.team ); + level endon( "powerup points scaled_" + player.team ); + team = player.team; + level thread point_doubler_on_hud( drop_item, team ); + if ( isDefined( level.pers_upgrade_double_points ) && level.pers_upgrade_double_points ) + { + player thread maps/mp/zombies/_zm_pers_upgrades_functions::pers_upgrade_double_points_pickup_start(); + } + if ( isDefined( level.current_game_module ) && level.current_game_module == 2 ) + { + if ( isDefined( player._race_team ) ) + { + if ( player._race_team == 1 ) + { + level._race_team_double_points = 1; + } + else + { + level._race_team_double_points = 2; + } + } + } + level.zombie_vars[ team ][ "zombie_point_scalar" ] = 2; + players = get_players(); + player_index = 0; + while ( player_index < players.size ) + { + if ( team == players[ player_index ].team ) + { + players[ player_index ] setclientfield( "score_cf_double_points_active", 1 ); + } + player_index++; + } + wait 30; + level.zombie_vars[ team ][ "zombie_point_scalar" ] = 1; + level._race_team_double_points = undefined; + players = get_players(); + player_index = 0; + while ( player_index < players.size ) + { + if ( team == players[ player_index ].team ) + { + players[ player_index ] setclientfield( "score_cf_double_points_active", 0 ); + } + player_index++; + } +} + +full_ammo_powerup( drop_item, player ) +{ + players = get_players( player.team ); + if ( isDefined( level._get_game_module_players ) ) + { + players = [[ level._get_game_module_players ]]( player ); + } + i = 0; + while ( i < players.size ) + { + if ( players[ i ] maps/mp/zombies/_zm_laststand::player_is_in_laststand() ) + { + i++; + continue; + } + else + { + primary_weapons = players[ i ] getweaponslist( 1 ); + players[ i ] notify( "zmb_max_ammo" ); + players[ i ] notify( "zmb_lost_knife" ); + players[ i ] notify( "zmb_disable_claymore_prompt" ); + players[ i ] notify( "zmb_disable_spikemore_prompt" ); + x = 0; + while ( x < primary_weapons.size ) + { + if ( level.headshots_only && is_lethal_grenade( primary_weapons[ x ] ) ) + { + x++; + continue; + } + else + { + if ( isDefined( level.zombie_include_equipment ) && isDefined( level.zombie_include_equipment[ primary_weapons[ x ] ] ) ) + { + x++; + continue; + } + else + { + if ( isDefined( level.zombie_weapons_no_max_ammo ) && isDefined( level.zombie_weapons_no_max_ammo[ primary_weapons[ x ] ] ) ) + { + x++; + continue; + } + else + { + if ( players[ i ] hasweapon( primary_weapons[ x ] ) ) + { + players[ i ] givemaxammo( primary_weapons[ x ] ); + } + } + } + } + x++; + } + } + i++; + } + level thread full_ammo_on_hud( drop_item, player.team ); +} + +insta_kill_powerup( drop_item, player ) +{ + level notify( "powerup instakill_" + player.team ); + level endon( "powerup instakill_" + player.team ); + if ( isDefined( level.insta_kill_powerup_override ) ) + { + level thread [[ level.insta_kill_powerup_override ]]( drop_item, player ); + return; + } + if ( is_classic() ) + { + player thread maps/mp/zombies/_zm_pers_upgrades_functions::pers_upgrade_insta_kill_upgrade_check(); + } + team = player.team; + level thread insta_kill_on_hud( drop_item, team ); + level.zombie_vars[ team ][ "zombie_insta_kill" ] = 1; + wait 30; + level.zombie_vars[ team ][ "zombie_insta_kill" ] = 0; + players = get_players( team ); + i = 0; + while ( i < players.size ) + { + if ( isDefined( players[ i ] ) ) + { + players[ i ] notify( "insta_kill_over" ); + } + i++; + } +} + +is_insta_kill_active() +{ + return level.zombie_vars[ self.team ][ "zombie_insta_kill" ]; +} + +check_for_instakill( player, mod, hit_location ) +{ + if ( isDefined( player ) && isalive( player ) && isDefined( level.check_for_instakill_override ) ) + { + if ( !( self [[ level.check_for_instakill_override ]]( player ) ) ) + { + return; + } + if ( player.use_weapon_type == "MOD_MELEE" ) + { + player.last_kill_method = "MOD_MELEE"; + } + else + { + player.last_kill_method = "MOD_UNKNOWN"; + } + modname = remove_mod_from_methodofdeath( mod ); + if ( isDefined( self.no_gib ) && !self.no_gib ) + { + self maps/mp/zombies/_zm_spawner::zombie_head_gib(); + } + self.health = 1; + self dodamage( self.health + 666, self.origin, player, self, hit_location, modname ); + player notify( "zombie_killed" ); + } + if ( isDefined( player ) && isalive( player ) || level.zombie_vars[ player.team ][ "zombie_insta_kill" ] && isDefined( player.personal_instakill ) && player.personal_instakill ) + { + if ( is_magic_bullet_shield_enabled( self ) ) + { + return; + } + if ( isDefined( self.instakill_func ) ) + { + self thread [[ self.instakill_func ]](); + return; + } + if ( player.use_weapon_type == "MOD_MELEE" ) + { + player.last_kill_method = "MOD_MELEE"; + } + else + { + player.last_kill_method = "MOD_UNKNOWN"; + } + modname = remove_mod_from_methodofdeath( mod ); + if ( flag( "dog_round" ) ) + { + self.health = 1; + self dodamage( self.health + 666, self.origin, player, self, hit_location, modname ); + player notify( "zombie_killed" ); + return; + } + else + { + if ( isDefined( self.no_gib ) && !self.no_gib ) + { + self maps/mp/zombies/_zm_spawner::zombie_head_gib(); + } + self.health = 1; + self dodamage( self.health + 666, self.origin, player, self, hit_location, modname ); + player notify( "zombie_killed" ); + } + } +} + +insta_kill_on_hud( drop_item, player_team ) +{ + if ( level.zombie_vars[ player_team ][ "zombie_powerup_insta_kill_on" ] ) + { + level.zombie_vars[ player_team ][ "zombie_powerup_insta_kill_time" ] = 30; + return; + } + level.zombie_vars[ player_team ][ "zombie_powerup_insta_kill_on" ] = 1; + level thread time_remaning_on_insta_kill_powerup( player_team ); +} + +time_remaning_on_insta_kill_powerup( player_team ) +{ + temp_enta = spawn( "script_origin", ( 0, 0, 0 ) ); + temp_enta playloopsound( "zmb_insta_kill_loop" ); + while ( level.zombie_vars[ player_team ][ "zombie_powerup_insta_kill_time" ] >= 0 ) + { + wait 0.05; + level.zombie_vars[ player_team ][ "zombie_powerup_insta_kill_time" ] -= 0.05; + } + get_players()[ 0 ] playsoundtoteam( "zmb_insta_kill", player_team ); + temp_enta stoploopsound( 2 ); + level.zombie_vars[ player_team ][ "zombie_powerup_insta_kill_on" ] = 0; + level.zombie_vars[ player_team ][ "zombie_powerup_insta_kill_time" ] = 30; + temp_enta delete(); +} + +point_doubler_on_hud( drop_item, player_team ) +{ + self endon( "disconnect" ); + if ( level.zombie_vars[ player_team ][ "zombie_powerup_point_doubler_on" ] ) + { + level.zombie_vars[ player_team ][ "zombie_powerup_point_doubler_time" ] = 30; + return; + } + level.zombie_vars[ player_team ][ "zombie_powerup_point_doubler_on" ] = 1; + level thread time_remaining_on_point_doubler_powerup( player_team ); +} + +time_remaining_on_point_doubler_powerup( player_team ) +{ + temp_ent = spawn( "script_origin", ( 0, 0, 0 ) ); + temp_ent playloopsound( "zmb_double_point_loop" ); + while ( level.zombie_vars[ player_team ][ "zombie_powerup_point_doubler_time" ] >= 0 ) + { + wait 0.05; + level.zombie_vars[ player_team ][ "zombie_powerup_point_doubler_time" ] -= 0.05; + } + level.zombie_vars[ player_team ][ "zombie_powerup_point_doubler_on" ] = 0; + players = get_players( player_team ); + i = 0; + while ( i < players.size ) + { + players[ i ] playsound( "zmb_points_loop_off" ); + i++; + } + temp_ent stoploopsound( 2 ); + level.zombie_vars[ player_team ][ "zombie_powerup_point_doubler_time" ] = 30; + temp_ent delete(); +} + +toggle_bonfire_sale_on() +{ + level endon( "powerup bonfire sale" ); + if ( !isDefined( level.zombie_vars[ "zombie_powerup_bonfire_sale_on" ] ) ) + { + return; + } + if ( level.zombie_vars[ "zombie_powerup_bonfire_sale_on" ] ) + { + if ( isDefined( level.bonfire_init_func ) ) + { + level thread [[ level.bonfire_init_func ]](); + } + level waittill( "bonfire_sale_off" ); + } +} + +toggle_fire_sale_on() +{ + level endon( "powerup fire sale" ); + if ( !isDefined( level.zombie_vars[ "zombie_powerup_fire_sale_on" ] ) ) + { + return; + } + while ( level.zombie_vars[ "zombie_powerup_fire_sale_on" ] ) + { + i = 0; + while ( i < level.chests.size ) + { + show_firesale_box = level.chests[ i ] [[ level._zombiemode_check_firesale_loc_valid_func ]](); + if ( show_firesale_box ) + { + level.chests[ i ].zombie_cost = 10; + if ( level.chest_index != i ) + { + level.chests[ i ].was_temp = 1; + if ( is_true( level.chests[ i ].hidden ) ) + { + level.chests[ i ] thread maps/mp/zombies/_zm_magicbox::show_chest(); + } + wait_network_frame(); + } + } + i++; + } + level waittill( "fire_sale_off" ); + waittillframeend; + i = 0; + while ( i < level.chests.size ) + { + show_firesale_box = level.chests[ i ] [[ level._zombiemode_check_firesale_loc_valid_func ]](); + if ( show_firesale_box ) + { + if ( level.chest_index != i && isDefined( level.chests[ i ].was_temp ) ) + { + level.chests[ i ].was_temp = undefined; + level thread remove_temp_chest( i ); + } + level.chests[ i ].zombie_cost = level.chests[ i ].old_cost; + } + i++; + } + } +} + +fire_sale_weapon_wait() +{ + self.zombie_cost = self.old_cost; + while ( isDefined( self.chest_user ) ) + { + wait_network_frame(); + } + self set_hint_string( self, "default_treasure_chest", self.zombie_cost ); +} + +remove_temp_chest( chest_index ) +{ + while ( isDefined( level.chests[ chest_index ].chest_user ) || isDefined( level.chests[ chest_index ]._box_open ) && level.chests[ chest_index ]._box_open == 1 ) + { + wait_network_frame(); + } + if ( level.zombie_vars[ "zombie_powerup_fire_sale_on" ] ) + { + level.chests[ chest_index ].was_temp = 1; + level.chests[ chest_index ].zombie_cost = 10; + return; + } + i = 0; + while ( i < chest_index ) + { + wait_network_frame(); + i++; + } + playfx( level._effect[ "poltergeist" ], level.chests[ chest_index ].orig_origin ); + level.chests[ chest_index ].zbarrier playsound( "zmb_box_poof_land" ); + level.chests[ chest_index ].zbarrier playsound( "zmb_couch_slam" ); + wait_network_frame(); + level.chests[ chest_index ] maps/mp/zombies/_zm_magicbox::hide_chest(); +} + +devil_dialog_delay() +{ + wait 1; +} + +full_ammo_on_hud( drop_item, player_team ) +{ + self endon( "disconnect" ); + hudelem = maps/mp/gametypes_zm/_hud_util::createserverfontstring( "objective", 2, player_team ); + hudelem maps/mp/gametypes_zm/_hud_util::setpoint( "TOP", undefined, 0, level.zombie_vars[ "zombie_timer_offset" ] - ( level.zombie_vars[ "zombie_timer_offset_interval" ] * 2 ) ); + hudelem.sort = 0.5; + hudelem.alpha = 0; + hudelem fadeovertime( 0.5 ); + hudelem.alpha = 1; + if ( isDefined( drop_item ) ) + { + hudelem.label = drop_item.hint; + } + hudelem thread full_ammo_move_hud( player_team ); +} + +full_ammo_move_hud( player_team ) +{ + players = get_players( player_team ); + players[ 0 ] playsoundtoteam( "zmb_full_ammo", player_team ); + wait 0.5; + move_fade_time = 1.5; + self fadeovertime( move_fade_time ); + self moveovertime( move_fade_time ); + self.y = 270; + self.alpha = 0; + wait move_fade_time; + self destroy(); +} + +check_for_rare_drop_override( pos ) +{ + if ( isDefined( flag( "ape_round" ) ) && flag( "ape_round" ) ) + { + return 0; + } + return 0; +} + +setup_firesale_audio() +{ + wait 2; + intercom = getentarray( "intercom", "targetname" ); + while ( 1 ) + { + while ( level.zombie_vars[ "zombie_powerup_fire_sale_on" ] == 0 ) + { + wait 0.2; + } + i = 0; + while ( i < intercom.size ) + { + intercom[ i ] thread play_firesale_audio(); + i++; + } + while ( level.zombie_vars[ "zombie_powerup_fire_sale_on" ] == 1 ) + { + wait 0.1; + } + level notify( "firesale_over" ); + } +} + +play_firesale_audio() +{ + if ( isDefined( level.sndfiresalemusoff ) && level.sndfiresalemusoff ) + { + return; + } + if ( isDefined( level.sndannouncerisrich ) && level.sndannouncerisrich ) + { + self playloopsound( "mus_fire_sale_rich" ); + } + else + { + self playloopsound( "mus_fire_sale" ); + } + level waittill( "firesale_over" ); + self stoploopsound(); +} + +setup_bonfiresale_audio() +{ + wait 2; + intercom = getentarray( "intercom", "targetname" ); + while ( 1 ) + { + while ( level.zombie_vars[ "zombie_powerup_fire_sale_on" ] == 0 ) + { + wait 0.2; + } + i = 0; + while ( i < intercom.size ) + { + intercom[ i ] thread play_bonfiresale_audio(); + i++; + } + while ( level.zombie_vars[ "zombie_powerup_fire_sale_on" ] == 1 ) + { + wait 0.1; + } + level notify( "firesale_over" ); + } +} + +play_bonfiresale_audio() +{ + if ( isDefined( level.sndfiresalemusoff ) && level.sndfiresalemusoff ) + { + return; + } + if ( isDefined( level.sndannouncerisrich ) && level.sndannouncerisrich ) + { + self playloopsound( "mus_fire_sale_rich" ); + } + else + { + self playloopsound( "mus_fire_sale" ); + } + level waittill( "firesale_over" ); + self stoploopsound(); +} + +free_perk_powerup( item ) +{ + players = get_players(); + i = 0; + while ( i < players.size ) + { + if ( !players[ i ] maps/mp/zombies/_zm_laststand::player_is_in_laststand() && players[ i ].sessionstate != "spectator" ) + { + player = players[ i ]; + if ( isDefined( item.ghost_powerup ) ) + { + player maps/mp/zombies/_zm_stats::increment_client_stat( "buried_ghost_perk_acquired", 0 ); + player maps/mp/zombies/_zm_stats::increment_player_stat( "buried_ghost_perk_acquired" ); + player notify( "player_received_ghost_round_free_perk" ); + } + free_perk = player maps/mp/zombies/_zm_perks::give_random_perk(); + if ( isDefined( level.disable_free_perks_before_power ) && level.disable_free_perks_before_power ) + { + player thread disable_perk_before_power( free_perk ); + } + } + i++; + } +} + +disable_perk_before_power( perk ) +{ + self endon( "disconnect" ); + if ( isDefined( perk ) ) + { + wait 0.1; + if ( !flag( "power_on" ) ) + { + a_players = get_players(); + if ( isDefined( a_players ) && a_players.size == 1 && perk == "specialty_quickrevive" ) + { + return; + } + self perk_pause( perk ); + flag_wait( "power_on" ); + self perk_unpause( perk ); + } + } +} + +random_weapon_powerup_throttle() +{ + self.random_weapon_powerup_throttle = 1; + wait 0.25; + self.random_weapon_powerup_throttle = 0; +} + +random_weapon_powerup( item, player ) +{ + if ( player.sessionstate == "spectator" || player maps/mp/zombies/_zm_laststand::player_is_in_laststand() ) + { + return 0; + } + if ( isDefined( player.random_weapon_powerup_throttle ) && !player.random_weapon_powerup_throttle || player isswitchingweapons() && player.is_drinking > 0 ) + { + return 0; + } + current_weapon = player getcurrentweapon(); + current_weapon_type = weaponinventorytype( current_weapon ); + if ( !is_tactical_grenade( item.weapon ) ) + { + if ( current_weapon_type != "primary" && current_weapon_type != "altmode" ) + { + return 0; + } + if ( !isDefined( level.zombie_weapons[ current_weapon ] ) && !maps/mp/zombies/_zm_weapons::is_weapon_upgraded( current_weapon ) && current_weapon_type != "altmode" ) + { + return 0; + } + } + player thread random_weapon_powerup_throttle(); + weapon_string = item.weapon; + if ( weapon_string == "knife_ballistic_zm" ) + { + weapon = player maps/mp/zombies/_zm_melee_weapon::give_ballistic_knife( weapon_string, 0 ); + } + else + { + if ( weapon_string == "knife_ballistic_upgraded_zm" ) + { + weapon = player maps/mp/zombies/_zm_melee_weapon::give_ballistic_knife( weapon_string, 1 ); + } + } + player thread maps/mp/zombies/_zm_weapons::weapon_give( weapon_string ); + return 1; +} + +bonus_points_player_powerup( item, player ) +{ + points = randomintrange( 1, 25 ) * 100; + if ( isDefined( level.bonus_points_powerup_override ) ) + { + points = [[ level.bonus_points_powerup_override ]](); + } + if ( !player maps/mp/zombies/_zm_laststand::player_is_in_laststand() && player.sessionstate != "spectator" ) + { + player maps/mp/zombies/_zm_score::player_add_points( "bonus_points_powerup", points ); + } +} + +bonus_points_team_powerup( item ) +{ + points = randomintrange( 1, 25 ) * 100; + if ( isDefined( level.bonus_points_powerup_override ) ) + { + points = [[ level.bonus_points_powerup_override ]](); + } + players = get_players(); + i = 0; + while ( i < players.size ) + { + if ( !players[ i ] maps/mp/zombies/_zm_laststand::player_is_in_laststand() && players[ i ].sessionstate != "spectator" ) + { + players[ i ] maps/mp/zombies/_zm_score::player_add_points( "bonus_points_powerup", points ); + } + i++; + } +} + +lose_points_team_powerup( item ) +{ + points = randomintrange( 1, 25 ) * 100; + players = get_players(); + i = 0; + while ( i < players.size ) + { + if ( !players[ i ] maps/mp/zombies/_zm_laststand::player_is_in_laststand() && players[ i ].sessionstate != "spectator" ) + { + if ( ( players[ i ].score - points ) <= 0 ) + { + players[ i ] maps/mp/zombies/_zm_score::minus_to_player_score( players[ i ].score ); + i++; + continue; + } + else + { + players[ i ] maps/mp/zombies/_zm_score::minus_to_player_score( points ); + } + } + i++; + } +} + +lose_perk_powerup( item ) +{ + players = get_players(); + i = 0; + while ( i < players.size ) + { + player = players[ i ]; + if ( !player maps/mp/zombies/_zm_laststand::player_is_in_laststand() && player.sessionstate != "spectator" ) + { + player maps/mp/zombies/_zm_perks::lose_random_perk(); + } + i++; + } +} + +empty_clip_powerup( item ) +{ + players = get_players(); + i = 0; + while ( i < players.size ) + { + player = players[ i ]; + if ( !player maps/mp/zombies/_zm_laststand::player_is_in_laststand() && player.sessionstate != "spectator" ) + { + weapon = player getcurrentweapon(); + player setweaponammoclip( weapon, 0 ); + } + i++; + } +} + +minigun_weapon_powerup( ent_player, time ) +{ + ent_player endon( "disconnect" ); + ent_player endon( "death" ); + ent_player endon( "player_downed" ); + if ( !isDefined( time ) ) + { + time = 30; + } + if ( isDefined( level._minigun_time_override ) ) + { + time = level._minigun_time_override; + } + if ( ent_player.zombie_vars[ "zombie_powerup_minigun_on" ] || ent_player getcurrentweapon() == "minigun_zm" && isDefined( ent_player.has_minigun ) && ent_player.has_minigun ) + { + if ( ent_player.zombie_vars[ "zombie_powerup_minigun_time" ] < time ) + { + ent_player.zombie_vars[ "zombie_powerup_minigun_time" ] = time; + } + return; + } + ent_player notify( "replace_weapon_powerup" ); + ent_player._show_solo_hud = 1; + level._zombie_minigun_powerup_last_stand_func = ::minigun_watch_gunner_downed; + ent_player.has_minigun = 1; + ent_player.has_powerup_weapon = 1; + ent_player increment_is_drinking(); + ent_player._zombie_gun_before_minigun = ent_player getcurrentweapon(); + ent_player giveweapon( "minigun_zm" ); + ent_player switchtoweapon( "minigun_zm" ); + ent_player.zombie_vars[ "zombie_powerup_minigun_on" ] = 1; + level thread minigun_weapon_powerup_countdown( ent_player, "minigun_time_over", time ); + level thread minigun_weapon_powerup_replace( ent_player, "minigun_time_over" ); +} + +minigun_weapon_powerup_countdown( ent_player, str_gun_return_notify, time ) +{ + ent_player endon( "death" ); + ent_player endon( "disconnect" ); + ent_player endon( "player_downed" ); + ent_player endon( str_gun_return_notify ); + ent_player endon( "replace_weapon_powerup" ); + setclientsysstate( "levelNotify", "minis", ent_player ); + ent_player.zombie_vars[ "zombie_powerup_minigun_time" ] = time; + while ( ent_player.zombie_vars[ "zombie_powerup_minigun_time" ] > 0 ) + { + wait 0.05; + ent_player.zombie_vars[ "zombie_powerup_minigun_time" ] -= 0.05; + } + setclientsysstate( "levelNotify", "minie", ent_player ); + level thread minigun_weapon_powerup_remove( ent_player, str_gun_return_notify ); +} + +minigun_weapon_powerup_replace( ent_player, str_gun_return_notify ) +{ + ent_player endon( "death" ); + ent_player endon( "disconnect" ); + ent_player endon( "player_downed" ); + ent_player endon( str_gun_return_notify ); + ent_player waittill( "replace_weapon_powerup" ); + ent_player takeweapon( "minigun_zm" ); + ent_player.zombie_vars[ "zombie_powerup_minigun_on" ] = 0; + ent_player.has_minigun = 0; + ent_player decrement_is_drinking(); +} + +minigun_weapon_powerup_remove( ent_player, str_gun_return_notify ) +{ + ent_player endon( "death" ); + ent_player endon( "player_downed" ); + ent_player takeweapon( "minigun_zm" ); + ent_player.zombie_vars[ "zombie_powerup_minigun_on" ] = 0; + ent_player._show_solo_hud = 0; + ent_player.has_minigun = 0; + ent_player.has_powerup_weapon = 0; + ent_player notify( str_gun_return_notify ); + ent_player decrement_is_drinking(); + while ( isDefined( ent_player._zombie_gun_before_minigun ) ) + { + player_weapons = ent_player getweaponslistprimaries(); + i = 0; + while ( i < player_weapons.size ) + { + if ( player_weapons[ i ] == ent_player._zombie_gun_before_minigun ) + { + ent_player switchtoweapon( ent_player._zombie_gun_before_minigun ); + return; + } + i++; + } + } + primaryweapons = ent_player getweaponslistprimaries(); + if ( primaryweapons.size > 0 ) + { + ent_player switchtoweapon( primaryweapons[ 0 ] ); + } + else + { + allweapons = ent_player getweaponslist( 1 ); + i = 0; + while ( i < allweapons.size ) + { + if ( is_melee_weapon( allweapons[ i ] ) ) + { + ent_player switchtoweapon( allweapons[ i ] ); + return; + } + i++; + } + } +} + +minigun_weapon_powerup_off() +{ + self.zombie_vars[ "zombie_powerup_minigun_time" ] = 0; +} + +minigun_watch_gunner_downed() +{ + if ( isDefined( self.has_minigun ) && !self.has_minigun ) + { + return; + } + primaryweapons = self getweaponslistprimaries(); + i = 0; + while ( i < primaryweapons.size ) + { + if ( primaryweapons[ i ] == "minigun_zm" ) + { + self takeweapon( "minigun_zm" ); + } + i++; + } + self notify( "minigun_time_over" ); + self.zombie_vars[ "zombie_powerup_minigun_on" ] = 0; + self._show_solo_hud = 0; + wait 0.05; + self.has_minigun = 0; + self.has_powerup_weapon = 0; +} + +tesla_weapon_powerup( ent_player, time ) +{ + ent_player endon( "disconnect" ); + ent_player endon( "death" ); + ent_player endon( "player_downed" ); + if ( !isDefined( time ) ) + { + time = 11; + } + if ( ent_player.zombie_vars[ "zombie_powerup_tesla_on" ] || ent_player getcurrentweapon() == "tesla_gun_zm" && isDefined( ent_player.has_tesla ) && ent_player.has_tesla ) + { + ent_player givemaxammo( "tesla_gun_zm" ); + if ( ent_player.zombie_vars[ "zombie_powerup_tesla_time" ] < time ) + { + ent_player.zombie_vars[ "zombie_powerup_tesla_time" ] = time; + } + return; + } + ent_player notify( "replace_weapon_powerup" ); + ent_player._show_solo_hud = 1; + level._zombie_tesla_powerup_last_stand_func = ::tesla_watch_gunner_downed; + ent_player.has_tesla = 1; + ent_player.has_powerup_weapon = 1; + ent_player increment_is_drinking(); + ent_player._zombie_gun_before_tesla = ent_player getcurrentweapon(); + ent_player giveweapon( "tesla_gun_zm" ); + ent_player givemaxammo( "tesla_gun_zm" ); + ent_player switchtoweapon( "tesla_gun_zm" ); + ent_player.zombie_vars[ "zombie_powerup_tesla_on" ] = 1; + level thread tesla_weapon_powerup_countdown( ent_player, "tesla_time_over", time ); + level thread tesla_weapon_powerup_replace( ent_player, "tesla_time_over" ); +} + +tesla_weapon_powerup_countdown( ent_player, str_gun_return_notify, time ) +{ + ent_player endon( "death" ); + ent_player endon( "player_downed" ); + ent_player endon( str_gun_return_notify ); + ent_player endon( "replace_weapon_powerup" ); + setclientsysstate( "levelNotify", "minis", ent_player ); + ent_player.zombie_vars[ "zombie_powerup_tesla_time" ] = time; + while ( 1 ) + { + ent_player waittill_any( "weapon_fired", "reload", "zmb_max_ammo" ); + if ( !ent_player getweaponammostock( "tesla_gun_zm" ) ) + { + clip_count = ent_player getweaponammoclip( "tesla_gun_zm" ); + if ( !clip_count ) + { + break; + } + else if ( clip_count == 1 ) + { + ent_player.zombie_vars[ "zombie_powerup_tesla_time" ] = 1; + } + else + { + if ( clip_count == 3 ) + { + ent_player.zombie_vars[ "zombie_powerup_tesla_time" ] = 6; + } + } + continue; + } + else + { + ent_player.zombie_vars[ "zombie_powerup_tesla_time" ] = 11; + } + } + setclientsysstate( "levelNotify", "minie", ent_player ); + level thread tesla_weapon_powerup_remove( ent_player, str_gun_return_notify ); +} + +tesla_weapon_powerup_replace( ent_player, str_gun_return_notify ) +{ + ent_player endon( "death" ); + ent_player endon( "disconnect" ); + ent_player endon( "player_downed" ); + ent_player endon( str_gun_return_notify ); + ent_player waittill( "replace_weapon_powerup" ); + ent_player takeweapon( "tesla_gun_zm" ); + ent_player.zombie_vars[ "zombie_powerup_tesla_on" ] = 0; + ent_player.has_tesla = 0; + ent_player decrement_is_drinking(); +} + +tesla_weapon_powerup_remove( ent_player, str_gun_return_notify ) +{ + ent_player endon( "death" ); + ent_player endon( "player_downed" ); + ent_player takeweapon( "tesla_gun_zm" ); + ent_player.zombie_vars[ "zombie_powerup_tesla_on" ] = 0; + ent_player._show_solo_hud = 0; + ent_player.has_tesla = 0; + ent_player.has_powerup_weapon = 0; + ent_player notify( str_gun_return_notify ); + ent_player decrement_is_drinking(); + while ( isDefined( ent_player._zombie_gun_before_tesla ) ) + { + player_weapons = ent_player getweaponslistprimaries(); + i = 0; + while ( i < player_weapons.size ) + { + if ( player_weapons[ i ] == ent_player._zombie_gun_before_tesla ) + { + ent_player switchtoweapon( ent_player._zombie_gun_before_tesla ); + return; + } + i++; + } + } + primaryweapons = ent_player getweaponslistprimaries(); + if ( primaryweapons.size > 0 ) + { + ent_player switchtoweapon( primaryweapons[ 0 ] ); + } + else + { + allweapons = ent_player getweaponslist( 1 ); + i = 0; + while ( i < allweapons.size ) + { + if ( is_melee_weapon( allweapons[ i ] ) ) + { + ent_player switchtoweapon( allweapons[ i ] ); + return; + } + i++; + } + } +} + +tesla_weapon_powerup_off() +{ + self.zombie_vars[ "zombie_powerup_tesla_time" ] = 0; +} + +tesla_watch_gunner_downed() +{ + if ( isDefined( self.has_tesla ) && !self.has_tesla ) + { + return; + } + primaryweapons = self getweaponslistprimaries(); + i = 0; + while ( i < primaryweapons.size ) + { + if ( primaryweapons[ i ] == "tesla_gun_zm" ) + { + self takeweapon( "tesla_gun_zm" ); + } + i++; + } + self notify( "tesla_time_over" ); + self.zombie_vars[ "zombie_powerup_tesla_on" ] = 0; + self._show_solo_hud = 0; + wait 0.05; + self.has_tesla = 0; + self.has_powerup_weapon = 0; +} + +tesla_powerup_active() +{ + players = get_players(); + i = 0; + while ( i < players.size ) + { + if ( players[ i ].zombie_vars[ "zombie_powerup_tesla_on" ] ) + { + return 1; + } + i++; + } + return 0; +} + +print_powerup_drop( powerup, type ) +{ +} + +register_carpenter_node( node, callback ) +{ + if ( !isDefined( level._additional_carpenter_nodes ) ) + { + level._additional_carpenter_nodes = []; + } + node._post_carpenter_callback = callback; + level._additional_carpenter_nodes[ level._additional_carpenter_nodes.size ] = node; +} + +start_carpenter_new( origin ) +{ + level.carpenter_powerup_active = 1; + window_boards = getstructarray( "exterior_goal", "targetname" ); + if ( isDefined( level._additional_carpenter_nodes ) ) + { + window_boards = arraycombine( window_boards, level._additional_carpenter_nodes, 0, 0 ); + } + carp_ent = spawn( "script_origin", ( 0, 0, 0 ) ); + carp_ent playloopsound( "evt_carpenter" ); + boards_near_players = get_near_boards( window_boards ); + boards_far_from_players = get_far_boards( window_boards ); + level repair_far_boards( boards_far_from_players, maps/mp/zombies/_zm_powerups::is_carpenter_boards_upgraded() ); + i = 0; + while ( i < boards_near_players.size ) + { + window = boards_near_players[ i ]; + num_chunks_checked = 0; + last_repaired_chunk = undefined; + while ( 1 ) + { + if ( all_chunks_intact( window, window.barrier_chunks ) ) + { + break; + } + else chunk = get_random_destroyed_chunk( window, window.barrier_chunks ); + if ( !isDefined( chunk ) ) + { + break; + } + else window thread maps/mp/zombies/_zm_blockers::replace_chunk( window, chunk, undefined, maps/mp/zombies/_zm_powerups::is_carpenter_boards_upgraded(), 1 ); + last_repaired_chunk = chunk; + if ( isDefined( window.clip ) ) + { + window.clip enable_trigger(); + window.clip disconnectpaths(); + } + else + { + blocker_disconnect_paths( window.neg_start, window.neg_end ); + } + wait_network_frame(); + num_chunks_checked++; + if ( num_chunks_checked >= 20 ) + { + break; + } + else + { + } + } + if ( isDefined( window.zbarrier ) ) + { + if ( isDefined( last_repaired_chunk ) ) + { + while ( window.zbarrier getzbarrierpiecestate( last_repaired_chunk ) == "closing" ) + { + wait 0.05; + } + if ( isDefined( window._post_carpenter_callback ) ) + { + window [[ window._post_carpenter_callback ]](); + } + } + i++; + continue; + } + else while ( isDefined( last_repaired_chunk ) && last_repaired_chunk.state == "mid_repair" ) + { + wait 0.05; + } + i++; + } + carp_ent stoploopsound( 1 ); + carp_ent playsoundwithnotify( "evt_carpenter_end", "sound_done" ); + carp_ent waittill( "sound_done" ); + players = get_players(); + i = 0; + while ( i < players.size ) + { + players[ i ] maps/mp/zombies/_zm_score::player_add_points( "carpenter_powerup", 200 ); + i++; + } + carp_ent delete(); + level notify( "carpenter_finished" ); + level.carpenter_powerup_active = undefined; +} + +is_carpenter_boards_upgraded() +{ + if ( isDefined( level.pers_carpenter_boards_active ) && level.pers_carpenter_boards_active == 1 ) + { + return 1; + } + return 0; +} + +get_near_boards( windows ) +{ + players = get_players(); + boards_near_players = []; + j = 0; + while ( j < windows.size ) + { + close = 0; + i = 0; + while ( i < players.size ) + { + origin = undefined; + if ( isDefined( windows[ j ].zbarrier ) ) + { + origin = windows[ j ].zbarrier.origin; + } + else + { + origin = windows[ j ].origin; + } + if ( distancesquared( players[ i ].origin, origin ) <= level.board_repair_distance_squared ) + { + close = 1; + break; + } + else + { + i++; + } + } + if ( close ) + { + boards_near_players[ boards_near_players.size ] = windows[ j ]; + } + j++; + } + return boards_near_players; +} + +get_far_boards( windows ) +{ + players = get_players(); + boards_far_from_players = []; + j = 0; + while ( j < windows.size ) + { + close = 0; + i = 0; + while ( i < players.size ) + { + origin = undefined; + if ( isDefined( windows[ j ].zbarrier ) ) + { + origin = windows[ j ].zbarrier.origin; + } + else + { + origin = windows[ j ].origin; + } + if ( distancesquared( players[ i ].origin, origin ) >= level.board_repair_distance_squared ) + { + close = 1; + break; + } + else + { + i++; + } + } + if ( close ) + { + boards_far_from_players[ boards_far_from_players.size ] = windows[ j ]; + } + j++; + } + return boards_far_from_players; +} + +repair_far_boards( barriers, upgrade ) +{ + i = 0; + while ( i < barriers.size ) + { + barrier = barriers[ i ]; + if ( all_chunks_intact( barrier, barrier.barrier_chunks ) ) + { + i++; + continue; + } + else + { + while ( isDefined( barrier.zbarrier ) ) + { + a_pieces = barrier.zbarrier getzbarrierpieceindicesinstate( "open" ); + while ( isDefined( a_pieces ) ) + { + xx = 0; + while ( xx < a_pieces.size ) + { + chunk = a_pieces[ xx ]; + if ( upgrade ) + { + barrier.zbarrier zbarrierpieceuseupgradedmodel( chunk ); + barrier.zbarrier.chunk_health[ chunk ] = barrier.zbarrier getupgradedpiecenumlives( chunk ); + xx++; + continue; + } + else + { + barrier.zbarrier zbarrierpieceusedefaultmodel( chunk ); + barrier.zbarrier.chunk_health[ chunk ] = 0; + } + xx++; + } + } + x = 0; + while ( x < barrier.zbarrier getnumzbarrierpieces() ) + { + barrier.zbarrier setzbarrierpiecestate( x, "closed" ); + barrier.zbarrier showzbarrierpiece( x ); + x++; + } + } + if ( isDefined( barrier.clip ) ) + { + barrier.clip enable_trigger(); + barrier.clip disconnectpaths(); + } + else + { + blocker_disconnect_paths( barrier.neg_start, barrier.neg_end ); + } + if ( ( i % 4 ) == 0 ) + { + wait_network_frame(); + } + } + i++; + } +} + +func_should_never_drop() +{ + return 0; +} + +func_should_always_drop() +{ + return 1; +} + +func_should_drop_minigun() +{ + if ( minigun_no_drop() ) + { + return 0; + } + return 1; +} + +func_should_drop_carpenter() +{ + if ( get_num_window_destroyed() < 5 ) + { + return 0; + } + return 1; +} + +func_should_drop_fire_sale() +{ + if ( level.zombie_vars[ "zombie_powerup_fire_sale_on" ] != 1 || level.chest_moves < 1 && isDefined( level.disable_firesale_drop ) && level.disable_firesale_drop ) + { + return 0; + } + return 1; +} + +powerup_move() +{ + self endon( "powerup_timedout" ); + self endon( "powerup_grabbed" ); + drag_speed = 75; + while ( 1 ) + { + self waittill( "move_powerup", moveto, distance ); + drag_vector = moveto - self.origin; + range_squared = lengthsquared( drag_vector ); + if ( range_squared > ( distance * distance ) ) + { + drag_vector = vectornormalize( drag_vector ); + drag_vector = distance * drag_vector; + moveto = self.origin + drag_vector; + } + self.origin = moveto; + } +} + +powerup_emp() +{ + self endon( "powerup_timedout" ); + self endon( "powerup_grabbed" ); + if ( !should_watch_for_emp() ) + { + return; + } + while ( 1 ) + { + level waittill( "emp_detonate", origin, radius ); + if ( distancesquared( origin, self.origin ) < ( radius * radius ) ) + { + playfx( level._effect[ "powerup_off" ], self.origin ); + self thread powerup_delete_delayed(); + self notify( "powerup_timedout" ); + } + } +} + +get_powerups( origin, radius ) +{ + if ( isDefined( origin ) && isDefined( radius ) ) + { + powerups = []; + _a3603 = level.active_powerups; + _k3603 = getFirstArrayKey( _a3603 ); + while ( isDefined( _k3603 ) ) + { + powerup = _a3603[ _k3603 ]; + if ( distancesquared( origin, powerup.origin ) < ( radius * radius ) ) + { + powerups[ powerups.size ] = powerup; + } + _k3603 = getNextArrayKey( _a3603, _k3603 ); + } + return powerups; + } + return level.active_powerups; +} + +should_award_stat( powerup_name ) +{ + if ( powerup_name != "teller_withdrawl" && powerup_name != "blue_monkey" || powerup_name == "free_perk" && powerup_name == "bonus_points_player" ) + { + return 0; + } + if ( isDefined( level.statless_powerups ) && isDefined( level.statless_powerups[ powerup_name ] ) ) + { + return 0; + } + return 1; +} + +teller_withdrawl( powerup, player ) +{ + player maps/mp/zombies/_zm_score::add_to_player_score( powerup.value ); +} + + + diff --git a/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/zombies/_zm_weapons.gsc b/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/zombies/_zm_weapons.gsc new file mode 100644 index 0000000..3be55fc --- /dev/null +++ b/Fixed Zombies GSCs for compiling/patch_zm/maps/mp/zombies/_zm_weapons.gsc @@ -0,0 +1,3058 @@ +#include maps/mp/zombies/_zm_weap_cymbal_monkey; +#include maps/mp/zombies/_zm_weapons; +#include maps/mp/zombies/_zm_stats; +#include maps/mp/zombies/_zm_equipment; +#include maps/mp/zombies/_zm_score; +#include maps/mp/zombies/_zm_pers_upgrades_functions; +#include maps/mp/zombies/_zm_melee_weapon; +#include maps/mp/zombies/_zm_audio; +#include maps/mp/gametypes_zm/_weapons; +#include maps/mp/gametypes_zm/_weaponobjects; +#include maps/mp/zombies/_zm_magicbox; +#include maps/mp/zombies/_zm_utility; +#include maps/mp/_utility; +#include common_scripts/utility; +#include maps/mp/zombies/_zm_weap_claymore; +#include maps/mp/zombies/_zm_weap_ballistic_knife; + + +init() +{ +/* +/# + println( "ZM >> init (_zm_weapons.gsc)" ); +#/ +*/ + + init_weapons(); + init_weapon_upgrade(); + init_weapon_toggle(); + precacheshader( "minimap_icon_mystery_box" ); + precacheshader( "specialty_instakill_zombies" ); + precacheshader( "specialty_firesale_zombies" ); + precacheitem( "zombie_fists_zm" ); + level._weaponobjects_on_player_connect_override = ::weaponobjects_on_player_connect_override; + level._zombiemode_check_firesale_loc_valid_func = ::default_check_firesale_loc_valid_func; + level.missileentities = []; + setupretrievablehintstrings(); + level thread onplayerconnect(); + +} + +setupretrievablehintstrings() +{ + maps/mp/gametypes_zm/_weaponobjects::createretrievablehint( "claymore", &"ZOMBIE_CLAYMORE_PICKUP" ); +} + +onplayerconnect() +{ + for ( ;; ) + { + level waittill( "connecting", player ); + player thread onplayerspawned(); + } +} + +onplayerspawned() +{ + self endon( "disconnect" ); + for ( ;; ) + { + self waittill( "spawned_player" ); + self thread watchforgrenadeduds(); + self thread watchforgrenadelauncherduds(); + self.staticweaponsstarttime = getTime(); + } +} + +watchforgrenadeduds() +{ + self endon( "spawned_player" ); + self endon( "disconnect" ); + while ( 1 ) + { + self waittill( "grenade_fire", grenade, weapname ); + if ( !is_equipment( weapname ) && weapname != "claymore_zm" ) + { + grenade thread checkgrenadefordud( weapname, 1, self ); + grenade thread watchforscriptexplosion( weapname, 1, self ); + } + } +} + +watchforgrenadelauncherduds() +{ + self endon( "spawned_player" ); + self endon( "disconnect" ); + while ( 1 ) + { + self waittill( "grenade_launcher_fire", grenade, weapname ); + grenade thread checkgrenadefordud( weapname, 0, self ); + grenade thread watchforscriptexplosion( weapname, 0, self ); + } +} + +grenade_safe_to_throw( player, weapname ) +{ + if ( isDefined( level.grenade_safe_to_throw ) ) + { + return self [[ level.grenade_safe_to_throw ]]( player, weapname ); + } + return 1; +} + +grenade_safe_to_bounce( player, weapname ) +{ + if ( isDefined( level.grenade_safe_to_bounce ) ) + { + return self [[ level.grenade_safe_to_bounce ]]( player, weapname ); + } + return 1; +} + +makegrenadedudanddestroy() +{ + self endon( "death" ); + self notify( "grenade_dud" ); + self makegrenadedud(); + wait 3; + if ( isDefined( self ) ) + { + self delete(); + } +} + +checkgrenadefordud( weapname, isthrowngrenade, player ) +{ + self endon( "death" ); + player endon( "zombify" ); + if ( !self grenade_safe_to_throw( player, weapname ) ) + { + self thread makegrenadedudanddestroy(); + return; + } + for ( ;; ) + { + self waittill_any_timeout( 0.25, "grenade_bounce", "stationary" ); + if ( !self grenade_safe_to_bounce( player, weapname ) ) + { + self thread makegrenadedudanddestroy(); + return; + } + } +} + +wait_explode() +{ + self endon( "grenade_dud" ); + self endon( "done" ); + self waittill( "explode", position ); + level.explode_position = position; + level.explode_position_valid = 1; + self notify( "done" ); +} + +wait_timeout( time ) +{ + self endon( "grenade_dud" ); + self endon( "done" ); + wait time; + self notify( "done" ); +} + +wait_for_explosion( time ) +{ + level.explode_position = ( 0, 0, 0 ); + level.explode_position_valid = 0; + self thread wait_explode(); + self thread wait_timeout( time ); + self waittill( "done" ); + self notify( "death_or_explode" ); +} + +watchforscriptexplosion( weapname, isthrowngrenade, player ) +{ + self endon( "grenade_dud" ); + if ( is_lethal_grenade( weapname ) || is_grenade_launcher( weapname ) ) + { + self thread wait_for_explosion( 20 ); + self waittill( "death_or_explode", exploded, position ); + if ( exploded ) + { + level notify( "grenade_exploded" ); + } + } +} + +get_nonalternate_weapon( altweapon ) +{ + if ( is_alt_weapon( altweapon ) ) + { + alt = weaponaltweaponname( altweapon ); + while ( alt == "none" ) + { + primaryweapons = self getweaponslistprimaries(); + alt = primaryweapons[ 0 ]; + _a201 = primaryweapons; + _k201 = getFirstArrayKey( _a201 ); + while ( isDefined( _k201 ) ) + { + weapon = _a201[ _k201 ]; + if ( weaponaltweaponname( weapon ) == altweapon ) + { + alt = weapon; + break; + } + else + { + _k201 = getNextArrayKey( _a201, _k201 ); + } + } + } + return alt; + } + return altweapon; +} + +switch_from_alt_weapon( current_weapon ) +{ + if ( is_alt_weapon( current_weapon ) ) + { + alt = weaponaltweaponname( current_weapon ); + while ( alt == "none" ) + { + primaryweapons = self getweaponslistprimaries(); + alt = primaryweapons[ 0 ]; + _a227 = primaryweapons; + _k227 = getFirstArrayKey( _a227 ); + while ( isDefined( _k227 ) ) + { + weapon = _a227[ _k227 ]; + if ( weaponaltweaponname( weapon ) == current_weapon ) + { + alt = weapon; + break; + } + else + { + _k227 = getNextArrayKey( _a227, _k227 ); + } + } + } + self switchtoweaponimmediate( alt ); + self waittill_notify_or_timeout( "weapon_change_complete", 1 ); + return alt; + } + return current_weapon; +} + +give_fallback_weapon() +{ + self giveweapon( "zombie_fists_zm" ); + self switchtoweapon( "zombie_fists_zm" ); +} + +take_fallback_weapon() +{ + if ( self hasweapon( "zombie_fists_zm" ) ) + { + self takeweapon( "zombie_fists_zm" ); + } +} + +switch_back_primary_weapon( oldprimary ) +{ + if ( isDefined( self.laststand ) && self.laststand ) + { + return; + } + primaryweapons = self getweaponslistprimaries(); + if ( isDefined( oldprimary ) && isinarray( primaryweapons, oldprimary ) ) + { + self switchtoweapon( oldprimary ); + } + else + { + if ( isDefined( primaryweapons ) && primaryweapons.size > 0 ) + { + self switchtoweapon( primaryweapons[ 0 ] ); + } + } +} + +add_retrievable_knife_init_name( name ) +{ + if ( !isDefined( level.retrievable_knife_init_names ) ) + { + level.retrievable_knife_init_names = []; + } + level.retrievable_knife_init_names[ level.retrievable_knife_init_names.size ] = name; +} + +watchweaponusagezm() +{ + self endon( "death" ); + self endon( "disconnect" ); + level endon( "game_ended" ); + for ( ;; ) + { + self waittill( "weapon_fired", curweapon ); + self.lastfiretime = getTime(); + self.hasdonecombat = 1; + if ( isDefined( self.hitsthismag[ curweapon ] ) ) + { + self thread updatemagshots( curweapon ); + } + switch( weaponclass( curweapon ) ) + { + case "rifle": + if ( curweapon == "crossbow_explosive_mp" ) + { + level.globalcrossbowfired++; + self addweaponstat( curweapon, "shots", 1 ); + self thread begingrenadetracking(); + break; + } + case "pistol": + case "pistol spread": + case "pistolspread": + case "mg": + case "smg": + case "spread": + self trackweaponfire( curweapon ); + level.globalshotsfired++; + break; + case "grenade": + case "rocketlauncher": + if ( is_alt_weapon( curweapon ) ) + { + curweapon = weaponaltweaponname( curweapon ); + } + self addweaponstat( curweapon, "shots", 1 ); + break; + default: + + switch( curweapon ) + { + case "m202_flash_mp": + case "m220_tow_mp": + case "m32_mp": + case "minigun_mp": + case "mp40_blinged_mp": + self.usedkillstreakweapon[ curweapon ] = 1; + break; + continue; + default: + + } + } + } +} + +trackweaponzm() +{ + self.currentweapon = self getcurrentweapon(); + self.currenttime = getTime(); + spawnid = getplayerspawnid( self ); + while ( 1 ) + { + event = self waittill_any_return( "weapon_change", "death", "disconnect", "bled_out" ); + newtime = getTime(); + if ( event == "weapon_change" ) + { + newweapon = self getcurrentweapon(); + if ( newweapon != "none" && newweapon != self.currentweapon ) + { + updatelastheldweapontimingszm( newtime ); + self.currentweapon = newweapon; + self.currenttime = newtime; + } + continue; + } + else + { + if ( event != "disconnect" ) + { + updateweapontimingszm( newtime ); + } + return; + } + } +} + +updatelastheldweapontimingszm( newtime ) +{ + if ( isDefined( self.currentweapon ) && isDefined( self.currenttime ) ) + { + curweapon = self.currentweapon; + totaltime = int( ( newtime - self.currenttime ) / 1000 ); + if ( totaltime > 0 ) + { + if ( is_alt_weapon( curweapon ) ) + { + curweapon = weaponaltweaponname( curweapon ); + } + self addweaponstat( curweapon, "timeUsed", totaltime ); + } + } +} + +updateweapontimingszm( newtime ) +{ + if ( self is_bot() ) + { + return; + } + updatelastheldweapontimingszm( newtime ); + if ( !isDefined( self.staticweaponsstarttime ) ) + { + return; + } + totaltime = int( ( newtime - self.staticweaponsstarttime ) / 1000 ); + if ( totaltime < 0 ) + { + return; + } + self.staticweaponsstarttime = newtime; +} + +watchweaponchangezm() +{ + self endon( "death" ); + self endon( "disconnect" ); + self.lastdroppableweapon = self getcurrentweapon(); + self.hitsthismag = []; + weapon = self getcurrentweapon(); + if ( isDefined( weapon ) && weapon != "none" && !isDefined( self.hitsthismag[ weapon ] ) ) + { + self.hitsthismag[ weapon ] = weaponclipsize( weapon ); + } + while ( 1 ) + { + previous_weapon = self getcurrentweapon(); + self waittill( "weapon_change", newweapon ); + if ( maydropweapon( newweapon ) ) + { + self.lastdroppableweapon = newweapon; + } + if ( newweapon != "none" ) + { + if ( !isDefined( self.hitsthismag[ newweapon ] ) ) + { + self.hitsthismag[ newweapon ] = weaponclipsize( newweapon ); + } + } + } +} + +weaponobjects_on_player_connect_override_internal() +{ + self maps/mp/gametypes_zm/_weaponobjects::createbasewatchers(); + self createclaymorewatcher_zm(); + i = 0; + while ( i < level.retrievable_knife_init_names.size ) + { + self createballisticknifewatcher_zm( level.retrievable_knife_init_names[ i ], level.retrievable_knife_init_names[ i ] + "_zm" ); + i++; + } + self maps/mp/gametypes_zm/_weaponobjects::setupretrievablewatcher(); + if ( !isDefined( self.weaponobjectwatcherarray ) ) + { + self.weaponobjectwatcherarray = []; + } + self thread maps/mp/gametypes_zm/_weaponobjects::watchweaponobjectspawn(); + self thread maps/mp/gametypes_zm/_weaponobjects::watchweaponprojectileobjectspawn(); + self thread maps/mp/gametypes_zm/_weaponobjects::deleteweaponobjectson(); + self.concussionendtime = 0; + self.hasdonecombat = 0; + self.lastfiretime = 0; + self thread watchweaponusagezm(); + self thread maps/mp/gametypes_zm/_weapons::watchgrenadeusage(); + self thread maps/mp/gametypes_zm/_weapons::watchmissileusage(); + self thread watchweaponchangezm(); + self thread maps/mp/gametypes_zm/_weapons::watchturretuse(); + self thread trackweaponzm(); + self notify( "weapon_watchers_created" ); +} + +weaponobjects_on_player_connect_override() +{ + add_retrievable_knife_init_name( "knife_ballistic" ); + add_retrievable_knife_init_name( "knife_ballistic_upgraded" ); + onplayerconnect_callback( ::weaponobjects_on_player_connect_override_internal ); +} + +createclaymorewatcher_zm() +{ + watcher = self maps/mp/gametypes_zm/_weaponobjects::createuseweaponobjectwatcher( "claymore", "claymore_zm", self.team ); + watcher.onspawnretrievetriggers = ::on_spawn_retrieve_trigger; + watcher.adjusttriggerorigin = ::adjust_trigger_origin; + watcher.pickup = level.pickup_claymores; + watcher.pickup_trigger_listener = level.pickup_claymores_trigger_listener; + watcher.skip_weapon_object_damage = 1; + watcher.headicon = 0; + watcher.watchforfire = 1; + watcher.detonate = ::claymoredetonate; + watcher.ondamage = level.claymores_on_damage; +} + +createballisticknifewatcher_zm( name, weapon ) +{ + watcher = self maps/mp/gametypes_zm/_weaponobjects::createuseweaponobjectwatcher( name, weapon, self.team ); + watcher.onspawn = ::on_spawn; + watcher.onspawnretrievetriggers = ::on_spawn_retrieve_trigger; + watcher.storedifferentobject = 1; + watcher.headicon = 0; +} + +isempweapon( weaponname ) +{ + if ( isDefined( weaponname ) && weaponname != "emp_mp" || weaponname == "emp_grenade_mp" && weaponname == "emp_grenade_zm" ) + { + return 1; + } + return 0; +} + +claymoredetonate( attacker, weaponname ) +{ + from_emp = isempweapon( weaponname ); + if ( from_emp ) + { + self delete(); + return; + } + if ( isDefined( attacker ) ) + { + self detonate( attacker ); + } + else if ( isDefined( self.owner ) && isplayer( self.owner ) ) + { + self detonate( self.owner ); + } + else + { + self detonate(); + } +} + +default_check_firesale_loc_valid_func() +{ + return 1; +} + +add_zombie_weapon( weapon_name, upgrade_name, hint, cost, weaponvo, weaponvoresp, ammo_cost, create_vox ) +{ + if ( isDefined( level.zombie_include_weapons ) && !isDefined( level.zombie_include_weapons[ weapon_name ] ) ) + { + return; + } + table = "mp/zombiemode.csv"; + table_cost = tablelookup( table, 0, weapon_name, 1 ); + table_ammo_cost = tablelookup( table, 0, weapon_name, 2 ); + if ( isDefined( table_cost ) && table_cost != "" ) + { + cost = round_up_to_ten( int( table_cost ) ); + } + if ( isDefined( table_ammo_cost ) && table_ammo_cost != "" ) + { + ammo_cost = round_up_to_ten( int( table_ammo_cost ) ); + } + precachestring( hint ); + struct = spawnstruct(); + if ( !isDefined( level.zombie_weapons ) ) + { + level.zombie_weapons = []; + } + if ( !isDefined( level.zombie_weapons_upgraded ) ) + { + level.zombie_weapons_upgraded = []; + } + if ( isDefined( upgrade_name ) ) + { + level.zombie_weapons_upgraded[ upgrade_name ] = weapon_name; + } + struct.weapon_name = weapon_name; + struct.upgrade_name = upgrade_name; + struct.weapon_classname = "weapon_" + weapon_name; + struct.hint = hint; + struct.cost = cost; + struct.vox = weaponvo; + struct.vox_response = weaponvoresp; + /* +/# + println( "ZM >> Looking for weapon - " + weapon_name ); +#/ + */ + struct.is_in_box = level.zombie_include_weapons[ weapon_name ]; + if ( !isDefined( ammo_cost ) ) + { + ammo_cost = round_up_to_ten( int( cost * 0.5 ) ); + } + struct.ammo_cost = ammo_cost; + level.zombie_weapons[ weapon_name ] = struct; + if ( isDefined( level.zombiemode_reusing_pack_a_punch ) && level.zombiemode_reusing_pack_a_punch && isDefined( upgrade_name ) ) + { + add_attachments( weapon_name, upgrade_name ); + } + if ( isDefined( create_vox ) ) + { + level.vox maps/mp/zombies/_zm_audio::zmbvoxadd( "player", "weapon_pickup", weapon_name, weaponvo, undefined ); + } + /* +/# + if ( isDefined( level.devgui_add_weapon ) ) + { + [[ level.devgui_add_weapon ]]( weapon_name, upgrade_name, hint, cost, weaponvo, weaponvoresp, ammo_cost ); +#/ + } + */ +} + +add_attachments( weapon_name, upgrade_name ) +{ + table = "zm/pap_attach.csv"; + if ( isDefined( level.weapon_attachment_table ) ) + { + table = level.weapon_attachment_table; + } + row = tablelookuprownum( table, 0, upgrade_name ); + while ( row > -1 ) + { + level.zombie_weapons[ weapon_name ].default_attachment = tablelookup( table, 0, upgrade_name, 1 ); + level.zombie_weapons[ weapon_name ].addon_attachments = []; + index = 2; + next_addon = tablelookup( table, 0, upgrade_name, index ); + while ( isDefined( next_addon ) && next_addon.size > 0 ) + { + level.zombie_weapons[ weapon_name ].addon_attachments[ level.zombie_weapons[ weapon_name ].addon_attachments.size ] = next_addon; + index++; + next_addon = tablelookup( table, 0, upgrade_name, index ); + } + } +} + +default_weighting_func() +{ + return 1; +} + +default_tesla_weighting_func() +{ + num_to_add = 1; + if ( isDefined( level.pulls_since_last_tesla_gun ) ) + { + if ( isDefined( level.player_drops_tesla_gun ) && level.player_drops_tesla_gun == 1 ) + { + num_to_add += int( 0.2 * level.zombie_include_weapons.size ); + } + if ( !isDefined( level.player_seen_tesla_gun ) || level.player_seen_tesla_gun == 0 ) + { + if ( level.round_number > 10 ) + { + num_to_add += int( 0.2 * level.zombie_include_weapons.size ); + } + else + { + if ( level.round_number > 5 ) + { + num_to_add += int( 0.15 * level.zombie_include_weapons.size ); + } + } + } + } + return num_to_add; +} + +default_1st_move_weighting_func() +{ + if ( level.chest_moves > 0 ) + { + num_to_add = 1; + return num_to_add; + } + else + { + return 0; + } +} + +default_upgrade_weapon_weighting_func() +{ + if ( level.chest_moves > 1 ) + { + return 1; + } + else + { + return 0; + } +} + +default_cymbal_monkey_weighting_func() +{ + players = get_players(); + count = 0; + i = 0; + while ( i < players.size ) + { + if ( players[ i ] has_weapon_or_upgrade( "cymbal_monkey_zm" ) ) + { + count++; + } + i++; + } + if ( count > 0 ) + { + return 1; + } + else + { + if ( level.round_number < 10 ) + { + return 3; + } + else + { + return 5; + } + } +} + +is_weapon_included( weapon_name ) +{ + if ( !isDefined( level.zombie_weapons ) ) + { + return 0; + } + return isDefined( level.zombie_weapons[ weapon_name ] ); +} + +is_weapon_or_base_included( weapon_name ) +{ + if ( !isDefined( level.zombie_weapons ) ) + { + return 0; + } + if ( isDefined( level.zombie_weapons[ weapon_name ] ) ) + { + return 1; + } + base = get_base_weapon_name( weapon_name, 1 ); + if ( isDefined( level.zombie_weapons[ base ] ) ) + { + return 1; + } + return 0; +} + +include_zombie_weapon( weapon_name, in_box, collector, weighting_func ) +{ + if ( !isDefined( level.zombie_include_weapons ) ) + { + level.zombie_include_weapons = []; + } + if ( !isDefined( in_box ) ) + { + in_box = 1; + } + /* +/# + println( "ZM >> Including weapon - " + weapon_name ); +#/ + */ + level.zombie_include_weapons[ weapon_name ] = in_box; + precacheitem( weapon_name ); + if ( !isDefined( weighting_func ) ) + { + level.weapon_weighting_funcs[ weapon_name ] = ::default_weighting_func; + } + else + { + level.weapon_weighting_funcs[ weapon_name ] = weighting_func; + } +} + +init_weapons() +{ + //throws exe_client_field_mismatch on join + //or the server won't rotate to the map + if ( isDefined( level._zombie_custom_add_weapons ) ) + { + //[[ level._zombie_custom_add_weapons ]](); + } + precachemodel( "zombie_teddybear" ); +} + +add_limited_weapon( weapon_name, amount ) +{ + if ( !isDefined( level.limited_weapons ) ) + { + level.limited_weapons = []; + } + level.limited_weapons[ weapon_name ] = amount; +} + +limited_weapon_below_quota( weapon, ignore_player, pap_triggers ) +{ + while ( isDefined( level.limited_weapons[ weapon ] ) ) + { + if ( !isDefined( pap_triggers ) ) + { + if ( !isDefined( level.pap_triggers ) ) + { + pap_triggers = getentarray( "specialty_weapupgrade", "script_noteworthy" ); + break; + } + else + { + pap_triggers = level.pap_triggers; + } + } + if ( is_true( level.no_limited_weapons ) ) + { + return 0; + } + upgradedweapon = weapon; + if ( isDefined( level.zombie_weapons[ weapon ] ) && isDefined( level.zombie_weapons[ weapon ].upgrade_name ) ) + { + upgradedweapon = level.zombie_weapons[ weapon ].upgrade_name; + } + players = get_players(); + count = 0; + limit = level.limited_weapons[ weapon ]; + i = 0; + while ( i < players.size ) + { + if ( isDefined( ignore_player ) && ignore_player == players[ i ] ) + { + i++; + continue; + } + else + { + if ( players[ i ] has_weapon_or_upgrade( weapon ) ) + { + count++; + if ( count >= limit ) + { + return 0; + } + } + } + i++; + } + k = 0; + while ( k < pap_triggers.size ) + { + if ( isDefined( pap_triggers[ k ].current_weapon ) || pap_triggers[ k ].current_weapon == weapon && pap_triggers[ k ].current_weapon == upgradedweapon ) + { + count++; + if ( count >= limit ) + { + return 0; + } + } + k++; + } + chestindex = 0; + while ( chestindex < level.chests.size ) + { + if ( isDefined( level.chests[ chestindex ].zbarrier.weapon_string ) && level.chests[ chestindex ].zbarrier.weapon_string == weapon ) + { + count++; + if ( count >= limit ) + { + return 0; + } + } + chestindex++; + } + if ( isDefined( level.custom_limited_weapon_checks ) ) + { + _a952 = level.custom_limited_weapon_checks; + _k952 = getFirstArrayKey( _a952 ); + while ( isDefined( _k952 ) ) + { + check = _a952[ _k952 ]; + count += [[ check ]]( weapon ); + _k952 = getNextArrayKey( _a952, _k952 ); + } + if ( count >= limit ) + { + return 0; + } + } + while ( isDefined( level.random_weapon_powerups ) ) + { + powerupindex = 0; + while ( powerupindex < level.random_weapon_powerups.size ) + { + if ( isDefined( level.random_weapon_powerups[ powerupindex ] ) && level.random_weapon_powerups[ powerupindex ].base_weapon == weapon ) + { + count++; + if ( count >= limit ) + { + return 0; + } + } + powerupindex++; + } + } + } + return 1; +} + +add_custom_limited_weapon_check( callback ) +{ + if ( !isDefined( level.custom_limited_weapon_checks ) ) + { + level.custom_limited_weapon_checks = []; + } + level.custom_limited_weapon_checks[ level.custom_limited_weapon_checks.size ] = callback; +} + +add_weapon_to_content( weapon_name, package ) +{ + if ( !isDefined( level.content_weapons ) ) + { + level.content_weapons = []; + } + level.content_weapons[ weapon_name ] = package; +} + +player_can_use_content( weapon ) +{ + if ( isDefined( level.content_weapons ) ) + { + if ( isDefined( level.content_weapons[ weapon ] ) ) + { + return self hasdlcavailable( level.content_weapons[ weapon ] ); + } + } + return 1; +} + +init_spawnable_weapon_upgrade() +{ + spawn_list = []; + spawnable_weapon_spawns = getstructarray( "weapon_upgrade", "targetname" ); + spawnable_weapon_spawns = arraycombine( spawnable_weapon_spawns, getstructarray( "bowie_upgrade", "targetname" ), 1, 0 ); + spawnable_weapon_spawns = arraycombine( spawnable_weapon_spawns, getstructarray( "sickle_upgrade", "targetname" ), 1, 0 ); + spawnable_weapon_spawns = arraycombine( spawnable_weapon_spawns, getstructarray( "tazer_upgrade", "targetname" ), 1, 0 ); + spawnable_weapon_spawns = arraycombine( spawnable_weapon_spawns, getstructarray( "buildable_wallbuy", "targetname" ), 1, 0 ); + if ( !is_true( level.headshots_only ) ) + { + spawnable_weapon_spawns = arraycombine( spawnable_weapon_spawns, getstructarray( "claymore_purchase", "targetname" ), 1, 0 ); + } + 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; + if ( location != "" ) + { + match_string = ( match_string + "_" ) + location; + } + match_string_plus_space = " " + match_string; + i = 0; + while ( i < spawnable_weapon_spawns.size ) + { + spawnable_weapon = spawnable_weapon_spawns[ i ]; + if ( isDefined( spawnable_weapon.zombie_weapon_upgrade ) && spawnable_weapon.zombie_weapon_upgrade == "sticky_grenade_zm" && is_true( level.headshots_only ) ) + { + i++; + continue; + } + else + { + if ( !isDefined( spawnable_weapon.script_noteworthy ) || spawnable_weapon.script_noteworthy == "" ) + { + spawn_list[ spawn_list.size ] = spawnable_weapon; + i++; + continue; + } + else + { + matches = strtok( spawnable_weapon.script_noteworthy, "," ); + j = 0; + while ( j < matches.size ) + { + if ( matches[ j ] == match_string || matches[ j ] == match_string_plus_space ) + { + spawn_list[ spawn_list.size ] = spawnable_weapon; + } + j++; + } + } + } + i++; + } + tempmodel = spawn( "script_model", ( 0, 0, 0 ) ); + i = 0; + while ( i < spawn_list.size ) + { + clientfieldname = ( spawn_list[ i ].zombie_weapon_upgrade + "_" ) + spawn_list[ i ].origin; + numbits = 2; + if ( isDefined( level._wallbuy_override_num_bits ) ) + { + numbits = level._wallbuy_override_num_bits; + } + registerclientfield( "world", clientfieldname, 1, numbits, "int" ); + target_struct = getstruct( spawn_list[ i ].target, "targetname" ); + if ( spawn_list[ i ].targetname == "buildable_wallbuy" ) + { + bits = 4; + if ( isDefined( level.buildable_wallbuy_weapons ) ) + { + bits = getminbitcountfornum( level.buildable_wallbuy_weapons.size + 1 ); + } + registerclientfield( "world", clientfieldname + "_idx", 12000, bits, "int" ); + spawn_list[ i ].clientfieldname = clientfieldname; + i++; + continue; + } + else + { + precachemodel( target_struct.model ); + unitrigger_stub = spawnstruct(); + unitrigger_stub.origin = spawn_list[ i ].origin; + unitrigger_stub.angles = spawn_list[ i ].angles; + tempmodel.origin = spawn_list[ i ].origin; + tempmodel.angles = spawn_list[ i ].angles; + mins = undefined; + maxs = undefined; + absmins = undefined; + absmaxs = undefined; + tempmodel setmodel( target_struct.model ); + tempmodel useweaponhidetags( spawn_list[ i ].zombie_weapon_upgrade ); + mins = tempmodel getmins(); + maxs = tempmodel getmaxs(); + absmins = tempmodel getabsmins(); + absmaxs = tempmodel getabsmaxs(); + bounds = absmaxs - absmins; + unitrigger_stub.script_length = bounds[ 0 ] * 0.25; + unitrigger_stub.script_width = bounds[ 1 ]; + unitrigger_stub.script_height = bounds[ 2 ]; + unitrigger_stub.origin -= anglesToRight( unitrigger_stub.angles ) * ( unitrigger_stub.script_length * 0.4 ); + unitrigger_stub.target = spawn_list[ i ].target; + unitrigger_stub.targetname = spawn_list[ i ].targetname; + unitrigger_stub.cursor_hint = "HINT_NOICON"; + if ( spawn_list[ i ].targetname == "weapon_upgrade" ) + { + unitrigger_stub.cost = get_weapon_cost( spawn_list[ i ].zombie_weapon_upgrade ); + if ( isDefined( level.monolingustic_prompt_format ) && !level.monolingustic_prompt_format ) + { + unitrigger_stub.hint_string = get_weapon_hint( spawn_list[ i ].zombie_weapon_upgrade ); + unitrigger_stub.hint_parm1 = unitrigger_stub.cost; + break; + } + else + { + unitrigger_stub.hint_parm1 = get_weapon_display_name( spawn_list[ i ].zombie_weapon_upgrade ); + if ( isDefined( unitrigger_stub.hint_parm1 ) || unitrigger_stub.hint_parm1 == "" && unitrigger_stub.hint_parm1 == "none" ) + { + unitrigger_stub.hint_parm1 = "missing weapon name " + spawn_list[ i ].zombie_weapon_upgrade; + } + unitrigger_stub.hint_parm2 = unitrigger_stub.cost; + unitrigger_stub.hint_string = &"ZOMBIE_WEAPONCOSTONLY"; + } + } + unitrigger_stub.weapon_upgrade = spawn_list[ i ].zombie_weapon_upgrade; + unitrigger_stub.script_unitrigger_type = "unitrigger_box_use"; + unitrigger_stub.require_look_at = 1; + if ( isDefined( spawn_list[ i ].require_look_from ) && spawn_list[ i ].require_look_from ) + { + unitrigger_stub.require_look_from = 1; + } + unitrigger_stub.zombie_weapon_upgrade = spawn_list[ i ].zombie_weapon_upgrade; + unitrigger_stub.clientfieldname = clientfieldname; + maps/mp/zombies/_zm_unitrigger::unitrigger_force_per_player_triggers( unitrigger_stub, 1 ); + if ( is_melee_weapon( unitrigger_stub.zombie_weapon_upgrade ) ) + { + if ( unitrigger_stub.zombie_weapon_upgrade == "tazer_knuckles_zm" && isDefined( level.taser_trig_adjustment ) ) + { + unitrigger_stub.origin += level.taser_trig_adjustment; + } + maps/mp/zombies/_zm_unitrigger::register_static_unitrigger( unitrigger_stub, ::weapon_spawn_think ); + } + else if ( unitrigger_stub.zombie_weapon_upgrade == "claymore_zm" ) + { + unitrigger_stub.prompt_and_visibility_func = ::claymore_unitrigger_update_prompt; + maps/mp/zombies/_zm_unitrigger::register_static_unitrigger( unitrigger_stub, ::buy_claymores ); + } + else + { + unitrigger_stub.prompt_and_visibility_func = ::wall_weapon_update_prompt; + maps/mp/zombies/_zm_unitrigger::register_static_unitrigger( unitrigger_stub, ::weapon_spawn_think ); + } + spawn_list[ i ].trigger_stub = unitrigger_stub; + } + i++; + } + level._spawned_wallbuys = spawn_list; + tempmodel delete(); +} + +add_dynamic_wallbuy( weapon, wallbuy, pristine ) +{ + spawned_wallbuy = undefined; + i = 0; + while ( i < level._spawned_wallbuys.size ) + { + if ( level._spawned_wallbuys[ i ].target == wallbuy ) + { + spawned_wallbuy = level._spawned_wallbuys[ i ]; + break; + } + else + { + i++; + } + } + if ( !isDefined( spawned_wallbuy ) ) + { + /* +/# + assertmsg( "Cannot find dynamic wallbuy" ); +#/ + */ + return; + } + if ( isDefined( spawned_wallbuy.trigger_stub ) ) + { + /* +/# + assertmsg( "Dynamic wallbuy already added" ); +#/ + */ + return; + } + target_struct = getstruct( wallbuy, "targetname" ); + wallmodel = spawn_weapon_model( weapon, undefined, target_struct.origin, target_struct.angles ); + clientfieldname = spawned_wallbuy.clientfieldname; + model = getweaponmodel( weapon ); + unitrigger_stub = spawnstruct(); + unitrigger_stub.origin = target_struct.origin; + unitrigger_stub.angles = target_struct.angles; + wallmodel.origin = target_struct.origin; + wallmodel.angles = target_struct.angles; + mins = undefined; + maxs = undefined; + absmins = undefined; + absmaxs = undefined; + wallmodel setmodel( model ); + wallmodel useweaponhidetags( weapon ); + mins = wallmodel getmins(); + maxs = wallmodel getmaxs(); + absmins = wallmodel getabsmins(); + absmaxs = wallmodel getabsmaxs(); + bounds = absmaxs - absmins; + unitrigger_stub.script_length = bounds[ 0 ] * 0.25; + unitrigger_stub.script_width = bounds[ 1 ]; + unitrigger_stub.script_height = bounds[ 2 ]; + unitrigger_stub.origin -= anglesToRight( unitrigger_stub.angles ) * ( unitrigger_stub.script_length * 0.4 ); + unitrigger_stub.target = spawned_wallbuy.target; + unitrigger_stub.targetname = "weapon_upgrade"; + unitrigger_stub.cursor_hint = "HINT_NOICON"; + unitrigger_stub.first_time_triggered = !pristine; + if ( !is_melee_weapon( weapon ) ) + { + if ( pristine || weapon == "claymore_zm" ) + { + unitrigger_stub.hint_string = get_weapon_hint( weapon ); + } + else + { + unitrigger_stub.hint_string = get_weapon_hint_ammo(); + } + unitrigger_stub.cost = get_weapon_cost( weapon ); + unitrigger_stub.hint_parm1 = unitrigger_stub.cost; + } + unitrigger_stub.weapon_upgrade = weapon; + unitrigger_stub.script_unitrigger_type = "unitrigger_box_use"; + unitrigger_stub.require_look_at = 1; + unitrigger_stub.zombie_weapon_upgrade = weapon; + unitrigger_stub.clientfieldname = clientfieldname; + maps/mp/zombies/_zm_unitrigger::unitrigger_force_per_player_triggers( unitrigger_stub, 1 ); + if ( is_melee_weapon( weapon ) ) + { + if ( weapon == "tazer_knuckles_zm" && isDefined( level.taser_trig_adjustment ) ) + { + unitrigger_stub.origin += level.taser_trig_adjustment; + } + maps/mp/zombies/_zm_melee_weapon::add_stub( unitrigger_stub, weapon ); + maps/mp/zombies/_zm_unitrigger::register_static_unitrigger( unitrigger_stub, ::melee_weapon_think ); + } + else if ( weapon == "claymore_zm" ) + { + unitrigger_stub.prompt_and_visibility_func = ::claymore_unitrigger_update_prompt; + maps/mp/zombies/_zm_unitrigger::register_static_unitrigger( unitrigger_stub, ::buy_claymores ); + } + else + { + unitrigger_stub.prompt_and_visibility_func = ::wall_weapon_update_prompt; + maps/mp/zombies/_zm_unitrigger::register_static_unitrigger( unitrigger_stub, ::weapon_spawn_think ); + } + spawned_wallbuy.trigger_stub = unitrigger_stub; + weaponidx = undefined; + while ( isDefined( level.buildable_wallbuy_weapons ) ) + { + i = 0; + while ( i < level.buildable_wallbuy_weapons.size ) + { + if ( weapon == level.buildable_wallbuy_weapons[ i ] ) + { + weaponidx = i; + break; + } + else + { + i++; + } + } + } + if ( isDefined( weaponidx ) ) + { + level setclientfield( clientfieldname + "_idx", weaponidx + 1 ); + wallmodel delete(); + if ( !pristine ) + { + level setclientfield( clientfieldname, 1 ); + } + } + else + { + level setclientfield( clientfieldname, 1 ); + wallmodel show(); + } +} + +wall_weapon_update_prompt( player ) +{ + weapon = self.stub.zombie_weapon_upgrade; + if ( isDefined( level.monolingustic_prompt_format ) && !level.monolingustic_prompt_format ) + { + player_has_weapon = player has_weapon_or_upgrade( weapon ); + if ( !player_has_weapon && isDefined( level.weapons_using_ammo_sharing ) && level.weapons_using_ammo_sharing ) + { + shared_ammo_weapon = player get_shared_ammo_weapon( self.zombie_weapon_upgrade ); + if ( isDefined( shared_ammo_weapon ) ) + { + weapon = shared_ammo_weapon; + player_has_weapon = 1; + } + } + if ( !player_has_weapon ) + { + cost = get_weapon_cost( weapon ); + self.stub.hint_string = get_weapon_hint( weapon ); + self sethintstring( self.stub.hint_string, cost ); + } + else if ( isDefined( level.use_legacy_weapon_prompt_format ) && level.use_legacy_weapon_prompt_format ) + { + cost = get_weapon_cost( weapon ); + ammo_cost = get_ammo_cost( weapon ); + self.stub.hint_string = get_weapon_hint_ammo(); + self sethintstring( self.stub.hint_string, cost, ammo_cost ); + } + else + { + if ( player has_upgrade( weapon ) ) + { + ammo_cost = get_upgraded_ammo_cost( weapon ); + } + else + { + ammo_cost = get_ammo_cost( weapon ); + } + self.stub.hint_string = &"ZOMBIE_WEAPONAMMOONLY"; + self sethintstring( self.stub.hint_string, ammo_cost ); + } + } + else + { + if ( !player has_weapon_or_upgrade( weapon ) ) + { + string_override = 0; + if ( isDefined( player.pers_upgrades_awarded[ "nube" ] ) && player.pers_upgrades_awarded[ "nube" ] ) + { + string_override = maps/mp/zombies/_zm_pers_upgrades_functions::pers_nube_ammo_hint_string( player, weapon ); + } + if ( !string_override ) + { + cost = get_weapon_cost( weapon ); + weapon_display = get_weapon_display_name( weapon ); + if ( isDefined( weapon_display ) || weapon_display == "" && weapon_display == "none" ) + { + weapon_display = "missing weapon name " + weapon; + } + self.stub.hint_string = &"ZOMBIE_WEAPONCOSTONLY"; + self sethintstring( self.stub.hint_string, weapon_display, cost ); + } + } + else + { + if ( player has_upgrade( weapon ) ) + { + ammo_cost = get_upgraded_ammo_cost( weapon ); + } + else + { + ammo_cost = get_ammo_cost( weapon ); + } + self.stub.hint_string = &"ZOMBIE_WEAPONAMMOONLY"; + self sethintstring( self.stub.hint_string, ammo_cost ); + } + } + if ( getDvarInt( #"1F0A2129" ) ) + { + self.stub.cursor_hint = "HINT_WEAPON"; + self.stub.cursor_hint_weapon = weapon; + self setcursorhint( self.stub.cursor_hint, self.stub.cursor_hint_weapon ); + } + else + { + self.stub.cursor_hint = "HINT_NOICON"; + self.stub.cursor_hint_weapon = undefined; + self setcursorhint( self.stub.cursor_hint ); + } + return 1; +} + +reset_wallbuy_internal( set_hint_string ) +{ + if ( isDefined( self.first_time_triggered ) && self.first_time_triggered == 1 ) + { + self.first_time_triggered = 0; + if ( isDefined( self.clientfieldname ) ) + { + level setclientfield( self.clientfieldname, 0 ); + } + if ( set_hint_string ) + { + hint_string = get_weapon_hint( self.zombie_weapon_upgrade ); + cost = get_weapon_cost( self.zombie_weapon_upgrade ); + self sethintstring( hint_string, cost ); + } + } +} + +reset_wallbuys() +{ + weapon_spawns = []; + weapon_spawns = getentarray( "weapon_upgrade", "targetname" ); + melee_and_grenade_spawns = []; + melee_and_grenade_spawns = getentarray( "bowie_upgrade", "targetname" ); + melee_and_grenade_spawns = arraycombine( melee_and_grenade_spawns, getentarray( "sickle_upgrade", "targetname" ), 1, 0 ); + melee_and_grenade_spawns = arraycombine( melee_and_grenade_spawns, getentarray( "tazer_upgrade", "targetname" ), 1, 0 ); + if ( !is_true( level.headshots_only ) ) + { + melee_and_grenade_spawns = arraycombine( melee_and_grenade_spawns, getentarray( "claymore_purchase", "targetname" ), 1, 0 ); + } + i = 0; + while ( i < weapon_spawns.size ) + { + weapon_spawns[ i ] reset_wallbuy_internal( 1 ); + i++; + } + i = 0; + while ( i < melee_and_grenade_spawns.size ) + { + melee_and_grenade_spawns[ i ] reset_wallbuy_internal( 0 ); + i++; + } + while ( isDefined( level._unitriggers ) ) + { + candidates = []; + i = 0; + while ( i < level._unitriggers.trigger_stubs.size ) + { + stub = level._unitriggers.trigger_stubs[ i ]; + tn = stub.targetname; + if ( tn != "weapon_upgrade" && tn != "bowie_upgrade" && tn != "sickle_upgrade" || tn == "tazer_upgrade" && tn == "claymore_purchase" ) + { + stub.first_time_triggered = 0; + if ( isDefined( stub.clientfieldname ) ) + { + level setclientfield( stub.clientfieldname, 0 ); + } + if ( tn == "weapon_upgrade" ) + { + stub.hint_string = get_weapon_hint( stub.zombie_weapon_upgrade ); + stub.cost = get_weapon_cost( stub.zombie_weapon_upgrade ); + stub.hint_parm1 = stub.cost; + } + } + i++; + } + } +} + +init_weapon_upgrade() +{ + init_spawnable_weapon_upgrade(); + weapon_spawns = []; + weapon_spawns = getentarray( "weapon_upgrade", "targetname" ); + i = 0; + while ( i < weapon_spawns.size ) + { + if ( isDefined( level.monolingustic_prompt_format ) && !level.monolingustic_prompt_format ) + { + hint_string = get_weapon_hint( weapon_spawns[ i ].zombie_weapon_upgrade ); + cost = get_weapon_cost( weapon_spawns[ i ].zombie_weapon_upgrade ); + weapon_spawns[ i ] sethintstring( hint_string, cost ); + weapon_spawns[ i ] setcursorhint( "HINT_NOICON" ); + } + else + { + cost = get_weapon_cost( weapon_spawns[ i ].zombie_weapon_upgrade ); + weapon_display = get_weapon_display_name( weapon_spawns[ i ].zombie_weapon_upgrade ); + if ( isDefined( weapon_display ) || weapon_display == "" && weapon_display == "none" ) + { + weapon_display = "missing weapon name " + weapon_spawns[ i ].zombie_weapon_upgrade; + } + hint_string = &"ZOMBIE_WEAPONCOSTONLY"; + weapon_spawns[ i ] sethintstring( hint_string, weapon_display, cost ); + } + weapon_spawns[ i ] usetriggerrequirelookat(); + weapon_spawns[ i ] thread weapon_spawn_think(); + model = getent( weapon_spawns[ i ].target, "targetname" ); + if ( isDefined( model ) ) + { + model useweaponhidetags( weapon_spawns[ i ].zombie_weapon_upgrade ); + model hide(); + } + i++; + } +} + +init_weapon_toggle() +{ + if ( !isDefined( level.magic_box_weapon_toggle_init_callback ) ) + { + return; + } + level.zombie_weapon_toggles = []; + level.zombie_weapon_toggle_max_active_count = 0; + level.zombie_weapon_toggle_active_count = 0; + precachestring( &"ZOMBIE_WEAPON_TOGGLE_DISABLED" ); + precachestring( &"ZOMBIE_WEAPON_TOGGLE_ACTIVATE" ); + precachestring( &"ZOMBIE_WEAPON_TOGGLE_DEACTIVATE" ); + precachestring( &"ZOMBIE_WEAPON_TOGGLE_ACQUIRED" ); + level.zombie_weapon_toggle_disabled_hint = &"ZOMBIE_WEAPON_TOGGLE_DISABLED"; + level.zombie_weapon_toggle_activate_hint = &"ZOMBIE_WEAPON_TOGGLE_ACTIVATE"; + level.zombie_weapon_toggle_deactivate_hint = &"ZOMBIE_WEAPON_TOGGLE_DEACTIVATE"; + level.zombie_weapon_toggle_acquired_hint = &"ZOMBIE_WEAPON_TOGGLE_ACQUIRED"; + precachemodel( "zombie_zapper_cagelight" ); + precachemodel( "zombie_zapper_cagelight_green" ); + precachemodel( "zombie_zapper_cagelight_red" ); + precachemodel( "zombie_zapper_cagelight_on" ); + level.zombie_weapon_toggle_disabled_light = "zombie_zapper_cagelight"; + level.zombie_weapon_toggle_active_light = "zombie_zapper_cagelight_green"; + level.zombie_weapon_toggle_inactive_light = "zombie_zapper_cagelight_red"; + level.zombie_weapon_toggle_acquired_light = "zombie_zapper_cagelight_on"; + weapon_toggle_ents = []; + weapon_toggle_ents = getentarray( "magic_box_weapon_toggle", "targetname" ); + i = 0; + while ( i < weapon_toggle_ents.size ) + { + struct = spawnstruct(); + struct.trigger = weapon_toggle_ents[ i ]; + struct.weapon_name = struct.trigger.script_string; + struct.upgrade_name = level.zombie_weapons[ struct.trigger.script_string ].upgrade_name; + struct.enabled = 0; + struct.active = 0; + struct.acquired = 0; + target_array = []; + target_array = getentarray( struct.trigger.target, "targetname" ); + j = 0; + while ( j < target_array.size ) + { + switch( target_array[ j ].script_string ) + { + case "light": + struct.light = target_array[ j ]; + struct.light setmodel( level.zombie_weapon_toggle_disabled_light ); + break; + j++; + continue; + case "weapon": + struct.weapon_model = target_array[ j ]; + struct.weapon_model hide(); + break; + j++; + continue; + } + j++; + } + struct.trigger sethintstring( level.zombie_weapon_toggle_disabled_hint ); + struct.trigger setcursorhint( "HINT_NOICON" ); + struct.trigger usetriggerrequirelookat(); + struct thread weapon_toggle_think(); + level.zombie_weapon_toggles[ struct.weapon_name ] = struct; + i++; + } + level thread [[ level.magic_box_weapon_toggle_init_callback ]](); +} + +get_weapon_toggle( weapon_name ) +{ + if ( !isDefined( level.zombie_weapon_toggles ) ) + { + return undefined; + } + if ( isDefined( level.zombie_weapon_toggles[ weapon_name ] ) ) + { + return level.zombie_weapon_toggles[ weapon_name ]; + } + keys = getarraykeys( level.zombie_weapon_toggles ); + i = 0; + while ( i < keys.size ) + { + if ( weapon_name == level.zombie_weapon_toggles[ keys[ i ] ].upgrade_name ) + { + return level.zombie_weapon_toggles[ keys[ i ] ]; + } + i++; + } + return undefined; +} + +is_weapon_toggle( weapon_name ) +{ + return isDefined( get_weapon_toggle( weapon_name ) ); +} + +disable_weapon_toggle( weapon_name ) +{ + toggle = get_weapon_toggle( weapon_name ); + if ( !isDefined( toggle ) ) + { + return; + } + if ( toggle.active ) + { + level.zombie_weapon_toggle_active_count--; + + } + toggle.enabled = 0; + toggle.active = 0; + toggle.light setmodel( level.zombie_weapon_toggle_disabled_light ); + toggle.weapon_model hide(); + toggle.trigger sethintstring( level.zombie_weapon_toggle_disabled_hint ); +} + +enable_weapon_toggle( weapon_name ) +{ + toggle = get_weapon_toggle( weapon_name ); + if ( !isDefined( toggle ) ) + { + return; + } + toggle.enabled = 1; + toggle.weapon_model show(); + toggle.weapon_model useweaponhidetags( weapon_name ); + deactivate_weapon_toggle( weapon_name ); +} + +activate_weapon_toggle( weapon_name, trig_for_vox ) +{ + if ( level.zombie_weapon_toggle_active_count >= level.zombie_weapon_toggle_max_active_count ) + { + if ( isDefined( trig_for_vox ) ) + { + trig_for_vox thread maps/mp/zombies/_zm_audio::weapon_toggle_vox( "max" ); + } + return; + } + toggle = get_weapon_toggle( weapon_name ); + if ( !isDefined( toggle ) ) + { + return; + } + if ( isDefined( trig_for_vox ) ) + { + trig_for_vox thread maps/mp/zombies/_zm_audio::weapon_toggle_vox( "activate", weapon_name ); + } + level.zombie_weapon_toggle_active_count++; + toggle.active = 1; + toggle.light setmodel( level.zombie_weapon_toggle_active_light ); + toggle.trigger sethintstring( level.zombie_weapon_toggle_deactivate_hint ); +} + +deactivate_weapon_toggle( weapon_name, trig_for_vox ) +{ + toggle = get_weapon_toggle( weapon_name ); + if ( !isDefined( toggle ) ) + { + return; + } + if ( isDefined( trig_for_vox ) ) + { + trig_for_vox thread maps/mp/zombies/_zm_audio::weapon_toggle_vox( "deactivate", weapon_name ); + } + if ( toggle.active ) + { + level.zombie_weapon_toggle_active_count--; + + } + toggle.active = 0; + toggle.light setmodel( level.zombie_weapon_toggle_inactive_light ); + toggle.trigger sethintstring( level.zombie_weapon_toggle_activate_hint ); +} + +acquire_weapon_toggle( weapon_name, player ) +{ + toggle = get_weapon_toggle( weapon_name ); + if ( !isDefined( toggle ) ) + { + return; + } + if ( !toggle.active || toggle.acquired ) + { + return; + } + toggle.acquired = 1; + toggle.light setmodel( level.zombie_weapon_toggle_acquired_light ); + toggle.trigger sethintstring( level.zombie_weapon_toggle_acquired_hint ); + toggle thread unacquire_weapon_toggle_on_death_or_disconnect_thread( player ); +} + +unacquire_weapon_toggle_on_death_or_disconnect_thread( player ) +{ + self notify( "end_unacquire_weapon_thread" ); + self endon( "end_unacquire_weapon_thread" ); + player waittill_any( "spawned_spectator", "disconnect" ); + unacquire_weapon_toggle( self.weapon_name ); +} + +unacquire_weapon_toggle( weapon_name ) +{ + toggle = get_weapon_toggle( weapon_name ); + if ( !isDefined( toggle ) ) + { + return; + } + if ( !toggle.active || !toggle.acquired ) + { + return; + } + toggle.acquired = 0; + toggle.light setmodel( level.zombie_weapon_toggle_active_light ); + toggle.trigger sethintstring( level.zombie_weapon_toggle_deactivate_hint ); + toggle notify( "end_unacquire_weapon_thread" ); +} + +weapon_toggle_think() +{ + for ( ;; ) + { + self.trigger waittill( "trigger", player ); + if ( !is_player_valid( player ) ) + { + player thread ignore_triggers( 0.5 ); + continue; + } + else if ( !self.enabled || self.acquired ) + { + self.trigger thread maps/mp/zombies/_zm_audio::weapon_toggle_vox( "max" ); + continue; + } + else + { + if ( !self.active ) + { + activate_weapon_toggle( self.weapon_name, self.trigger ); + break; + } + else + { + deactivate_weapon_toggle( self.weapon_name, self.trigger ); + } + } + } +} + +get_weapon_hint( weapon_name ) +{ +/* +/# + assert( isDefined( level.zombie_weapons[ weapon_name ] ), weapon_name + " was not included or is not part of the zombie weapon list." ); +#/ +*/ + return level.zombie_weapons[ weapon_name ].hint; +} + +get_weapon_cost( weapon_name ) +{ +/* +/# + assert( isDefined( level.zombie_weapons[ weapon_name ] ), weapon_name + " was not included or is not part of the zombie weapon list." ); +#/ +*/ + return level.zombie_weapons[ weapon_name ].cost; +} + +get_ammo_cost( weapon_name ) +{ +/* +/# + assert( isDefined( level.zombie_weapons[ weapon_name ] ), weapon_name + " was not included or is not part of the zombie weapon list." ); +#/ +*/ + return level.zombie_weapons[ weapon_name ].ammo_cost; +} + +get_upgraded_ammo_cost( weapon_name ) +{ +/* +/# + assert( isDefined( level.zombie_weapons[ weapon_name ] ), weapon_name + " was not included or is not part of the zombie weapon list." ); +#/ +*/ + if ( isDefined( level.zombie_weapons[ weapon_name ].upgraded_ammo_cost ) ) + { + return level.zombie_weapons[ weapon_name ].upgraded_ammo_cost; + } + return 4500; +} + +get_weapon_display_name( weapon_name ) +{ + weapon_display = getweapondisplayname( weapon_name ); + if ( isDefined( weapon_display ) || weapon_display == "" && weapon_display == "none" ) + { + weapon_display = &"MPUI_NONE"; +/* +/# + weapon_display = "missing weapon name " + weapon_name; +#/ +*/ + } + return weapon_display; +} + +get_is_in_box( weapon_name ) +{ +/* +/# + assert( isDefined( level.zombie_weapons[ weapon_name ] ), weapon_name + " was not included or is not part of the zombie weapon list." ); +#/ +*/ + return level.zombie_weapons[ weapon_name ].is_in_box; +} + +weapon_supports_default_attachment( weaponname ) +{ + weaponname = get_base_weapon_name( weaponname ); + if ( isDefined( weaponname ) ) + { + attachment = level.zombie_weapons[ weaponname ].default_attachment; + } + return isDefined( attachment ); +} + +default_attachment( weaponname ) +{ + weaponname = get_base_weapon_name( weaponname ); + if ( isDefined( weaponname ) ) + { + attachment = level.zombie_weapons[ weaponname ].default_attachment; + } + if ( isDefined( attachment ) ) + { + return attachment; + } + else + { + return "none"; + } +} + +weapon_supports_attachments( weaponname ) +{ + weaponname = get_base_weapon_name( weaponname ); + if ( isDefined( weaponname ) ) + { + attachments = level.zombie_weapons[ weaponname ].addon_attachments; + } + if ( isDefined( attachments ) ) + { + return attachments.size > 1; + } +} + +random_attachment( weaponname, exclude ) +{ + lo = 0; + if ( isDefined( level.zombie_weapons[ weaponname ].addon_attachments ) && level.zombie_weapons[ weaponname ].addon_attachments.size > 0 ) + { + attachments = level.zombie_weapons[ weaponname ].addon_attachments; + } + else + { + attachments = getweaponsupportedattachments( weaponname ); + lo = 1; + } + minatt = lo; + if ( isDefined( exclude ) && exclude != "none" ) + { + minatt = lo + 1; + } + while ( attachments.size > minatt ) + { + while ( 1 ) + { + idx = randomint( attachments.size - lo ) + lo; + if ( !isDefined( exclude ) || attachments[ idx ] != exclude ) + { + return attachments[ idx ]; + } + } + } + return "none"; +} + +get_base_name( weaponname ) +{ + split = strtok( weaponname, "+" ); + if ( split.size > 1 ) + { + return split[ 0 ]; + } + return weaponname; +} + +get_attachment_name( weaponname, att_id ) +{ + split = strtok( weaponname, "+" ); + if ( isDefined( att_id ) ) + { + attachment = att_id + 1; + if ( split.size > attachment ) + { + return split[ attachment ]; + } + } + else + { + if ( split.size > 1 ) + { + att = split[ 1 ]; + idx = 2; + while ( split.size > idx ) + { + att = ( att + "+" ) + split[ idx ]; + idx++; + } + return att; + } + } + return undefined; +} + +get_attachment_index( weapon ) +{ + att = get_attachment_name( weapon ); + if ( att == "none" ) + { + return -1; + } + base = get_base_name( weapon ); + if ( att == level.zombie_weapons[ base ].default_attachment ) + { + return 0; + } + while ( isDefined( level.zombie_weapons[ base ].addon_attachments ) ) + { + i = 0; + while ( i < level.zombie_weapons[ base ].addon_attachments.size ) + { + if ( level.zombie_weapons[ base ].addon_attachments[ i ] == att ) + { + return i + 1; + } + i++; + } + } +/* +/# + println( "ZM WEAPON ERROR: Unrecognized attachment in weapon " + weapon ); +#/ +*/ + return -1; +} + +weapon_supports_this_attachment( weapon, att ) +{ + base = get_base_name( weapon ); + if ( att == level.zombie_weapons[ base ].default_attachment ) + { + return 1; + } + while ( isDefined( level.zombie_weapons[ base ].addon_attachments ) ) + { + i = 0; + while ( i < level.zombie_weapons[ base ].addon_attachments.size ) + { + if ( level.zombie_weapons[ base ].addon_attachments[ i ] == att ) + { + return 1; + } + i++; + } + } + return 0; +} + +has_attachment( weaponname, att ) +{ + split = strtok( weaponname, "+" ); + idx = 1; + while ( split.size > idx ) + { + if ( att == split[ idx ] ) + { + return 1; + } + } + return 0; +} + +get_base_weapon_name( upgradedweaponname, base_if_not_upgraded ) +{ + if ( !isDefined( upgradedweaponname ) || upgradedweaponname == "" ) + { + return undefined; + } + upgradedweaponname = tolower( upgradedweaponname ); + upgradedweaponname = get_base_name( upgradedweaponname ); + if ( isDefined( level.zombie_weapons_upgraded[ upgradedweaponname ] ) ) + { + return level.zombie_weapons_upgraded[ upgradedweaponname ]; + } + if ( isDefined( base_if_not_upgraded ) && base_if_not_upgraded ) + { + return upgradedweaponname; + } + return undefined; +} + +get_upgrade_weapon( weaponname, add_attachment ) +{ + rootweaponname = tolower( weaponname ); + rootweaponname = get_base_name( rootweaponname ); + baseweaponname = get_base_weapon_name( rootweaponname, 1 ); + newweapon = rootweaponname; + if ( !is_weapon_upgraded( rootweaponname ) ) + { + newweapon = level.zombie_weapons[ rootweaponname ].upgrade_name; + } + if ( isDefined( add_attachment ) && add_attachment && isDefined( level.zombiemode_reusing_pack_a_punch ) && level.zombiemode_reusing_pack_a_punch ) + { + oldatt = get_attachment_name( weaponname ); + att = random_attachment( baseweaponname, oldatt ); + newweapon = ( newweapon + "+" ) + att; + } + else + { + if ( isDefined( level.zombie_weapons[ rootweaponname ] ) && isDefined( level.zombie_weapons[ rootweaponname ].default_attachment ) ) + { + att = level.zombie_weapons[ rootweaponname ].default_attachment; + newweapon = ( newweapon + "+" ) + att; + } + } + return newweapon; +} + +can_upgrade_weapon( weaponname ) +{ + if ( isDefined( weaponname ) || weaponname == "" && weaponname == "zombie_fists_zm" ) + { + return 0; + } + weaponname = tolower( weaponname ); + weaponname = get_base_name( weaponname ); + if ( !is_weapon_upgraded( weaponname ) ) + { + return isDefined( level.zombie_weapons[ weaponname ].upgrade_name ); + } + if ( isDefined( level.zombiemode_reusing_pack_a_punch ) && level.zombiemode_reusing_pack_a_punch && weapon_supports_attachments( weaponname ) ) + { + return 1; + } + return 0; +} + +will_upgrade_weapon_as_attachment( weaponname ) +{ + if ( isDefined( weaponname ) || weaponname == "" && weaponname == "zombie_fists_zm" ) + { + return 0; + } + weaponname = tolower( weaponname ); + weaponname = get_base_name( weaponname ); + if ( !is_weapon_upgraded( weaponname ) ) + { + return 0; + } + if ( isDefined( level.zombiemode_reusing_pack_a_punch ) && level.zombiemode_reusing_pack_a_punch && weapon_supports_attachments( weaponname ) ) + { + return 1; + } + return 0; +} + +is_weapon_upgraded( weaponname ) +{ + if ( isDefined( weaponname ) || weaponname == "" && weaponname == "zombie_fists_zm" ) + { + return 0; + } + weaponname = tolower( weaponname ); + weaponname = get_base_name( weaponname ); + if ( isDefined( level.zombie_weapons_upgraded[ weaponname ] ) ) + { + return 1; + } + return 0; +} + +get_weapon_with_attachments( weaponname ) +{ + if ( self hasweapon( weaponname ) ) + { + return weaponname; + } + while ( isDefined( level.zombiemode_reusing_pack_a_punch ) && level.zombiemode_reusing_pack_a_punch ) + { + weaponname = tolower( weaponname ); + weaponname = get_base_name( weaponname ); + weapons = self getweaponslist( 1 ); + _a2245 = weapons; + _k2245 = getFirstArrayKey( _a2245 ); + while ( isDefined( _k2245 ) ) + { + weapon = _a2245[ _k2245 ]; + weapon = tolower( weapon ); + weapon_base = get_base_name( weapon ); + if ( weaponname == weapon_base ) + { + return weapon; + } + _k2245 = getNextArrayKey( _a2245, _k2245 ); + } + } + return undefined; +} + +has_weapon_or_attachments( weaponname ) +{ + if ( self hasweapon( weaponname ) ) + { + return 1; + } + while ( isDefined( level.zombiemode_reusing_pack_a_punch ) && level.zombiemode_reusing_pack_a_punch ) + { + weaponname = tolower( weaponname ); + weaponname = get_base_name( weaponname ); + weapons = self getweaponslist( 1 ); + _a2267 = weapons; + _k2267 = getFirstArrayKey( _a2267 ); + while ( isDefined( _k2267 ) ) + { + weapon = _a2267[ _k2267 ]; + weapon = tolower( weapon ); + weapon = get_base_name( weapon ); + if ( weaponname == weapon ) + { + return 1; + } + _k2267 = getNextArrayKey( _a2267, _k2267 ); + } + } + return 0; +} + +has_upgrade( weaponname ) +{ + weaponname = get_base_name( weaponname ); + has_upgrade = 0; + if ( isDefined( level.zombie_weapons[ weaponname ] ) && isDefined( level.zombie_weapons[ weaponname ].upgrade_name ) ) + { + has_upgrade = self has_weapon_or_attachments( level.zombie_weapons[ weaponname ].upgrade_name ); + } + if ( !has_upgrade && weaponname == "knife_ballistic_zm" ) + { + has_weapon = self maps/mp/zombies/_zm_melee_weapon::has_upgraded_ballistic_knife(); + } + return has_upgrade; +} + +has_weapon_or_upgrade( weaponname ) +{ + weaponname = get_base_name( weaponname ); + upgradedweaponname = weaponname; + if ( isDefined( level.zombie_weapons[ weaponname ] ) && isDefined( level.zombie_weapons[ weaponname ].upgrade_name ) ) + { + upgradedweaponname = level.zombie_weapons[ weaponname ].upgrade_name; + } + has_weapon = 0; + if ( isDefined( level.zombie_weapons[ weaponname ] ) ) + { + if ( !self has_weapon_or_attachments( weaponname ) ) + { + has_weapon = self has_upgrade( weaponname ); + } + } + if ( !has_weapon && weaponname == "knife_ballistic_zm" ) + { + has_weapon = self maps/mp/zombies/_zm_melee_weapon::has_any_ballistic_knife(); + } + if ( !has_weapon && is_equipment( weaponname ) ) + { + has_weapon = self is_equipment_active( weaponname ); + } + return has_weapon; +} + +add_shared_ammo_weapon( str_weapon, str_base_weapon ) +{ + level.zombie_weapons[ str_weapon ].shared_ammo_weapon = str_base_weapon; +} + +get_shared_ammo_weapon( base_weapon ) +{ + base_weapon = get_base_name( base_weapon ); + weapons = self getweaponslist( 1 ); + _a2355 = weapons; + _k2355 = getFirstArrayKey( _a2355 ); + while ( isDefined( _k2355 ) ) + { + weapon = _a2355[ _k2355 ]; + weapon = tolower( weapon ); + weapon = get_base_name( weapon ); + if ( !isDefined( level.zombie_weapons[ weapon ] ) && isDefined( level.zombie_weapons_upgraded[ weapon ] ) ) + { + weapon = level.zombie_weapons_upgraded[ weapon ]; + } + if ( isDefined( level.zombie_weapons[ weapon ] ) && isDefined( level.zombie_weapons[ weapon ].shared_ammo_weapon ) && level.zombie_weapons[ weapon ].shared_ammo_weapon == base_weapon ) + { + return weapon; + } + _k2355 = getNextArrayKey( _a2355, _k2355 ); + } + return undefined; +} + +get_player_weapon_with_same_base( weaponname ) +{ + weaponname = tolower( weaponname ); + weaponname = get_base_name( weaponname ); + retweapon = get_weapon_with_attachments( weaponname ); + if ( !isDefined( retweapon ) ) + { + if ( isDefined( level.zombie_weapons[ weaponname ] ) ) + { + retweapon = get_weapon_with_attachments( level.zombie_weapons[ weaponname ].upgrade_name ); + } + else + { + if ( isDefined( level.zombie_weapons_upgraded[ weaponname ] ) ) + { + return get_weapon_with_attachments( level.zombie_weapons_upgraded[ weaponname ] ); + } + } + } + return retweapon; +} + +get_weapon_hint_ammo() +{ + if ( isDefined( level.has_pack_a_punch ) && !level.has_pack_a_punch ) + { + return &"ZOMBIE_WEAPONCOSTAMMO"; + } + else + { + return &"ZOMBIE_WEAPONCOSTAMMO_UPGRADE"; + } +} + +weapon_set_first_time_hint( cost, ammo_cost ) +{ + self sethintstring( get_weapon_hint_ammo(), cost, ammo_cost ); +} + +weapon_spawn_think() +{ + cost = get_weapon_cost( self.zombie_weapon_upgrade ); + ammo_cost = get_ammo_cost( self.zombie_weapon_upgrade ); + is_grenade = weapontype( self.zombie_weapon_upgrade ) == "grenade"; + shared_ammo_weapon = undefined; + second_endon = undefined; + if ( isDefined( self.stub ) ) + { + second_endon = "kill_trigger"; + self.first_time_triggered = self.stub.first_time_triggered; + } + if ( isDefined( self.stub ) && isDefined( self.stub.trigger_per_player ) && self.stub.trigger_per_player ) + { + self thread decide_hide_show_hint( "stop_hint_logic", second_endon, self.parent_player ); + } + else + { + self thread decide_hide_show_hint( "stop_hint_logic", second_endon ); + } + if ( is_grenade ) + { + self.first_time_triggered = 0; + hint = get_weapon_hint( self.zombie_weapon_upgrade ); + self sethintstring( hint, cost ); + } + else if ( !isDefined( self.first_time_triggered ) ) + { + self.first_time_triggered = 0; + if ( isDefined( self.stub ) ) + { + self.stub.first_time_triggered = 0; + } + } + else + { + if ( self.first_time_triggered ) + { + if ( isDefined( level.use_legacy_weapon_prompt_format ) && level.use_legacy_weapon_prompt_format ) + { + self weapon_set_first_time_hint( cost, get_ammo_cost( self.zombie_weapon_upgrade ) ); + } + } + } + for ( ;; ) + { + self waittill( "trigger", player ); + if ( !is_player_valid( player ) ) + { + player thread ignore_triggers( 0.5 ); + continue; + } + else if ( !player can_buy_weapon() ) + { + wait 0.1; + continue; + } + else if ( isDefined( self.stub ) && isDefined( self.stub.require_look_from ) && self.stub.require_look_from ) + { + toplayer = player get_eye() - self.origin; + forward = -1 * anglesToRight( self.angles ); + dot = vectordot( toplayer, forward ); + if ( dot < 0 ) + { + continue; + } + } + else if ( player has_powerup_weapon() ) + { + wait 0.1; + continue; + } + else + { + player_has_weapon = player has_weapon_or_upgrade( self.zombie_weapon_upgrade ); + if ( !player_has_weapon && isDefined( level.weapons_using_ammo_sharing ) && level.weapons_using_ammo_sharing ) + { + shared_ammo_weapon = player get_shared_ammo_weapon( self.zombie_weapon_upgrade ); + if ( isDefined( shared_ammo_weapon ) ) + { + player_has_weapon = 1; + } + } + if ( isDefined( level.pers_upgrade_nube ) && level.pers_upgrade_nube ) + { + player_has_weapon = maps/mp/zombies/_zm_pers_upgrades_functions::pers_nube_should_we_give_raygun( player_has_weapon, player, self.zombie_weapon_upgrade ); + } + cost = get_weapon_cost( self.zombie_weapon_upgrade ); + if ( player maps/mp/zombies/_zm_pers_upgrades_functions::is_pers_double_points_active() ) + { + cost = int( cost / 2 ); + } + if ( !player_has_weapon ) + { + if ( player.score >= cost ) + { + if ( self.first_time_triggered == 0 ) + { + self show_all_weapon_buys( player, cost, ammo_cost, is_grenade ); + } + player maps/mp/zombies/_zm_score::minus_to_player_score( cost, 1 ); + bbprint( "zombie_uses", "playername %s playerscore %d round %d cost %d name %s x %f y %f z %f type %s", player.name, player.score, level.round_number, cost, self.zombie_weapon_upgrade, self.origin, "weapon" ); + level notify( "weapon_bought" ); + if ( self.zombie_weapon_upgrade == "riotshield_zm" ) + { + player maps/mp/zombies/_zm_equipment::equipment_give( "riotshield_zm" ); + if ( isDefined( player.player_shield_reset_health ) ) + { + player [[ player.player_shield_reset_health ]](); + } + } + else if ( self.zombie_weapon_upgrade == "jetgun_zm" ) + { + player maps/mp/zombies/_zm_equipment::equipment_give( "jetgun_zm" ); + } + else + { + if ( is_lethal_grenade( self.zombie_weapon_upgrade ) ) + { + player takeweapon( player get_player_lethal_grenade() ); + player set_player_lethal_grenade( self.zombie_weapon_upgrade ); + } + str_weapon = self.zombie_weapon_upgrade; + if ( isDefined( level.pers_upgrade_nube ) && level.pers_upgrade_nube ) + { + str_weapon = maps/mp/zombies/_zm_pers_upgrades_functions::pers_nube_weapon_upgrade_check( player, str_weapon ); + } + player weapon_give( str_weapon ); + } + player maps/mp/zombies/_zm_stats::increment_client_stat( "wallbuy_weapons_purchased" ); + player maps/mp/zombies/_zm_stats::increment_player_stat( "wallbuy_weapons_purchased" ); + } + else + { + play_sound_on_ent( "no_purchase" ); + player maps/mp/zombies/_zm_audio::create_and_play_dialog( "general", "no_money_weapon" ); + } + } + else str_weapon = self.zombie_weapon_upgrade; + if ( isDefined( shared_ammo_weapon ) ) + { + str_weapon = shared_ammo_weapon; + } + if ( isDefined( level.pers_upgrade_nube ) && level.pers_upgrade_nube ) + { + str_weapon = maps/mp/zombies/_zm_pers_upgrades_functions::pers_nube_weapon_ammo_check( player, str_weapon ); + } + if ( isDefined( self.hacked ) && self.hacked ) + { + if ( !player has_upgrade( str_weapon ) ) + { + ammo_cost = 4500; + } + else + { + ammo_cost = get_ammo_cost( str_weapon ); + } + } + else + { + if ( player has_upgrade( str_weapon ) ) + { + ammo_cost = 4500; + break; + } + else + { + ammo_cost = get_ammo_cost( str_weapon ); + } + } + if ( isDefined( player.pers_upgrades_awarded[ "nube" ] ) && player.pers_upgrades_awarded[ "nube" ] ) + { + ammo_cost = maps/mp/zombies/_zm_pers_upgrades_functions::pers_nube_override_ammo_cost( player, self.zombie_weapon_upgrade, ammo_cost ); + } + if ( player maps/mp/zombies/_zm_pers_upgrades_functions::is_pers_double_points_active() ) + { + ammo_cost = int( ammo_cost / 2 ); + } + if ( str_weapon == "riotshield_zm" ) + { + play_sound_on_ent( "no_purchase" ); + } + else if ( player.score >= ammo_cost ) + { + if ( self.first_time_triggered == 0 ) + { + self show_all_weapon_buys( player, cost, ammo_cost, is_grenade ); + } + if ( player has_upgrade( str_weapon ) ) + { + player maps/mp/zombies/_zm_stats::increment_client_stat( "upgraded_ammo_purchased" ); + player maps/mp/zombies/_zm_stats::increment_player_stat( "upgraded_ammo_purchased" ); + } + else + { + player maps/mp/zombies/_zm_stats::increment_client_stat( "ammo_purchased" ); + player maps/mp/zombies/_zm_stats::increment_player_stat( "ammo_purchased" ); + } + if ( str_weapon == "riotshield_zm" ) + { + if ( isDefined( player.player_shield_reset_health ) ) + { + ammo_given = player [[ player.player_shield_reset_health ]](); + } + else + { + ammo_given = 0; + } + } + else if ( player has_upgrade( str_weapon ) ) + { + ammo_given = player ammo_give( level.zombie_weapons[ str_weapon ].upgrade_name ); + } + else + { + ammo_given = player ammo_give( str_weapon ); + } + if ( ammo_given ) + { + player maps/mp/zombies/_zm_score::minus_to_player_score( ammo_cost, 1 ); + bbprint( "zombie_uses", "playername %s playerscore %d round %d cost %d name %s x %f y %f z %f type %s", player.name, player.score, level.round_number, ammo_cost, str_weapon, self.origin, "ammo" ); + } + } + else play_sound_on_ent( "no_purchase" ); + if ( isDefined( level.custom_generic_deny_vo_func ) ) + { + player [[ level.custom_generic_deny_vo_func ]](); + } + else + { + player maps/mp/zombies/_zm_audio::create_and_play_dialog( "general", "no_money_weapon" ); + } + if ( isDefined( self.stub ) && isDefined( self.stub.prompt_and_visibility_func ) ) + { + self [[ self.stub.prompt_and_visibility_func ]]( player ); + } + } + } +} + +show_all_weapon_buys( player, cost, ammo_cost, is_grenade ) +{ + model = getent( self.target, "targetname" ); + if ( isDefined( model ) ) + { + model thread weapon_show( player ); + } + else + { + if ( isDefined( self.clientfieldname ) ) + { + level setclientfield( self.clientfieldname, 1 ); + } + } + self.first_time_triggered = 1; + if ( isDefined( self.stub ) ) + { + self.stub.first_time_triggered = 1; + } + if ( !is_grenade ) + { + self weapon_set_first_time_hint( cost, ammo_cost ); + } + if ( isDefined( level.dont_link_common_wallbuys ) && !level.dont_link_common_wallbuys && isDefined( level._spawned_wallbuys ) ) + { + i = 0; + while ( i < level._spawned_wallbuys.size ) + { + wallbuy = level._spawned_wallbuys[ i ]; + if ( isDefined( self.stub ) && isDefined( wallbuy.trigger_stub ) && self.stub.clientfieldname == wallbuy.trigger_stub.clientfieldname ) + { + i++; + continue; + } + else + { + if ( self.zombie_weapon_upgrade == wallbuy.zombie_weapon_upgrade ) + { + if ( isDefined( wallbuy.trigger_stub ) && isDefined( wallbuy.trigger_stub.clientfieldname ) ) + { + level setclientfield( wallbuy.trigger_stub.clientfieldname, 1 ); + } + else + { + if ( isDefined( wallbuy.target ) ) + { + model = getent( wallbuy.target, "targetname" ); + if ( isDefined( model ) ) + { + model thread weapon_show( player ); + } + } + } + if ( isDefined( wallbuy.trigger_stub ) ) + { + wallbuy.trigger_stub.first_time_triggered = 1; + if ( isDefined( wallbuy.trigger_stub.trigger ) ) + { + wallbuy.trigger_stub.trigger.first_time_triggered = 1; + if ( !is_grenade ) + { + wallbuy.trigger_stub.trigger weapon_set_first_time_hint( cost, ammo_cost ); + } + } + i++; + continue; + } + else + { + if ( !is_grenade ) + { + wallbuy weapon_set_first_time_hint( cost, ammo_cost ); + } + } + } + } + i++; + } + } +} + +weapon_show( player ) +{ + player_angles = vectorToAngles( player.origin - self.origin ); + player_yaw = player_angles[ 1 ]; + weapon_yaw = self.angles[ 1 ]; + if ( isDefined( self.script_int ) ) + { + weapon_yaw -= self.script_int; + } + yaw_diff = absAngleClamp180( player_yaw - weapon_yaw ); + if ( yaw_diff > 0 ) + { + yaw = weapon_yaw - 90; + } + else + { + yaw = weapon_yaw + 90; + } + self.og_origin = self.origin; + self.origin += anglesToForward( ( 0, yaw, 0 ) ) * 8; + wait 0.05; + self show(); + play_sound_at_pos( "weapon_show", self.origin, self ); + time = 1; + if ( !isDefined( self._linked_ent ) ) + { + self moveto( self.og_origin, time ); + } +} + +get_pack_a_punch_weapon_options( weapon ) +{ + if ( !isDefined( self.pack_a_punch_weapon_options ) ) + { + self.pack_a_punch_weapon_options = []; + } + if ( !is_weapon_upgraded( weapon ) ) + { + return self calcweaponoptions( 0, 0, 0, 0, 0 ); + } + if ( isDefined( self.pack_a_punch_weapon_options[ weapon ] ) ) + { + return self.pack_a_punch_weapon_options[ weapon ]; + } + smiley_face_reticle_index = 1; + base = get_base_name( weapon ); + camo_index = 39; + if ( level.script == "zm_prison" ) + { + camo_index = 40; + } + else + { + if ( level.script == "zm_tomb" ) + { + camo_index = 45; + } + } + lens_index = randomintrange( 0, 6 ); + reticle_index = randomintrange( 0, 16 ); + reticle_color_index = randomintrange( 0, 6 ); + plain_reticle_index = 16; + r = randomint( 10 ); + use_plain = r < 3; + if ( base == "saritch_upgraded_zm" ) + { + reticle_index = smiley_face_reticle_index; + } + else + { + if ( use_plain ) + { + reticle_index = plain_reticle_index; + } + } +/* +/# + if ( getDvarInt( #"471F9AB9" ) >= 0 ) + { + reticle_index = getDvarInt( #"471F9AB9" ); +#/ + } +*/ + scary_eyes_reticle_index = 8; + purple_reticle_color_index = 3; + if ( reticle_index == scary_eyes_reticle_index ) + { + reticle_color_index = purple_reticle_color_index; + } + letter_a_reticle_index = 2; + pink_reticle_color_index = 6; + if ( reticle_index == letter_a_reticle_index ) + { + reticle_color_index = pink_reticle_color_index; + } + letter_e_reticle_index = 7; + green_reticle_color_index = 1; + if ( reticle_index == letter_e_reticle_index ) + { + reticle_color_index = green_reticle_color_index; + } + self.pack_a_punch_weapon_options[ weapon ] = self calcweaponoptions( camo_index, lens_index, reticle_index, reticle_color_index ); + return self.pack_a_punch_weapon_options[ weapon ]; +} + +weapon_give( weapon, is_upgrade, magic_box, nosound ) +{ + primaryweapons = self getweaponslistprimaries(); + current_weapon = self getcurrentweapon(); + current_weapon = self maps/mp/zombies/_zm_weapons::switch_from_alt_weapon( current_weapon ); + /* +/# + assert( self player_can_use_content( weapon ) ); +#/ + */ + if ( !isDefined( is_upgrade ) ) + { + is_upgrade = 0; + } + weapon_limit = get_player_weapon_limit( self ); + if ( is_equipment( weapon ) ) + { + self maps/mp/zombies/_zm_equipment::equipment_give( weapon ); + } + if ( weapon == "riotshield_zm" ) + { + if ( isDefined( self.player_shield_reset_health ) ) + { + self [[ self.player_shield_reset_health ]](); + } + } + if ( self hasweapon( weapon ) ) + { + if ( issubstr( weapon, "knife_ballistic_" ) ) + { + self notify( "zmb_lost_knife" ); + } + self givestartammo( weapon ); + if ( !is_offhand_weapon( weapon ) ) + { + self switchtoweapon( weapon ); + } + return; + } + if ( is_melee_weapon( weapon ) ) + { + current_weapon = maps/mp/zombies/_zm_melee_weapon::change_melee_weapon( weapon, current_weapon ); + } + else if ( is_lethal_grenade( weapon ) ) + { + old_lethal = self get_player_lethal_grenade(); + if ( isDefined( old_lethal ) && old_lethal != "" ) + { + self takeweapon( old_lethal ); + unacquire_weapon_toggle( old_lethal ); + } + self set_player_lethal_grenade( weapon ); + } + else if ( is_tactical_grenade( weapon ) ) + { + old_tactical = self get_player_tactical_grenade(); + if ( isDefined( old_tactical ) && old_tactical != "" ) + { + self takeweapon( old_tactical ); + unacquire_weapon_toggle( old_tactical ); + } + self set_player_tactical_grenade( weapon ); + } + else + { + if ( is_placeable_mine( weapon ) ) + { + old_mine = self get_player_placeable_mine(); + if ( isDefined( old_mine ) ) + { + self takeweapon( old_mine ); + unacquire_weapon_toggle( old_mine ); + } + self set_player_placeable_mine( weapon ); + } + } + if ( !is_offhand_weapon( weapon ) ) + { + self maps/mp/zombies/_zm_weapons::take_fallback_weapon(); + } + if ( primaryweapons.size >= weapon_limit ) + { + if ( is_placeable_mine( current_weapon ) || is_equipment( current_weapon ) ) + { + current_weapon = undefined; + } + if ( isDefined( current_weapon ) ) + { + if ( !is_offhand_weapon( weapon ) ) + { + if ( current_weapon == "tesla_gun_zm" ) + { + level.player_drops_tesla_gun = 1; + } + if ( issubstr( current_weapon, "knife_ballistic_" ) ) + { + self notify( "zmb_lost_knife" ); + } + self takeweapon( current_weapon ); + unacquire_weapon_toggle( current_weapon ); + } + } + } + if ( isDefined( level.zombiemode_offhand_weapon_give_override ) ) + { + if ( self [[ level.zombiemode_offhand_weapon_give_override ]]( weapon ) ) + { + return; + } + } + if ( weapon == "cymbal_monkey_zm" ) + { + self maps/mp/zombies/_zm_weap_cymbal_monkey::player_give_cymbal_monkey(); + self play_weapon_vo( weapon, magic_box ); + return; + } + else if ( issubstr( weapon, "knife_ballistic_" ) ) + { + weapon = self maps/mp/zombies/_zm_melee_weapon::give_ballistic_knife( weapon, issubstr( weapon, "upgraded" ) ); + } + else + { + if ( weapon == "claymore_zm" ) + { + self thread maps/mp/zombies/_zm_weap_claymore::claymore_setup(); + self play_weapon_vo( weapon, magic_box ); + return; + } + } + if ( isDefined( level.zombie_weapons_callbacks ) && isDefined( level.zombie_weapons_callbacks[ weapon ] ) ) + { + self thread [[ level.zombie_weapons_callbacks[ weapon ] ]](); + play_weapon_vo( weapon, magic_box ); + return; + } + if ( isDefined( nosound ) && !nosound ) + { + self play_sound_on_ent( "purchase" ); + } + if ( weapon == "ray_gun_zm" ) + { + playsoundatposition( "mus_raygun_stinger", ( 0, 0, 0 ) ); + } + if ( !is_weapon_upgraded( weapon ) ) + { + self giveweapon( weapon ); + } + else + { + self giveweapon( weapon, 0, self get_pack_a_punch_weapon_options( weapon ) ); + } + acquire_weapon_toggle( weapon, self ); + self givestartammo( weapon ); + if ( !is_offhand_weapon( weapon ) ) + { + if ( !is_melee_weapon( weapon ) ) + { + self switchtoweapon( weapon ); + } + else + { + self switchtoweapon( current_weapon ); + } + } + self play_weapon_vo( weapon, magic_box ); +} + +play_weapon_vo( weapon, magic_box ) +{ + if ( isDefined( level._audio_custom_weapon_check ) ) + { + type = self [[ level._audio_custom_weapon_check ]]( weapon, magic_box ); + } + else + { + type = self weapon_type_check( weapon ); + } + if ( type == "crappy" ) + { + return; + } + if ( type != "favorite" && type != "upgrade" ) + { + type = weapon; + } + self maps/mp/zombies/_zm_audio::create_and_play_dialog( "weapon_pickup", type ); +} + +weapon_type_check( weapon ) +{ + if ( !isDefined( self.entity_num ) ) + { + return "crappy"; + } + weapon = get_base_name( weapon ); + if ( self is_favorite_weapon( weapon ) ) + { + return "favorite"; + } + if ( issubstr( weapon, "upgraded" ) ) + { + return "upgrade"; + } + else + { + return level.zombie_weapons[ weapon ].vox; + } +} + +get_player_index( player ) +{ +/* +/# + assert( isplayer( player ) ); +#/ +/# + assert( isDefined( player.characterindex ) ); +#/ +/# + if ( player.entity_num == 0 && getDvar( #"2222BA21" ) != "" ) + { + new_vo_index = getDvarInt( #"2222BA21" ); + return new_vo_index; +#/ + } + */ + return player.characterindex; +} + +ammo_give( weapon ) +{ + give_ammo = 0; + if ( !is_offhand_weapon( weapon ) ) + { + weapon = get_weapon_with_attachments( weapon ); + if ( isDefined( weapon ) ) + { + stockmax = 0; + stockmax = weaponstartammo( weapon ); + clipcount = self getweaponammoclip( weapon ); + currstock = self getammocount( weapon ); + if ( ( currstock - clipcount ) >= stockmax ) + { + give_ammo = 0; + } + else + { + give_ammo = 1; + } + } + } + else + { + if ( self has_weapon_or_upgrade( weapon ) ) + { + if ( self getammocount( weapon ) < weaponmaxammo( weapon ) ) + { + give_ammo = 1; + } + } + } + if ( give_ammo ) + { + self play_sound_on_ent( "purchase" ); + self givemaxammo( weapon ); + alt_weap = weaponaltweaponname( weapon ); + if ( alt_weap != "none" ) + { + self givemaxammo( alt_weap ); + } + return 1; + } + if ( !give_ammo ) + { + return 0; + } +} + +get_player_weapondata( player, weapon ) +{ + weapondata = []; + if ( !isDefined( weapon ) ) + { + weapondata[ "name" ] = player getcurrentweapon(); + } + else + { + weapondata[ "name" ] = weapon; + } + weapondata[ "dw_name" ] = weapondualwieldweaponname( weapondata[ "name" ] ); + weapondata[ "alt_name" ] = weaponaltweaponname( weapondata[ "name" ] ); + if ( weapondata[ "name" ] != "none" ) + { + weapondata[ "clip" ] = player getweaponammoclip( weapondata[ "name" ] ); + weapondata[ "stock" ] = player getweaponammostock( weapondata[ "name" ] ); + weapondata[ "fuel" ] = player getweaponammofuel( weapondata[ "name" ] ); + weapondata[ "heat" ] = player isweaponoverheating( 1, weapondata[ "name" ] ); + weapondata[ "overheat" ] = player isweaponoverheating( 0, weapondata[ "name" ] ); + } + else + { + weapondata[ "clip" ] = 0; + weapondata[ "stock" ] = 0; + weapondata[ "fuel" ] = 0; + weapondata[ "heat" ] = 0; + weapondata[ "overheat" ] = 0; + } + if ( weapondata[ "dw_name" ] != "none" ) + { + weapondata[ "lh_clip" ] = player getweaponammoclip( weapondata[ "dw_name" ] ); + } + else + { + weapondata[ "lh_clip" ] = 0; + } + if ( weapondata[ "alt_name" ] != "none" ) + { + weapondata[ "alt_clip" ] = player getweaponammoclip( weapondata[ "alt_name" ] ); + weapondata[ "alt_stock" ] = player getweaponammostock( weapondata[ "alt_name" ] ); + } + else + { + weapondata[ "alt_clip" ] = 0; + weapondata[ "alt_stock" ] = 0; + } + return weapondata; +} + +weapon_is_better( left, right ) +{ + if ( left != right ) + { + left_upgraded = !isDefined( level.zombie_weapons[ left ] ); + right_upgraded = !isDefined( level.zombie_weapons[ right ] ); + if ( left_upgraded && right_upgraded ) + { + leftatt = get_attachment_index( left ); + rightatt = get_attachment_index( right ); + return leftatt > rightatt; + } + else + { + if ( left_upgraded ) + { + return 1; + } + } + } + return 0; +} + +merge_weapons( oldweapondata, newweapondata ) +{ + weapondata = []; + weapondata[ "name" ] = "none"; + if ( weapon_is_better( oldweapondata[ "name" ], newweapondata[ "name" ] ) ) + { + weapondata[ "name" ] = oldweapondata[ "name" ]; + } + else + { + weapondata[ "name" ] = newweapondata[ "name" ]; + } + name = weapondata[ "name" ]; + dw_name = weapondualwieldweaponname( name ); + alt_name = weaponaltweaponname( name ); + if ( name != "none" ) + { + weapondata[ "clip" ] = newweapondata[ "clip" ] + oldweapondata[ "clip" ]; + weapondata[ "clip" ] = int( min( weapondata[ "clip" ], weaponclipsize( name ) ) ); + weapondata[ "stock" ] = newweapondata[ "stock" ] + oldweapondata[ "stock" ]; + weapondata[ "stock" ] = int( min( weapondata[ "stock" ], weaponmaxammo( name ) ) ); + weapondata[ "fuel" ] = newweapondata[ "fuel" ] + oldweapondata[ "fuel" ]; + weapondata[ "fuel" ] = int( min( weapondata[ "fuel" ], weaponfuellife( name ) ) ); + weapondata[ "heat" ] = int( min( newweapondata[ "heat" ], oldweapondata[ "heat" ] ) ); + weapondata[ "overheat" ] = int( min( newweapondata[ "overheat" ], oldweapondata[ "overheat" ] ) ); + } + if ( dw_name != "none" ) + { + weapondata[ "lh_clip" ] = newweapondata[ "lh_clip" ] + oldweapondata[ "lh_clip" ]; + weapondata[ "lh_clip" ] = int( min( weapondata[ "lh_clip" ], weaponclipsize( dw_name ) ) ); + } + if ( alt_name != "none" ) + { + weapondata[ "alt_clip" ] = newweapondata[ "alt_clip" ] + oldweapondata[ "alt_clip" ]; + weapondata[ "alt_clip" ] = int( min( weapondata[ "alt_clip" ], weaponclipsize( alt_name ) ) ); + weapondata[ "alt_stock" ] = newweapondata[ "alt_stock" ] + oldweapondata[ "alt_stock" ]; + weapondata[ "alt_stock" ] = int( min( weapondata[ "alt_stock" ], weaponmaxammo( alt_name ) ) ); + } + return weapondata; +} + +weapondata_give( weapondata ) +{ + current = get_player_weapon_with_same_base( weapondata[ "name" ] ); + if ( isDefined( current ) ) + { + curweapondata = get_player_weapondata( self, current ); + self takeweapon( current ); + weapondata = merge_weapons( curweapondata, weapondata ); + } + name = weapondata[ "name" ]; + weapon_give( name, undefined, undefined, 1 ); + dw_name = weapondualwieldweaponname( name ); + alt_name = weaponaltweaponname( name ); + if ( name != "none" ) + { + self setweaponammoclip( name, weapondata[ "clip" ] ); + self setweaponammostock( name, weapondata[ "stock" ] ); + if ( isDefined( weapondata[ "fuel" ] ) ) + { + self setweaponammofuel( name, weapondata[ "fuel" ] ); + } + if ( isDefined( weapondata[ "heat" ] ) && isDefined( weapondata[ "overheat" ] ) ) + { + self setweaponoverheating( weapondata[ "overheat" ], weapondata[ "heat" ], name ); + } + } + if ( dw_name != "none" ) + { + self setweaponammoclip( dw_name, weapondata[ "lh_clip" ] ); + } + if ( alt_name != "none" ) + { + self setweaponammoclip( alt_name, weapondata[ "alt_clip" ] ); + self setweaponammostock( alt_name, weapondata[ "alt_stock" ] ); + } +} + +register_zombie_weapon_callback( str_weapon, func ) +{ + if ( !isDefined( level.zombie_weapons_callbacks ) ) + { + level.zombie_weapons_callbacks = []; + } + if ( !isDefined( level.zombie_weapons_callbacks[ str_weapon ] ) ) + { + level.zombie_weapons_callbacks[ str_weapon ] = func; + } +} + + + diff --git a/Fixed Zombies GSCs for compiling/readme.md b/Fixed Zombies GSCs for compiling/readme.md index 2aba4fc..eb444ce 100644 --- a/Fixed Zombies GSCs for compiling/readme.md +++ b/Fixed Zombies GSCs for compiling/readme.md @@ -12,6 +12,7 @@ patch_zm/maps/mp/zombies/_zm_hackables_packapunch.gsc patch_zm/maps/mp/zombies/_zm_hackables_perks.gsc patch_zm/maps/mp/zombies/_zm_hackables_powerups.gsc patch_zm/maps/mp/zombies/_zm_hackables_wallbuys.gsc +patch_zm/maps/mp/zombies/_zm_perk_electric_cherry.gsc patch_zm/maps/mp/zombies/_zm_pers_upgrades.gsc patch_zm/maps/mp/zombies/_zm_pers_upgrades_functions.gsc patch_zm/maps/mp/zombies/_zm_pers_upgrades_system.gsc @@ -31,22 +32,32 @@ zm_transit_patch/maps/mp/zm_transit_utility.gsc zm_transit_patch/maps/mp/gametypes_zm/zgrief.gsc ``` ### The following scripts compile and run successfully with major errors: +``` +patch_zm/maps/mp/zombies/_zm_magicbox.gsc +patch_zm/maps/mp/zombies/_zm_perks.gsc +patch_zm/maps/mp/zombies/_zm_powerups.gsc +patch_zm/maps/mp/zombies/_zm_weapons.gsc +``` + +``` +patch_zm/maps/mp/gametypes_zm/_zm_gametype.gsc +``` + ``` zm_transit_patch/maps/mp/zombies/_zm_weap_jetgun.gsc ``` +``` +zm_highrise_patch/maps/mp/zombies/_zm_weap_slipgun.gsc +``` ### The following scripts compile and run serverside but clients cannot join due to exe_client_field_mismatch ``` -patch_zm/maps/mp/zombies/_zm_weapons.gsc +patch_zm/maps/mp/zombies/_zm.gsc patch_zm/maps/mp/zombies/_zm_gump.gsc patch_zm/maps/mp/zombies/_zm_equipment.gsc -patch_zm/maps/mp/zombies/_zm_perks.gsc ``` ### The following scripts compile but cause a minidump or other severe error: ``` patch_zm/maps/mp/zombies/_load.gsc -patch_zm/maps/mp/zombies/_zm.gsc -patch_zm/maps/mp/zombies/_zm_powerups.gsc -patch_zm/maps/mp/zombies/_zm_magicbox.gsc ``` ### notes: diff --git a/Fixed Zombies GSCs for compiling/zm_highrise_patch/maps/mp/zombies/_zm_weap_slipgun.gsc b/Fixed Zombies GSCs for compiling/zm_highrise_patch/maps/mp/zombies/_zm_weap_slipgun.gsc new file mode 100644 index 0000000..8fda028 --- /dev/null +++ b/Fixed Zombies GSCs for compiling/zm_highrise_patch/maps/mp/zombies/_zm_weap_slipgun.gsc @@ -0,0 +1,891 @@ +#include maps/mp/zombies/_zm_audio; +#include maps/mp/zombies/_zm_powerups; +#include maps/mp/zombies/_zm_ai_basic; +#include maps/mp/animscripts/zm_shared; +#include maps/mp/animscripts/zm_utility; +#include maps/mp/zombies/_zm; +#include maps/mp/zombies/_zm_spawner; +#include maps/mp/gametypes_zm/_weaponobjects; +#include maps/mp/zombies/_zm_equipment; +#include maps/mp/zombies/_zm_weapons; +#include maps/mp/zombies/_zm_utility; +#include maps/mp/_utility; +#include common_scripts/utility; + +set_zombie_var_once( var, value, is_float, column, is_team_based ) +{ + if ( !isDefined( level.zombie_vars ) || !isDefined( level.zombie_vars[ var ] ) ) + { + set_zombie_var( var, value, is_float, column, is_team_based ); + } +} + +init() +{ + if ( !maps/mp/zombies/_zm_weapons::is_weapon_included( "slipgun_zm" ) ) + { + return; + } + precachemodel( "t5_weapon_crossbow_bolt" ); + precacheitem( "slip_bolt_zm" ); + precacheitem( "slip_bolt_upgraded_zm" ); + if ( is_true( level.slipgun_as_equipment ) ) + { + maps/mp/zombies/_zm_equipment::register_equipment( "slipgun_zm", &"ZM_HIGHRISE_EQUIP_SLIPGUN_PICKUP_HINT_STRING", &"ZM_HIGHRISE_EQUIP_SLIPGUN_HOWTO", "jetgun_zm_icon", "slipgun", ::slipgun_activation_watcher_thread, ::transferslipgun, ::dropslipgun, ::pickupslipgun ); + maps/mp/zombies/_zm_equipment::enemies_ignore_equipment( "slipgun_zm" ); + maps/mp/gametypes_zm/_weaponobjects::createretrievablehint( "slipgun", &"ZM_HIGHRISE_EQUIP_SLIPGUN_PICKUP_HINT_STRING" ); + } + set_zombie_var_once( "slipgun_reslip_max_spots", 8 ); + set_zombie_var_once( "slipgun_reslip_rate", 6 ); + set_zombie_var_once( "slipgun_max_kill_chain_depth", 16 ); + set_zombie_var_once( "slipgun_max_kill_round", 100 ); + set_zombie_var_once( "slipgun_chain_radius", 120 ); + set_zombie_var_once( "slipgun_chain_wait_min", 0.75, 1 ); + set_zombie_var_once( "slipgun_chain_wait_max", 1.5, 1 ); + level.slippery_spot_count = 0; + level.sliquifier_distance_checks = 0; + maps/mp/zombies/_zm_spawner::register_zombie_damage_callback( ::slipgun_zombie_damage_response ); + maps/mp/zombies/_zm_spawner::register_zombie_death_animscript_callback( ::slipgun_zombie_death_response ); + level._effect[ "slipgun_explode" ] = loadfx( "weapon/liquifier/fx_liquifier_goo_explo" ); + level._effect[ "slipgun_splatter" ] = loadfx( "maps/zombie/fx_zmb_goo_splat" ); + level._effect[ "slipgun_simmer" ] = loadfx( "weapon/liquifier/fx_liquifier_goo_sizzle" ); + level._effect[ "slipgun_viewmodel_eject" ] = loadfx( "weapon/liquifier/fx_liquifier_clip_eject" ); + level._effect[ "slipgun_viewmodel_reload" ] = loadfx( "weapon/liquifier/fx_liquifier_reload_steam" ); + onplayerconnect_callback( ::slipgun_player_connect ); + thread wait_init_damage(); +} + +wait_init_damage() +{ + while ( !isDefined( level.zombie_vars ) || !isDefined( level.zombie_vars[ "zombie_health_start" ] ) ) + { + wait 1; + } + wait 1; + level.slipgun_damage = maps/mp/zombies/_zm::ai_zombie_health( level.zombie_vars[ "slipgun_max_kill_round" ] ); + level.slipgun_damage_mod = "MOD_PROJECTILE_SPLASH"; +} + +slipgun_player_connect() +{ + self thread watch_for_slip_bolt(); +} + +watch_for_slip_bolt() +{ + self endon( "death" ); + self endon( "disconnect" ); + for ( ;; ) + { + self waittill( "grenade_fire", grenade, weaponname, parent ); + self.num_sliquifier_kills = 0; + switch( weaponname ) + { + case "slip_bolt_zm": + grenade thread slip_bolt( self, 0 ); + break; + continue; + case "slip_bolt_upgraded_zm": + grenade thread slip_bolt( self, 1 ); + break; + continue; + } + } +} + +slip_bolt( player, upgraded ) +{ + startpos = player getweaponmuzzlepoint(); + self waittill( "explode", position ); + duration = 24; + if ( upgraded ) + { + duration = 36; + } + thread add_slippery_spot( position, duration, startpos ); +} + +dropslipgun() +{ + item = self maps/mp/zombies/_zm_equipment::placed_equipment_think( "t6_wpn_zmb_slipgun_world", "slipgun_zm", self.origin + vectorScale( ( 0, 0, 1 ), 30 ), self.angles ); + if ( isDefined( item ) ) + { + item.original_owner = self; + item.owner = undefined; + item.name = "slipgun_zm"; + item.requires_pickup = 1; + item.clipammo = self getweaponammoclip( item.name ); + item.stockammo = self getweaponammostock( item.name ); + } + self takeweapon( "slipgun_zm" ); + return item; +} + +pickupslipgun( item ) +{ + item.owner = self; + self giveweapon( item.name ); + if ( isDefined( item.clipammo ) && isDefined( item.stockammo ) ) + { + self setweaponammoclip( item.name, item.clipammo ); + self setweaponammostock( item.name, item.stockammo ); + item.clipammo = undefined; + item.stockammo = undefined; + } +} + +transferslipgun( fromplayer, toplayer ) +{ + toplayer notify( "slipgun_zm_taken" ); + fromplayer notify( "slipgun_zm_taken" ); +} + +slipgun_activation_watcher_thread() +{ + self endon( "zombified" ); + self endon( "disconnect" ); + self endon( "slipgun_zm_taken" ); + while ( 1 ) + { + self waittill_either( "slipgun_zm_activate", "slipgun_zm_deactivate" ); + } +} + +slipgun_debug_circle( origin, radius, seconds, onslope, parent, start ) +{ +/* +/# + if ( getDvarInt( #"6136A815" ) ) + { + frames = int( 20 * seconds ); + if ( isDefined( parent ) ) + { + time = seconds; + frames = 1; + while ( time > 0 ) + { + morigin = origin + ( parent.origin - start ); + if ( isDefined( onslope ) && onslope ) + { + circle( morigin, radius, ( 0, 0, 1 ), 0, 1, frames ); + } + else + { + circle( morigin, radius, ( 0, 0, 1 ), 0, 1, frames ); + } + time -= 0,05; + wait 0,05; + } + } + else if ( isDefined( onslope ) && onslope ) + { + circle( origin, radius, ( 0, 0, 1 ), 0, 1, frames ); + return; + } + else + { + circle( origin, radius, ( 0, 0, 1 ), 0, 1, frames ); +#/ + } + } +*/ +} + +slipgun_debug_line( start, end, color, seconds ) +{ +/* +/# + if ( getDvarInt( #"6136A815" ) ) + { + frames = int( 20 * seconds ); + line( start, end, color, 1, 0, frames ); +#/ + } +*/ +} + +canzombieongoofall() +{ + if ( is_true( self.is_inert ) ) + { + return 0; + } + if ( is_true( self.is_traversing ) ) + { + return 0; + } + if ( is_true( self.barricade_enter ) ) + { + return 0; + } + if ( randomint( 100 ) < 20 ) + { + trace = groundtrace( self.origin + vectorScale( ( 0, 0, 1 ), 5 ), self.origin + vectorScale( ( 0, 0, 1 ), 300 ), 0, undefined ); + origin = trace[ "position" ]; + groundnormal = trace[ "normal" ]; + if ( distancesquared( self.origin, origin ) > 256 ) + { + return 0; + } + dot = vectordot( ( 0, 0, 1 ), groundnormal ); + if ( dot < 0.9 ) + { + return 0; + } + trace_origin = self.origin + vectorScale( anglesToForward( self.angles ), 200 ); + trace = groundtrace( trace_origin + vectorScale( ( 0, 0, 1 ), 5 ), self.origin + vectorScale( ( 0, 0, 1 ), 300 ), 0, undefined ); + origin = trace[ "position" ]; + groundnormal = trace[ "normal" ]; + if ( distancesquared( trace_origin, origin ) > 256 ) + { + return 0; + } + dot = vectordot( ( 0, 0, 1 ), groundnormal ); + if ( dot < 0.9 ) + { + return 0; + } + return 1; + } + return 0; +} + +zombiemoveongoo() +{ + self endon( "death" ); + self endon( "removed" ); + level endon( "intermission" ); + if ( is_true( self.sliding_on_goo ) ) + { + return; + } + self notify( "endOnGoo" ); + self endon( "endOnGoo" ); + self notify( "stop_zombie_goto_entrance" ); + self notify( "stop_find_flesh" ); + self notify( "zombie_acquire_enemy" ); + self.goo_last_vel = self getvelocity(); + self.goo_last_pos = self.origin; + slide_direction = anglesToForward( self.angles ); + self animmode( "slide" ); + self orientmode( "face enemy" ); + self.forcemovementscriptstate = 1; + self.ai_state = "zombieMoveOnGoo"; + self maps/mp/zombies/_zm_spawner::zombie_history( "zombieMoveOnGoo " + getTime() ); + self.sliding_on_goo = 0; + self thread zombiemoveongoo_on_killanimscript(); + for ( ;; ) + { + while ( 1 ) + { + if ( isDefined( self.is_on_goo ) ) + { + self_on_goo = self.is_on_goo; + } + velocity = self getvelocity(); + velocitylength = length( self getvelocity() ); + if ( isDefined( self.has_legs ) ) + { + iscrawler = !self.has_legs; + } + isleaper = self is_leaper(); + while ( is_true( self.is_leaping ) ) + { + wait 0.1; + } + if ( !self_on_goo ) + { + self animcustom( ::zombie_moveongoo_animcustom_recover ); + self waittill( "zombie_MoveOnGoo_animCustom_recover_done" ); + break; + } + else + { + if ( velocitylength <= 0.2 ) + { + self animmode( "normal" ); + wait 0.1; + self animmode( "slide" ); + } + if ( !self.sliding_on_goo || !issubstr( self.zombie_move_speed, "slide" ) ) + { + if ( !iscrawler && !isleaper && !isDefined( self.fell_while_sliding ) && canzombieongoofall() ) + { + self animcustom( ::zombie_moveongoo_animcustom_fall ); + self waittill( "zombie_MoveOnGoo_animCustom_fall_done" ); + } + } + else self.sliding_on_goo = 1; + if ( velocitylength <= 0.2 ) + { + wait 0.1; + } + self animmode( "slide" ); + self orientmode( "face enemy" ); + if ( self.zombie_move_speed == "sprint" ) + { + if ( !isDefined( self.zombie_move_speed ) || isDefined( self.zombie_move_speed ) && self.zombie_move_speed != "sprint_slide" ) + { + animstatedef = self maps/mp/animscripts/zm_utility::append_missing_legs_suffix( "sprint_slide" ); + self set_zombie_run_cycle( animstatedef ); + } + break; + } + else if ( self.zombie_move_speed == "run" ) + { + if ( !isDefined( self.zombie_move_speed ) || isDefined( self.zombie_move_speed ) && self.zombie_move_speed != "run_slide" ) + { + animstatedef = self maps/mp/animscripts/zm_utility::append_missing_legs_suffix( "run_slide" ); + self set_zombie_run_cycle( animstatedef ); + } + break; + } + else + { + if ( !isDefined( self.zombie_move_speed ) || isDefined( self.zombie_move_speed ) && self.zombie_move_speed != "walk_slide" ) + { + animstatedef = self maps/mp/animscripts/zm_utility::append_missing_legs_suffix( "walk_slide" ); + self set_zombie_run_cycle( animstatedef ); + } + } + } + wait 0.05; + } + } + zombiemoveongoo_gobacktonormal(); +} + +zombie_moveongoo_animcustom_fall() +{ + self endon( "death" ); + self endon( "removed" ); + level endon( "intermission" ); + self.fell_while_sliding = 1; + self animmode( "normal" ); + self orientmode( "face angle", self.angles[ 1 ] ); + fallanimstatedef = "zm_move_slide_fall"; + self setanimstatefromasd( fallanimstatedef ); + maps/mp/animscripts/zm_shared::donotetracks( "slide_fall_anim" ); + self notify( "zombie_MoveOnGoo_animCustom_fall_done" ); +} + +zombie_moveongoo_animcustom_recover() +{ + self endon( "death" ); + self endon( "removed" ); + level endon( "intermission" ); + self.recovering_from_goo = 1; + if ( randomint( 100 ) < 50 ) + { + animstatedef = maps/mp/animscripts/zm_utility::append_missing_legs_suffix( "zm_move_slide_recover" ); + self setanimstatefromasd( animstatedef ); + maps/mp/animscripts/zm_shared::donotetracks( "slide_recover_anim" ); + } + self.recovering_from_goo = 0; + zombiemoveongoo_gobacktonormal(); + self notify( "zombie_MoveOnGoo_animCustom_recover_done" ); +} + +zombiemoveongoo_on_killanimscript() +{ + self endon( "death" ); + self endon( "removed" ); + level endon( "intermission" ); + self notify( "zombieMoveOnGoo_on_killAnimScript_thread" ); + self endon( "zombieMoveOnGoo_on_killAnimScript_thread" ); + self waittill_any( "endOnGoo", "killanimscript" ); + zombiemoveongoo_gobacktonormal(); +} + +zombiemoveongoo_gobacktonormal() +{ + self animmode( "normal" ); + self set_zombie_run_cycle(); + self.sliding_on_goo = 0; + self.fell_while_sliding = undefined; + self notify( "zombieMoveOnGoo_on_killAnimScript_thread" ); + self notify( "endOnGoo" ); + self.forcemovementscriptstate = 0; + if ( !is_true( self.completed_emerging_into_playable_area ) ) + { + /* +/# + assert( isDefined( self.first_node ) ); +#/ + */ + self maps/mp/zombies/_zm_spawner::reset_attack_spot(); + self orientmode( "face default" ); + self thread maps/mp/zombies/_zm_spawner::zombie_goto_entrance( self.first_node ); + } + else + { + self orientmode( "face enemy" ); + self thread maps/mp/zombies/_zm_ai_basic::find_flesh(); + } +} + +zombie_can_slip() +{ + if ( is_true( self.barricade_enter ) ) + { + return 0; + } + if ( is_true( self.is_traversing ) ) + { + return 0; + } + if ( !is_true( self.completed_emerging_into_playable_area ) && !isDefined( self.first_node ) ) + { + return 0; + } + if ( is_true( self.is_leaping ) ) + { + return 0; + } + return 1; +} + +zombie_set_slipping( onoff ) +{ + if ( isDefined( self ) ) + { + self.is_on_goo = onoff; + if ( onoff ) + { + self thread zombiemoveongoo(); + } + } +} + +slippery_spot_choke( lifetime ) +{ + level.sliquifier_distance_checks++; + if ( level.sliquifier_distance_checks >= 32 ) + { + level.sliquifier_distance_checks = 0; + lifetime -= 0.05; + wait 0.05; + } + return lifetime; +} + +add_slippery_spot( origin, duration, startpos ) +{ + wait 0.5; + level.slippery_spot_count++; + hit_norm = vectornormalize( startpos - origin ); + hit_from = 6 * hit_norm; + trace_height = 120; + trace = bullettrace( origin + hit_from, origin + hit_from + ( 0, 0, trace_height * -1 ), 0, undefined ); + if ( isDefined( trace[ "entity" ] ) ) + { + parent = trace[ "entity" ]; + if ( is_true( parent.can_move ) ) + { + return; + } + } + fxorigin = origin + hit_from; + /* +/# + red = ( 0, 0, 1 ); + green = ( 0, 0, 1 ); + dkgreen = vectorScale( ( 0, 0, 1 ), 0,15 ); + blue = ( 0, 0, 1 ); + grey = vectorScale( ( 0, 0, 1 ), 0,3 ); + black = ( 0, 0, 1 ); + slipgun_debug_line( origin, origin + hit_from, red, duration ); + if ( trace[ "fraction" ] == 1 ) + { + slipgun_debug_line( origin + hit_from, origin + hit_from + ( 0, 0, trace_height * -1 ), grey, duration ); + } + else + { + slipgun_debug_line( origin + hit_from, trace[ "position" ], green, duration ); + slipgun_debug_line( trace[ "position" ], origin + hit_from + ( 0, 0, trace_height * -1 ), dkgreen, duration ); +#/ + } + */ + if ( trace[ "fraction" ] == 1 ) + { + return; + } + moving_parent = undefined; + moving_parent_start = ( 0, 0, 1 ); + if ( isDefined( trace[ "entity" ] ) ) + { + parent = trace[ "entity" ]; + if ( is_true( parent.can_move ) ) + { + return; + } + } + origin = trace[ "position" ]; + thread pool_of_goo( fxorigin, duration ); + if ( !isDefined( level.slippery_spots ) ) + { + level.slippery_spots = []; + } + level.slippery_spots[ level.slippery_spots.size ] = origin; + radius = 60; + height = 48; + /* +/# + thread slipgun_debug_circle( origin, radius, duration, 0, moving_parent, moving_parent_start ); +#/ + */ + slicked_players = []; + slicked_zombies = []; + lifetime = duration; + radius2 = radius * radius; + while ( lifetime > 0 ) + { + oldlifetime = lifetime; + _a612 = get_players(); + _k612 = getFirstArrayKey( _a612 ); + while ( isDefined( _k612 ) ) + { + player = _a612[ _k612 ]; + num = player getentitynumber(); + morigin = origin; + if ( isDefined( moving_parent ) ) + { + morigin = origin + ( moving_parent.origin - moving_parent_start ); + } + if ( distance2dsquared( player.origin, morigin ) < radius2 ) + { + should_be_slick = abs( player.origin[ 2 ] - morigin[ 2 ] ) < height; + } + is_slick = isDefined( slicked_players[ num ] ); + if ( should_be_slick != is_slick ) + { + if ( !isDefined( player.slick_count ) ) + { + player.slick_count = 0; + } + if ( should_be_slick ) + { + player.slick_count++; + slicked_players[ num ] = player; + } + else + { + player.slick_count--; +/* +/# + assert( player.slick_count >= 0 ); +#/ +*/ + } + player forceslick( player.slick_count ); + } + lifetime = slippery_spot_choke( lifetime ); + _k612 = getNextArrayKey( _a612, _k612 ); + } + zombies = get_round_enemy_array(); + while ( isDefined( zombies ) ) + { + _a645 = zombies; + _k645 = getFirstArrayKey( _a645 ); + while ( isDefined( _k645 ) ) + { + zombie = _a645[ _k645 ]; + if ( isDefined( zombie ) ) + { + num = zombie getentitynumber(); + morigin = origin; + if ( isDefined( moving_parent ) ) + { + morigin = origin + ( moving_parent.origin - moving_parent_start ); + } + if ( distance2dsquared( zombie.origin, morigin ) < radius2 ) + { + should_be_slick = abs( zombie.origin[ 2 ] - morigin[ 2 ] ) < height; + } + if ( should_be_slick && !zombie zombie_can_slip() ) + { + should_be_slick = 0; + } + is_slick = isDefined( slicked_zombies[ num ] ); + if ( should_be_slick != is_slick ) + { + if ( !isDefined( zombie.slick_count ) ) + { + zombie.slick_count = 0; + } + if ( should_be_slick ) + { + zombie.slick_count++; + slicked_zombies[ num ] = zombie; + } + else + { + if ( zombie.slick_count > 0 ) + { + zombie.slick_count--; + + } + } + zombie zombie_set_slipping( zombie.slick_count > 0 ); + } + lifetime = slippery_spot_choke( lifetime ); + } + _k645 = getNextArrayKey( _a645, _k645 ); + } + } + if ( oldlifetime == lifetime ) + { + lifetime -= 0.05; + wait 0.05; + } + } + _a684 = slicked_players; + _k684 = getFirstArrayKey( _a684 ); + while ( isDefined( _k684 ) ) + { + player = _a684[ _k684 ]; + player.slick_count--; + /* + +/# + assert( player.slick_count >= 0 ); +#/ + */ + player forceslick( player.slick_count ); + _k684 = getNextArrayKey( _a684, _k684 ); + } + _a690 = slicked_zombies; + _k690 = getFirstArrayKey( _a690 ); + while ( isDefined( _k690 ) ) + { + zombie = _a690[ _k690 ]; + if ( isDefined( zombie ) ) + { + if ( zombie.slick_count > 0 ) + { + zombie.slick_count--; + + } + zombie zombie_set_slipping( zombie.slick_count > 0 ); + } + _k690 = getNextArrayKey( _a690, _k690 ); + } + arrayremovevalue( level.slippery_spots, origin, 0 ); + level.slippery_spot_count--; + +} + +pool_of_goo( origin, duration ) +{ + effect_life = 24; + if ( duration > effect_life ) + { + pool_of_goo( origin, duration - effect_life ); + duration = effect_life; + } + if ( isDefined( level._effect[ "slipgun_splatter" ] ) ) + { + playfx( level._effect[ "slipgun_splatter" ], origin ); + } + wait duration; +} + +explode_into_goo( player, chain_depth ) +{ + if ( isDefined( self.marked_for_insta_upgraded_death ) ) + { + return; + } + tag = "J_SpineLower"; + if ( is_true( self.isdog ) ) + { + tag = "tag_origin"; + } + self.guts_explosion = 1; + self playsound( "wpn_slipgun_zombie_explode" ); + if ( isDefined( level._effect[ "slipgun_explode" ] ) ) + { + playfx( level._effect[ "slipgun_explode" ], self gettagorigin( tag ) ); + } + if ( !is_true( self.isdog ) ) + { + wait 0.1; + } + self ghost(); + if ( !isDefined( self.goo_chain_depth ) ) + { + self.goo_chain_depth = chain_depth; + } + chain_radius = level.zombie_vars[ "slipgun_chain_radius" ]; + level thread explode_to_near_zombies( player, self.origin, chain_radius, self.goo_chain_depth ); +} + +explode_to_near_zombies( player, origin, radius, chain_depth ) +{ + if ( level.zombie_vars[ "slipgun_max_kill_chain_depth" ] > 0 && chain_depth > level.zombie_vars[ "slipgun_max_kill_chain_depth" ] ) + { + return; + } + enemies = get_round_enemy_array(); + enemies = get_array_of_closest( origin, enemies ); + minchainwait = level.zombie_vars[ "slipgun_chain_wait_min" ]; + maxchainwait = level.zombie_vars[ "slipgun_chain_wait_max" ]; + rsquared = radius * radius; + tag = "J_Head"; + marked_zombies = []; + while ( isDefined( enemies ) && enemies.size ) + { + index = 0; + enemy = enemies[ index ]; + while ( distancesquared( enemy.origin, origin ) < rsquared ) + { + if ( isalive( enemy ) && !is_true( enemy.guts_explosion ) && !is_true( enemy.nuked ) && !isDefined( enemy.slipgun_sizzle ) ) + { + trace = bullettrace( origin + vectorScale( ( 0, 0, 1 ), 50 ), enemy.origin + vectorScale( ( 0, 0, 1 ), 50 ), 0, undefined, 1 ); + if ( isDefined( trace[ "fraction" ] ) && trace[ "fraction" ] == 1 ) + { + enemy.slipgun_sizzle = playfxontag( level._effect[ "slipgun_simmer" ], enemy, tag ); + marked_zombies[ marked_zombies.size ] = enemy; + } + } + index++; + if ( index >= enemies.size ) + { + break; + } + else + { + enemy = enemies[ index ]; + } + } + } + while ( isDefined( marked_zombies ) && marked_zombies.size ) + { + _a799 = marked_zombies; + _k799 = getFirstArrayKey( _a799 ); + while ( isDefined( _k799 ) ) + { + enemy = _a799[ _k799 ]; + if ( isalive( enemy ) && !is_true( enemy.guts_explosion ) && !is_true( enemy.nuked ) ) + { + wait randomfloatrange( minchainwait, maxchainwait ); + if ( isalive( enemy ) && !is_true( enemy.guts_explosion ) && !is_true( enemy.nuked ) ) + { + if ( !isDefined( enemy.goo_chain_depth ) ) + { + enemy.goo_chain_depth = chain_depth; + } + if ( enemy.health > 0 ) + { + if ( player maps/mp/zombies/_zm_powerups::is_insta_kill_active() ) + { + enemy.health = 1; + } + enemy dodamage( level.slipgun_damage, origin, player, player, "none", level.slipgun_damage_mod, 0, "slip_goo_zm" ); + } + if ( level.slippery_spot_count < level.zombie_vars[ "slipgun_reslip_max_spots" ] ) + { + if ( isDefined( enemy.slick_count ) && enemy.slick_count == 0 && enemy.health <= 0 ) + { + if ( level.zombie_vars[ "slipgun_reslip_rate" ] > 0 && randomint( level.zombie_vars[ "slipgun_reslip_rate" ] ) == 0 ) + { + startpos = origin; + duration = 24; + thread add_slippery_spot( enemy.origin, duration, startpos ); + } + } + } + } + } + _k799 = getNextArrayKey( _a799, _k799 ); + } + } +} + +slipgun_zombie_1st_hit_response( upgraded, player ) +{ + self notify( "stop_find_flesh" ); + self notify( "zombie_acquire_enemy" ); + self orientmode( "face default" ); + self.ignoreall = 1; + self.gibbed = 1; + if ( isalive( self ) ) + { + if ( !isDefined( self.goo_chain_depth ) ) + { + self.goo_chain_depth = 0; + } + if ( self.health > 0 ) + { + if ( player maps/mp/zombies/_zm_powerups::is_insta_kill_active() ) + { + self.health = 1; + } + self dodamage( level.slipgun_damage, self.origin, player, player, "none", level.slipgun_damage_mod, 0, "slip_goo_zm" ); + } + } +} + +slipgun_zombie_hit_response_internal( mod, damageweapon, player ) +{ + if ( !self is_slipgun_damage( mod, damageweapon ) && !is_slipgun_explosive_damage( mod, damageweapon ) ) + { + return 0; + } + self playsound( "wpn_slipgun_zombie_impact" ); + upgraded = damageweapon == "slipgun_upgraded_zm"; + self thread slipgun_zombie_1st_hit_response( upgraded, player ); + if ( isDefined( player ) && isplayer( player ) ) + { + player thread slipgun_play_zombie_hit_vox(); + } + return 1; +} + +slipgun_zombie_damage_response( mod, hit_location, hit_origin, player, amount ) +{ + return slipgun_zombie_hit_response_internal( mod, self.damageweapon, player ); +} + +slipgun_zombie_death_response() +{ + if ( !self is_slipgun_damage( self.damagemod, self.damageweapon ) && !is_slipgun_explosive_damage( self.damagemod, self.damageweapon ) ) + { + return 0; + } + level maps/mp/zombies/_zm_spawner::zombie_death_points( self.origin, self.damagemod, self.damagelocation, self.attacker, self ); + self explode_into_goo( self.attacker, 0 ); + return 1; +} + +is_slipgun_explosive_damage( mod, weapon ) +{ + if ( isDefined( weapon ) ) + { + if ( weapon != "slip_goo_zm" && weapon != "slip_bolt_zm" ) + { + return weapon == "slip_bolt_upgraded_zm"; + } + } +} + +is_slipgun_damage( mod, weapon ) +{ + if ( isDefined( weapon ) ) + { + if ( weapon != "slipgun_zm" ) + { + return weapon == "slipgun_upgraded_zm"; + } + } +} + +slipgun_play_zombie_hit_vox() +{ + rand = randomintrange( 0, 101 ); + if ( rand >= 20 ) + { + self maps/mp/zombies/_zm_audio::create_and_play_dialog( "kill", "human" ); + } +} +