From cb9bea73ecbdc11ea666d45a57aaabbb6dbb0dab Mon Sep 17 00:00:00 2001 From: Z-Tavern Date: Fri, 18 Oct 2024 00:19:19 +0000 Subject: [PATCH] Full code added --- README.md | 52 +- bo2/!restart_servers.bat | 41 + bo2/!start_zm_serverbrutus.bat | 23 + bo2/!start_zm_serverburied.bat | 23 + bo2/!start_zm_serverdierise.bat | 23 + bo2/!start_zm_servermotd.bat | 23 + bo2/!start_zm_servernuketown.bat | 23 + bo2/!start_zm_serverorigin.bat | 23 + bo2/!start_zm_serverorigin2.bat | 23 + bo2/!start_zm_serverpanzer.bat | 23 + bo2/!start_zm_serverprivate.bat | 23 + bo2/!start_zm_serverraid.bat | 23 + bo2/!start_zm_servertitb.bat | 23 + bo2/!start_zm_servertown.bat | 23 + bo2/!start_zm_servertown2.bat | 23 + bo2/!start_zm_servertown3.bat | 23 + bo2/!start_zm_servertranzit.bat | 23 + bo2/binkw32.dll | Bin 0 -> 215040 bytes bo2/getCmdPID.bat | 39 + bo2/getCmdPID.exe | Bin 0 -> 6144 bytes bo2/wlanapi.dll | Bin 0 -> 336928 bytes .../Configuration/NSMConfiguration.json | 192 + node-server-manager/Lib/CLICommands.js | 84 + node-server-manager/Lib/Classes.js | 63 + node-server-manager/Lib/ClientData.js | 16 + node-server-manager/Lib/Commands.js | 95 + node-server-manager/Lib/ConfigMaker.js | 139 + node-server-manager/Lib/DatabaseModels.js | 36 + node-server-manager/Lib/Entity/Player.js | 106 + node-server-manager/Lib/Entity/Server.js | 279 + .../Lib/Entity/give_tb-compiled.gsc | Bin 0 -> 424 bytes .../Lib/Entity/setround-compiled.gsc | Bin 0 -> 304 bytes .../Lib/Entity/statsaprilfool-compiled.gsc | Bin 0 -> 3964 bytes node-server-manager/Lib/EventDispatcher.js | 118 + node-server-manager/Lib/EventLogWatcher.js | 54 + node-server-manager/Lib/EventParser.js | 106 + node-server-manager/Lib/InitDatabase.js | 1227 ++++ node-server-manager/Lib/MasterServer.js | 151 + node-server-manager/Lib/Models/NSMAliases.js | 37 + node-server-manager/Lib/Models/NSMAudit.js | 35 + node-server-manager/Lib/Models/NSMClients.js | 51 + .../Lib/Models/NSMConnections.js | 41 + node-server-manager/Lib/Models/NSMKills.js | 56 + node-server-manager/Lib/Models/NSMMessages.js | 40 + node-server-manager/Lib/Models/NSMMeta.js | 37 + .../Lib/Models/NSMPenalties.js | 53 + .../Lib/Models/NSMPlayerStatHistory.js | 39 + .../Lib/Models/NSMPlayerStats.js | 53 + node-server-manager/Lib/Models/NSMReports.js | 45 + node-server-manager/Lib/Models/NSMSettings.js | 35 + node-server-manager/Lib/Models/NSMTokens.js | 29 + node-server-manager/Lib/NodeLogServer.js | 94 + node-server-manager/Lib/NodeServerManager.js | 184 + .../Lib/RconCommandPrefixes/Default.js | 42 + .../Lib/RconCommandPrefixes/IW3.js | 40 + .../Lib/RconCommandPrefixes/IW4.js | 39 + .../Lib/RconCommandPrefixes/IW5.js | 43 + .../Lib/RconCommandPrefixes/IW6.js | 39 + .../Lib/RconCommandPrefixes/T4.js | 40 + .../Lib/RconCommandPrefixes/T6.js | 39 + node-server-manager/Lib/RconConnection.js | 196 + node-server-manager/Lib/ServerLogWatcher.js | 56 + ...e799e520-62cc-4ff1-bc4c-1cb0816c9aaa.vsidx | Bin 0 -> 173784 bytes .../Plugins/.vs/Plugins/v17/.wsuo | Bin 0 -> 9216 bytes .../Plugins/.vs/VSWorkspaceState.json | 6 + node-server-manager/Plugins/.vs/slnx.sqlite | Bin 0 -> 90112 bytes node-server-manager/Plugins/AntiVPN.js | 205 + node-server-manager/Plugins/ClanTag.js | 3894 +++++++++++ node-server-manager/Plugins/DiscordWebhook.js | 98 + .../Plugins/Global/AutoMessages.js | 84 + .../Plugins/Global/DiscordBot.js | 1012 +++ .../Plugins/Global/GlobalChat.js | 53 + .../Plugins/Global/ProfileMeta.js | 31 + node-server-manager/Plugins/MoreCommands.js | 416 ++ node-server-manager/Plugins/NativeCommands.js | 800 +++ node-server-manager/Plugins/Penalties.js | 46 + node-server-manager/Plugins/Routes/Discord.js | 50 + .../Plugins/Routes/SocialMedia.js | 28 + node-server-manager/Plugins/Routes/ZStats.js | 41 + node-server-manager/Plugins/Routes/index.js | 10 + node-server-manager/Plugins/ScriptCommands.js | 269 + node-server-manager/Plugins/StatLogger.js | 85 + node-server-manager/Plugins/Voting.js | 290 + .../Plugins/WelcomeMessages.js | 88 + node-server-manager/Plugins/ZombiesBank.js | 4627 +++++++++++++ node-server-manager/Plugins/ZombiesLocker.js | 187 + node-server-manager/Plugins/ZombiesStats.js | 390 ++ t6/compiled/t6/_zm_ai_brutus.gsc | Bin 0 -> 48630 bytes t6/compiled/t6/panzerwave.gsc | Bin 0 -> 61773 bytes t6/compiled/t6/zm_alcatraz_brutus.gsc | Bin 0 -> 3030 bytes t6/dedicated_zmbrutus.cfg | 93 + t6/dedicated_zmburied.cfg | 94 + t6/dedicated_zmdierise.cfg | 93 + t6/dedicated_zmmotd.cfg | 93 + t6/dedicated_zmnuketown.cfg | 93 + t6/dedicated_zmorigin.cfg | 93 + t6/dedicated_zmorigin2.cfg | 93 + t6/dedicated_zmpanzer.cfg | 93 + t6/dedicated_zmprivate.cfg | 93 + t6/dedicated_zmtitb.cfg | 93 + t6/dedicated_zmtown.cfg | 93 + t6/dedicated_zmtown2.cfg | 93 + t6/dedicated_zmtown3.cfg | 93 + t6/dedicated_zmtranzit.cfg | 93 + t6/maps/mp/zombies/_zm_ai_avogadro.gsc | Bin 0 -> 28866 bytes t6/maps/mp/zombies/_zm_ai_mechz_claw.gsc | 587 ++ t6/maps/mp/zombies/_zm_weap_slowgun.gsc | Bin 0 -> 12863 bytes t6/maps/zm_tomb_craftables.gsc | Bin 0 -> 33697 bytes t6/plugins/ClanTagRank.dll | Bin 0 -> 58880 bytes t6/plugins/t6-gsc-utils.dll | Bin 0 -> 1341440 bytes t6/scripts/.vs/VSWorkspaceState.json | 9 + ...c5d3733d-6424-4e4b-82ab-a8dda1e2dbef.vsidx | Bin 0 -> 282768 bytes t6/scripts/.vs/scripts/v17/.wsuo | Bin 0 -> 28160 bytes .../.vs/scripts/v17/DocumentLayout.json | 12 + t6/scripts/.vs/slnx.sqlite | Bin 0 -> 90112 bytes t6/scripts/AATs_Perks.gsc | 3346 ++++++++++ t6/scripts/_clientids.gsc | 240 + t6/scripts/announcements.gsc | 105 + t6/scripts/bankv2.gsc | 258 + t6/scripts/dev.gsc | 4 + t6/scripts/difficulty_selector.gsc | 0 t6/scripts/disable_lunge.gsc | 15 + t6/scripts/disable_revive_money.gsc | 188 + t6/scripts/dropweapon.gsc | 141 + t6/scripts/dvar.gsc | 30 + t6/scripts/ee_timer.gsc | 134 + t6/scripts/faster_revive.gsc | 181 + t6/scripts/fastwavespawn.gsc | 104 + t6/scripts/first_room.gsc | 131 + t6/scripts/gigapass.gsc | 16 + t6/scripts/give.gsc | 83 + t6/scripts/glitch_fix.gsc | 69 + t6/scripts/gmode_and_permakill.gsc | 35 + t6/scripts/godnoclip.gsc | 40 + t6/scripts/hat.gsc | 122 + t6/scripts/killzm.gsc | 185 + t6/scripts/king.gsc | 99 + t6/scripts/lod.gsc | 5 + t6/scripts/maxammo.gsc | 50 + t6/scripts/more_zm.gsc | 22 + t6/scripts/mp/ranked.gsc | 817 +++ t6/scripts/music.gsc | 128 + t6/scripts/no_fog.gsc | 14 + t6/scripts/on_player_connect.gsc | 17 + t6/scripts/perkaholic.gsc | 71 + t6/scripts/points_multiplier.gsc | 189 + t6/scripts/rank_requirements.gsc | 134 + t6/scripts/spectatormode.gsc | 75 + t6/scripts/staff.gsc | 7 + t6/scripts/stam_mule_no_whoswho.gsc | 213 + t6/scripts/stats.gsc | 195 + t6/scripts/time_slip.gsc | 416 ++ t6/scripts/upgrade.gsc | 66 + t6/scripts/vipcommands.gsc | 232 + t6/scripts/vipperks.gsc | 266 + t6/scripts/zm/.vs/VSWorkspaceState.json | 8 + t6/scripts/zm/.vs/slnx.sqlite | Bin 0 -> 90112 bytes ...1f61263b-7daa-48a5-a4a7-1c01623509e9.vsidx | Bin 0 -> 182029 bytes t6/scripts/zm/.vs/zm/v17/.wsuo | Bin 0 -> 12288 bytes t6/scripts/zm/ranked.gsc | 531 ++ .../zm/zm_buried/buried_disable_trample.gsc | 267 + t6/scripts/zm/zm_buried/buried_ee_fix.gsc | 46 + .../zm_buried/buried_remove_spawn_slide.gsc | 26 + .../remove_limited_weapon_buried.gsc | 147 + t6/scripts/zm/zm_buried/witchspeed.gsc | 8 + .../zm/zm_highrise/no_spawn_elevator.gsc | 46 + .../remove_limited_weapon_highrise.gsc | 143 + t6/scripts/zm/zm_highrise/sliquifier.gsc | 99 + .../zm_nuked/remove_limited_weapon_nuked.gsc | 120 + t6/scripts/zm/zm_prison/afterlife_fix.gsc | 29 + t6/scripts/zm/zm_prison/brutuswave.gsc | 3888 +++++++++++ t6/scripts/zm/zm_prison/item_watcher.gsc | 53 + t6/scripts/zm/zm_prison/motd_perk_back.gsc | 672 ++ t6/scripts/zm/zm_prison/no_lightning.gsc | 14 + t6/scripts/zm/zm_prison/zm_spin.gsc | 48 + t6/scripts/zm/zm_tomb/M/M_zm_ai_mechz.gsc | 1989 ++++++ .../zm/zm_tomb/M/M_zm_ai_mechz_claw.gsc | 606 ++ t6/scripts/zm/zm_tomb/M/M_zm_tomb.gsc | 2194 +++++++ t6/scripts/zm/zm_tomb/boss_ivo1.gsc | 1637 +++++ t6/scripts/zm/zm_tomb/boss_kiels1.gsc | 326 + t6/scripts/zm/zm_tomb/nomudslow.gsc | 90 + t6/scripts/zm/zm_tomb/origin_ee.gsc | 129 + t6/scripts/zm/zm_tomb/panzerwave.gsc | 5814 +++++++++++++++++ t6/scripts/zm/zm_tomb/pet_drones.gsc | 318 + t6/scripts/zm/zm_tomb/raid_boss.gsc | 2160 ++++++ .../zm/zm_tomb/update/box_no_limits.gsc | 1592 +++++ .../zm/zm_tomb/update/custom_perk_powerup.gsc | 2546 ++++++++ t6/scripts/zm/zm_tomb/update/trials.gsc | 1844 ++++++ .../zm/zm_transit/emp_no_perk_disable.gsc | 68 + t6/scripts/zm/zm_transit/jetgun.gsc | 31 + t6/scripts/zm/zm_transit/no_locker.gsc | 203 + .../remove_limited_weapon_transit.gsc | 170 + t6/scripts/zm/zm_transit/tranzitinthebus.gsc | 2883 ++++++++ t6/scripts/zm/zm_transit/zm_no_explosion.gsc | 50 + t6/scripts/zmafk.gsc | 609 ++ t6/scripts/zmcounterhealthwatermark.gsc | 305 + t6/uncompiled mods/8playerhud-compiled.gsc | Bin 0 -> 1224 bytes t6/uncompiled mods/8playerhud.gsc | 59 + t6/uncompiled mods/AATs_Perks - Copie.gsc | 3145 +++++++++ t6/uncompiled mods/AATs_Perks.gsc | 3056 +++++++++ t6/uncompiled mods/Compiler.exe | Bin 0 -> 49664 bytes t6/uncompiled mods/Irony.dll | Bin 0 -> 149504 bytes t6/uncompiled mods/Perks.gsc | 3016 +++++++++ t6/uncompiled mods/Zompiler.exe | Bin 0 -> 49664 bytes t6/uncompiled mods/_clientids.gsc | 198 + t6/uncompiled mods/_zm_magicbox.gsc | Bin 0 -> 25108 bytes t6/uncompiled mods/_zm_weap_slowgun.gsc | 814 +++ .../_zm_weapon_locker-compiled.gsc | Bin 0 -> 9558 bytes t6/uncompiled mods/_zm_weapon_locker.gsc | 530 ++ t6/uncompiled mods/afktocrash.gsc | 438 ++ t6/uncompiled mods/announcements.gsc | 37 + t6/uncompiled mods/bankv2 - Copie.gsc | 125 + t6/uncompiled mods/bankv2.gsc | 517 ++ t6/uncompiled mods/bankv2tournament.gsc | 567 ++ t6/uncompiled mods/bo2_aats - Copie.gsc | 1803 +++++ t6/uncompiled mods/bo2_aats-compiled.gsc | Bin 0 -> 58416 bytes t6/uncompiled mods/bo2_aats.gsc | 1769 +++++ t6/uncompiled mods/boss_ivo1 - Copy.gsc | 1393 ++++ t6/uncompiled mods/box_no_limits.gsc | 1610 +++++ t6/uncompiled mods/clantag.gsc | 8 + t6/uncompiled mods/crash.gsc | 63 + t6/uncompiled mods/createstruct.gsc | 31 + .../custom_perk_powerup-compiled.gsc | Bin 0 -> 47174 bytes t6/uncompiled mods/custom_perk_powerup.gsc | 2546 ++++++++ t6/uncompiled mods/customperks - Copie.gsc | 1070 +++ t6/uncompiled mods/customperks.gsc | 1067 +++ t6/uncompiled mods/dropweapon.gsc | 131 + t6/uncompiled mods/emp_no_perk_disable.gsc | 71 + t6/uncompiled mods/fastwavespawn.gsc | 104 + t6/uncompiled mods/give.gsc | 76 + t6/uncompiled mods/godnoclip.gsc | 37 + t6/uncompiled mods/guild.gsc | 176 + t6/uncompiled mods/hitmarker.gsc | 80 + t6/uncompiled mods/hpspeed.gsc | 147 + .../infinite_money-compiled.gsc | Bin 0 -> 2512 bytes t6/uncompiled mods/infinite_money.gsc | 127 + t6/uncompiled mods/isSaved.gsc | 4 + t6/uncompiled mods/killzm.gsc | 123 + t6/uncompiled mods/killzmtourneymotd.gsc | 266 + t6/uncompiled mods/killzmtourneyorigin.gsc | 266 + t6/uncompiled mods/king.gsc | 45 + t6/uncompiled mods/mafk.gsc | 399 ++ t6/uncompiled mods/mafk3.gsc | 396 ++ t6/uncompiled mods/message (4).gsc | 283 + .../multiply_points-compiled.gsc | Bin 0 -> 604 bytes t6/uncompiled mods/multiply_points.gsc | 28 + t6/uncompiled mods/no_fog-compiled.gsc | Bin 0 -> 156 bytes t6/uncompiled mods/no_fog.gsc | 4 + t6/uncompiled mods/nomudslow.gsc | 90 + t6/uncompiled mods/out_of_bound_zm_check.gsc | 34 + .../perma_perks_on_all_maps-compiled.gsc | Bin 0 -> 3264 bytes .../perma_perks_on_all_maps.gsc | 136 + t6/uncompiled mods/permaperks.gsc | 150 + t6/uncompiled mods/raid.gsc | 238 + t6/uncompiled mods/reloadspeed.gsc | 23 + t6/uncompiled mods/restartmsg.gsc | 50 + t6/uncompiled mods/setround.gsc | 14 + t6/uncompiled mods/show_position-compiled.gsc | Bin 0 -> 892 bytes t6/uncompiled mods/show_position.gsc | 42 + t6/uncompiled mods/sliquifier.gsc | 99 + t6/uncompiled mods/slowgun.gsc | 44 + t6/uncompiled mods/spectatormode.gsc | 60 + .../stam + mule + no whoswho.gsc | 192 + t6/uncompiled mods/stats.gsc | 174 + t6/uncompiled mods/supersprinter.gsc | 144 + t6/uncompiled mods/tombstoneremoval.gsc | 9 + t6/uncompiled mods/town_perk.gsc | 1206 ++++ t6/uncompiled mods/town_perkMODIFIED.gsc | 1020 +++ t6/uncompiled mods/trials-compiled.gsc | Bin 0 -> 55272 bytes t6/uncompiled mods/trials.gsc | 1844 ++++++ .../unlimitedsprint-compiled.gsc | Bin 0 -> 408 bytes t6/uncompiled mods/unlimitedsprint.gsc | 25 + t6/uncompiled mods/vipcommands.gsc | 112 + t6/uncompiled mods/vipperks.gsc | 70 + t6/uncompiled mods/witchspeed.gsc | 10 + t6/uncompiled mods/zm_tomb-compiled.gsc | Bin 0 -> 62878 bytes t6/uncompiled mods/zm_tomb.gsc | 2251 +++++++ .../zm_universal_bank_mod_main.gsc | 204 + .../zm_universal_bank_transit_mod_main.gsc | 7 + t6/uncompiled mods/zmafk.gsc | 528 ++ t6/uncompiled mods/zmafkv2.gsc | 94 + .../zmcounterhealthwatermark.gsc | 194 + t6/uncompiled mods/zombiecounter-compiled.gsc | Bin 0 -> 780 bytes t6/uncompiled mods/zombiecounter.gsc | 32 + 284 files changed, 94999 insertions(+), 1 deletion(-) create mode 100644 bo2/!restart_servers.bat create mode 100644 bo2/!start_zm_serverbrutus.bat create mode 100644 bo2/!start_zm_serverburied.bat create mode 100644 bo2/!start_zm_serverdierise.bat create mode 100644 bo2/!start_zm_servermotd.bat create mode 100644 bo2/!start_zm_servernuketown.bat create mode 100644 bo2/!start_zm_serverorigin.bat create mode 100644 bo2/!start_zm_serverorigin2.bat create mode 100644 bo2/!start_zm_serverpanzer.bat create mode 100644 bo2/!start_zm_serverprivate.bat create mode 100644 bo2/!start_zm_serverraid.bat create mode 100644 bo2/!start_zm_servertitb.bat create mode 100644 bo2/!start_zm_servertown.bat create mode 100644 bo2/!start_zm_servertown2.bat create mode 100644 bo2/!start_zm_servertown3.bat create mode 100644 bo2/!start_zm_servertranzit.bat create mode 100644 bo2/binkw32.dll create mode 100644 bo2/getCmdPID.bat create mode 100644 bo2/getCmdPID.exe create mode 100644 bo2/wlanapi.dll create mode 100644 node-server-manager/Configuration/NSMConfiguration.json create mode 100644 node-server-manager/Lib/CLICommands.js create mode 100644 node-server-manager/Lib/Classes.js create mode 100644 node-server-manager/Lib/ClientData.js create mode 100644 node-server-manager/Lib/Commands.js create mode 100644 node-server-manager/Lib/ConfigMaker.js create mode 100644 node-server-manager/Lib/DatabaseModels.js create mode 100644 node-server-manager/Lib/Entity/Player.js create mode 100644 node-server-manager/Lib/Entity/Server.js create mode 100644 node-server-manager/Lib/Entity/give_tb-compiled.gsc create mode 100644 node-server-manager/Lib/Entity/setround-compiled.gsc create mode 100644 node-server-manager/Lib/Entity/statsaprilfool-compiled.gsc create mode 100644 node-server-manager/Lib/EventDispatcher.js create mode 100644 node-server-manager/Lib/EventLogWatcher.js create mode 100644 node-server-manager/Lib/EventParser.js create mode 100644 node-server-manager/Lib/InitDatabase.js create mode 100644 node-server-manager/Lib/MasterServer.js create mode 100644 node-server-manager/Lib/Models/NSMAliases.js create mode 100644 node-server-manager/Lib/Models/NSMAudit.js create mode 100644 node-server-manager/Lib/Models/NSMClients.js create mode 100644 node-server-manager/Lib/Models/NSMConnections.js create mode 100644 node-server-manager/Lib/Models/NSMKills.js create mode 100644 node-server-manager/Lib/Models/NSMMessages.js create mode 100644 node-server-manager/Lib/Models/NSMMeta.js create mode 100644 node-server-manager/Lib/Models/NSMPenalties.js create mode 100644 node-server-manager/Lib/Models/NSMPlayerStatHistory.js create mode 100644 node-server-manager/Lib/Models/NSMPlayerStats.js create mode 100644 node-server-manager/Lib/Models/NSMReports.js create mode 100644 node-server-manager/Lib/Models/NSMSettings.js create mode 100644 node-server-manager/Lib/Models/NSMTokens.js create mode 100644 node-server-manager/Lib/NodeLogServer.js create mode 100644 node-server-manager/Lib/NodeServerManager.js create mode 100644 node-server-manager/Lib/RconCommandPrefixes/Default.js create mode 100644 node-server-manager/Lib/RconCommandPrefixes/IW3.js create mode 100644 node-server-manager/Lib/RconCommandPrefixes/IW4.js create mode 100644 node-server-manager/Lib/RconCommandPrefixes/IW5.js create mode 100644 node-server-manager/Lib/RconCommandPrefixes/IW6.js create mode 100644 node-server-manager/Lib/RconCommandPrefixes/T4.js create mode 100644 node-server-manager/Lib/RconCommandPrefixes/T6.js create mode 100644 node-server-manager/Lib/RconConnection.js create mode 100644 node-server-manager/Lib/ServerLogWatcher.js create mode 100644 node-server-manager/Plugins/.vs/Plugins/FileContentIndex/e799e520-62cc-4ff1-bc4c-1cb0816c9aaa.vsidx create mode 100644 node-server-manager/Plugins/.vs/Plugins/v17/.wsuo create mode 100644 node-server-manager/Plugins/.vs/VSWorkspaceState.json create mode 100644 node-server-manager/Plugins/.vs/slnx.sqlite create mode 100644 node-server-manager/Plugins/AntiVPN.js create mode 100644 node-server-manager/Plugins/ClanTag.js create mode 100644 node-server-manager/Plugins/DiscordWebhook.js create mode 100644 node-server-manager/Plugins/Global/AutoMessages.js create mode 100644 node-server-manager/Plugins/Global/DiscordBot.js create mode 100644 node-server-manager/Plugins/Global/GlobalChat.js create mode 100644 node-server-manager/Plugins/Global/ProfileMeta.js create mode 100644 node-server-manager/Plugins/MoreCommands.js create mode 100644 node-server-manager/Plugins/NativeCommands.js create mode 100644 node-server-manager/Plugins/Penalties.js create mode 100644 node-server-manager/Plugins/Routes/Discord.js create mode 100644 node-server-manager/Plugins/Routes/SocialMedia.js create mode 100644 node-server-manager/Plugins/Routes/ZStats.js create mode 100644 node-server-manager/Plugins/Routes/index.js create mode 100644 node-server-manager/Plugins/ScriptCommands.js create mode 100644 node-server-manager/Plugins/StatLogger.js create mode 100644 node-server-manager/Plugins/Voting.js create mode 100644 node-server-manager/Plugins/WelcomeMessages.js create mode 100644 node-server-manager/Plugins/ZombiesBank.js create mode 100644 node-server-manager/Plugins/ZombiesLocker.js create mode 100644 node-server-manager/Plugins/ZombiesStats.js create mode 100644 t6/compiled/t6/_zm_ai_brutus.gsc create mode 100644 t6/compiled/t6/panzerwave.gsc create mode 100644 t6/compiled/t6/zm_alcatraz_brutus.gsc create mode 100644 t6/dedicated_zmbrutus.cfg create mode 100644 t6/dedicated_zmburied.cfg create mode 100644 t6/dedicated_zmdierise.cfg create mode 100644 t6/dedicated_zmmotd.cfg create mode 100644 t6/dedicated_zmnuketown.cfg create mode 100644 t6/dedicated_zmorigin.cfg create mode 100644 t6/dedicated_zmorigin2.cfg create mode 100644 t6/dedicated_zmpanzer.cfg create mode 100644 t6/dedicated_zmprivate.cfg create mode 100644 t6/dedicated_zmtitb.cfg create mode 100644 t6/dedicated_zmtown.cfg create mode 100644 t6/dedicated_zmtown2.cfg create mode 100644 t6/dedicated_zmtown3.cfg create mode 100644 t6/dedicated_zmtranzit.cfg create mode 100644 t6/maps/mp/zombies/_zm_ai_avogadro.gsc create mode 100644 t6/maps/mp/zombies/_zm_ai_mechz_claw.gsc create mode 100644 t6/maps/mp/zombies/_zm_weap_slowgun.gsc create mode 100644 t6/maps/zm_tomb_craftables.gsc create mode 100644 t6/plugins/ClanTagRank.dll create mode 100644 t6/plugins/t6-gsc-utils.dll create mode 100644 t6/scripts/.vs/VSWorkspaceState.json create mode 100644 t6/scripts/.vs/scripts/FileContentIndex/c5d3733d-6424-4e4b-82ab-a8dda1e2dbef.vsidx create mode 100644 t6/scripts/.vs/scripts/v17/.wsuo create mode 100644 t6/scripts/.vs/scripts/v17/DocumentLayout.json create mode 100644 t6/scripts/.vs/slnx.sqlite create mode 100644 t6/scripts/AATs_Perks.gsc create mode 100644 t6/scripts/_clientids.gsc create mode 100644 t6/scripts/announcements.gsc create mode 100644 t6/scripts/bankv2.gsc create mode 100644 t6/scripts/dev.gsc create mode 100644 t6/scripts/difficulty_selector.gsc create mode 100644 t6/scripts/disable_lunge.gsc create mode 100644 t6/scripts/disable_revive_money.gsc create mode 100644 t6/scripts/dropweapon.gsc create mode 100644 t6/scripts/dvar.gsc create mode 100644 t6/scripts/ee_timer.gsc create mode 100644 t6/scripts/faster_revive.gsc create mode 100644 t6/scripts/fastwavespawn.gsc create mode 100644 t6/scripts/first_room.gsc create mode 100644 t6/scripts/gigapass.gsc create mode 100644 t6/scripts/give.gsc create mode 100644 t6/scripts/glitch_fix.gsc create mode 100644 t6/scripts/gmode_and_permakill.gsc create mode 100644 t6/scripts/godnoclip.gsc create mode 100644 t6/scripts/hat.gsc create mode 100644 t6/scripts/killzm.gsc create mode 100644 t6/scripts/king.gsc create mode 100644 t6/scripts/lod.gsc create mode 100644 t6/scripts/maxammo.gsc create mode 100644 t6/scripts/more_zm.gsc create mode 100644 t6/scripts/mp/ranked.gsc create mode 100644 t6/scripts/music.gsc create mode 100644 t6/scripts/no_fog.gsc create mode 100644 t6/scripts/on_player_connect.gsc create mode 100644 t6/scripts/perkaholic.gsc create mode 100644 t6/scripts/points_multiplier.gsc create mode 100644 t6/scripts/rank_requirements.gsc create mode 100644 t6/scripts/spectatormode.gsc create mode 100644 t6/scripts/staff.gsc create mode 100644 t6/scripts/stam_mule_no_whoswho.gsc create mode 100644 t6/scripts/stats.gsc create mode 100644 t6/scripts/time_slip.gsc create mode 100644 t6/scripts/upgrade.gsc create mode 100644 t6/scripts/vipcommands.gsc create mode 100644 t6/scripts/vipperks.gsc create mode 100644 t6/scripts/zm/.vs/VSWorkspaceState.json create mode 100644 t6/scripts/zm/.vs/slnx.sqlite create mode 100644 t6/scripts/zm/.vs/zm/FileContentIndex/1f61263b-7daa-48a5-a4a7-1c01623509e9.vsidx create mode 100644 t6/scripts/zm/.vs/zm/v17/.wsuo create mode 100644 t6/scripts/zm/ranked.gsc create mode 100644 t6/scripts/zm/zm_buried/buried_disable_trample.gsc create mode 100644 t6/scripts/zm/zm_buried/buried_ee_fix.gsc create mode 100644 t6/scripts/zm/zm_buried/buried_remove_spawn_slide.gsc create mode 100644 t6/scripts/zm/zm_buried/remove_limited_weapon_buried.gsc create mode 100644 t6/scripts/zm/zm_buried/witchspeed.gsc create mode 100644 t6/scripts/zm/zm_highrise/no_spawn_elevator.gsc create mode 100644 t6/scripts/zm/zm_highrise/remove_limited_weapon_highrise.gsc create mode 100644 t6/scripts/zm/zm_highrise/sliquifier.gsc create mode 100644 t6/scripts/zm/zm_nuked/remove_limited_weapon_nuked.gsc create mode 100644 t6/scripts/zm/zm_prison/afterlife_fix.gsc create mode 100644 t6/scripts/zm/zm_prison/brutuswave.gsc create mode 100644 t6/scripts/zm/zm_prison/item_watcher.gsc create mode 100644 t6/scripts/zm/zm_prison/motd_perk_back.gsc create mode 100644 t6/scripts/zm/zm_prison/no_lightning.gsc create mode 100644 t6/scripts/zm/zm_prison/zm_spin.gsc create mode 100644 t6/scripts/zm/zm_tomb/M/M_zm_ai_mechz.gsc create mode 100644 t6/scripts/zm/zm_tomb/M/M_zm_ai_mechz_claw.gsc create mode 100644 t6/scripts/zm/zm_tomb/M/M_zm_tomb.gsc create mode 100644 t6/scripts/zm/zm_tomb/boss_ivo1.gsc create mode 100644 t6/scripts/zm/zm_tomb/boss_kiels1.gsc create mode 100644 t6/scripts/zm/zm_tomb/nomudslow.gsc create mode 100644 t6/scripts/zm/zm_tomb/origin_ee.gsc create mode 100644 t6/scripts/zm/zm_tomb/panzerwave.gsc create mode 100644 t6/scripts/zm/zm_tomb/pet_drones.gsc create mode 100644 t6/scripts/zm/zm_tomb/raid_boss.gsc create mode 100644 t6/scripts/zm/zm_tomb/update/box_no_limits.gsc create mode 100644 t6/scripts/zm/zm_tomb/update/custom_perk_powerup.gsc create mode 100644 t6/scripts/zm/zm_tomb/update/trials.gsc create mode 100644 t6/scripts/zm/zm_transit/emp_no_perk_disable.gsc create mode 100644 t6/scripts/zm/zm_transit/jetgun.gsc create mode 100644 t6/scripts/zm/zm_transit/no_locker.gsc create mode 100644 t6/scripts/zm/zm_transit/remove_limited_weapon_transit.gsc create mode 100644 t6/scripts/zm/zm_transit/tranzitinthebus.gsc create mode 100644 t6/scripts/zm/zm_transit/zm_no_explosion.gsc create mode 100644 t6/scripts/zmafk.gsc create mode 100644 t6/scripts/zmcounterhealthwatermark.gsc create mode 100644 t6/uncompiled mods/8playerhud-compiled.gsc create mode 100644 t6/uncompiled mods/8playerhud.gsc create mode 100644 t6/uncompiled mods/AATs_Perks - Copie.gsc create mode 100644 t6/uncompiled mods/AATs_Perks.gsc create mode 100644 t6/uncompiled mods/Compiler.exe create mode 100644 t6/uncompiled mods/Irony.dll create mode 100644 t6/uncompiled mods/Perks.gsc create mode 100644 t6/uncompiled mods/Zompiler.exe create mode 100644 t6/uncompiled mods/_clientids.gsc create mode 100644 t6/uncompiled mods/_zm_magicbox.gsc create mode 100644 t6/uncompiled mods/_zm_weap_slowgun.gsc create mode 100644 t6/uncompiled mods/_zm_weapon_locker-compiled.gsc create mode 100644 t6/uncompiled mods/_zm_weapon_locker.gsc create mode 100644 t6/uncompiled mods/afktocrash.gsc create mode 100644 t6/uncompiled mods/announcements.gsc create mode 100644 t6/uncompiled mods/bankv2 - Copie.gsc create mode 100644 t6/uncompiled mods/bankv2.gsc create mode 100644 t6/uncompiled mods/bankv2tournament.gsc create mode 100644 t6/uncompiled mods/bo2_aats - Copie.gsc create mode 100644 t6/uncompiled mods/bo2_aats-compiled.gsc create mode 100644 t6/uncompiled mods/bo2_aats.gsc create mode 100644 t6/uncompiled mods/boss_ivo1 - Copy.gsc create mode 100644 t6/uncompiled mods/box_no_limits.gsc create mode 100644 t6/uncompiled mods/clantag.gsc create mode 100644 t6/uncompiled mods/crash.gsc create mode 100644 t6/uncompiled mods/createstruct.gsc create mode 100644 t6/uncompiled mods/custom_perk_powerup-compiled.gsc create mode 100644 t6/uncompiled mods/custom_perk_powerup.gsc create mode 100644 t6/uncompiled mods/customperks - Copie.gsc create mode 100644 t6/uncompiled mods/customperks.gsc create mode 100644 t6/uncompiled mods/dropweapon.gsc create mode 100644 t6/uncompiled mods/emp_no_perk_disable.gsc create mode 100644 t6/uncompiled mods/fastwavespawn.gsc create mode 100644 t6/uncompiled mods/give.gsc create mode 100644 t6/uncompiled mods/godnoclip.gsc create mode 100644 t6/uncompiled mods/guild.gsc create mode 100644 t6/uncompiled mods/hitmarker.gsc create mode 100644 t6/uncompiled mods/hpspeed.gsc create mode 100644 t6/uncompiled mods/infinite_money-compiled.gsc create mode 100644 t6/uncompiled mods/infinite_money.gsc create mode 100644 t6/uncompiled mods/isSaved.gsc create mode 100644 t6/uncompiled mods/killzm.gsc create mode 100644 t6/uncompiled mods/killzmtourneymotd.gsc create mode 100644 t6/uncompiled mods/killzmtourneyorigin.gsc create mode 100644 t6/uncompiled mods/king.gsc create mode 100644 t6/uncompiled mods/mafk.gsc create mode 100644 t6/uncompiled mods/mafk3.gsc create mode 100644 t6/uncompiled mods/message (4).gsc create mode 100644 t6/uncompiled mods/multiply_points-compiled.gsc create mode 100644 t6/uncompiled mods/multiply_points.gsc create mode 100644 t6/uncompiled mods/no_fog-compiled.gsc create mode 100644 t6/uncompiled mods/no_fog.gsc create mode 100644 t6/uncompiled mods/nomudslow.gsc create mode 100644 t6/uncompiled mods/out_of_bound_zm_check.gsc create mode 100644 t6/uncompiled mods/perma_perks_on_all_maps-compiled.gsc create mode 100644 t6/uncompiled mods/perma_perks_on_all_maps.gsc create mode 100644 t6/uncompiled mods/permaperks.gsc create mode 100644 t6/uncompiled mods/raid.gsc create mode 100644 t6/uncompiled mods/reloadspeed.gsc create mode 100644 t6/uncompiled mods/restartmsg.gsc create mode 100644 t6/uncompiled mods/setround.gsc create mode 100644 t6/uncompiled mods/show_position-compiled.gsc create mode 100644 t6/uncompiled mods/show_position.gsc create mode 100644 t6/uncompiled mods/sliquifier.gsc create mode 100644 t6/uncompiled mods/slowgun.gsc create mode 100644 t6/uncompiled mods/spectatormode.gsc create mode 100644 t6/uncompiled mods/stam + mule + no whoswho.gsc create mode 100644 t6/uncompiled mods/stats.gsc create mode 100644 t6/uncompiled mods/supersprinter.gsc create mode 100644 t6/uncompiled mods/tombstoneremoval.gsc create mode 100644 t6/uncompiled mods/town_perk.gsc create mode 100644 t6/uncompiled mods/town_perkMODIFIED.gsc create mode 100644 t6/uncompiled mods/trials-compiled.gsc create mode 100644 t6/uncompiled mods/trials.gsc create mode 100644 t6/uncompiled mods/unlimitedsprint-compiled.gsc create mode 100644 t6/uncompiled mods/unlimitedsprint.gsc create mode 100644 t6/uncompiled mods/vipcommands.gsc create mode 100644 t6/uncompiled mods/vipperks.gsc create mode 100644 t6/uncompiled mods/witchspeed.gsc create mode 100644 t6/uncompiled mods/zm_tomb-compiled.gsc create mode 100644 t6/uncompiled mods/zm_tomb.gsc create mode 100644 t6/uncompiled mods/zm_universal_bank_mod_main.gsc create mode 100644 t6/uncompiled mods/zm_universal_bank_transit_mod_main.gsc create mode 100644 t6/uncompiled mods/zmafk.gsc create mode 100644 t6/uncompiled mods/zmafkv2.gsc create mode 100644 t6/uncompiled mods/zmcounterhealthwatermark.gsc create mode 100644 t6/uncompiled mods/zombiecounter-compiled.gsc create mode 100644 t6/uncompiled mods/zombiecounter.gsc diff --git a/README.md b/README.md index d417f79..12bf5fe 100644 --- a/README.md +++ b/README.md @@ -1 +1,51 @@ -# ZTavern \ No newline at end of file +# ZTavern Bo2 Mods & Server setup +## Install +- Setup a Bo2 Server +https://plutonium.pw/docs/server/t6/setting-up-a-server/ + +- Install Fed's Node Server Manager +https://github.com/alicealys/node-server-manager + +- Copy & paste all folder contents +node-server-manager -> node-server-manager installed folder +bo2 -> your bo2 server root directory +t6 -> %localappdata%\Plutonium\storage\t6 + +### Server keys +- Make sure to add your Plutonium server keys in all "!start_zm_serverxxx.bat" +- Change the gamelogs path for each server according to yours in node-server-manager/Configuration/NSMConfiguration.json + +**Server name** +- Server key name must be named as follow : +(Your server name) | BRUTUS ON THE BRIDGE | (extra txt) + +- Server name list : +PRIVATE SERVER +RAID BOSS +BRUTUS ON THE BRIDGE +TRANZIT IN THE BUS +PANZER IN AGARTHA +ORIGINS +ORIGINS2 +BURIED +TRANZIT2 +DIE RISE +TOWN +TOWN2 +TOWN3 +MOTD +NUKETOWN + +### Auto server restart .bat file +- Depending on where you installed node-server-manager folder, edit the path used in bo2/!restart_servers.bat + +## How to run +- bo2/!restart_servers.bat start and restart all servers along with NSM every 6 hours + +## Misc. +### Where to look in NSM folders ? +- 99% of my work on the NodeJS side is located in the Plugin folder : ZombieBank.js, ClanTag.js & ZombieStats.js + +### Add moderator permissions +- Add the .id of target in staff.gsc (t6/scripts directory) +- Add the .pguid of target in ZombieBank.js, ClanTag.js, ZombieStats.js, NativeCommands.js diff --git a/bo2/!restart_servers.bat b/bo2/!restart_servers.bat new file mode 100644 index 0000000..8b540b4 --- /dev/null +++ b/bo2/!restart_servers.bat @@ -0,0 +1,41 @@ +@echo off +call getCmdPID +set "current_pid=%errorlevel%" + +:loop +for /f "skip=3 tokens=2 delims= " %%a in ('tasklist /fi "imagename eq cmd.exe"') do ( + if "%%a" neq "%current_pid%" ( + TASKKILL /PID %%a /f >nul 2>nul + ) +) +taskkill /f /im node.exe +taskkill /f /im plutonium-bootstrapper-win32.exe + +start !start_zm_serverdierise.bat +start !start_zm_servernuketown.bat +start !start_zm_serverburied.bat +start !start_zm_serverprivate.bat +start !start_zm_servermotd.bat +timeout 5 >nul +start !start_zm_servertitb.bat +start !start_zm_serverpanzer.bat +start !start_zm_serverbrutus.bat +start !start_zm_serverorigin.bat +start !start_zm_serverorigin2.bat +timeout 5 >nul +start !start_zm_serverraid.bat +start !start_zm_servertown.bat +start !start_zm_servertown2.bat +start !start_zm_servertown3.bat +start !start_zm_servertranzit.bat +timeout 50 >nul + +:: Replace path depending on where you put NSM folder +:: StartNSM.bat must be started while being on the same directory, hence why I use "cd" to move around +cd C:\bo2\node-server-manager +start "" cmd /c C:\bo2\node-server-manager\StartNSM.bat +cd C:\bo2 + + +timeout 21540 >nul +goto loop \ No newline at end of file diff --git a/bo2/!start_zm_serverbrutus.bat b/bo2/!start_zm_serverbrutus.bat new file mode 100644 index 0000000..1026331 --- /dev/null +++ b/bo2/!start_zm_serverbrutus.bat @@ -0,0 +1,23 @@ +@echo off +::Paste the server key from https://platform.plutonium.pw/serverkeys here +set key=your_key +::Name of the config file the server should use. (default: dedicated_zm.cfg) +set cfg=dedicated_zmbrutus.cfg +::Name of the server shown in the title of the cmd window. This will NOT bet shown ingame. +set name=. +::Port used by the server (default: 4976) +set port=30001 +::Only change this when you don't want to keep the bat files in the game folder. MOST WON'T NEED TO EDIT THIS! +set gamepath=%cd% + +title BRUTUS +echo Visit plutonium.pw / Join the Discord (a6JM2Tv) for NEWS and Updates! +echo Server "%name%" will load %cfg% and listen on port %port% UDP! +echo To shut down the server close this window first! +echo (%date%) - (%time%) %name% server start. + +cd /D %LOCALAPPDATA%\Plutonium +:server +start /wait /abovenormal bin\plutonium-bootstrapper-win32.exe t6zm "%gamepath%" -dedicated +set key %key% +sv_config %cfg% +net_port %port% +echo (%date%) - (%time%) WARNING: %name% server closed or dropped... server restarts. +goto server \ No newline at end of file diff --git a/bo2/!start_zm_serverburied.bat b/bo2/!start_zm_serverburied.bat new file mode 100644 index 0000000..5893d6e --- /dev/null +++ b/bo2/!start_zm_serverburied.bat @@ -0,0 +1,23 @@ +@echo off +::Paste the server key from https://platform.plutonium.pw/serverkeys here +set key=your_key +::Name of the config file the server should use. (default: dedicated_zm.cfg) +set cfg=dedicated_zmburied.cfg +::Name of the server shown in the title of the cmd window. This will NOT bet shown ingame. +set name=Buried +::Port used by the server (default: 4976) +set port=30002 +::Only change this when you don't want to keep the bat files in the game folder. MOST WON'T NEED TO EDIT THIS! +set gamepath=%cd% + +title Buried +echo Visit plutonium.pw / Join the Discord (a6JM2Tv) for NEWS and Updates! +echo Server "%name%" will load %cfg% and listen on port %port% UDP! +echo To shut down the server close this window first! +echo (%date%) - (%time%) %name% server start. + +cd /D %LOCALAPPDATA%\Plutonium +:server +start /wait /abovenormal bin\plutonium-bootstrapper-win32.exe t6zm "%gamepath%" -dedicated +set key %key% +sv_config %cfg% +net_port %port% +echo (%date%) - (%time%) WARNING: %name% server closed or dropped... server restarts. +goto server \ No newline at end of file diff --git a/bo2/!start_zm_serverdierise.bat b/bo2/!start_zm_serverdierise.bat new file mode 100644 index 0000000..037e63e --- /dev/null +++ b/bo2/!start_zm_serverdierise.bat @@ -0,0 +1,23 @@ +@echo off +::Paste the server key from https://platform.plutonium.pw/serverkeys here +set key=your_key +::Name of the config file the server should use. (default: dedicated_zm.cfg) +set cfg=dedicated_zmdierise.cfg +::Name of the server shown in the title of the cmd window. This will NOT bet shown ingame. +set name=DieRise +::Port used by the server (default: 4976) +set port=30003 +::Only change this when you don't want to keep the bat files in the game folder. MOST WON'T NEED TO EDIT THIS! +set gamepath=%cd% + +title Die Rise +echo Visit plutonium.pw / Join the Discord (a6JM2Tv) for NEWS and Updates! +echo Server "%name%" will load %cfg% and listen on port %port% UDP! +echo To shut down the server close this window first! +echo (%date%) - (%time%) %name% server start. + +cd /D %LOCALAPPDATA%\Plutonium +:server +start /wait /abovenormal bin\plutonium-bootstrapper-win32.exe t6zm "%gamepath%" -dedicated +set key %key% +sv_config %cfg% +net_port %port% +echo (%date%) - (%time%) WARNING: %name% server closed or dropped... server restarts. +goto server \ No newline at end of file diff --git a/bo2/!start_zm_servermotd.bat b/bo2/!start_zm_servermotd.bat new file mode 100644 index 0000000..02e887a --- /dev/null +++ b/bo2/!start_zm_servermotd.bat @@ -0,0 +1,23 @@ +@echo off +::Paste the server key from https://platform.plutonium.pw/serverkeys here +set key=your_key +::Name of the config file the server should use. (default: dedicated_zm.cfg) +set cfg=dedicated_zmmotd.cfg +::Name of the server shown in the title of the cmd window. This will NOT bet shown ingame. +set name=. +::Port used by the server (default: 4976) +set port=30004 +::Only change this when you don't want to keep the bat files in the game folder. MOST WON'T NEED TO EDIT THIS! +set gamepath=%cd% + +title MOTD +echo Visit plutonium.pw / Join the Discord (a6JM2Tv) for NEWS and Updates! +echo Server "%name%" will load %cfg% and listen on port %port% UDP! +echo To shut down the server close this window first! +echo (%date%) - (%time%) %name% server start. + +cd /D %LOCALAPPDATA%\Plutonium +:server +start /wait /abovenormal bin\plutonium-bootstrapper-win32.exe t6zm "%gamepath%" -dedicated +set key %key% +sv_config %cfg% +net_port %port% +echo (%date%) - (%time%) WARNING: %name% server closed or dropped... server restarts. +goto server \ No newline at end of file diff --git a/bo2/!start_zm_servernuketown.bat b/bo2/!start_zm_servernuketown.bat new file mode 100644 index 0000000..284bc68 --- /dev/null +++ b/bo2/!start_zm_servernuketown.bat @@ -0,0 +1,23 @@ +@echo off +::Paste the server key from https://platform.plutonium.pw/serverkeys here +set key=your_key +::Name of the config file the server should use. (default: dedicated_zm.cfg) +set cfg=dedicated_zmnuketown.cfg +::Name of the server shown in the title of the cmd window. This will NOT bet shown ingame. +set name=. +::Port used by the server (default: 4976) +set port=30006 +::Only change this when you don't want to keep the bat files in the game folder. MOST WON'T NEED TO EDIT THIS! +set gamepath=%cd% + +title Nuketown +echo Visit plutonium.pw / Join the Discord (a6JM2Tv) for NEWS and Updates! +echo Server "%name%" will load %cfg% and listen on port %port% UDP! +echo To shut down the server close this window first! +echo (%date%) - (%time%) %name% server start. + +cd /D %LOCALAPPDATA%\Plutonium +:server +start /wait /abovenormal bin\plutonium-bootstrapper-win32.exe t6zm "%gamepath%" -dedicated +set key %key% +sv_config %cfg% +net_port %port% +echo (%date%) - (%time%) WARNING: %name% server closed or dropped... server restarts. +goto server \ No newline at end of file diff --git a/bo2/!start_zm_serverorigin.bat b/bo2/!start_zm_serverorigin.bat new file mode 100644 index 0000000..c4dde99 --- /dev/null +++ b/bo2/!start_zm_serverorigin.bat @@ -0,0 +1,23 @@ +@echo off +::Paste the server key from https://platform.plutonium.pw/serverkeys here +set key=your_key +::Name of the config file the server should use. (default: dedicated_zm.cfg) +set cfg=dedicated_zmorigin.cfg +::Name of the server shown in the title of the cmd window. This will NOT bet shown ingame. +set name=. +::Port used by the server (default: 4976) +set port=30007 +::Only change this when you don't want to keep the bat files in the game folder. MOST WON'T NEED TO EDIT THIS! +set gamepath=%cd% + +title Origin 1 +echo Visit plutonium.pw / Join the Discord (a6JM2Tv) for NEWS and Updates! +echo Server "%name%" will load %cfg% and listen on port %port% UDP! +echo To shut down the server close this window first! +echo (%date%) - (%time%) %name% server start. + +cd /D %LOCALAPPDATA%\Plutonium +:server +start /wait /abovenormal bin\plutonium-bootstrapper-win32.exe t6zm "%gamepath%" -dedicated +set key %key% +sv_config %cfg% +net_port %port% +echo (%date%) - (%time%) WARNING: %name% server closed or dropped... server restarts. +goto server \ No newline at end of file diff --git a/bo2/!start_zm_serverorigin2.bat b/bo2/!start_zm_serverorigin2.bat new file mode 100644 index 0000000..f9f006f --- /dev/null +++ b/bo2/!start_zm_serverorigin2.bat @@ -0,0 +1,23 @@ +@echo off +::Paste the server key from https://platform.plutonium.pw/serverkeys here +set key=your_key +::Name of the config file the server should use. (default: dedicated_zm.cfg) +set cfg=dedicated_zmorigin2.cfg +::Name of the server shown in the title of the cmd window. This will NOT bet shown ingame. +set name=. +::Port used by the server (default: 4976) +set port=30008 +::Only change this when you don't want to keep the bat files in the game folder. MOST WON'T NEED TO EDIT THIS! +set gamepath=%cd% + +title Origin 2 +echo Visit plutonium.pw / Join the Discord (a6JM2Tv) for NEWS and Updates! +echo Server "%name%" will load %cfg% and listen on port %port% UDP! +echo To shut down the server close this window first! +echo (%date%) - (%time%) %name% server start. + +cd /D %LOCALAPPDATA%\Plutonium +:server +start /wait /abovenormal bin\plutonium-bootstrapper-win32.exe t6zm "%gamepath%" -dedicated +set key %key% +sv_config %cfg% +net_port %port% +echo (%date%) - (%time%) WARNING: %name% server closed or dropped... server restarts. +goto server \ No newline at end of file diff --git a/bo2/!start_zm_serverpanzer.bat b/bo2/!start_zm_serverpanzer.bat new file mode 100644 index 0000000..b1ed15b --- /dev/null +++ b/bo2/!start_zm_serverpanzer.bat @@ -0,0 +1,23 @@ +@echo off +::Paste the server key from https://platform.plutonium.pw/serverkeys here +set key=your_key +::Name of the config file the server should use. (default: dedicated_zm.cfg) +set cfg=dedicated_zmpanzer.cfg +::Name of the server shown in the title of the cmd window. This will NOT bet shown ingame. +set name=. +::Port used by the server (default: 4976) +set port=30010 +::Only change this when you don't want to keep the bat files in the game folder. MOST WON'T NEED TO EDIT THIS! +set gamepath=%cd% + +title PANZER +echo Visit plutonium.pw / Join the Discord (a6JM2Tv) for NEWS and Updates! +echo Server "%name%" will load %cfg% and listen on port %port% UDP! +echo To shut down the server close this window first! +echo (%date%) - (%time%) %name% server start. + +cd /D %LOCALAPPDATA%\Plutonium +:server +start /wait /abovenormal bin\plutonium-bootstrapper-win32.exe t6zm "%gamepath%" -dedicated +set key %key% +sv_config %cfg% +net_port %port% +echo (%date%) - (%time%) WARNING: %name% server closed or dropped... server restarts. +goto server \ No newline at end of file diff --git a/bo2/!start_zm_serverprivate.bat b/bo2/!start_zm_serverprivate.bat new file mode 100644 index 0000000..560c60a --- /dev/null +++ b/bo2/!start_zm_serverprivate.bat @@ -0,0 +1,23 @@ +@echo off +::Paste the server key from https://platform.plutonium.pw/serverkeys here +set key=your_key +::Name of the config file the server should use. (default: dedicated_zm.cfg) +set cfg=dedicated_zmprivate.cfg +::Name of the server shown in the title of the cmd window. This will NOT bet shown ingame. +set name=. +::Port used by the server (default: 4976) +set port=30005 +::Only change this when you don't want to keep the bat files in the game folder. MOST WON'T NEED TO EDIT THIS! +set gamepath=%cd% + +title PRIVATE +echo Visit plutonium.pw / Join the Discord (a6JM2Tv) for NEWS and Updates! +echo Server "%name%" will load %cfg% and listen on port %port% UDP! +echo To shut down the server close this window first! +echo (%date%) - (%time%) %name% server start. + +cd /D %LOCALAPPDATA%\Plutonium +:server +start /wait /abovenormal bin\plutonium-bootstrapper-win32.exe t6zm "%gamepath%" -dedicated +set key %key% +sv_config %cfg% +net_port %port% +echo (%date%) - (%time%) WARNING: %name% server closed or dropped... server restarts. +goto server \ No newline at end of file diff --git a/bo2/!start_zm_serverraid.bat b/bo2/!start_zm_serverraid.bat new file mode 100644 index 0000000..8f222c2 --- /dev/null +++ b/bo2/!start_zm_serverraid.bat @@ -0,0 +1,23 @@ +@echo off +::Paste the server key from https://platform.plutonium.pw/serverkeys here +set key=your_key +::Name of the config file the server should use. (default: dedicated_zm.cfg) +set cfg=dedicated_zmorigin3.cfg +::Name of the server shown in the title of the cmd window. This will NOT bet shown ingame. +set name=. +::Port used by the server (default: 4976) +set port=30009 +::Only change this when you don't want to keep the bat files in the game folder. MOST WON'T NEED TO EDIT THIS! +set gamepath=%cd% + +title Origin 3 +echo Visit plutonium.pw / Join the Discord (a6JM2Tv) for NEWS and Updates! +echo Server "%name%" will load %cfg% and listen on port %port% UDP! +echo To shut down the server close this window first! +echo (%date%) - (%time%) %name% server start. + +cd /D %LOCALAPPDATA%\Plutonium +:server +start /wait /abovenormal bin\plutonium-bootstrapper-win32.exe t6zm "%gamepath%" -dedicated +set key %key% +sv_config %cfg% +net_port %port% +echo (%date%) - (%time%) WARNING: %name% server closed or dropped... server restarts. +goto server \ No newline at end of file diff --git a/bo2/!start_zm_servertitb.bat b/bo2/!start_zm_servertitb.bat new file mode 100644 index 0000000..361d5f8 --- /dev/null +++ b/bo2/!start_zm_servertitb.bat @@ -0,0 +1,23 @@ +@echo off +::Paste the server key from https://platform.plutonium.pw/serverkeys here +set key=your_key +::Name of the config file the server should use. (default: dedicated_zm.cfg) +set cfg=dedicated_zmtitb.cfg +::Name of the server shown in the title of the cmd window. This will NOT bet shown ingame. +set name=. +::Port used by the server (default: 4976) +set port=30011 +::Only change this when you don't want to keep the bat files in the game folder. MOST WON'T NEED TO EDIT THIS! +set gamepath=%cd% + +title TITB +echo Visit plutonium.pw / Join the Discord (a6JM2Tv) for NEWS and Updates! +echo Server "%name%" will load %cfg% and listen on port %port% UDP! +echo To shut down the server close this window first! +echo (%date%) - (%time%) %name% server start. + +cd /D %LOCALAPPDATA%\Plutonium +:server +start /wait /abovenormal bin\plutonium-bootstrapper-win32.exe t6zm "%gamepath%" -dedicated +set key %key% +sv_config %cfg% +net_port %port% +echo (%date%) - (%time%) WARNING: %name% server closed or dropped... server restarts. +goto server \ No newline at end of file diff --git a/bo2/!start_zm_servertown.bat b/bo2/!start_zm_servertown.bat new file mode 100644 index 0000000..6550174 --- /dev/null +++ b/bo2/!start_zm_servertown.bat @@ -0,0 +1,23 @@ +@echo off +::Paste the server key from https://platform.plutonium.pw/serverkeys here +set key=your_key +::Name of the config file the server should use. (default: dedicated_zm.cfg) +set cfg=dedicated_zmtown.cfg +::Name of the server shown in the title of the cmd window. This will NOT bet shown ingame. +set name=. +::Port used by the server (default: 4976) +set port=30012 +::Only change this when you don't want to keep the bat files in the game folder. MOST WON'T NEED TO EDIT THIS! +set gamepath=%cd% + +title Town +echo Visit plutonium.pw / Join the Discord (a6JM2Tv) for NEWS and Updates! +echo Server "%name%" will load %cfg% and listen on port %port% UDP! +echo To shut down the server close this window first! +echo (%date%) - (%time%) %name% server start. + +cd /D %LOCALAPPDATA%\Plutonium +:server +start /wait /abovenormal bin\plutonium-bootstrapper-win32.exe t6zm "%gamepath%" -dedicated +set key %key% +sv_config %cfg% +net_port %port% +echo (%date%) - (%time%) WARNING: %name% server closed or dropped... server restarts. +goto server \ No newline at end of file diff --git a/bo2/!start_zm_servertown2.bat b/bo2/!start_zm_servertown2.bat new file mode 100644 index 0000000..0edcb2f --- /dev/null +++ b/bo2/!start_zm_servertown2.bat @@ -0,0 +1,23 @@ +@echo off +::Paste the server key from https://platform.plutonium.pw/serverkeys here +set key=your_key +::Name of the config file the server should use. (default: dedicated_zm.cfg) +set cfg=dedicated_zmtown2.cfg +::Name of the server shown in the title of the cmd window. This will NOT bet shown ingame. +set name=. +::Port used by the server (default: 4976) +set port=30013 +::Only change this when you don't want to keep the bat files in the game folder. MOST WON'T NEED TO EDIT THIS! +set gamepath=%cd% + +title Town 2 +echo Visit plutonium.pw / Join the Discord (a6JM2Tv) for NEWS and Updates! +echo Server "%name%" will load %cfg% and listen on port %port% UDP! +echo To shut down the server close this window first! +echo (%date%) - (%time%) %name% server start. + +cd /D %LOCALAPPDATA%\Plutonium +:server +start /wait /abovenormal bin\plutonium-bootstrapper-win32.exe t6zm "%gamepath%" -dedicated +set key %key% +sv_config %cfg% +net_port %port% +echo (%date%) - (%time%) WARNING: %name% server closed or dropped... server restarts. +goto server \ No newline at end of file diff --git a/bo2/!start_zm_servertown3.bat b/bo2/!start_zm_servertown3.bat new file mode 100644 index 0000000..01c5e90 --- /dev/null +++ b/bo2/!start_zm_servertown3.bat @@ -0,0 +1,23 @@ +@echo off +::Paste the server key from https://platform.plutonium.pw/serverkeys here +set key=your_key +::Name of the config file the server should use. (default: dedicated_zm.cfg) +set cfg=dedicated_zmtown3.cfg +::Name of the server shown in the title of the cmd window. This will NOT bet shown ingame. +set name=. +::Port used by the server (default: 4976) +set port=30014 +::Only change this when you don't want to keep the bat files in the game folder. MOST WON'T NEED TO EDIT THIS! +set gamepath=%cd% + +title Town 3 +echo Visit plutonium.pw / Join the Discord (a6JM2Tv) for NEWS and Updates! +echo Server "%name%" will load %cfg% and listen on port %port% UDP! +echo To shut down the server close this window first! +echo (%date%) - (%time%) %name% server start. + +cd /D %LOCALAPPDATA%\Plutonium +:server +start /wait /abovenormal bin\plutonium-bootstrapper-win32.exe t6zm "%gamepath%" -dedicated +set key %key% +sv_config %cfg% +net_port %port% +echo (%date%) - (%time%) WARNING: %name% server closed or dropped... server restarts. +goto server \ No newline at end of file diff --git a/bo2/!start_zm_servertranzit.bat b/bo2/!start_zm_servertranzit.bat new file mode 100644 index 0000000..7de0d51 --- /dev/null +++ b/bo2/!start_zm_servertranzit.bat @@ -0,0 +1,23 @@ +@echo off +::Paste the server key from https://platform.plutonium.pw/serverkeys here +set key=your_key +::Name of the config file the server should use. (default: dedicated_zm.cfg) +set cfg=dedicated_zmtranzit.cfg +::Name of the server shown in the title of the cmd window. This will NOT bet shown ingame. +set name=Tranzit +::Port used by the server (default: 4976) +set port=30015 +::Only change this when you don't want to keep the bat files in the game folder. MOST WON'T NEED TO EDIT THIS! +set gamepath=%cd% + +title Tranzit +echo Visit plutonium.pw / Join the Discord (a6JM2Tv) for NEWS and Updates! +echo Server "%name%" will load %cfg% and listen on port %port% UDP! +echo To shut down the server close this window first! +echo (%date%) - (%time%) %name% server start. + +cd /D %LOCALAPPDATA%\Plutonium +:server +start /wait /abovenormal bin\plutonium-bootstrapper-win32.exe t6zm "%gamepath%" -dedicated +set key %key% +sv_config %cfg% +net_port %port% +echo (%date%) - (%time%) WARNING: %name% server closed or dropped... server restarts. +goto server \ No newline at end of file diff --git a/bo2/binkw32.dll b/bo2/binkw32.dll new file mode 100644 index 0000000000000000000000000000000000000000..e5b15005eb93be3fa006976602d44a50d6094a50 GIT binary patch literal 215040 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Ξ53quirk(O%#tT#{hA%7U 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%0A7J2W>VKDe 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 literal 0 HcmV?d00001 diff --git a/bo2/getCmdPID.bat b/bo2/getCmdPID.bat new file mode 100644 index 0000000..a8ac9cb --- /dev/null +++ b/bo2/getCmdPID.bat @@ -0,0 +1,39 @@ +@if (@X)==(@Y) @end /* JScript comment +@echo off +setlocal + +for /f "tokens=* delims=" %%v in ('dir /b /s /a:-d /o:-n "%SystemRoot%\Microsoft.NET\Framework\*jsc.exe"') do ( + set "jsc=%%v" +) + + +if not exist "%~n0.exe" ( + "%jsc%" /nologo /out:"%~n0.exe" "%~dpsfnx0" +) + +%~n0.exe + +::pause +endlocal & exit /b %errorlevel% + +*/ + +//http://stackoverflow.com/questions/2531837/how-can-i-get-the-pid-of-the-parent-process-of-my-application +import System; +import System.Diagnostics; +import System.ComponentModel; +import System.Management; + +var myId = Process.GetCurrentProcess().Id; +var query = String.Format("SELECT ParentProcessId FROM Win32_Process WHERE ProcessId = {0}", myId); +var search = new ManagementObjectSearcher("root\\CIMV2", query); +var results = search.Get().GetEnumerator(); +if (!results.MoveNext()) { + Console.WriteLine("Error"); + Environment.Exit(-1); +} +var queryObj = results.Current; +var parentId = queryObj["ParentProcessId"]; +var parent = Process.GetProcessById(parentId); +Console.WriteLine(parent.Id); +Environment.Exit(parent.Id); diff --git a/bo2/getCmdPID.exe b/bo2/getCmdPID.exe new file mode 100644 index 0000000000000000000000000000000000000000..66725e7a6d5ff4ea3dcca4a321ac03a0155e8299 GIT binary patch literal 6144 zcmeHLZ){sv6+iFUu~VnFfm2lop^r z1->F0qrFYK)~2-)Z2~9caj$&>wShc}%!PqU_i%$!__?NKWbio!X!KcSgzc~~Rj*Xc zq$${)VPcf%Z+<^+uB5X>8&?|dfiQ?#o77v;KHSt!x#FUW_Vou)K&G&*8z1bmDOr;R zh!wU`5WG-v3w1?NV&2??8 zY_-;co)LMqLAJ@)8stX#qXyY7-)xW_!6v#TiP=SxVHD3}skCK43d&zXcZsPac#&mb z4a(yhcuaLAH-K4-umqC|hWkQ&OHBAP!Jds=g7+ewSJ{W1oj$)Etou+|h9`opeM?;3 zhk92Mo{l`myIPh2F$o_=wj|MxY`D9TWDK%pc&%X`J1OF#o91+YT4G6;g5K9DYcTn0 zXO|CTGxvnUf=gU%+t8WZ0?r~k?nn|FEwT(p24lg#C9c<_R|6-zpcZSnhsHXyJd@44 zuy0x@k4eJOv91TNVhJ?Bdx7Egb;*96>#g#2Rd-7_fOfJQT_Yh(fkJH|wavoG2f+&` zv5ujg9xM3}I6HTBq;&#lZ_g$Z;O(NZ+>tR&odWMnEexg7sloK%z&{5+2eg{_?SjXOzIr=vc^CI;gIypIxdL#A^!{{9=J9DgzgyyDGn{|RJ z(LehJ`RoF`I_j9W!UuEIgUpALc`Roh(eHJpS#pxLQ-n-f0(}j1h`vGJNBO3re}yti zf1p1@=Uv*5@;1s4g|zJ$DXL|_d01n9N|k$1hG-1Z2;~*$wBl63;pC0VeqsvKf@c~n zY#18A9T>n=zNGb_{IV)vQRUZE`7Kr6RORa^vj#d*XzLZN19r+@i=NZE(YpRImUYrk zH3O|+FSl58Ct5M$x|?okyWqhqT8chSZ)tll{uOP6_R$};F_eGT4$&n2OFK%(N!O3l zQ;?nl-KL+0=4QPI3iJTg^efQ3q<3vd4&JdHA52QK$dJH>igJWfY)1!+}X zBfUaRo0d(}RzW&7XWmWu3RI~T99g#JD7RR1Ma8dD)23~fL`B#x9m4)L%ejJ66_jx* zRjVvy6YqeF^DSed)F)<8PO;~ZE<`F=SwGy6t{Dt!UaY(qC zx@7H!H%h`igPsQ+SutJ8JH8Y0j*s7g{ft>ILp0`Kx~5I1q~(e!_Wi^~3kxjVV~#y- z)oSqatXZyOu4?yq7ILmxIG=Z_tT!&^O+e=tqHmr}dwnvFkOi@u)qHGYJo5}(<_d4E z57G(+>$P*ugHhJ0u4$Jr;Yu-!E4Q(wy)91Ep2I1wkxPOqM19Sz6piB~n^Yp3 z9HnDX0X03cRx1N(g{mmwZe;8k&_&RQ483c0r(w@lHhDZxo5F`c;RX1RS5H8ruA~y0 zE^J9eJGQw1y<^B1S^I$uv?PAMm6l12NtbgpK~u;X#7Tp)u+Y%Rf^skefjMBaL))N( zbOLYQX;7yyR~xs*ZaRZr&6+Gb42vg_*Lg1i*S)c=RvW>IogY#NyCs169S-);t# zf*1bxX8fQar{TAG_;4QnoQEF=u+@g)MH74zetc~$ZzI=cuD>{b zVN>Aoz0`W+i8GgDzll87`h(9rJ=;C>_H!+Uro~$V1|{@R0&gCzCyIs^2*qPzLx(6H z3*jp^8jl5`8AWuC_dubwh4g3?9rS2IZ-HVo3bjNc9@}696FmuCkH;X?6M7If(M{7@ zg9gRh+bEPs_zGbPBoeU$I);t+w6abjOnSUU?};i{?RuD^;ZVGL^%n|59&Zh52=rNv zjy6JfzcDLh4H0XEpSSq+8yQ^Ebty({QFo>C^s=|^!yj%hUM1=jb)+-Z%T^y4(Y0~{L>3m3Nll=lucJvcu+zjuCMpg5d12eA*I z(kSm+Uk&o_i)A9$|CZ+G)aRHsn7T7HzPUZgnT#VRE(#U6)w&3gDkA7|y4^>{sG>fY zLQ~%+>zryaz-@+t_}2p?r= zx_%I0`DMBh{0EF`K*yniV_@knmfli2XwP@U_NoXTEeB@ti;U4CEb6 zvMR>45pa&7W<5>@a=+4PARmW>Lm%U)uEEK=X?#IxE7;ZsM2I184vBci9wra_TAlUYGJyZ1w9W&D T_y3Jo8V7Ej_@n0kw+H?UqB4fC literal 0 HcmV?d00001 diff --git a/bo2/wlanapi.dll b/bo2/wlanapi.dll new file mode 100644 index 0000000000000000000000000000000000000000..07a84d39ce9e063368879633af04c73cb65b6cb3 GIT binary patch literal 336928 zcmeFa3wTu3)i=IpGD(JzWQLGvgs1}s1-TdqD9FVC2?Pl+5Uz3ym_UdKX_x`LputI$ z@i@wB)!MhVjf#Ek``I?NYJ*x0U=6fh@KTFPYqV%54Q-=RjEc_p`|Ukv&Y8(fM0@$3 z|MUDu&szKJz4qQ~uf5jV*AwPkv0EewA#8X;At73T`74s}D}Y6a%yXa26p!_JaZrn; z?8QL~t2bY;qOPD|cPJxw2|hMn+nGxac1Y z{N8nMUHgxr`tzD~-OzjRzBB9Ous=%t;jq^w?i%)@q&qS6)QwC(G3-ql|BqpBOWZx| zza_R0RqttG{E19ou;I#T))CtxcZm>XmK2eB^Y}4(TD!0g>TAh#h9 zw1&%r49veGmRGl>?n*>TnLsvD$a{Lw6^*K^+PE2nlo4emN`ZgcgKipP|Nmbc3ACOs zoUT`evtpvvS$mI7YUtQ3T~md4b(L@`^`VvvvB_#NYpIA;t(M(3r~SWd&SI3Y`yG_i zE}XZS!beQuq5Xxk^)BOp@U`(@z*pB~tF!(|;XGV|cH&_j z{FQA`^<d7BuDsV5<01#8Zoi%?)lR9paCN=}rMl{~4yw2BxXFfK!1B!uclw_rZGw zF!OH&1`^xD@4FYN_dSgKhQ9{Lz8>XGLjK?bsxPZu!g(1h^jacqX7PK_?~MK?zt$$< zEP^cSCs-vmmtg}BOHKO2I;!zr8;)bTP9MUL;UYZdJdCRVU6ZLC_DM6|pEi|68odqX zvdsBdmJ4*pO=YpaPT@Tr`e!bWbgYLzb9v^xOe+Q5B;;k7Kk`t9_l4m&rpp8Xb2-dI zTGpXs>KNbow5HpfExAhn_@04Br=w1lK@s_o?%)~1iIGOS?EWUY1xP0?AJQ!a9qXVD z_r;@^w-gacc;iF5F4W63GM;IoTVc0|pU$?+hjbO$ip~WZhlwt2VIOfh-uaO3deE^A z{OS2Ai`o=JHcTU*td~!7l95J!r-kF0&y6zi+T+K3gOI|y_^_=v;bFWv57W*w(cO&q zX>sV7Ki@=mFaaI;8)2eLLxtlJ$EP;U;1widl8J5_=*Sx%b9-HQpJt*f20=XjiaKpg z^CZfLq$qyO{SnKnIgR=FOVk#|Cz79TpYeFr?K57QZl8LZnIGLg^)#~%&^{CKc^1;x zpE`{>pKiN)nP%NV7Wt!{>FH*f>-HBfjs28}AKgF4%f|{6)hEkDp?bY+hcj$Dtc&UV zG2A-ZumKs_6Vx+`bAlq^f-#c59zi+&yMWDc`Jgk$H6WeiI@{nbPfFvsAc3|2~?E6^6BU+S&>C%BIUnem8FB_P;p9@S~&jY58 zDCwNur13YhOlfmv@b93NZXe|o+3P1~o-Czk)%b)mk_)7OQ!?N;)< z514Wo{~h&S2244gxJSv!iFfLg3z&2xfT{oYhSOVtncfb}bp6LTzO&DWpN5?f^Wi#x zeaAI|^DNbmq@$nE*9F}J6+h&KV~@TLsLoU6uoJWK==1&-lq2~>9P7~M`L83M@8)08 ztI$n6<~Tjv+JunvArw;oV}uGGMd)w~LRd&*6auhfd5(DtK{H>Qp8{xt?O6++0jPbJ zudM(T`vKaY18}ziG#_FCFCv6}43tLzF0flgAouOMxOwM#1EBejj3W^5;3*=gCBR+< ze(iX$BZ2bX18{%9I)Vg$0jNI?P;?Rrhd%*uox=3{dbbfYvPl&0c__tpK�h+D_D7X%w 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%0AkwHH(gZ{ri|%Y5EfBd*_LYFcslb6UDrIfnr%4T$ zc7e;Uq!Dm~3tc`14a){orr@MNGr}B)Y(pcJrv*)i1sX170vTgB64f?be>I2*&0XXa z;Cww@0f&~x$-w-Lnf^9(N=4LKJb%RLVb;#>8eJ6ewPmw>0<^`l!vtOj0u4_Jyk1N4 zT4NQ&4yZf)z9S7S3SwK5^52JQx~+9RV9`N^MKRZJ#8_&Mki&;vbOUg67_&hmr6wap zZC`Yn&~#Km_!vL_9EE|F9<7+G3L05poTQI%(D-&TYx!ihTO$g&`sWqDE7IkOg|`^J zv9iXPf2Uk>Ggru_3hy*p(f`1RTyB(cs~~IbCGZuC$^qRh83_PNIC+e@J{dv(H}fj9 z*(}9n0g0;za(~c#5IstNS4OzCm;o1_bU(I8fE9*x*?W-TawHwG2~4U1kxyBtr&uj^ zl~kHUl}y8T;545ya1uVvC-ixHhx(+n-9w*HaHO{sLHmN!>mL`&SH};oF0sck{&O%X z^E2M$j0r8YXzDV#3d|n|E5@HJaS~{6XnsU4Pr&+g1lD9S&c22mv^*%r zS4Ndm@6lNqw6QTF7YcPtjOIPT8r8^h-AFpTSh)VtVGT2=3`%T_h?WoP7%-pV>|-n4 zfYLPPI}&KPOO!}oQwO3o9evWd>&{REI1>A&DDcc&A@HgXp<7K6(PZ-fwD{Oq{VLp2 zj=g(M-=u`QuAO)EC_AZPm9$-u>=1(9W_5VpP#ub<9s@}1o1)}1e=JHG)nSbHO%YL< zst!k|b{Jj_DqgX)8UY=(1&h&{owLF%6+t4bopdFSAPajWsYM)w@PtiEs-g#d;-Xq| zXASy`629Dmva5WiKpS{ zLtqXX#oHXmBJJ-+nmy4uM0=kMxsOg$E=jk55Z5R{A=^0Fc^<&U=nHeu!h$4MqorX+ zM6bqtg`?JLIK}>4@J@URi!m{|7_EaB<5s;G0&!uYTC5e2efBfvhpBg@0=};+vLff7 z3K67?kXPXZ)>~cwMkGI*k2}Na`YQNtS>S?q3i{^6|Lb25dsyHFX5@bMoY{ zZIn)f%Bv*UCl=Zcv%6UOXHf(J*&E2%9%D?2QJtc0u@>c*h2q4RIF%gHAA_<>#`Vt4?Q*67u2U)idg>!rYSsPFD zX{4=QPj#dQUao(G#Cy!h=a4$^3KW8~Ga$Qvu^Rs0Wyw*Ox4w8kzt3qj-Z<7WNsd{L z`0WAn^|^emVOt5`MpY3n+Ko2?=C@?26tDVQ77Gu%g8eu(oo`gOyPtQQ#X&79)3u8- z{W}STe`BAoYgXZ_)g2sUnZgO}%=C3#+6I5*45ouz(L1&od-2h= z^ma=e15937G48$j<>YdhU*%lV{hI*O>pSoOE|01qmV*mHZK|yU(R6!hmJV!dm}={Q zYHL!mt*2>A+;1QFJfRLN%{4dQ>Dvis)**Ujl<+$tknZPmGNWY&P~0nZyfD%+$JqoC za7VtbmUZVG0;V(YzR3y;A*N%*8ESklbO1NhSwR+`nnQtNYo^=WOWS4%rqR5W1- zDJQCG2qwb)_z@XVB5%!g8cCDl?DymlP#lAh>#wU{?Nq3}TAWat%?Ej-;tQyH@qPBX z{n^I4mzIbZr5+LB%EmnxVn11 z!{M!L3ppa!=PY#yvl_O@fhOF)88E*$Ul$5j4=Mn; zwiGVrV{<5jeVMihzRZpq5t}8r%tgr9YzNmCBxD*`YWcjVgXp07Ss^^(9Hs0kOoYCm z54_OLa%Lr1+4#-Y5%~K^jVDbBtBmb{J+{38^L(Mt(&>u~2Hlu>*)M@JFGAY6CUVCS z3j)H8#Gm35cNqVJwsHG2*S^U`Clm}{mA?v3QVPU^Z%#V@rSb}VVuK8+*efu;;V+*Xht^0zVELhvV_59Lo;}w-^6raB_W6 z(5i`Maa)m)#N2mgIWeUM8Uhb<)YY_^zfRp2*~Yt_>x3}}r&sYeShdt#Dmr5UuZ?xB zosx_U)v<|XaGzYNQsnwdUV6pI&;uHYhobr(`(P$Fg42ua zG9om4eO>q_qi1)MYA|0(R0ong%7KPvsSdMxiC~+(oncCviX{z`@`LJ%!)JsqRNESl z!SE5-BxQ}T90qmbYB-b((UyYX(!Q*^Oj{xqfSQ>Rcb<&4SGrT&36Sfk+KkpHm=!P= zUS|(k5*x{oM{RJgr~f;B9W$fF3#95)q?weeeSF1jz#NyXDh{0evn`4i&p&0hE2Ir( zTR1yqw)ryKnN+rBTLkNU1QkAZh?!3<9;M^$?P_~dH1a?t-NC<>i>Dfb!yBeMt zFomE;#$S4^o_e?#2Z8?Kd!off%0_~v#FG|AVIvq2D{C{avy2YmGdN>m<%Z)K6D^() zy(uqxt>Opu^}Lr}7geri`G($kYWM6h8!uOiQzqS!ob=3jogXmi;Qach1m%xVL{Pp3 zKN6)=P-=WgF63A=Q#&n$!Z){IzwC8x7eJ2LmvXIOUQXYd+~~r|(S=iufTRQRwVK1O z*9Mo{1fTsV`0%9LjM~$z6FjteWo-eNMHwMqS4&yJudPY^-P&+K=}HfpUn-J%r|S4G zvvvI2!CEoQ^s7tNdi^Cn(wOkkQJHz8kb7ecQxd(J%pOZK_>yL`HfS1ao2rDmEOzEhmvGy zfqmhRxRD1JSq`gWPI)z;q6{GL8HY<)HN(HRZ<=}COG3#beIvu?Y8k(Ser#@^FisuV zTW&+|vY}6$8^XEX%J$GXsw9J|-NC!2VYw>uguCu1QWb(96;^iOy@VR@052}#X=N}0 zMo|udk`cVL(;k67OrV2H;!~uM$mZsznKTAaMF9~WMKhq#l}%|9FNKm*P?Y+^vr;cnD+SZ;ff6eGw(OHv)DOH|X)`@s71GEeZf~Nv<_64|fx?{%@g|>V~ z8x%bCjj{(?_(|4bxXTW?ID<=7FIbLYP@Qe-#r+piMc}03pFP8Gc!CQAmY@A{wPvzGUj?S(XTN4PqZO2} zkGMqV&o#CXdSsy^vnaAMC#|8LCZfZl^IWp|o920(6fs}8nyQ0#)t%rD?nb3%H}aS| zI+v=`t~=1sCHENWhNyG3cKYs`#j4E9Mb@z`r3nmP{%)hC)Vv6lq-t#>s}kKN3rJ=z zt(ANcM+wcCoL+-*8lI)e{3%S7QyNc?ABy_5l= zYJfR#*EIl*es^E|vvK!*#&-90R%>_P&6d0G!b?OPN^#Cky8EiupOn_`lGYRA?)!UO z&)H44B)z}qI8^f?yZJ1u`Bhf)|3sqv7tL>%=0_!)e}Lw#g9m7yBBWcp>xL;dkd%qO znx6_t_9ajZ?&6WAx01LVYg+7mQG{CYWBBDpMH88~t}*oq#^h$} z>5}Jq3)h@Q#2;8JM3-&AR=>|GE-bA6s|<;ujyvVPt*_hsFO=1?n9lmkWiemnr(9F) zQZzuh1=t&2 z6RiQb>J>I!Zw>0Kc6Yf>cx zyHDZCzsHYDF9Gh{TU=bfSm6FJKLtOYAsHinet73^iTSsnCoCz~jVsT(X7k~TW!_s9 zpzkT^D=_@e#7MWJ%ZQ&8e%lL#A`1t;B<9=PVGA4S{4r2l`loL`)*@yS!aLFRQYKa(UE zd4iykAbz)v_}XJp5dWvFNXju{Vt(?jbF8@<187Z`2&k4j-P$}v#d1^ZKP*QvxF+sd zU|f;2aGj(2x0XBBX%TLZx$WWs7~jfI8DW>42;I2o8)wM?Q>mBokW$xWIOhbglX0Rl zUMn|`%Ox0jai(|95JpSV|VDm5m}D zHv_qO5_hCGl}}jEk{wi+il#>u&CV%3-{9*+5p^_8!YOki^6^7 z%X7YTp>Y3+nS%T7y4Pernfe}!@{3f3l~2zZ3MZt{k0{iWnI2x#lbI2^+qiLZY*soU zb4R=^;bA&A@-^o2^O$B96iNqTyCYCQGXB7q@S7#E)#Sd_Qw!cHC2-SVC!bP@qNKMQ zPCl~w+R5ju%t@SlR^#Nubf~X)gmUtkDby;#AqcZ2N~*5U!RKko;a?E&C_xj1Fixv~ zMiBWqe#$cZ4#y;9Z6YpUr?QN)+}I2EDq&!nSl=sXUtxvK9&~rUD^tfBWb4k4G)(=P zNNTT{U!P9lZq3)9RNDRw#ac`^y2S~i4JQaW1(RI;7@Q!S)qg=>&m~~~<+k*M-^;M_((Cda$ON7Rbr@Y@Pcd5 z{(kL*vCsT$zJ_dWeUm`8f}h3*puKRNu+)(GKuJl}dO#-rKKS?(9?)!PhuxHDY^3N+ z6P8k8zd|V-SMnd%(7gC6{UtQo(gFp={GeDOZOkJm7zv5G=9tf`a|!I5AE{|ilcBdY zJuIg!|4)lPEXQp;JMtrWgL)(En0Q|NJowcn@py&h0xo9sVL1u}3J=RkAoDzpMTleW zbCbmIV1=xc@;%&3=tBg_g6K5m86(kJ8iD`A!q1iBHv6qBr!i?A*Y>sSwBZkyW$rv`DfB@$->CD~a* zrG-8gDJLTs+HKS_Hw;mQo9Ci2fp-nWzM(jWQirvc!@0r(c4b7*`yaEcJ11(Cn^`}8 zDih6B6K&?KC6$S<-rAOefV~7&mr#dpRJm$3qN)HJ)l_nf);qSc5ZdK7+i2Y-YXge- z@thbevML|-OC!hg)?TR8M&U;D<^KgtL>?L!sX36hc9c=m93yts@TDLAFz!)pDMgeT z#npOnvX!y1yYwV1B+4W7rr;5=!rv!6Xk=0v+fF1>5XvSq?G207#yDtRDx)8Q%$x_A zApwcmH~kagjgn-hq&U)tua!~LD@|I0d{1~ju>c#^OPeC_@~u1Aho<(c!f}W|G#Px1 z&hUnhhR$JlET+D79ChNfHS-f;#~@QbWvn{ho-jap^*6|pln_#an{oCbETk48`(wd5 z?)fO<>OqWdmZ2$ZnH3>QfO3L8rzQA9 zn{t8r20|<_&X~Vl*_$pC+?6iB14^5BDNF{zZHon8Lf`7V4_;U-7KBM>ANkCcP1)zv9fo&6jZn0_L8$F#i5^*4653I>3!S8Zju9WC;bw?l2O zGok|FK*M6$qrX?gCt{|BZo5p5rBF`9yeKpba8|{?+T`mNq$lF6_zt4l5^>r5->QnO znYT&RaIws);(*Dke7nS{3Zx-qm?94Oaqi-yFyb|)gI1fT8inVS8kclBoS~99raPLc zX~2;BbWMSW)WSo7>(5mSX#=O7pG3;WWKz>1HeXIoTvd|50UwkKUR2r-U%>(ll=mND zO#~eq)&4qU{_L|98AJtv4kWER0NeaLnE};Y%L({^worRzzc*c!grTc3>?tVr(wKR> zYKbYkELwj)2Urdevzod?ut8`lVtqRG#?3L)zQ4bAjqUa7j- zpxLU-$i9o9P@mzllJGt(cwd-~2HEdScdck9iuf!xJZ?W?c4ig(dkn8=NYFSPd21;B z9o2o8CP^=d$k@H%q*Cu?gZ84>69=*$PHKN^iem2`rPz}jMxxm3Lahf5p2fQMpaS!& zAS8nA=`61BQC_x|=A&#!SNN#Eo~_mi{!e)Qf}YMl$#Lt@2E(4txk4;hE%P%%To{$& zE=K?cYhaA(N%2w|pkxKhP_9DsC59^l^AmW8yNHK{-nXFOY!d;Jy%4%Qa&lzof()@H_L?dRe1>gP)N`4fIlQ$M}(v&D*BML-=%{cXIB zxKjHlLx<+pKBU%=ByVGHHveM-@=oJA@-Ov{3E#n48fnTP%>GF*&JL%2lY2*Y%FiNV z6Ga*`B8f4pvsXqQ%=ldRGb@doPMWtcua$=T(U!(PI?RRq7|{}G!h4CrnH$H=f!t7~ z`UiyJB8$a7iN>`=V!-Kv68%Gmo;wQ+7?0>@o*{#6BpYeDIhC|6R{4}D>Jz?SOXiA# zU(+zN+_fET1g9toc?;eVk47SOiFZTAlFs#Nx?J9$c(eKA^?JHy?Q`-Fy2D%95n4fB z-IQoOk^|{|XqjY1%P4HFzIMt%0@X*3pSgB=Ijbd+){rac<2gr!Y;3Jke0~6qWUH2vvBaB!K!`K@t9NeLRd8_dG>T5k;cO9^r+2!~ToDJvZ z=Q1+o&cq`Z2ia_az6;XyehQtqXMKfb_)&&J}GudB5mM`GxHPW5zrHV8VdcQQ0VbzY6^|0B&15qrd$KiQv+C_F-ccq#h&O| z=dPA-68Ndul}!hz!kgHqO2Wz7<#|&4FO%e5+G>`=>mQ;Fu<6IBf*#VnOJ!g(8JJAe zFtHr=i_Y&S+o2_jWFxCur-n_kw^6%cF1-omTMk#`@`l@3+WX~|nnJ+5C$-bO$QOx> z*wa+(k-^4S!y9A1Cv0@{ZML3*!#SrNv6{Wm|FF3drNYt= zpH-|!fl*W6u$NuTzRhY#@L>42i<_hwI-doxZQ0tx%w5+aK+XHQReS{x$Rj8Kq5t_( zoXvxTxFuF*n(xD6$rpWyqDqRNYs)n*E!Vi~Hqcz8W+xTH_cT0dH`{18`$WKeYm(J0 zI+snveubhEx5T^#UsdTXr0+%QIm^n&&$2tQg{M5LgIs)MR>Jfm1mXL*&KV2uT^S8H zKKx<-Ap4uqOkN{&;Z&c9J*GKMugc8&g3DNy6Z{mzZkyb~5On4$1qz&KWxL)R>Pkkp z2)X1l@#U}-;-^JIl7@DfGLcssa=szEqRW7m>{nVbQFJX6s^as!Jd=+bm*A`y&U$$j z&&rx=^CE0T!dJkJ{qzD#4`I8VidO1F#f5y7mx8d$M>d0tE-q}=`Ft==U{X%uK^VaA zVTimnZ7*-4Q~GW>ZQqxxzAaYLGUHyT)P;7}sZ`8e`wiCJHsYr8J@ok{`fTW>C!w_+ zl+(L*2J}R+r?47(Cdy0)^k(Hk_qQ1D4@|R31^~|cDIaj+cOO29i-))XylLL|J@7}_ zaJ6N&^8H6$k~G8w|>q4Q*-N;gw@T*S{D@aCGN zC6_B=DCasNiJ~>AYT_5e(MWeVuZ#sFIVlZ4#IKdhOE7tNJ2uX8LUYh^=-5g(a-xBX zc!Ql*%+YjOwiS}iA3PwvM;La6^uxydPm#WgrBq12nFkB$kAOh78}f(Dsz5e$Q|IKs$hlqa` zNc!&(e-TH@r$PKbkJ5-gqkfrC`&pv}@lkei0>6U@3Ykai293AQT6HBT9ctgO1x|yU zx28gNQ}I3RLgCNOmDvqi#&@6~`ec>!K%cDAaKJn=L5g!eB4yhyM?C36q)PQQU})hPA^hMxbQ0om_hkc+%Zn??;wBew!)<0zR(^O*2R!lzDQrO~t@z;ZnoG1&_sFJ5lP8)HTa-ga zPCR3nlDJ&;E~G+afydK*>~}`-RO5|v_D9}xMdx~_13?!fL^HZf^2;n&>Vk6P?y1p| z$%Stc_`WB8ma%VldnOsrJo4ZuY+3Ed?1^XY{!7M`H=}pYjFwEZQoTmHJVeX~0_9cD z0f4G$NW{jRX$<(z#vBPhlQ1P+qk(A?=QsgO1;Kb@_vQCpjUB(-oX?sVrPBmAUNhIg zlNobnyucrKI<56S5 z*>jD#*&aYa_QH|PypJx(hBHbO?u*Vnd+s@nk@ll~b90Lf?xj+WAWbxSjdT+J83QwF zx~n=EdxIMLA@i4ye$p4cT4_;CC^?QGvkPAdyViRj3}vs};Qh(TaK;s{Kl;iZBfX)U z&y!xcrky`wM=*2Ao`|=P2Zub6R-Taig|7tD+)ur--pjv@wJl4KZeotQbSm^mK~Jb) zilyaMwY;vX1xJE&jkkd*$sj1H6lGWTr+RSLPU0=eBOLD9vv?{G&Xp7rPg74)Q;b_` zUO|4c&XY7o>MhJGi9iLp=FYIQ<+$tG_+**OyCWy>4WX4tO|+qzU)_PYGnP|VC&kI> ze3IY0WQgREsFEKr+Yd#-WD*#Z^;U_4d%5|a^1gduqoGyOU?@0fwBwhWwfN1(7Y#Mi z@KyFG2ep;2+B&a)U}vc5FEwXKTf>AVL<^T!ZDkw{)?m%Hjf_%dkFY~a6BZk)oxp&1 zOlNmO>4oxXW=f}*rGkAu&8d#>m9%IG8WvPYUbLD|@!P<>Qk9H)^Ja*n9O;vTqX#A* zypGfsj*yo-J*oknU1MbYrT%_G6X+u&bOs5kQaf=iHPxLHF^#F*&ih4;Bc@=|$(3{c zX`JyvMeKp}M~BU;Z44iua%|pmw0l|0xVe$lP;?hKH6Yz!`J$4lt%7M&tX{?+QQEg@ zWSg>*jUZiMS?3=TfNwYU|zb5O2Q=45>5*$5ryZz06n&D1Rc@ga# ziKiR%3SAMS)IipK>FeAc$P|8BziSV z<62Tuis8E~QC{#4N=J9C><6WZch?&77$ACA&+MG^&^-{&7;3s+{;DIfH&*SC2lGk@ z6Ii&!m_304e9nBuz^0Te*lqNxa-(#)X+pt3;(6p03=fZ{zbLBoc)mA%^{{Aq@ZR`Y zq`S`vEHdA9=zB0DUK9TEt)<{QhzluBc zcJ`EI82z=*SQO#L2Yuv8njk0k#bg5-pUacc?Y%lQ!hSE*)OK6&Q00B&W6CL3vT@yn zpmRwDY;?D-DF@s^#n=)0A#FK;We8Iv$6X;Z^__tM@%RNHcjR~=l>0(fQQG>>F_e0t zA}xD;{OAj#<-UUTY?XV* z2iK&fWv7KQ@UQ3zJDVgOY+8JjvG1~B>FMi_wVu;BNoiwkpiEaG`ibz$#Z^?Ul81%d zmf?h@R`z$8Bfc#xPp_H5U+w*d62rVtY&Cc{`U&E%9wEyK^9~-p;cj>Bm+2NWy1Vvv z9ykvr*C)>6?%KuthB3d=AajIS5-2sE-^&2|7g%W5J!kf_h~Z544&}fl7l=_P6z+j8 zv~Xf~X7QWC?mBT^kzBUka7$=(|NUEZku8#0y#pP|(I#IjrP5-;9Cm}*MsKOY{cY|4 zz1}xVG2F-fy|mV0ObZwb7h5=4zF3B_&ViY8ywP;Z$ir2UnnW5#Qg$-hebaDq5o+lg_3Zy&R!vD3M3jZUGh-AYsmxzsY;jvSO>o z%a@~OmHOLluHdibSmUwilmrAKo;&z#{7$-4ifW-<;`1!Jd==u@ft%hm0#b`QPP)7q z^SC5hl7Q69;%CU*$@eFzH0Ag)Yvg)mw-o$GPBLe*)nlY92drc#8Xtp?8WV%#pb5P3 zd4gO};UY+PFfG8A%2Qjuu4iy+A3Vjws?$VDr%v4|vYVy>$}F)zC1tHlPfRy{$mr{O zp5C(DH9p`?USIr@yfZ>0XOpw8uq?Ow!}w)J&S9CtSI`;v&lLk`!gxbX*qZDU;wqpf zo8CWJ>)42NsyJj|I4CH92HPvUD&>BV`3zmj@Oh?7XbB*>xVD)DJGr%T&vABdEo z?zp!H@E|^D_P}cEFJd~Pp7_ZmZ$v#KrOVV({T#8=ThlAy8<%%JChrS{b&~~q`GEX9 zge#*;6Y!Ricu}M`_NZsl9z|)a4H~WxvF|8i-#WPb{^CQFyv(>(fO8aX+_-50G)!k8 zSdiRCuGFR>9z$dGQFG0c0-kR3EAlt#<|7O89lW^*VX+*yH94#-5`E0|5|Tlh`DIAB zaEmD}oL?y|c%8IYeI$bQc^-9SHkyu^Bizq7iU@N&vis_lIP&_?y|~KxnC~9^jX*W! z;*UJ1@ZIWN-~o4gg=1S8b@0cDXk^wZ8K333kj_;m>Et;mcrPwoZ&%2U{Khw}MaS&? zuzKzW0gke^$mUQj&_aU^Q#0#Oo>LmNl_9X-VFQkoj6 znwq4VS|&GAw|qlZGhuF4e~+4*_{$oSh1lXYby_5yg06y)b;lc?6eFmR5ZqJj{kJ^+ zc>}*QjlS05!r7{D?9J0n?=wcGpk%^W1!cA;qDm{$>>fnbPm7biW}e5!Jo|)om7;$6 zU3o>rggdclL%Kjgan(6$Ud^x@)>(77RLy~t;x3szOdV}?vrEa|>H}Y3+Cq1bRT{GD~{q}lT-dIess6oP_Dx;fu zX6l(m2`MnzCa5mxKQy&WMuDhF(v6mz>TfytG zn{f8e#-Cv&Lh(m2m7Q(M@j%szGK7irMOEwhdsvcF+DF15HbOO+M}t$|jj3dB(eJj? zaLlm|ZEIZ{j~p%E?cncnf>Lwi(0EF|gYdog|BE4t1CQ~|Cnz6_$&}0$AJOPjGUixJ z0ASwFi^xmzEzMo~U5c;tz9b*qbx-gk@=}Zb5|M_~tYW{C&x%bka{GQIHGdc|Zkzzi zVqtRW1OeGP0w5dj$ImqOr7SEAlN^4ZfC07JA#LoInLMIq?-HU!jG zJ8HfxTJE=mANnItl7BhqT;{IbMmdM)>7QM5qSz#KF(dKSB*Z#MltQGVaEW{Hc_!DqipKnk&iFt0E?9+76~5SJ)ysMKDjp3 zBt-hdO9;ZMeAQ2h+!DE9a+M>`)hGs&UJ`OO0k0l^F7AoG3DE1M z(cE|$D({luxKd#Y!2)5083XPNi9)}t`m92~XDwO?r(NZurZmtjEqRbOzzVNYV1oIbpVh;Bs>O9~s!%>R$ypkTigtBY1f-OtpqgC16qF!!~H16l(L`Jjm zO5=Nu!{$a;ZaiNKI-YB>%bmS{{d?`}ckfSwXukqh9yXn>TsBbx=j%k_LH9$~v9lyM zoAiSA+IjeI(Oj?%JCetaUZO4gcMlW%Xtzj?W(oR9Klst5Wtb%7xy&Sxzf;Jl&Shk| zrE$z~NX?aOegphBB_gKl@NuFiT?DB`fn`1z=J0KX=A_d0EccH0iGcgQIrt(F*&6kxjJXjOX=5D%HfAM8cq`_sr2Wd`OLE(*yy zUt4admAiAEJj6_S&puh$2FL)1lYE_DYq@ z@f@41f;z6IQB1KXRCzWooIoN?gy3bJkH~D0B4luI-@>LD2m7T6o7)&PJYl;6I#cp= zbw(W3XGC8A8S$@{SZF-xC&!Pv_rV2_qfxgkN~}(w=6f>r;w0Iv5`9dfc%y_?BlHF| zmU9#pL6#ikp!2y$V2ew)7&DSb zyjIqr9YK{%)CClY{cJixFQyzn+!wn^=%|FJ9Y9CB6&*G98E+yLi9fTVqka!`bk_f$ z=%_DI!~_T+JD84k3mrB7fC^9Or~AthPv2P&UX-&e@pdO%DzVRHhB$-OlRoy~1t zxd?+6E{g1wDhUcRl~n%rvt#TEH`KG>b+ujGPreczBdfO|UF`^jYKucdiC5-YOYA*o z^(br$Yn%;dWMr?8G$RTauPA?A;p0kz`Adygj=cvmF2YMrPz#E@?kqvq-7Zw*)r2r| zMUn90xi3fq#_oQSC>kPIJB_qr`GWNC$5vSp&n*d($avFchX(?lv|MGvjiVJ>#cMfX zL<>K$1o7N1_#_|TbFAZ-no`oDRw~!FkXh6Nq}I;C3EN}Ne~9sxN&H|Wjoc8CF&_I4 z(j76hf1-_c=NDXA}JDeMjc&k6V=SWCPP5Y(v_T{NrdOm zr7&(Dy5M#xI1Q4bTbJt}wC+&_C!`iUAO*9N1^)@5pn9u9u`fq!36Mqvt;<_?T5t(vdndLKmqibDui1>Iw11S?kgBnI>i5 zvdb=@tfRjyvF26T99=dbWuLXn<{2adl}xMMS=RO+ZNKr!;ngauWNyWce?X#ga88Mm zl9@oXVK_aR8z^M#Zdmbcxhs3nJR#KIcIzHq&@-{1vmKUMv<9vGC3i%O+h7>ef^(Oe zrH90x=HB>%Fx5U&+0>RD`wPp1d&M)n#J%DK?iJtWk&DTZJ0yynuAR5k9ItAxyM&t9 z;*R~L?)A0jYE#@9=pQ9!{A&e0=06W&=B>nU=N@gGlaVZx{$4X3$kuXQ++bhNp~T*Bf>a+jISCs>7S5Yo8K}&-TO91ei|J^rIJe3(n)(e-GYGss z7mD1eHv(Xf*b_-Pd2S>Eovycj_=k*qvHRi@gR$!gQBYHg~TLsjz(s+MP0 zYey*6y?w$Yq_;GXdUt!4s+KpXT7K|$y4sqov)`&SLDdJ$yCGg;MHm#p)Y)TzY3 zWp{fv6)s%QuEC{R)jBe8S?1HMpx-8xI>}|ZKsooboN}vRAvc=z6$dLnbtf7w0+@tn z3|KC;!7O!rXe3LODc9l?@v+xoa_{`Ye+?jhe!0% zp3qqIHlyKXk00m8klt0o*VWu_GpQV72ed`i(mdfliCk7gE(dOlCNSlc9X01uTr|u@ z{1qEH2?^ymIH>8>`fow6{_#gWB6r;=K?P#FVf}8Bi;XpS!^Ku9133ZKS2+aHMQLL` ztR|r^ka5{jUr#IK1Qf~29LtCYaXZR4juw^jhh~gkBFd_!3N3iJ>%PYNh=K@9ir7a> z1B`w^qD&-)HBDK9^$U03&%6@1;e-}_F=8wHDmPplLFqKUqQ zz6Idx#@H1;iYfAT&{UZsGpcoN+!eeKrsvSR7H@Co#zjC<>VAy?lGD)qyDWhc9+o9e zDueSTdO0@7DLNAgm$Q1Rh=$hrUeA!sz@PMh!gotC2%IW5J*C(IDYipUOT^6^q!?$O zDmE>pSg#bzuv?oX#hes7n@(q>6q^C>iur9J->nMF zR=9u+<6YsFUY9-M+Z-!7zpqTcO{p{*e$2?2GCbw!zp$QN@?Mw-+H z^`0d+1aIlQLiN=Wt!zo2|4pCt1sz=Ib8q|w>q^LUImq8L5`}NLAKA7dGIK`L}&A0X4+9z9+-@183_3 zqY2Mjd~LmzdqbZ!%C@0rnJgZz!5rMGC`_B@8)eO6m8bf%`VAK{aL#Si9yP;_Kg4f) zQ9{scI3X@JAqVX);&znzQz7tN2s*$EkL5e&KVY@HTEyG75tj z*OkqX5pQnzCO}0{Vc6>|bCa~>+rkpa)lhMIjnwQ_+kUThi50{dwpI{mvw0G4Nobt0 zM_+;b{ny0+;9zx+kPF6!_#S9c?D1m zY=}u%AYc_~T(!kz7Z8a88y?Gbt^WG5zgiWm*0$DSYmuPU@Q{a6M4^gGZPZj}U0S20 z5HPa;?|0_jyLUIcEBLoRKOf26-8*N_oO9;PIcLtCIheW4UEo4}2T)bGI+qb!-VrWY}5f0^H6|_qDE?> z1+MsbQR^x0q@`58C(sjLHyps%A;@V&S2}~K-jP^ERr_}@zTUF=$51IWl4?G~$5xs5 zReHpig)`nPcuG66jbg$0&mq&~J+yg~-fYxiHdDv#j`&nTA^mK93(wX=uN$Fad&6o_ z-8fs{s^H1|E_CukbaKYr94scZbT{uIcpe0A4^A5DUc&0G$cWHQ&6|i&Z5ti*71N~F z?}VPv(fcL+HN*4B^M7vy&UV76D(6XdX)1+$;2hT4tIWgtt*q4?e^|fO+Z~YuoY_RN zZJK@RM(aqJiR7!|gRi@RHdZwX$xEJ2 zHUjren97GyHV4prhWc#n>($`g!#ABIK@NX zhbF-a?JcqNb2s`)_bfTaOjGFGA0RT|kbTuuqgQq~+9k%L!_e8_#>>k|?AOH`Hv$w4 zDf=plr3Kvi5?sCk?kp?jSGmL{O>E1!H*g`Kv|86*<2T*Fp)8!p@`&2PK=1+;=Nsx?t2F5=EMva-o*a`fewSCPv&ntaxZksL2ut_fEe^_c|x@ z-|_tCD*jW#f2^av04QgA&NaG>W%4*Ik+>4f-E|HQ*^ZqN$Ow1QuDK!5jh45HgfTE| zp`k7>1~kh6zT*<-ssS*>hydAm2!)c2hFiai80p3S7G?{b8ptA-c=czJCJ;BQl4*5g zO_)W53AqH8AjgRqi2X5Sn{G4S0K|HvEl}%jZiA>E4SlGAG0drtc%t% zZNE!A0tg`n@hW)H#$NFXB?$_~J4kYukQ#JIp1Tdo`E&^N;TMA_5mbw+b9%xh5U3nb z)}f8JMSRVXqB`4EtP||udYX&5$8=*{V093O=+I9j3eBLc$iz^S--fgTt|noFL2abI6o zM6$R14aZ@sUX(QnaHNficjl2ctt?L-a?8hIHqBQMfU)CyNGmJkF}Je8uyp-5@4-1E zxbMHie-ghJB+IsWoswk(Bu4!dr4&NGSv-qTrc&GwDYxR3}W?{jnO^#bfp>=u0 zf@!9cX29!el1J*c<2JpB@9Bu|Dc*C1GbJ$fYHZq>OjJ4fTdrdPAL_44Nl@b~-xNk7 zpe_-Q$4JEEcvrq;Q2AnF?kO}#*U!rOMn6&h@GBi{03^ogQ+}FB9(+NqpT@V5-uJIpI-$C5 z$Axi>$%$D77&1(@3ed0V?ZCodFQLZIlBCd0Z z7mp|8S$^I9wcyzUJOGHJsm&~Gdw{H?hq@GmW)R7PzyA7cXxutHbz*9!r@tYyy)Arc z%)rZH5c-u&q0u2ZvR^FJt$XiPCPT*KUB!?RJedp`iVs$hnFP7N9US3JqH<=G;qo5n zT&}{nlPGo-&b88C_GMALotNU6k)>3;+&vbz01w&3P`tIgbm=0@WUhDVmi5jmQ;l8N z_7b#B!roG)SVus`Na)IRP6;xdAm2R(*QCA$(I$w-e({nk0mEVFVVXLr10P<4-xC{S zNoT6pC92VjM9ZQD*P(mGyybW@nYR!h6!Y9ZIn!Mt53NJh_#Q+WfF_xqelO53Ts7l1 zQ;)kBxx}0ILi2TzKj{WrF87JBS#EE@Pf7*><2*^|v)Mei!XhZ{#ju@^Lh_`lec;a+ zDiwe_3`%3~Z2(ay{}oSYZ*QO`(9vBIx(;TW940!UJ)P;vV<+@CO}%xeOH7u1=%(R~ z`Zk?!iPbbbkWgEnwrQ9|Sd=cn28+1)Ih`?4`*FJQ6$X)9IV^>B{GSA}vdx`e*E$Q5 z;$21i@lc$w7zPU2X!G=wi)PI9$IeL_$~b%#(K$F>Cy)1Pt%o!rU$ZyJ_47`1{TwTU z1oj55pOHJ}Mea~5L}L>{9cqK@aCxUKUf%*6;`7hd66#w>f=_}ien=^T@5j?zDuM%@ zS4dPvu&j^=5%JXDk)umZb2$iBbz~M5vLgQo8tMbX0(z&kPsS?y#4?mE9Ljevluq^u z?#->+M|*w5tEBfH*4f+@@V)52d0!F>{1Qp}3nl3XD9Lg#VNF^eadu>Ji=a3H%;e=>??eWxrXv? zx~Orp9WTl^46z(WbUcIQppBuOr|V%L^A3@D>I{LOXpk*`y2$7K*PBIF=)T-j{VW>|Eh@iKCVJ_fWVO0--xFuuRWnV@y|@P~Iby z=K&==2(Mi$#~%&VMDb?r0P%aHH@r$EYV({e#ptZ)dw=J9tMFbzNp(_E*I`E|0GAEf zwWx-YKvG|l6Mcs_g`_e^P^1~?V8l8zN_WVhK&Iz>bA>q95KZQOif5n;lu)RJLhix% zhM}DvB&5RbYm$eyw|Ef8Nem)~c=8}tw%-s3xoUE$xLUp@*Is)AuV^Mc?JINeBv%Vs zA|`BB5EY{g*r8AGv9oC7<_2A~%YKSFI_$t8Oa zMt89S!{AuD=UfshFUoi>u;N|=LNdWtD^FBX_lWB%qLMmDb?^gpkm(uE4z4n(#dC9_ zC*X$%s<*C5h{k<&9EI$)jgT- z65j=ADG%5nyjpkt%1oIk#gnP>hM97qoSW~t#05s{5IvW8V|adzE^(!@2O1~bomAr1 zj3*QHetf8|RAf}ZQIt9xz{BfJOBg$-%}9CJgKaBWo&qakQC&w#oLyW<#cC{dvfJ=1 zQ~EluiSiA@NoJ%j-E+R7e{kK9#U#1~DPsT9X=P~B+I^`-2zsrDtb^AaNS8fHBbMR% z{o?pk9au^W#_bY+$FaFidWyyH3hG+tfc+bmN%o_Bd{Fji?sS?@RPbq`Z|XqSJWLIAIDRiWQ*r%G{}^M zrv?R5`Z{4^Qy-4wDsGQWvf^E#{FfrmlWpFiQd|ZZ;u1sO5FvLlAd|jGQv%=L5b5Ox z-&4hU4zvA7pC;lwZxpC2;>6#$l$@6Z-lbz3!}_G2PPt3m2Eg)Vh9kKGC>NM3K@tR_H7d)BlZs#1MUVe)8sZ zc50)OH;GegFgoSrb-Kh)L-A}rkc`cjDmGuN*sQN42Agw%z7hYMb&tMIoAdf@F3eW7+N8oIx&Wch^ICeb8*0JbgG<0&T!#12_sQSxc0BmqEEu z2c&y0Fz}Cw{@uzZbBrb!Z-~`Ecz!2p6{G0iFR}bdA(*7*JQVpqz*8jzw8u>$*hL|T zoAbA^lTxFT5VpN^X<%Su$+)=5E(1$OG%vg-x$ZtBaWQmv%6ZOOBjP8Y=#)vucD3wB zLy7X*9BHbyh$+_?Tul{1{671+1pRd4D?QEyv@0_ft2t`~qhbb;R9%y-V&lig0IHf9 z!*ZcFIy(&Ks|h>_Pq7ntzxZI9&bu)t@4R?T@ooa1Ox|6A4>5~ya76!-&3kwUbmZW`!^%<>FH>F}g`92|I~V54_q*61KS=bw$+rAA0aBGGQel4E`ro`P>%}4}Yi+ zk<4eDpIeE4z+e9$sc5S!>*oE`=BS%6CQjALIoP64k9*xa$a#V1HNlubh+4Ayj%=p6;i55dmjd^_jcu%-<`Ov(49#OXT*PNwEf z>LVG}G}xHRMp;6zn~`ZKhYBGvjjjFSxv{4r3U?90PXVEmDBxtW8(uVp;g%oZ_Y;Bo zJ!{K9p&&4UxLLc5QJzgQ)YIx6zWi=@Q$vqVMCfx+WYN6HB0Y%v5j*J14q}?DEB^#Z z-SDdCmZIRN!h{0 zTQmgma9-WyDAEmkAPZ$_F{11eEqx^COAhBt4)=)}#wQ%c^uJ>mIP(#kj3V#;3_lGG z?xY4UxE(K@vIeKuBn}->N1*PS6kT>YF*k z<2Q4p18hXEEV)&kgBEro>I{a+v8M2&eL7u-*4-9SVGPv=v8s?J9sj=NCV0uJMK!C*kH5{b-|DE-tLhx zx`0GO&P+&Fpby~51Wj8!#-?&#?-D-&a5Lm=#+!@k#>Gdf61cBl8>upksFabaDwjC? zmQEi-ENZ{Td6i*iB)BlSO^Tq!Li(SP2Gdh*lvlgNBJ|pc<=c=}c7HV(J_X6;3DU|a z<2DZ}Uc(~luNbB0wl*>pEHaIuM6+8}dU}-lClgH$?3G5AgXzY!q;b#$s@Q=*!UW$ZhvlY*IDHNWv zw)zEIG2jte!jy3&AnbWl@9})St#>KgdAxd0-dh`KuZJe%eQAb6sg1Qo?wA4l+j$*y z%7gLwvu1#6XmXd!ct^^OB&+OQ2J5}u#IzqpIh%0vXn!NU4)Mza2^pJLw}6cGAcHJX zN?THwlhI!>1TZBsGO2Bp&eC!CNzs!jOePmNPc4(Uk$PH$_JgY*gVJ&a8)q; zl41h&waH*QyjBJm5o9(%CQN0UQ69&E1iCc3y^|#BZ|KsLi|nPuPNLH?1!&S zWgE`6H==D4-XsSh)yB382z3^%%VwfHv~=Wxm)Y)E~c8_U>xUT984RhKp<`0A`t}~$Af#( zI^KPfdCiov+vm`nYql)#h7p@I1#Tdr76Pj7I8EE5FOgRp&V{|Wh@js2D8lp%5(A9)VuHXi0p)jrua=av3)%ExG*xf&v{Sw04h)5H@&Jp6 zJUSfDqZpNA@v}N>o745PWYT#LB%N>246I6DOW|h?<_J#gNyr^kNtpreygpm!4mQEL z#jirK28WXF4O9~HND-2maET`fR4+@9Av`zE8lv zdey>SgrKcHve+Z~h0tUTc7jjWiGhTn&T zFbEJj@tiArUfn+G+~YG&Tj!FyV#6*|=f1b2v(DuXiPE|9RIU-MlBaSlij$7DxEY{A z4D{$acho8A+zZ(BVl*{%ZfLn72fEso`5jX8Ziv^sF)1GZ9nE|BY6G{FnzxYSSdKK$ zgj{me4JMZ=YY<4@?VA8Gkb)_5_3RDYkWtem4NvBDIRZLZrwcQnL}Ul3Y^1h-z$Aek;S5+98IVSNpi15JI}Bb&gl z2JlV<+=e*OWRfqp8o$1a@*}9Tx*Kk0p!`6f{9vH`ki^HB+Q80q zFPMZ{g@AU-wp>C*rqR}9%vn5$*pmkl&%i-MbqBFbMhY<{8=HD!-S;qE8SFMs)3I~K za(qBLXa=M%YPbqErvJ5lS9E>9Tzh)a)p$~OLZK)gBxjbgzlo1 z4ltRxMil3&S*!U_V6rWQVjvOBEj6C+%Z!_9P?BAfuL<0Boz7vD*};)BnCvG1*dW14 zGo7UvC#~iRv9B)bl_Yn^xeSUMwTs;wbjUBO#P8p>Lw+%PesybShrF*OH~6j_ zXs7OwGr}eo17t#n{QUnjhn#@|(F1r$!8K>hDV;6j9;bL?3mKAd>+l;msvza;!8e`w{>a2WOYUsX4mb@OLs(iH>_uc4!9}UOUL&2nZ}KUva8TzXlLm( z9&dnABx`iC*C(nF_RW|XI7=%l2#m+Q28Ds~H=wuxDzO(w=4)LuznEXT(|1&sV$bn` z6lvm)bHSdngV_7QTj>?h2m%PPYys5I_!;m{f_KdhE?gF@^aiKQ1O8fG4esuX`0^vZ zJY1lT%~t!yvK*C;d=PcMn}g#W&bnu&nk#l5&a(QqkJ80g4h9vIKorZ4dEB~U8F9*G zp@M@x{8HQm!3p--W`r`6xH4+_Mx>`)8;=w2g9GW)BMYxbE$Rm`@Zw0wk3tR5v5=Ca zEG}oi)keSCmk^Btcse-%axZ{L^s#5o$_)pX>DVc$Nv=Vs6J`Nmb}|omTs^H<;3L87vm%Y zbvu#>#VI;F%vln(23SZ5xUBoPGy3bDrQDpqf&i`rfX-Y-ZVfi)UEp$$>nvRE6v0T! z<$Z+R^n%G{q%)`X*56=*9~uoXnh-7UxH!kY!dPiQoP$AAB@IlZGNpmX$*j`wCczg0 ze29DfMw~-BJ6F_Ie;a=9DTO-r6OEml<3u5Os6*EeX5iwUe1oy60v89^%XiUBXU0kc zXaT412&Aydz~Sjl-;spz zzZKv^OqJCq@fCH~#z!h+&LPBW^3Jh*`Nkq;q~hC-35koV*8_#Ic9B47UV)&2kuqU!IhwqY3;%0GF@RE9ZJz;={Bp!-L`# zs+6dW#JT4I3skT)>K4Io`5xX-~hdpNI0mNIJ(M4e9Oi zB+8B6OXBkik2N zkM>&PVnSVBkSUGt`R2HXy2So7nV9H1!`)LMHQC+WrTLn*_9IVda@bVkqh@8@kk&2TggYQycvFPH*sILXxWDtqb+8DV+r}pQ3Ey@`_>iV)YZUTf}aQQv1-8k zf2Ia*AOh*e_zY1xbv4kKtJ4y6jNxZYI>dL`%P;;2Ds|rc%dgu&HLzfuWex9SoF&~} zVzP(00Fb31GX*~N_L8e#Csv)}_7anxMdPzzRs8nSxcF)RU)x@yS`(GPL5}w8xn-K) zsSQ>pREYOC=wP{Qn^xL8&=j(>l>D7Y051SQ0{)_C6^-xvnG$!Jv-NKTJJG-kuI1Ow z*0R$f2SxW@r^3y5 z*vr43Ny5$hS=(sqRr+i-Q!drAm2{rYC(OG5(>hN%kr-!c!Cw_jXM9;5RoRCpBh_xj zQ~D0mrLwi`%HHq+-cYMI3#pi^H%|*T)}g!5@9>0p$j+>;c;E(MaM}!6#3n~Slrk#* z)F=FAUgejxh?p_s6370`2uK-v)oKu2&JN&888Pp7C|K=l2@iunM#*G74BJRc#A0%Y zir*WQlI3q$&+p?~^{*6&K!}fPCaIPk|4(eWWt#7u>Z4qWD(-=&hK;<7;(1Dd+5=(@L}aJ^R`ITYcCuwF5cn)b!)YQgiw>;e$nzgHvln z1KNjvh3}O`Zj`A*hUIH#>2fhbtuc^`<#>-^Jxg_v-aBGU37#kvPCyJ_Z|?cC1jjR@ z5E<=MAog?)F-SXA;vtDD%~;g`>#h$zW&CLavD*Bb1PqY5%Ow8~OYrMyl*D9CskjCp zB}!QQjFOnlVp4=>K_ZjztkWBuN;BHrV(X69p=a^EQ4({>uXRN_#H9DnOlUzXwB`8F zNCg^xMv_@iC1x7a-3cjeq>))R(>uGT`n*vdK`JFG(KAwv56?dp7Ca4P#T8E_Vu7mv zuV1+aAM^S`2kW(a^{Uraf7zNwu6BQ)09@`@zVvGy3tS793j=8h%6fWnBP=}1y6Pal zgN{D99`t2_b`|2a0=90B8$4?KwGR76z-AHduv7j!4JFAPxB@MAXIduS2uz->jmZvV zhHsGod5{kt#v1%0C&~;u~cb z?81{_4gBeGU5JM%AqFi{=%U6)&@{B3kXYtb$+0T^ArmJ*ERE9}F|l)tG0hKY#2>{t#c;Ik zy!K-uK(ak~(*-GZiSsOzns20^c=2%qC*@`_SDfY>GZ2)~#+6PT9^~n3UaV|yppoaV z&%@J)cruvy@5eeZ@pJsF^x7wQGW8lw!bYwhp%?IvWMZ^duVuR|x*;M{e)`92sUq$+ zo=#QBujeZj)KPDim~tcdS|pZX_9tiW6f1l0_?1aYqdag|0MP|Hg(v+uXdo)kx-*0G z(zrLwRKCJuGFT6(u^LmL{*aNdsU~&OvOKrC#NQs%5n)7)b`S2pwl|QW@;uzX@W7~- zS&V7Fu;l6|Gs~KBYdy+j@%Z;atQj9)nP`^9M#iEimtrDgz5@ZDH8Pg+ z+|q3>F~UG!pPsnJ6Nx`b_NR>b={pyhAh?E)63+`6cJTH z>-kKbT#B-~l9l`JxmL@?eY;CMxIPi%veg~*6%`b2+=cZH?i&cywo74nNp9!w@Ln%< zceHZ0Qo{Fx+*HEn1Fn*t9WvnutC+DU^oy!&-m}8D&oth~$+yvlPhxMlACp(jzeLec z*sS{5-ZZf{NzetD-=rm_YLQyKz89Zlg>cW#U388lg~{s4;xQuxhf@ zk))!%AydJz*;mpLG~sN+hv3xF;f=Th0+-U^F4si&q_NUm7YMe)YR;dy>w zkY;}4PXI0^De2fFn90{@Re9KA9#)POk^4LakBsP|Pb1ze?YR9!3_ol~)N+%aiF_jh>>2oV^nTvZea0hNKE)S&V#tH$G zzN55v!aUuii|Y>1Q+)ZbIkSCZL2Kr0ooh0TK@gMB+_AJMtj3*e|ANt8FTfaENaAFc z(gKz$;7u5c5~+=NGJ(^yjXCt#xQpN)2KewJQo~y^c~{4)j+ji|&}}lME2+mWIbiH0 z#0S-_)3b3mQ8@NXokCF$PdWo?s_%((=+i9K9@eV_^b7!XR?%34bL*UQ!NnDqfQzS9 zD=!^+C8ET@PiiE^MA$z(CZy;*7*8gh`{9F?iM(k@9DPV1qP*2QMw7oGuI#Gw@M@(_ z0GmY-6>KVZ6E=^m$DeG@B>aPbAAVTwXfgNxMEqgq9G$eXgYe8`(H8l$VKb&=oQ=I+ zWsJ&TT=GNAO6QY+Mlrm$uMEDX3SxI*KX3g41d82~U{Ngx?W*4oQ8V*+p#C%p;eFpF zZURs_UKYap0EAW66s_7=m-%h+bDLt2eHD+5@+?26imF7(IxFX=G-nmfqYG_kn>L2* zDVN$GxWw-Njhij?NskEkQpN1LDGa!#n)B*y;q8dhzW}lZCndr9xxgi6pu^6yN=CI> zS-xt>#VI(zLc=_)##6#E*Qwlr`)_`(kAyo2U;-1RY1;DWZafS6V8K_`4qZ-z1tk8Q zc;YA62>5o0?{SIi43tfY|7OHLcH&fsztAP#doTg7`XNqXcXV*9r9zI@UH zT*siI#7%&#sH~S*cuPEsrBW`w*BGY(>T=Wv5iJGk^vf2rDDiM|i z!$Z&D9V1hQB^LfSUMopX8POuuC_LBHO`U5js8^JJdJUy#csOjJaX2i$+KS6@;_~p% z3|vfhwWRhLBVGpz!68UieY`^-M#_T(C)mvu?55Kmn-)eSpY#ZLeIs2H6gQ`ldMB6 z$kjBf40X;%NVya-V_f{{CvjRarSFk4toRk--2`}@d5U>=KYhKC1C`24XbvWI^Jb&| z#g7dJzvnB}jlm-Hr`GyGcrw@ev++USpLf@yhUvw6@~kB##t7=}7ss%e%9&d#IYt|k z+Ejsk9Zx3Mt@sdQ2D<0C#Lt12S^GlO4tp%V?8P@xtA^yHT+`;d#D9Ji$Gzkyxs)Mc zu4DVf)BiD4X{st0H@L+8=p+G4k>5lM|K$?b0)*s|?71$}hF<_7+r|urzXfle4 zO(sR@ed))V8<*i(ga;#Tav7eKdaY39liwE8vEoW5jkiM0!HbGd8F(_G@-SCSN!`YJ z!v5@k;J+CsieQFRVg;NXU(rjl%7_iizAWj7mKIzRuE zP88ik;QxBSvbplMc;g5N)=9CtN7XsF9s1GtI0<+0N@`yHhHH#-QLSHI{kEMsO?%7> z-f-u8m5OE}E)AUI7I0+rCMv(KKVMeQgR>$EvqVkvfA(p;9 z3Y+qMp`Q^I-=6Rh{G&}Y67UyU6Yz1p9qze{y+YIIkKV8KtbiGfZsg%1aVd~3esf%) z4|h=~BIiCQFmWD6uB8Vi&X|w7Ci4RmXY(-7bjzi26K_Dm{EN6WE;wIhaH5arnRwCa7_7!ba}T;`v%s{Z=tB&G(N;`Kg5878af-HI1}7$=UrYom$v ziC#~VlckrLv#(DNM7r}u&3@pa}9i$LA2ee_}f(w|a)ke5>& zl11MUGgEc!6w!`g4zpBYp)6$A-&&532SLScgntEesw zeFr2;+43W{EHqnciK`uslwugZ6wt^oZd9qNknoZ$)g@_ji^h8m(m*6-5L6nehs3l0 z2F)cev08OU1QiQHAbkJ?LhfI57eDzBcm2v2&`lQxvT){zTBC+Dq+*6jk@ORaCe`-Gc7&cWlga3*LS3O$7$sq zV#x=_^{d4y%*c%xYk~--x*8B~uHb-*(4`y@axPVqm}p`YM{d8c!MSKKcaF9V(Zp{; zNNze4%%*iFA-(n7oAWMK1azli@E`JiOVV$Y#7#F=R-vsN&pieW7e(>oUJn7+8-T+u zW~g2&BpJ_8W9%6o4;pIiNK+*N5vC9C{~AJlti#PR;DS&fwM;@iqgf|+O3Dcx!bbs< za&ixC1I_L&Od^BLeb7vRG7QY5HuraNJ1{^gF^t;WJW)vM*jHYFC!Ip-J_N(&zR@Ml zKhLnanPd|ilGrc&U+Css)aHH*uPLy5@MMC086RS8?wedd*Y+3ZR~IW35I4stO>ax~k*|AA++?2FOyDLnyIm>4YCM^<>l%E}b!+2t%FXt(;U;rKQz=#) z*<{}0+hWMSbpFJ+$;@|9P?_&wLS@;FST}hEVej%|#xj)8bDId(7uDSx?<9W{^{SSx zc&{X8N~~n}1JS*lJ%)O%{~GlQX*`v(8-6*ql`&58(=8xZXD1okBemexeMlu|+DXDl zRnp88ZV-!c=tmBM;dx{wd>@@t$Ii!J1kkwTCc7h-)xSgr+Q+Y%)50;l<&>TTaEh^` z@nkZVQ8A0J)!0gqe^{ZTB<~zEH!Zmha5COGND!}z*8WJc2V*RsDLKrP88P0##Ne>Z zN*xBeq-@Kh#3IXRn=Ei*C~!baV3WddQ)cPE3GAWeI!T~5EsOL|Ka5WH7$Y@CSUG#d z5Qa+uI}Q-q{gvk>}?fhu>s>anDuXLgc{PCCh$s&!dJDf^@cem^Y{`whW9 zQXh*u5_Sy{Baf9@8G$F0+ZW7$N4%7)iU^P_-sbe(2OGhzt&x5dVe` zjlVw);!6?WBHg>em z^5Z`Bp1e=}4BV$~Uv(jpG*khhbMf@GGW|4$Af_(U2@07uc>Lj&U(4g)vuzRDcH*(j z#3qNkFkP)PhvOp%rgGa%kT2h*cMZlGxikCmgJQ#OJeh2G5g!^~z(0o9PXG2EqkZU? z_ysbm-(RH)np*A$ZDeyXycf6_b3eEDPKbdF{06~EgN8{9no_Tc!RS;eq0g9oP9=1) z-qPOC8*eD=DQ)u3Rfhc=U&243u@*k@W_0Kf7EO)0w(VuSD1N~MN$lRx?W$s(6R{F=0u)S6zxC(lcy_uc@j-sDlmqx8!O&rF_J3C98 z7p)CCCttX>u=&eqocu?SejC{1j3Aai2F*g$G6hPG%kwuGjB~YfTcHHgV6Yr?~ za2uY?{qSQTx^@5gd4ftKf@&|Ewy0cQ$g0U?)kv^vT>@5_i6!LOQ}H~L_hEkHgxYu& zG1pWPRd_N62@@uH+0{)P*o8}sfl*JCwcu)&9@;Lk>2l-il$+*_1d%}y@n)+!XzU>S z{)WW1SoRslSyGkp7~$T#xU(hniLUYoyVzKI#-&F4(DnEwm1uCa z5iQ-~MPtyyPNEU()=JT!DrtNe5Kcuj9$`;Q(UTMnS%XtUVT63tvC2byoh7Ywg@Urs zzUGR$C!KNjR7BMF`{ls7lN&XI}UL5h2Zu(zVSk^ji8QsfMU!-pgGj4EtdkW+B{hlziP{!uV$_T z=ft0Oj+x@8ePAYj9k{_<2db^>05hyIEg4qRtt%W$aEejpz+x7HKNK0`O}P-fLJ-IA zNW?zOcBEc&w(m(->@y-5T73?q5$~cc_vYWkUv>J0>CEf;E3{w zMt&p8F`kecPiA<+QKJ|MK0X{@V_~P(!6>neI7T$G{7X=BUv_i6Wyb`Hvf1)ujp#zmXsswiS1U z<<;F!X}TNPk^;lLm_%w+>44eENCBfn|?_R!PnS{|8{)@*gG(M$G-SMF`);ZOeQd*jD_CxJ@>Hvc%yyj1Mn!SDb(Tm z)o=zamEZ>feDvH!QQeF2CoW>*(;*M_vQZ-;32#ry zgxkx`SKSuJU2Lgx4yh9tGxwfK?C^C08U;X|ta#>-E?|aMFDATwE(v7dmXv2V65Q*z z8a!j!k<`)8o7muCqX86#EIq;bqGzDy#21>7^Ch+#^j*nm+7g3zO0#$#QMuGWC0SHg zWiF!DmTos=e90Z$n+fuLcOvS_gVpXdw=D=0kN@V%e^IFP2WV9H;;b}>dx&oI^*-xhjHX1y1~v&wujxPcHufRaYb<)tK6?`Du{#4Rayu z1DP=XPVvzgsYxpBc9TDaqM>~U$-57lA zg5aZ1$-3+yrI?>dz{ilt+39!>qBtb$UZj;JOc6-Bch!|3R|BN%T?R4DBU@KO7!-B6 zy<}4N0(`IzH;W*~8z4gI_&F}AV9h>V{a>xdh$CC93!z~1{E7*iY>ZDT$R_-OfNwdn z)xQ(tI{Rf`yMJXkHYv5$8SLFZKW+s`o=(vD=vK)tV}VF@bgLWt>4$z2ED*R_klbxW z?l%1R;-lL8@%4X`^0zy|K6$gr-)8^u%w@&`pJ_69zm*9)@WIO99KyKKfD!sNe#Qi< zP`3z7j^~7f1qBVQE%}{1oFacV7Q2*e=s_Gh=Ebq0Hfc3b#fFr#sV71H1|U0C@Y}}p zQC57ryA2fQbx%0o-TA~&QlfK{R$OWzt5LKHj7_zf%9pK_hD*6&xJ-yKT<#$7 zp8+^Bg=0br=gL-njaEH*4S+hZ@yj-NTAel~9MaH}`A?rgq)+*d_jidv`y73A3|!Ij zW}t<2o}{-@sp!2iKEx-F-2XQY%pD?5D-E0s4fb{FE44TF9$`8Rn4opah3fBoI}LAl zBJ{RBM%}0i9G{G?rZQy#F!RATo2QRFPwW84WSWTkVwd=FEui_b{dZrFP!LXY;1CAx zYS5}}s2J5vn{GoTh?OsQMEqA}VBMHH11ZT}#G*eTJ$|qF0sg4fX{Wcpgr6tjpXug; zqE6mcTRDWUUbRC(_dJK0wOiqI}(Nx%J_U_x#@}cg8O`z_;j`@4Xgw*SGG{M zc~B_rE587B%w_SP_y8jXSMcv_jJT+jD{wbKMhQ^$#UIdBS6i6}ruYegeptXfuOM z4{NyxO5|O_PUt+0Slr~qe>g(4-sT8QT!PH~D-$8kiWLg+N35X##{zm#_*X%mKk9uQ zKo#%axw-*AX5#e@N9RKcI z{S^KkjQ=CO*AlzcPvbe}ELAW6lZ1l?5^%BZ@JJMtV}Rf;&(TcAP;tl zTL5M~!?V?xFu;3iWFtqZP)?5P)Y+IceYCOp*zN6x-QJPFT$?&u6!Gs~agi|)PW@!l z=pvUm1HI41EUH!MKZ1vi1_1p9mkh+KQ>Qkbt!@FvmoKd>o}PZIu|{u@m>$!l+2mo>rygjnXe11{qTi5C-RhM z8b*j=pB)|c*gvRYm*8(;&TQ3wB-_`v;HF(lMr}uM;%sN+a?BiO$-~R>l{csEgmL?H zxLe)KOH40a-6)f*YvJ&%iJkS@W=RmGT$sd??m5>OVy+$vS7Xd|iC@p4Dm)at`v%zftE{Z4bAFZSsH}|iJ_H>Wn6wNNI@`FLDB^2Tq`^!WXWhKev(4|k1@({^ zAuw}2`rw1L*ns;SmncTpA@1Cg`DMuV=N+gekLbMLZsC1ll=n>VlWvNCyCDDy0ZWEo z+-*YeX{iZ&*} zwc0~Cwd8O|z?d=k0e|G0Ezwn>jMu!=FhHAS50a(LqL*2^^Ic+7l`%wYHWtX&&pA34 z^+r$$%<|^BE^!~s#N~PzC$+eFTDPr9g*V5fOrLMI7ICLepTyKEdQc~~m z6)*;c!=(js9hQ9{`@UOAeKXJgwS?!(qk(!FIjv%wCu$XQ%ZxH9ZCn%wegm+>7bzU# zRVEgH<2`o|msnfZo!1f!8Me${*i2< z-?{OUUhZ#dysTnnhz7yk1ujtz6y=CYcf>A?F=H9v5`}oN(_va=vMGD5S~nYwh;6)y zBdJ1%p^r;6I`v+qF7fuS(e7O0PIpJJq!(cxjBbM9d;cx*nk!FB;mlUdvQ3xR1lZRl zRs$ew+|dNnB5+-fYhS>wp8@rK{kp8-T?^BTx~`jM%h)}<=kgCShWA|CbKRuursj;{ zTMBK%x2)~Dt|q7H!_49PmVcN%eBatW>!vxHKClgcb@>O5;ji-D+@|I(c(;J>7B>;4 z8FS}slRcf#K1WZB(31xx0)jv6mW|n)H6Q2j=LaU)@OJ|KcGV_Mc8?28%GM@cHxmm_ zaH4a%Q@q0*@zu20T`riQ7eAHd8`dN;gVTDgo#fcuo(1K)npS;eBj3r~;S|3{3zsWw z+cC)jhad(IHDWLDSde1GnHWX39PzXq4sjQUxQjz{ScbT+Cb#Lst|Z48MUK2CPz~e& zP1b^f_pFFEJnJj^c^hNQH~kjBt0`ya)S? zE^+Qu*ggC3hE@f;r^6X34wkh$-5D;?6R=TVU@d)A9J8GRxb5zrP^OS$F;QphMTX1!tu> z#6q$j-4@lWx)=Z4*#Pg;_fjEj8Yx^UNeWjRp7fLM#{9tQXMm-0 z<;UP@{!Zzar>6to{&+dCn!Bv)epbMS<61{K7GGoE_-63F=kRUdr<7Mf<&VzbngRSH z<{+2cof}-!ji2yv-$A@IQ%u6wxLtJTYD#P_{twURfp=-Y>IqO)9D-+>v`4S0M8=bx zH^vz3F42Dq46*N^nPsIM!inb@DCP4!-RE-W=reBjwIEo;n+4N*z@hT$!;_ zRIyUjV38Y*YB*4pm$N9ew}|BzycaWB&ReLBM9mM+xwu($=P{pS)tkOEwJKcs>B|)! zh^EVBs7r2f$C$?|KF4?$)suI!=F5W;9V>e%)oLN0-Vw5kVOm#oJvcboR{D--K=GTZ zo4i0)u(AWL@iZGd>k`u$SETsvRDT!`bR~vlZ*YJIT2(H?*IoEnkJ@MU1_qztrHszR zW|4j6VSJigl4W1RVjPv#?#$x%=B%xalw7e8hWM<|PJCNE9orMDvoLF_a$PRX?%$dj zsA><6{mS2-;dyu6w$i=!)jz{~L-zWQXLxpxig;fE684Qv{w=m!nz$wG&X|t-X*0KI zy8>mcqEv!v_wUF6wDMN})(n7KH#U83*-11Cl(lJDLw1yuwb|D!g`OE%dvZ}>#MkEE zk}-WV^{@D{D^MwGMa^25%f4|;dS+|pK0+vqX!es$Ys(^~pWD}5ji&aMw@^`)XRjTb z8MuPQC6uDtt&>jjA8NyYc**((1bK?LBlzXj%5za*S85XXxLGB&IlhJNj2ZaFf&X(6 zEt^m{82=B&|3yLk?{rVbQ7HVh6aQndX-+)k_i|uf;Y}O92+YRYvkQyxd4w|u2IyhD z2FJQz37UI*qwNT7f29*veF27MN)#&WFPk%~c#qi5tgnA|X1Ky13nR+>S94ALJvviW z&6!Fi<;~u}gT{l%lAUH>wHzNHcFPb8ENg!nUj-Ltta}5?E84BC zion#tug=Enu>=m;3BHw-w|lN#egb7{uvE_Ii=~oFkuSFbg@xNh6H@$m{Kt3xx~j+~ zHoB;+J-w{$yj+Tqet4VmD6N` znw6t5xd0<(AB;x&=tmz&E?`UiKnjf15<5$E^fk8SIKg$ z66iz1uh2WV34F%9M-d#(`znpJn1+5zw=SOS7wO(1{3n->zL8owdg0pJ;kJeI=WFQ% zk5BVqMYuD<-PS>Nk??`bqshcsz{_Of9F9(B6x0fGi?&p1??T7}wTJ8tg)lT&Sty@> z!N6Sng-Speg((64QdFg9U0u|e;#)@{HrnKD&6!ip6|Ven(AEvRy@9g!;-j!70#(8( z{)il4+7es%Zuw!VfsK5u5>x}f!=wL1hJDRrd^nB=2D(uWY(SBg$u5|eJ7i~RS-X8D z%Z&Mtr?d2Un|)(W793jtiF99U#8S`8Ag4rq3#cvgq=XW7D0T6Vy`lFJo5uaZga_Ek^G zXHhb#!@i2vFPxi_Np0R<&?x?$gU0|gri$ke;c2(}S_eaSl+5m#>sbWVr`dYq9`iFY zP?fh(o6ysNzXh3Faa;KGh;JW0zVJ-23M>k(z`FcWA88tJVH}!G43ucPRfB^Rb*5X`5<<*po&U<6k)Tc>4M|P~!UszBCjN!6(ho|dK6wgTdVVDZ?} za^cR##C3Uo5jc;W&2s-Byc}9^Zf9!j(bw~`>`Dx#2I{Gz#Fy*6PErB2!=wRmRmm0J zEB#+)crH7-E!|i2M!0x)rE`8DJ8}hdB=mF$(<#zBAHFZz_bT1Cum?oC_|5r&+_8Zy zQ^0g%LZ^Q&>n2sI`!LjMB8g8uX>X9kug&KS-3kH_Gwo!+*BYpAEAbWBS2M=s-{#P= zOJ4^y7q)4YtwGyx%vKLHZSIiQGpn*Wi4SYzski*?5nmPyw6%wArCS!4;9`5FXCn)3 zp!DI$!uD#dSlf$&bCwA;(SH{f#HtQoPwZHBDXnT>)QwF1PDxd}4~no&d)+C1i-cN` z{}ZjM)xRxYt8W_z2@X`XmR1$mSI&W15EyBlT5<(a>w_G9b&a=9tLHsB-<8X#cc#`q zIR1pc{es0#%%39PweCzV0Ek+pUE!?RQFiiTQPP(-ZVndqOOSdK9RHQO2y!zf4{|dt zlf!~T`Ni=F(DK=XQ@(;=`D}syax&n48m<$H;5aJti5jO9?NGX{jM}sA>FP9x z6Ve;${Zy09@d7B_q_tkKt#q4jc+@1eHw=aTQ2yxocvAjo9-j2=es{M}1iBSBos=Dx z>9DQNx-qw>VNvaf^nMh86TzfkqF~awQ84Ku88EwtxU@hfOKV%bmqoFWN8NECK^o|1 zF}U(*ExJOqCdVbZU;S0&r5+eX=uR|_BGl%rE3_iisE>3@>6X}$jzcqr)kr)ktcKyq zz^X@xs|?MPXVDdRWPMk}_#Ed+pW|%lbDRawPGNV)4Q>QlZ@&uI^(A)9SCkvEfP{6n z29gO<{TQUOV)mWrsO=40WfW!)<4IxmV>}s{*~51ubnFw*CeS63-jBxtyC4e8JC}ew zE=j^l1Arqu+6`xvHwB^jLvhWATACNg=CKva-M!>UUE;~nJYUexomRqm5O8GKx9-Fa zgM1oa=q}X4AHjuE_dOUD+URe;t8GEi(6aXF!SarZ>C@}x{UXgV9SdLsT2ejg*Dc8C zs=Z;B$uS-(QgmU)9EW9!2KFj@0GR`i?5?bV#;A++$OSDT46H^qhNDARj|3GZtx&iC*pSjJiH7hNa=oG z*{xeM{Y}{=WgVU?5kU=J3+F96m@`cbkeffCM`g4N?~O>gX#>L{*p{Au5cX(;%{}`0;r+7Lx^eN{Q_{B%1CBA#Au;% zQwxnZwNMG3^!Ts4Z>RvDP?tFk$C3aEXE42m1(Dv%6GEfLQmpt7o)jy>cru{nh2F%c zMh=Ny*M!N=a=OwSGt#wW;~w=fr( z6A5ATGGSzyFlZMWFwP0J;1h0PLxO>?ws<$mSK+Lvs7nL-6@WZg7is38#Bhb#@d~@& z<4IxnD+}a)p>+y!ULZ3>S;u_2t}wqMQtXt#CEix(Rz+1SrMX5*X@!Anez=r73D*}E z0k1;%w0YuXmSH4nBP=3bARAlKIk-ritIx2=NXYoH6*Re+DS{BqwGxv&rJ*FSk*R>0 zx&_-fth%u3=#p#;K*V__13d?}RSkxm8aQmm+!O~+Q{hnU-a;;rSlQvhXEZ4f-cX#F zgEB6weIfdmNZkgbT^f|M>g)~M$b`4yOXgw5b=IP9;%CLhU3gMld)U=E2lU@f1T=iu>a&zua%2SBqKbMi?m zhGFlm5}hI*jo@(NvxyS0RANMujj-6Jp^?7MbPt+}Og~=ZKb$8I_t8$I^IUtl8s@OQ zf$IaQH3)yzJ$(6iqM5~zBu8go#nWqADV(p;a~#*1b}^ z+nq6Mejr2o1|4u!wG|uAOLMHsz$+^IP+RdLzR;fCgnu)4jAlsPzUB`A5}fo^DcsXX z`B>IAj_l zG=puvZuxWgd9AH`uuM4JnezkJcTabTL!V1)b`*R>MqS{qy{f*sm>Y_Y3O@&Rz{^@?*zkYRjO3Nm zKVuf$C)`oCMp7i*>(+ioB52QZ6hT`bNsGm9@`np6%%sTk9ChS*4%z9fMvTHK&NK!) zLErpvXSzg|F$B6z?Hts9m~`8;Bu}et*UH=cJM&gVI0nxOIOm;)pmxdB?$lHW^0mQg zTX0&AsA`cW_ASBcF2QMqV&p&N$C<(Et~cHwbQEY5qR#A8xcyQ2vBGbNV2c@_whmP(Gd_)`?KXX4qMzOH9k4Lx+8G){W zbnpSbrjyR9J9DO3eLu5KK%h|;EcB|UaxUUJ5Ex&^xR4d~0MI~WBD9q7@pm!)uBdN& z9I;G%w6A1bndU$?{?eXmR|Sei0rh$-^~n^-b(fd81rqJk-tZl~uhiB+JSnx+4^J3F zXOM%5@`>?T!Q$E( zb19L@O{98lyA)Z3%5K+BAo>sIRBBsf6jCWt?t)U0UPfjx(b3*;F(12Xuc3y(e614K z1;7J^=Mx;?7l+Zu_i>7FK3+KJ|8l9%2Db{~XJ0vxoeH^F#T-=3Un=6CK_n1)xFcrQ z27+x;`4yeY5NtddJ2>6L!vWd*$0$kd4ZkqkFr=key~fg}n@+p^MX<*2fS$o-Xtj9k zFmjXLgF5^9wkazibV@Xuw1XzPl|jDvJf zf61ym1I3*1523L$Ap|nSJS(nvHNwnWs8ZW;T8gooTM(+anFSdl-Z@9Nru$rQm)`ia z0?DC6Z$C+;H@U>u;T>O%|LA!6+N<^0P2PGLySb>um+dVm$?_CbSHpdQ+n3-anmdXU53upAVWyIo7Q`a&SL5Nbv$kZh+Lg~}-ET%^vyeTDun3l^Wr z`STjW28ijQKqa;#ZHQov(aKrRzlb!=TKsQ-*yKQgu=#=Xbsw$UIX^HqgKI-@tPKmC zQ@n>Drv#eCDP)O4?cQ1tgR&lv!U|fz5Ew%t?=#wj5MF(INiEjqcY(cDR>;+gB88YB zV}RT7SW@dyB2`-Mu&?|hzQN8$No}ruH63!T3b8yaIj@VADAA1OYnh>}0VNQ&?_6st?d3Z)h zJd+{u`GIcXY+IJcFS>NeRXoux({;pf1y?vmB3%an|N8S`Z!lDp?GE$&IlCuaqyeaY3G^ zUKp#@ww2cAEG|(M%Flx-8S%ANh;r`0loh~B)Q6J|!v{NaWrs1W!x)z5M=6G5M7s(Z z?J9l`46Z#~gBin`Bl5OS#`qgppF|Nu5(tcF4Ylhg$vh1!>+~V5m7t z-?jT`oDbQLO-k5jFfYrpGbagFX7|^(rGa4f)qb|0beMMP7WV7Wk~xd3?| zRRRIs#U0pR!rX6-35MPd25@%=;oZ!w0X$<4?py2}f@i4g!wf|~{E2QoLR2Ol9mIT=0q ze+tj=oE7oqiT${#t!@Lud%YjW?g#h1^Tq@)>6r#=(|VO|_4N!awc&;oY^Vj6WQWgN z&TaM_eC$=4;p-K+GTZ}SNLQ=hBvuW#V!qDO(p6uu1+o!T##SS)AaQJZ?UHnd_%~~)yu;I@9fA78C3o3; z=Wxd~QtVFGUV|1Ff0h)^4qZw)J1dBLDKfBSLEB$k3G1n$$=hE;6ltOZe0PYW@+*78 z$Djt`REM9(tK9cPOL2y3aGvJD>fm4-@rvGnn_;p+O?Zt3-jk}uRl)MZP!8gJe599{ z=5IpVfckL&W;2>%-?3u(ojuaD*KlN`CNu^kuXd-0M&hs0*$ma-IxUm%)F=qH0dXFz zb8h~rKitp++$O2<3{ox5K~5X7TfRiX&#rc-h5iA;)P#SDul?m6JWP*XDyWhMaBfhO z2C~J!Q1Ar1Vt7eZBUD58N__NUM`VvXXVb@||M#&8qrJlgZ$rA)T|2(EOlXU3%kS=y z<|_n&w3Cvoj{r0L0%F^=%P~V2W%CX1`)F|t1HkvgN=tmudbt%f*y;xiOsX##&r^8p z7-LHh7h}-k-((}UEp+lv1YooRfGosAd?LI}Jj2UhfP4`erHP@@0sI6%$N`)$2avrf zXBY-BjwM}i+@p2#e#|2;1dzt*aBa5@FRA zzoqZCS3D0Gb9Te&f~Vt-)LjVd=B)=W(wr*1_zE44dB5T}NLW@W@8xat0*LP;4Kdnq zT(n^Yj;+bO3rkz=xcDIhf{XL?q*Xmj6@PdtD7bhGtWs>S0=HJD=&5k)2i#!38J*2F z@C2c?GfK1VKW<`DnSium`+XZGtP{!u96nof+QKS%Ccpl7xKFhwr72CE8>gAAEzL4O=xt zFW%vLy|eUEsJm{U@-;T?q_$1I+X54kFnsoKcWsw8Hd_Mx4_@19P!F?&SE)*MCU=_b z4`O7vUv$)_T1v}C2qkhP%d&a9ISr;3*f7EJrV7{wn2%G&1bn-2njIH@1?snpS|$UQ zHIz#0xosWqX`8!Lohu+HrH0s$lUVRQc!&unpovd|?l)yn!`h$DbkmzCB_Z zMAfCWy8tb`4YpvGwgda~sL5NtM=RS0Yw~<7OZ}JM1xn81xRvN^VCz9y}HdyVJ=d|eRok5GBUxLyV_9E^(MCI|9$L_g3^ zmq@J2aOR^jO)b9sE-pp0F~>{pa@beV+KBW%{3xQ|yMp6U0|o0cJ|HC9-#DWOZ|J^a zyk>tsvH}Kb*76XK#{?JVRR{ju@)=a8JbS~0hK`ZrbG&&kKXO*q@@i}<;w`{t?tX~7 z8Fgtu&ly-H&?dO575_TLvgc)de&?#g_{iUb^2w?H9+WS`i03v@Z*mdj?5DL8k2D@` zf^I^%5x?X_O%L0e9D!kE+97yz3 zcmGi2J^WeXIX)X85jZxPX>G;%6JEY!d`>!ti(sTa+;Fa>!K%oe-TgO>NJHQFDUAu@ zmg$X~a$1Z3DxUsrM}%&UJ8#opDE_^%1_a7Q@XnE17EkR=vIWYThd24}bU?iyv9Dq> zn^v1gPxnPU9^H1HeHG6b2k!tsptaQrFnUKfx1?nx2$RhZYBC@Dm+<>V9irIFQ9ZAQu z;>ij9rS4i+VmXmm;*^7bM*$Cwl)mP9V0rx!E+aUsg7ZLdN19*%O)5`OTn=oxr-%?$}T!5OFWaSR5uuO|Gyew1j;g)1q!Yv89#z=vvrcqvu zHMkAa0ZNyq3 z7iDyiMKDNPTofGF;Y7}1MP%^^ZLf8>rooI;bz;+hB;7zOIdX$OP*73&!0cu{P*I7# zNh8>E2Pt8HLR%snoaVr$XYJu}#Z9gDXL~`*b$fwRH$>MnI);&Rb9`s-n3R()f20{= zOt^>eUhF)lnd84FJ8kDAxp;efL>A-V-7XN;|Gn(A;@#DO@>czb*|af`a*Tb8_bhF4 z9`!VSa|Wl45!-NK3&C=3D|!(uqNl*{3`icqh5rO3c02wSS(h>pf8jaa5<3X zhXn8AnjLFxA0!T(31|Oa2|>5o!UIcNz4x4^RfGmnP!S`bpaRamFNB08$`VM}6oHUTAdqC@%!EZi zfq;StBH)gSiaR3WhKd@2pP+&wprWE6qDDbMMMOn;KGoBcbV3Gy?|aUB&htLce-2-| zyKb$wZdKiTtGaWd>IIpMTo2R!1>378;c1czNBoo<6sJ3A7U`S9UsiyAC-ey`&gRlR6@JK zpUCVgcMv$Q*1;RWDu4i`AI8DI06~RXr*71l%;6nr)VgB%*0Orny6# z)$%q~&j%?8wajgE#+^j?M2(Rg4>iS9(Dq8XA6eeh~ zdF~u8vf`WP&gAY&?vR4kh(O!sp?F=g27~gsnd;KQ)AMKfW^6XUR z4S14X@w!@>a@T}uyhYG!)r1-Ha!ek%m2QXSS&%^Ae5djI8BAMm=x z_d_YjdhGi_vb@w8l2O@Jji1Ft8D^NTR%OAK&8eLh58;KCcVqEWp((_rwmqrs_ur79 zI^Fiwtodr9g>&b@jS<u z1?|foTGgE@u-ngS5s(@s8wi@QUgL=be&ZyG*brDqB0HEeS4?g)VqqR(DvHhZZk5a0aWTQ!`3pR5KuhDSQL>pNvzu&0xr7f!8e3#q{d5&i}MaKQO%@+^e@lO4n<}M&9@+pR-_tdZ@n zVmXq?K~WuO=bZ%TZ0 zvHQPZuN1M_G*@lY@dY9-1{-)0XpnrHVREYRvx7EVs0+*GHqy`q*YV!@b^MuEd3vtq zv}?>NM`3q#IODZA5l?XXzk-)Aj1?Q%MmWkwZx2LaVr6S2fbMTew=9t(i1oDz>w?!P-6aV8uVOmS6JMO=s`okqN@s z>j<8#wYzyDj_hUqX?NcLsIKl&t-5PuM)17iAGOk{Jtl6KyNMLyesw#f@@3TTgHfc^ z>YE~;U|C;%`1+3CikDvdgugC4m(d( z>oGRsC)(BX>=RPZ3RsSLW8;$Sss|z7LaI$^Xkh1YQk)Ulh6v|O=#*VG8zP6@>F@YA zWU6(!3VEW=$AE}0*PG_g=_C)HGKVrHsSfYf)??%4;S+hFP98uT%3PVMD6G~NK} zQnmSUv=JVp_l6A%xl<}Y*`b|7G9#3w{$+JfiCKX$C^0rp?@NOwrX8kF3q4G23E@XM5gXf?F z##&-U$C_3A(J0oa;*Tb=6szj9Q!QG#Qj?je)UNXR?MH>O8_4?!E`u@!B;xJX#k*$)!&w(H{g-xSI~pwCB7A6F@q zsX$NPs!M7*?yYubZ^ewvld%Yu+VL+dLlaB7)CX{AC zPuJIP`fEa21d`F`zb};gfSz8f{T~WtGDt?3;h*iSP2Z)fpQKONm7Lz^BcT+69x|f# zoAxn+r{$5jCTPf=keKdIRXQ|Sdal$yZ{=QwE$7Om`X{|o@|Wm$y1BK4 z*VI6&{MxWkxON4SIEMEMWt>DknsHzGr53*)S`RI+M4rRRM_T6NWqw+|GQYHX(h4nY zqQ3fm9&}hJ`9P*k(Dib1>90cZ0zF-ye)!KU=s?mrJ*AGvC$y`~@1Y-s@;uO|*XO@G z*P#3WlF_q@4azk@PuG|K{tX6YAJEhFa+>#;L5YH7^s8nYlxu;WuFrqrOoQ?u(9`w# z&$`K=ECqV{I$it6Mhr>}B%{xpYEbS4db&RUr(ypA%e>U2n z90Gc}zWklH8I*5;p000SyF!D~9q8%$^oy1nlocQued7v)@)1Zz?>gR~1VA$SH_Hvm z?;sg{^8*IuQ;>{4cb-AH3nZgo^}SH81xe}OK?lj`6$gcK2hh`J>f|@`Zi6xu$g%v& zy$0nykeDa*e0={7#v#z>qo=<-)S$cr^mP4tHF}Uixen;*`hGl?Z%`T+B&R<-(xAKm z^y&5G-+!w?c^2sDdO2)9!=R)AJzbwZdb>fH3-ok-`dxVj)Y3UjzKX2JzbxF zzeNUR6wuT4>33z3KhV?l^Ng{tK{*@f>H7Q|^foAMfS#^jkI#G6pmYVv=(bl3N^g*i ze&Htu#SD_stM(X_KS473?k`veKr(vY;|Aqwkc{57VTuv}$>Q938NIwoigGhZ zMt`_zit++TM(@}-MX`fq^dEmQC?`QO`rb2Al%Ii~uJ6BZo24knK{9&tzlD+p^mP6B z`8btr3ZSR!^FQ_x^8uGblcgjDFv@2IU!$jDFz{$Uo52 z_59mWWl#iYMM%?4#B(5Kh)=Z3Eh%3`3W>-qEN5rfj~=j8N{e?`7Q zvh*!KH7FfHGWr+feYj5kdii?sfI-;|^y&5WcXmusvVfkhpTBo@PEo!Adb&RUdoE2; zo(9S2t1e1W-T->KKL77Kr6_*^xi(L`Bt@AIq#dK$FIU#KUt}KgCuu}KS#+^MjjIMG z`A^zBiTn=zOMYYai|Vr5UR8hDvKU$RM_SpkE}2Qt|8}-kegQ@k*Ho+_}Tu5sBc*&`{{)zUo`5Q_g1d5?Yp?jU9>%16Kxv*FL?^$l0-DtrCFXN zjf^Mz@N(iN`ZCeZ?Mc!k`snH|@jA)+ok$Wlk^ca#PD8b;URGpzGLIeuPS2~UTH0A$ zWgX^omAty0Yl1g({w0qN)LGW)GOg}1pLPF|=A@Rtl<}%0ab=$JCwVyP(s&t#TxI^H zTxC5cag}{~16SGJo3yLsMPeMvc=B1MOUPthUdcGc1MBA%B()A>FRR_3GXE9-l4gd+ zo4H)|vLMs$`IodD7gzbZuui#h47ANYeO;f>%3Z@%?GNpmto?Gcpe#wAGQIrC`hTwF z`?Z$eL9UW_zjBpr`iraV2P6F;=e;wy%KDzgRnB|obLD)1=%`&U*REEsXAth?D&
vL4Qp3ttT@Kn+zKmJ?!xb-ykk#%{J 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%0AAZFCoc$&AwSD&1 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 { + console.log(Utils.COD2BashColor(`^7${msg}^7`)) + } + } + + this.Manager = Manager + this.customCommands = { + 'chat': { + callback: () => { + this.chatEnabled = !this.chatEnabled + this.Player.Tell(`Chat ${this.chatEnabled ? '^2enabled' : '^1disabled'}`) + } + } + } + + this.streamChat() + rl.on('line', this.processCommand.bind(this)) + } + streamChat() { + this.Managers.forEach(Manager => { + Manager.Server.on('message', async (Player, Message) => { + if (this.chatEnabled) { + this.Player.Tell(Utils.formatString(Localization['GLOBALCHAT_FORMAT'], { + Enabled: '', + Name: Player.Name, + Message, + Hostname: Player.Server.HostnameRaw + }, '%')[0]) + } + }) + }) + } + + async processCommand(line) { + var args = line.split(/\s+/) + + if (this.customCommands[args[0].toLocaleLowerCase()]) { + this.customCommands[args[0].toLocaleLowerCase()].callback() + return + } + + var executedMiddleware = await this.Manager.Commands.executeMiddleware(args[0], this.Player, args) + if (await this.Manager.Commands.execute(args[0], this.Player, args)) return + + var command = Utils.getCommand(this.Manager.commands, args[0]) + + switch (true) { + case (!this.Manager.commands[command]): + !executedMiddleware && this.Player.Tell(Localization['COMMAND_NOT_FOUND']) + return + case (this.Manager.commands[command].inGame || this.Manager.commands[command].inGame == undefined): + this.Player.Tell(Localization['COMMAND_ENV_ERROR']) + return + case (args.length - 1 < this.Manager.commands[command].ArgumentLength): + this.Player.Tell(Localization['COMMAND_ARGUMENT_ERROR']) + return + } + + this.Manager.Server.DB.logActivity(`@${this.Player.ClientId}`, Localization['AUDIT_CMD_EXEC'].replace('%NAME%', command), args.join(' ')) + this.Manager.commands[command].callback(this.Player, args) + } +} + +module.exports = CLICommands \ No newline at end of file diff --git a/node-server-manager/Lib/Classes.js b/node-server-manager/Lib/Classes.js new file mode 100644 index 0000000..1591a54 --- /dev/null +++ b/node-server-manager/Lib/Classes.js @@ -0,0 +1,63 @@ +const path = require('path') +const Localization = require(path.join(__dirname, `../Configuration/Localization-${process.env.LOCALE}.json`)).lookup +const Permissions = require(path.join(__dirname, `../Configuration/NSMConfiguration.json`)).Permissions + +const NodeServerManager = { + ClientId: 1, + Name: 'Node Server Manager', + Guid: 'node' +} + +class Command { + constructor(command = {}) { + this.name = command.name ? command.name : '' + this.alias = command.alias ? command.alias : '' + this.permission = command.permission ? Permissions.Levels[command.permission] : 0 + this.inGame = command.Ingame ? command.inGame : false + this.isMiddleware = command.isMiddleware ? command.isMiddleware : false + this.exceptions = command.exceptions ? command.exceptions : [] + this.params = command.params ? command.params : [] + this.callbacks = command.callbacks ? command.callbacks : [] + this.defaultCallback = (Player) => { + Player.Tell(Localization['COMMAND_NOT_SETUP']) + } + } + setName(name) { + this.name = name + return this + } + setMiddleware(bool) { + this.isMiddleware = bool + return this + } + setAlias(alias) { + this.alias = alias + return this + } + setInGame(inGame) { + this.inGame = inGame + return this + } + addException(error, callback) { + this.exceptions.push({ error, callback }) + return this + } + addParams(params) { + this.params = this.params.concat(params) + return this + } + addParam(param) { + this.params.push(param) + return this + } + addCallback(callback) { + this.callbacks.push(callback) + return this + } + setPermission(perm) { + this.permission = Permissions.Levels[perm] + return this + } +} + +module.exports = { Command, NodeServerManager } \ No newline at end of file diff --git a/node-server-manager/Lib/ClientData.js b/node-server-manager/Lib/ClientData.js new file mode 100644 index 0000000..a006296 --- /dev/null +++ b/node-server-manager/Lib/ClientData.js @@ -0,0 +1,16 @@ +class ClientData { + constructor() { + this.clientData = {} + } + getData(ClientId) { + if (this.clientData[ClientId]) { + return this.clientData[ClientId] + } + + this.clientData[ClientId] = {} + + return this.clientData[ClientId] + } +} + +module.exports = ClientData \ No newline at end of file diff --git a/node-server-manager/Lib/Commands.js b/node-server-manager/Lib/Commands.js new file mode 100644 index 0000000..28cb4b3 --- /dev/null +++ b/node-server-manager/Lib/Commands.js @@ -0,0 +1,95 @@ +const path = require('path') +const Localization = require(path.join(__dirname, `../Configuration/Localization-${process.env.LOCALE}.json`)).lookup + +class Commands { + constructor() { + this.Commands = {} + } + add(command) { + this.Commands[command.name] = command + } + findCommand(name) { + var found = false + Object.entries(this.Commands).forEach(command => { + if (command[0].toLocaleLowerCase() == name.toLocaleLowerCase() || (command[1].alias && command[1].alias.toLocaleLowerCase() == name.toLocaleLowerCase())) { + found = this.Commands[command[0]] + } + }) + return found + } + async executeMiddleware (name, Player, args, options = { delay: true, broadcast: false }) { + return new Promise((resolve, reject) => { + var next = () => { + resolve() + } + + Object.entries(this.Commands).forEach(command => { + if (!command[1].isMiddleware) return + + this.execute(command[1].name, Player, args, options, next) + }) + }) + } + async execute (name, Player, args, options = { delay: true, broadcast: false }, next = null) { + var command = this.findCommand(name) + + var funcs = { + Tell: (string) => { + options.broadcast ? (Player.Server.Broadcast(string)) : Player.Tell(string) + } + } + + switch (true) { + case (!next && command.isMiddleware): + case (!command): + return + case (command.inGame && !Player.inGame): + Player.Tell(Localization['COMMAND_ENV_ERROR']) + return 1 + case (Player.PermissionLevel < command.permission): + Player.Tell(Localization['COMMAND_FORBIDDEN']) + return 1 + } + + var defaultParam = { + join: false, + optional: false, + index: 0, + name: '' + } + + var params = {} + for (var i = 0; i < command.params.length; i++) { + + command.params[i] = {...defaultParam, ...command.params[i]} + + if (!args[command.params[i].index + 1]) { + if (command.params[i].optional) continue + + Player.Tell(Localization['COMMAND_ARGUMENT_ERROR']) + return 1 + } + params[command.params[i].name] = command.params[i].join ? args.slice(command.params[i].index + 1).join(' ') : args[command.params[i].index + 1] + } + + for (var i = 0; i < command.exceptions.length; i++) { + if (!command.exceptions[i].callback(Player, params, args)) { + Player.Tell(command.exceptions[i].error) + return 1 + } + } + + if (!command.callbacks.length) { + command.defaultCallback(Player, args) + return 1 + } + + for (var i = 0; i < command.callbacks.length; i++) { + await command.callbacks[i](Player, params, args, options, funcs, next) + } + + return 1 + } +} + +module.exports = Commands \ No newline at end of file diff --git a/node-server-manager/Lib/ConfigMaker.js b/node-server-manager/Lib/ConfigMaker.js new file mode 100644 index 0000000..b740cbb --- /dev/null +++ b/node-server-manager/Lib/ConfigMaker.js @@ -0,0 +1,139 @@ +const readline = require("readline") + +const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout +}) + +const fs = require('fs') +const path = require('path') + +class ConfigMaker { + init() { + return new Promise((resolve, reject) => { + + if (!fs.existsSync(path.join(__dirname, `../Configuration`))) { + fs.mkdirSync(path.join(__dirname, `../Configuration`)) + } + + var Gamenames = ['Default', 'IW3', 'IW4', 'IW5', 'T6'] + + var configTemplate = [ + {Question: 'Enable Webfront [true / false]', value: true}, + {Question: 'Webfront bind port: [0-65536]', value: 8000}, + {Question: 'Enable Webfront https', value: false}, + {Question: 'SSL Key file', value: '', depends: 2}, + {Question: 'SSL Certificate file', value: '', depends: 2}, + {Question: 'Webfront Hostname', value: ''}, + {Question: 'Discord WebHook url', value: ''}, + {Question: 'MOTD', value: 'No message of the day today :('}, + {Question: 'Command Prefix', value: '.'}, + {Question: 'Server IP', value: 'localhost'}, + {Question: 'Server Port', value: 27016}, + {Question: 'Server Rcon Password', value: ''}, + {Question: 'Server Log file path', value: '/pluto/storage/iw5/games_mp.log'}, + {Question: 'Server Gamename (0: Default, 1: IW3, 2: IW4, 3: IW5, 4: T6', value: '0'}, + {Question: 'Reserved slots:', value: 0}, + ] + + function askQuestion(Index) { + if (configTemplate[Index].depends && configTemplate[configTemplate[Index].depends].value != 'true') { + askQuestion(++Index) + return + } + rl.question(`${configTemplate[Index].Question} (default: ${configTemplate[Index].value}): `, (value) => { + value.length > 0 && (configTemplate[Index].value = value) + if (Index < configTemplate.length - 1) askQuestion(++Index) + else { + rl.close() + return + } + + }) + } + askQuestion(0) + + rl.on("close", function() { + var configuration = JSON.stringify({ + 'Webfront': configTemplate[0].value == 'true', + 'WebfrontPort': parseInt(configTemplate[1].value), + 'WebfrontSSL': configTemplate[2].value == 'true', + 'WebfrontSSL-Key': configTemplate[3].value, + 'WebfrontSSL-Cert': configTemplate[4].value, + 'webfrontHostname': configTemplate[5].value, + 'discordHookUrl': configTemplate[6].value, + 'MOTD': configTemplate[7].value, + 'Info': 'No info for now...', + 'commandPrefixes': [ configTemplate[8].value ], + 'broadcastCommandPrefixes': ['@'], + 'links': [], + 'socialMedia': [], + 'rules': [], + 'locale': 'en', + "autoMessagesInterval": 60, + "autoMessages": [ + "A total of ^5{TOTALCLIENTS}^7 players have played on this server", + "Join the discord at ^5discord.gg/^7!", + "This server uses ^1Node Server Manager^7 get it at ^5github.com/fedddddd/node-server-manager^7", + "There are ^5{PLAYERCOUNT}^7 online players across ^5{SERVERCOUNT}^7 servers at the moment", + "^5{TOTALKILLS}^7 players have been killed on this server", + "^5{TOTALPLAYEDTIME}^7 hours have been wasted playing on this server" + ], + 'Servers':[ + { + 'IP' : configTemplate[9].value, + 'PORT' : configTemplate[10].value, + 'PASSWORD' : configTemplate[11].value, + 'LOGFILE' : configTemplate[12].value, + 'Gamename' : Gamenames[parseInt(configTemplate[13].value)], + 'reservedSlots' : parseInt(configTemplate[14].value), + } + + ], + "Permissions" : { + "Levels" : { + "ROLE_BANNED" : -1, + "ROLE_USER" : 0, + "ROLE_FLAGGED" : 1, + "ROLE_TRUSTED" : 2, + "ROLE_MODERATOR" : 3, + "ROLE_ADMIN" : 4, + "ROLE_OWNER" : 5, + "ROLE_MANAGER": 6 + }, + "Commands" : { + "COMMAND_KICK" : "ROLE_MODERATOR", + "COMMAND_USER_CMDS" : "ROLE_USER", + "COMMANDS_KICK" : "ROLE_MODERATOR", + "COMMAND_FIND" : "ROLE_MODERATOR", + "COMMAND_SETROLE" : "ROLE_ADMIN", + "COMMAND_TP" : "ROLE_ADMIN", + "COMMAND_RCON" : "ROLE_OWNER", + "COMMAND_TOKEN" : "ROLE_MODERATOR", + "COMMAND_BAN" : "ROLE_MODERATOR", + "COMMAND_CHANGE_INFO" : "ROLE_ADMIN", + "COMMAND_MAP": "ROLE_ADMIN" + }, + "Roles" : { + "ROLE_BANNED" : "Banned", + "ROLE_USER" : "User", + "ROLE_FLAGGED" : "Flagged", + "ROLE_TRUSTED" : "Trusted", + "ROLE_MODERATOR" : "Moderator", + "ROLE_ADMIN" : "Admin", + "ROLE_OWNER" : "Owner", + "ROLE_MANAGER": "Node Server Manager" + } + } + }, null, 4) + + fs.writeFile(path.join(__dirname, `../Configuration/NSMConfiguration.json`), configuration, (err) => { + console.log('Config done! Rerun the executable to start') + resolve(configuration) + }) + }) + }) + } +} + +module.exports = ConfigMaker diff --git a/node-server-manager/Lib/DatabaseModels.js b/node-server-manager/Lib/DatabaseModels.js new file mode 100644 index 0000000..6f72027 --- /dev/null +++ b/node-server-manager/Lib/DatabaseModels.js @@ -0,0 +1,36 @@ +const fs = require('fs'); +const path = require('path'); +const sqlite3 = require('sqlite3').verbose(); +const directoryPath = path.join(__dirname, './Models') +const Sequelize = require('sequelize') +var Models = {} + +new sqlite3.Database(path.join(__dirname, '../Database/Database1.db'), (err) => { + var sequelize = new Sequelize({ + host: 'localhost', + dialect: 'sqlite', + pool: { + max: 5, + min: 0, + idle: 10000 + }, + logging: false, + storage: path.join(__dirname, '../Database/Database1.db') + }) + + Models.DB = sequelize + + fs.readdir(directoryPath, (err, files) => { + if (err) { + return console.log('Unable to scan directory: ' + err) + } + + files.forEach( (file) => { + file = path.join(__dirname, `./Models/${file}`) + var Model = require(file)(sequelize, Sequelize) + Models[path.basename(file, path.extname(file))] = Model + }) + }) +}) + +module.exports = Models \ No newline at end of file diff --git a/node-server-manager/Lib/Entity/Player.js b/node-server-manager/Lib/Entity/Player.js new file mode 100644 index 0000000..6484383 --- /dev/null +++ b/node-server-manager/Lib/Entity/Player.js @@ -0,0 +1,106 @@ +const EventEmitter = require('events') +const path = require('path') +const { NodeServerManager } = require(path.join(__dirname, '../Classes.js')) +const Utils = new (require(path.join(__dirname, `../../Utils/Utils.js`)))() +const Localization = require(path.join(__dirname, `../../Configuration/Localization-${process.env.LOCALE}.json`)).lookup + +class ePlayer extends EventEmitter { + constructor (Guid, Name, Clientslot, IPAddress, Server) { + super() + this.Guid = Guid + this.Name = Name + this.inGame = true + this.lastSeen = new Date() + this.IPAddress = IPAddress + this.Clientslot = Clientslot + this.Server = Server + this.Server.Clients[Clientslot] = this + } + async build() { + this.ClientId = await this.Server.DB.addClient(this.Guid) + + this.Server.DB.initializeStats(this.ClientId) + + this.PermissionLevel = await this.Server.DB.getClientLevel(this.ClientId) + this.Server.DB.logConnection(this) + + this.matchData = {} + + this.Data = this.Server.clientData.getData(this.ClientId) + + const id = this.IPAddress && this.IPAddress.split(':')[0] + ? this.IPAddress.split(':')[0] + : crypto.randomBytes(8).toString('hex') + + this.Session = this.Server.sessionStore.createSession(id) + this.Session && (this.Session.Data.Authorized = this.Session.Data.Authorized != undefined ? this.Session.Data.Authorized : false) + } + async getPersistentMeta(name, type = '') { + var result = await this.Server.DB.metaService.getPersistentMeta(name, this.ClientId, type) + + return result + } + Report(Reason, Origin = NodeServerManager) { + this.Server.DB.addReport(Origin.ClientId, this.ClientId, Reason) + this.Server.emit('report', Origin, this, Reason) + + this.Server.tellStaffGlobal(Utils.formatString(Localization['COMMAND_REPORT_TELL'], { + Origin: Origin.Name, + Hostname: this.Server.Hostname, + Target: this.Name, + Reason: Reason + }, '%')[0]) + } + Ban (Reason, Origin) { + this.Server.DB.addPenalty({ + TargetId: this.ClientId, + OriginId: Origin.ClientId, + PenaltyType: 'PENALTY_PERMA_BAN', + Duration: 0, + Reason: Reason + }) + + this.Server.emit('penalty', 'PENALTY_PERMA_BAN', this, Reason, Origin) + this.Kick(`You have been permanently banned for: ^5${Reason}`, Origin, false, '') + } + Tempban (Reason, Origin, Duration) { + this.Server.DB.addPenalty({ + TargetId: this.ClientId, + OriginId: Origin.ClientId, + PenaltyType: 'PENALTY_TEMP_BAN', + Duration: Duration, + Reason: Reason + }) + + this.Server.emit('penalty', 'PENALTY_TEMP_BAN', this, Reason, Origin, Duration) + this.Kick(`You have been banned for: ^5${Reason} ${Utils.secondsToDhms(Duration)}^7 left`, Origin, false, '') + } + async Tell (text) { + if (!text) return + + var chunks = Utils.breakString(text, this.Server.Rcon.commandPrefixes.Dvars.maxSayLength, ' ') + + for (var i = 0; i < chunks.length; i++) { + await this.Server.Rcon.executeCommandAsync(this.Server.Rcon.commandPrefixes.Rcon.Tell + .replace('%CLIENT%', this.Clientslot) + .replace('%MESSAGE%', chunks[i])) + } + } + Kick (Message, Origin = NodeServerManager, Log = true, Basemsg = 'You have been kicked: ^5') { + this.Server.DB.addPenalty({ + TargetId: this.ClientId, + OriginId: Origin.ClientId, + PenaltyType: 'PENALTY_KICK', + Duration: 0, + Reason: Message + }) + + Log && this.Server.emit('penalty', 'PENALTY_KICK', this, Message, Origin) + this.Server.Rcon.executeCommandAsync(this.Server.Rcon.commandPrefixes.Rcon.clientKick + .replace('%CLIENT%', this.Clientslot) + .replace('%REASON%', `${Basemsg}${Message}`)) + + //this.Server.Clients[this.Clientslot] = null + } +} +module.exports = ePlayer \ No newline at end of file diff --git a/node-server-manager/Lib/Entity/Server.js b/node-server-manager/Lib/Entity/Server.js new file mode 100644 index 0000000..079ebb4 --- /dev/null +++ b/node-server-manager/Lib/Entity/Server.js @@ -0,0 +1,279 @@ +const ePlayer = require('./Player.js') +const path = require('path') +const Commands = require(path.join(__dirname, `../Commands.js`)) +const EventEmitter = require('events') +const ip = require('public-ip') +const Game = require(path.join(__dirname, `../../Configuration/DefaultGameSettings.json`)) +const Maps = Game.Maps +const Gametypes = Game.Gametypes +const Permissions = require(path.join(__dirname, `../../Configuration/NSMConfiguration.json`)).Permissions +const wait = require('delay') +const Utils = new (require(path.join(__dirname, `../../Utils/Utils.js`)))() + +var wasRunning = true +class Server extends EventEmitter { + constructor(IP, Port, Rcon, Database, sessionStore, clientData, Managers, Id, Manager, config) { + super() + this.Clients = [] + this.Rcon = Rcon + this.IP = IP + this.Id = Id + this.PORT = Port + this.clientHistory = [] + this.clientActivity = [] + this.DB = Database + this.MaxClients = 18 + this.Mapname = '' + this.clientData = clientData + this.Gametype = 'UNKNOWN' + this.HostnameRaw = `[${this.IP}:${this.PORT}]` + this.uptime = 0 + this.configGamename = config.Gamename + this.Gamename = 'UNKNOWN' + this.Managers = Managers + this.Manager = Manager + this.previousUptime = 0 + this.previousStatus = null + this.heartbeatRetry = this.Rcon.commandPrefixes.Rcon.retries ? this.Rcon.commandPrefixes.Rcon.retries : 1 + this.sessionStore = sessionStore + this.lastInit = new Date() + this.on('init', this.onInitGame.bind(this)) + this.config = config + this.reservedSlots = config.reservedSlots + Manager.Commands = new Commands() + this.setMaxListeners(50) + } + getMap(name) { + return this.Maps.find(Map => Map.Name.toLocaleLowerCase().startsWith(name) || Map.Alias.toLocaleLowerCase().startsWith(name) ) + } + getGametype() { + return Gametypes[this.Gametype] ? { Name: this.Gametype, Alias: Gametypes[this.Gametype] } : { Name: this.Gametype, Alias: this.Gametype } + } + getClients() { + return this.Clients.filter(c => c) + } + getMapname() { + var map = this.getMap(this.Mapname) + return map ? map : { Name: this.Mapname, Alias: this.Mapname } + } + onInitGame() { + if (new Date() - this.lastInit < 500) { + return + } + + this.lastInit = new Date() + + var loadMap = async () => { + this.removeListener('line', loadMap) + this.Mapname = await this.Rcon.getDvar('mapname') + this.Gametype = await this.Rcon.getDvar('g_gametype') + this.emit('map_loaded', this.Mapname, this.Gametype) + } + + this.on('line', loadMap) + } + findLocalClient(name) { + var clientIdRegex = /\@([0-9]+)/g + var found = false + + name = name.match(clientIdRegex) ? clientIdRegex.exec(name)[1] : name + + this.Clients.forEach(Client => { + if (!Client) return + + if (Client.Name.toLocaleLowerCase().startsWith(name.toLocaleLowerCase()) || Client.ClientId == name) { + found = Client + } + }) + return found + } + getStaffMembers() { + var staff = [] + this.Clients.forEach(Client => { + if (!Client) return + Client.PermissionLevel >= Permissions.Levels['ROLE_MODERATOR'] && staff.push(Client) + }) + staff.sort((a, b) => { + return b.PermissionLevel - a.PermissionLevel + }) + return staff + } + async setDvarsAsync() { + try { + this.Gametype = await this.Rcon.getDvar(this.Rcon.commandPrefixes.Dvars.gametype) + + this.Gamename = !this.configGamename + ? await this.Rcon.getDvar(this.Rcon.commandPrefixes.Dvars.gamename) + : this.configGamename + + this.Maps = this.Gamename != 'UNKNOWN' ? Maps.find(x => x.Game == this.Gamename) ? Maps.find(x => x.Game == this.Gamename).Maps : [] : [] + + this.mapRotation = (await this.Rcon.getDvar(this.Rcon.commandPrefixes.Dvars.maprotation)) + this.mapRotation = this.mapRotation.match(/map +([a-z|_|\d]+)/gi) + ? this.mapRotation.match(/map +([a-z|_|\d]+)/gi).map(x => x.trim().split(/\s+/g)[1]) + : [] + + this.Hostname = await this.Rcon.getDvarRaw(this.Rcon.commandPrefixes.Dvars.hostname) + this.HostnameRaw = this.Hostname + + this.Mapname = await this.Rcon.getDvar(this.Rcon.commandPrefixes.Dvars.mapname) + + this.MaxClients = parseInt(this.config.maxClientsOverride + ? this.config.maxClientsOverride + : await this.Rcon.getDvar(this.Rcon.commandPrefixes.Dvars.maxclients)) + + this.Clients = new Array(this.MaxClients).fill(null) + + this.Rcon.isRunning = true + + this.externalIP = !this.IP.match(/(^127\.)|(localhost)|(^192\.168\.)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^::1$)|(^[fF][cCdD])/g) ? this.IP : await ip.v4() + this.emit('dvars_loaded', this) + this.dvarsLoaded = true + + this.HeartbeatInt = setInterval(this.Heartbeat.bind(this), 15000) + } + catch (e) { } + } + tellStaffGlobal(Message) { + this.Managers.forEach(Manager => { + Manager.Server.tellStaff(Message) + }) + } + tellStaff(Message) { + this.Clients.filter(x => x && x.PermissionLevel >= Permissions.Levels['ROLE_MODERATOR'] && x.Tell(Message)) + } + async getClient(name) { + var clientIdRegex = /\@([0-9]+)/g + + if (!name.match(/\@([0-9]+)/g) && this.findClientByName(name)) { + return this.findClientByName(name) + } + + var Clients = name.match(clientIdRegex) + ? [await this.DB.getClient(clientIdRegex.exec(name)[1])] + : ((name.length >= 3 && !name.match('%')) ? (await this.DB.getClientByName(name, 20)) : false) + + var Client = Clients ? Clients.reverse()[0] : false + return Client + } + toString() { + return `${this.IP}:${this.PORT}` + } + getAddress() { + return `${this.externalIP}:${this.PORT}` + } + getPlayerByName(Name) { + var Client = this.Clients.find(x => x && x.Name.startsWith(Name)) + return Client + } + findClientByName(Name) { + var Client = null + + this.Managers.forEach(Manager => { + if (Client) return + Client = Manager.Server.Clients.find(x => x && x.Name.toLocaleLowerCase().startsWith(Name.toLocaleLowerCase())) + }) + + return Client + } + findClient(ClientId) { + var Client = null + + this.Managers.forEach(Manager => { + if (Client) return + Client = Manager.Server.Clients.find(x => x && x.ClientId == ClientId) + }) + + return Client + } + async Heartbeat() { + try { + var status = await this.Rcon.executeCommandAsync('status') + + if (!status) { + if (this.heartbeatRetry <= 0) { + this.Rcon.isRunning = false + wasRunning && this.Manager.log(`^1Connection lost with ^6[${this.toString()}]^7`) + wasRunning = false + } + this.heartbeatRetry > 0 && this.heartbeatRetry-- + } else { + this.heartbeatRetry = 2 + this.Rcon.isRunning = true + } + + if (!this.Rcon.isRunning && status != false) { + this.heartbeatRetry = 1 + this.Rcon.isRunning = true + wasRunning = true + this.Manager.log(`^1Connection re-established with ^6[${this.toString()}]^7`) + setTimeout( async () => { + await this.loadClientsAsync() + this.emit('reload') + }, 10000) + } + } + catch (e) {} + } + async loadClientsAsync(retry = 1) { + var status = await this.Rcon.getStatus() + + if (!status) { + await wait(1000 * retry) + this.loadClientsAsync(++retry) + return + } + + for (var i = 0; i < this.Clients.length; i++) { + if (!this.Clients[i]) continue + this.Clients[i].removeAllListeners() + this.Clients[i] = null + } + + status.data.clients.forEach(async c => { + if (this.Clients[c.num]) this.Clients[c.num].removeAllListeners() + this.Clients[c.num] = new ePlayer(c.guid, c.name, c.num, c.address, this) + + await this.Clients[c.num].build() + + if (!this.Clients[c.num]) return + + this.emit('connect', this.Clients[c.num]) + this.emit('any_event', {type: 'join', Origin: this.Clients[c.num]}) + }) + } + globalBroadcast(Message) { + this.Managers.forEach(Manager => { + Manager.Server.Broadcast(Message) + }) + } + async Broadcast (string) { + string = string.toString() + + if (!string) { + return + } + + string = string.replace(new RegExp(/\s+/g), ' ') + + var chunks = Utils.breakString(string, this.Rcon.commandPrefixes.Dvars.maxSayLength, ' ') + + for (var i = 0; i < chunks.length; i++) { + await this.Rcon.executeCommandAsync(this.Rcon.commandPrefixes.Rcon.Say.replace('%MESSAGE%', chunks[i])) + } + } + isZM() { + return ['zclassic', 'zstandard'].includes(this.Gametype) + } + isZMAlt() { + return ['zgrief', 'zcleansed'].includes(this.Gametype) + } + isAliens() { + return ['aliens'].includes(this.Gametypes) + } + isMP() { + return !this.isZM() && !this.isZMAlt() && !this.isAliens() + } +} + +module.exports = Server \ No newline at end of file diff --git a/node-server-manager/Lib/Entity/give_tb-compiled.gsc b/node-server-manager/Lib/Entity/give_tb-compiled.gsc new file mode 100644 index 0000000000000000000000000000000000000000..107a91b8aa6dac8301d2a4f8906833ed3fb4c552 GIT binary patch literal 424 zcmX|-F-t=+6opS-ZHHpPO`d}|*(Xw;L#d!p1qa;)*N|6Z34Li}^R%>6e?jN|1ouvz zx^?Ui(A7b36%i5i-dYSf`ECv;SLdZ73ZV5u8VKN(I3(6d*QCdlICF+P0_3;^ z*=U*vEwcnxIUidW4>~q6+Q)KWWlt+7Gh?+($c1T}Y?-HcqhoESEq$YFT;}8Z%%mpk z<2F@I*;AC`uu-W@Qq^ctOzXCE%6okSsj5dc$QGY2RejxE!LKO)n)?6vlKR}OY*e{t zN2*~nH^CG$RElF9V8mW&2XmBzC=6U#M4^x;*hVPAV5^L%654p;N3{q7G8TXS+8&Q?xh4?eld384i#Q{G6UY3X_MGnP F#9zmaVXOcE literal 0 HcmV?d00001 diff --git a/node-server-manager/Lib/Entity/setround-compiled.gsc b/node-server-manager/Lib/Entity/setround-compiled.gsc new file mode 100644 index 0000000000000000000000000000000000000000..011a3d8a28089772a7451ce98796716b8ce94216 GIT binary patch literal 304 zcmZp04|e9|Vqjwcg4saK#R#DVfb=yW{~Zt;0NEf60uBr;3`{@>1I4K&Mfs(9DGZr; znI#NhW_(_0Zc=Iy15m0emm#yDC^N4lCy&9{pje?KGbcx(Dp#SjASJORl>x{~25K&W z@>3Y9@^h0iQ{zkWOA>P!)L3kI75x}AbOlTp7@~m|ngNC6v~{_%81xttL3}W;7RY0O z^0{~w8TuGB7~D69&jIeUQSY8KJOK5KUK;W1HY|5$mX)au;iVh-r&pyT6zzIce9o zd;1HiAbT$XPJcS9ts9{f;I`X5I`m_)ek{?CrTX!hek{|EPW@=N%kw%aytu+k zD!jD9k5zbCg*z+Un{zVupo1G&@BeGalpJM9dNbuaHK4ZHZPXk2`#CdlP`{SYT((7R6H%%4!nR)s0hAm zV)=EmXC_$@dCt^#Ff>*YpeW?RsPde{qI`NLKIb5;JnD*yQ^|8SLm ztja%8<-az`e-HbOO06zYyHCf)WR784%81KD5|I(JeoLdwZ;1+}misJfo%rmIkkf5N zBx=<^6Ol%12G2HY#+LalDx!>5Sx??VX^M)f`&OKpE%%9>J#+sP(RPufUW5DEZD~&= z(7vi^Zi$p5p`Yjo=Nvg4O-!D1?EmJJBjFtO;FD;Mgh~>=R;fO)wpm|V38j0ZFS5dX zGJaHAA|Ih0U$>H+(^{>jNgX7W95$^PH3^|G1;rM(*5XM zF7w$(2Z_-s2Z`xJ==!%rX|jsFI!?{YS;j*7X5!=>i*JWH>WDh3UR9@+srTW&Yt`!b zBivk^3e2VIbLV}cnj*K<^w{UBft-ZwqMsx3V9iu{Z8Z~lo5H*;jBt%4Yg8gpvE%X-$}U@We73H}+?ZUpHiU~6`K`JvF?YoZsuxWvAVL9WEtaZnD$I$ls*f$Iv zH_bEH&E=e$e`0rH&nA8qdlW?Y9o_&Q1zlhr_#W5}c7pxj2sjDe1b+b+z*R5`BIsKH z7S)M-2;Kf3?GB9z$f4l_%*l= z{qMmu;Y)A~{uFM6P0KLa;Su~UxEp^n9Ho=D!i{hb+-8}QhOdF$*e}Az!7=Pp@CEPz zb4THA@PFYi;oERR(fHKjBXaBEH^F88Zf=H$z^}Nq*Fmkaqz9j`dC7qWRcGwQ-w$2^ z4-o4DNpKZh2aU=y4ls5J`wP&_@1#TckF(a#;chx40PBcf!_O#F8u4>r7rG9>d*Flc zUZspz;FI8Oa1k6~>?V8^{sMj#9)VB8qwpu}Kbw8KK`*$)`VH_8!RL%U0 this.Server.uptime) { + this.Server.previousUptime = this.Server.uptime + this.Server.loadClientsAsync() + this.Server.emit('reload') + return + } + + switch (event.type) { + case 'init': + this.Server.emit('init') + break + case 'say': + if (!event.data.Origin.Clientslot || !this.Server.Clients[event.data.Origin.Clientslot]) return + + var Player = this.Server.Clients[event.data.Origin.Clientslot] + Player.emit('message', event.data.Message) + this.Server.emit('message', Player, event.data.Message) + this.Server.emit('any_event', {type: 'say', Origin: this.Server.Clients[event.data.Origin.Clientslot], Data: event.data.Message}) + break + case 'join': + if (this.Server.Clients[event.data.Origin.Clientslot] != null + && this.Server.Clients[event.data.Origin.Clientslot].Guid == event.data.Origin.Guid) { + + this.Server.Clients[event.data.Origin.Clientslot].matchData = {} + + this.Server.emit('preconnect', this.Server.Clients[event.data.Origin.Clientslot]) + this.Server.emit('any_event', {type: 'join', Origin: this.Server.Clients[event.data.Origin.Clientslot]}) + return + } + + for (var i = 0; i < this.Server.Clients.length; i++) { + if (!this.Server.Clients[i]) continue + + if (this.Server.Clients[i].Guid == event.data.Origin.Guid && this.Server.Clients[i].Clientslot != event.data.Origin.Clientslot) { + this.Server.Clients[i].removeAllListeners() + this.Server.Clients[i] = null + } + } + + await wait(100) + + try { + var IPAddress = (await this.Server.Rcon.getClientByGuid(event.data.Origin.Guid)).address + } + catch (e) {} + if (!IPAddress) + IPAddress = `${randomInt(999)}.${randomInt(999)}.${randomInt(999)}.${randomInt(999)}` + var Player = new ePlayer(event.data.Origin.Guid, event.data.Origin.Name, event.data.Origin.Clientslot, IPAddress, this.Server) + await Player.build() + + this.Server.emit('connect', Player) + this.Server.emit('any_event', {type: 'join', Origin: Player}) + break + case 'quit': + this.Server.emit('event', {type: 'quit', Origin: this.Server.Clients[event.data.Origin.Clientslot]}) + + if (!event.data.Origin.Clientslot || !this.Server.Clients[event.data.Origin.Clientslot]) return + + for (var i = 0; i < this.Server.Clients.length; i++) { + if (!this.Server.Clients[i]) continue + + if (this.Server.Clients[i].Guid == event.data.Origin.Guid && this.Server.Clients[i].Clientslot != event.data.Origin.Clientslot) { + this.Server.Clients[i].removeAllListeners() + this.Server.Clients[i] = null + } + } + + this.Server.emit('disconnect', Object.assign({}, this.Server.Clients[event.data.Origin.Clientslot])) + + this.Server.Clients[event.data.Origin.Clientslot].removeAllListeners() + this.Server.Clients[event.data.Origin.Clientslot] = null + break + case 'kill': + var Target = this.Server.Clients[event.data.Target.Clientslot] + var Attacker = (event.data.Origin.Clientslot && event.data.Origin.Clientslot >= 0) ? this.Server.Clients[event.data.Origin.Clientslot] : Target + + if (Attacker.Clientslot != Target.Clientslot) { + Attacker.emit('kill', Target, event.data.Attack) + Target.emit('death', Attacker, event.data.Attack) + + this.Server.emit('death', Target, Attacker, event.data.Attack) + this.Server.emit('kill', Target, Attacker, event.data.Attack) + + this.Server.emit('any_event', {type: 'death', Origin: Target, Attack: event.data.Attack }) + this.Server.emit('any_event', { type:'kill', Origin: Attacker, Attack: event.data.Attack }) + return + } + + Attacker.emit('death', Attacker, event.data.Attack) + this.Server.emit('death', Attacker, Attacker, event.data.Attack) + break + + } + this.Server.previousUptime = event.data.TimeOffset + } + catch (e) { + this.Manager.logger.writeLn(`Error occurred while dispatching event`) + } + } +} + +module.exports = EventDispatcher \ No newline at end of file diff --git a/node-server-manager/Lib/EventLogWatcher.js b/node-server-manager/Lib/EventLogWatcher.js new file mode 100644 index 0000000..a6fd903 --- /dev/null +++ b/node-server-manager/Lib/EventLogWatcher.js @@ -0,0 +1,54 @@ +const EventParser = require('./EventParser.js') +const Tail = require('tail').Tail +const path = require('path') +const fs = require('fs') +const _EventDispatcher = require('./EventDispatcher.js') +const spawn = require('child_process').spawn + +class EventLogWatcher extends EventParser { + constructor (logfile, Server, Manager) { + super(Server) + this.previousMD5 = null + this.logfile = logfile + this.Server = Server + this.EventDispatcher = new _EventDispatcher(Server, Manager) + } + + init () { + var filePath = path.resolve(this.logfile) + + if (!fs.existsSync(filePath)) { + console.log(`Warning: log file "${filePath}" doesn't exist\nMake sure you selected the right file in Configuration/NSMConfiguration.json Servers -> LOGFILE\n`) + } + + if (process.platform == 'win32') { + var tail = spawn(`powershell`, ['-command', 'get-content', '-wait', '-Tail 0', `"${filePath}"`]) + tail.stdout.on('data', (data) => { + this.onLine(data.toString()) + }) + return + } + + var tail = new Tail(filePath) + tail.watch() + + tail.on('line', this.onLine.bind(this)) + } + + async onLine(line) { + this.Server.emit('line', line) + this.Server.emit('stripped_line', line.trim().replace(new RegExp(/([0-9]+:[0-9]+)\s+/g), '')) + + const lines = line.split('\n').filter(l => l.length > 0) + + for (var i = 0; i < lines.length; i++) { + const event = this.parseEvent(lines[i].trim()) + + if (!event) return + + this.EventDispatcher.dispatchCallback(event) + } + } +} + +module.exports = EventLogWatcher \ No newline at end of file diff --git a/node-server-manager/Lib/EventParser.js b/node-server-manager/Lib/EventParser.js new file mode 100644 index 0000000..b06329f --- /dev/null +++ b/node-server-manager/Lib/EventParser.js @@ -0,0 +1,106 @@ +class EventParser { + constructor(Server) { + this.Server = Server + } + + parseTimeStamp(timeStamp) { + if (timeStamp.includes(':')) { + const split = timeStamp.split(':') + + return parseInt(split[0]) * 60 + parseInt(split[1]) + } + + if (!this.Server.startTime) { + this.Server.startTime = parseInt(timeStamp) + } + + return parseInt(timeStamp) - this.Server.startTime + } + + getEventData(eventString) { + eventString = eventString.trim() + + var eventRegex = { + say: /^(.+) (say|sayteam);(-?[A-Fa-f0-9_]{1,32}|bot[0-9]+|0);([0-9]+);([^;]*);(.*)$/g, + join: /^(.+) (J);(-?[A-Fa-f0-9_]{1,32}|bot[0-9]+|0);([0-9]+);(.*)$/g, + quit: /^(.+) (Q);(-?[A-Fa-f0-9_]{1,32}|bot[0-9]+|0);([0-9]+);(.*)$/g, + damage: /^(.+) (D);(-?[A-Fa-f0-9_]{1,32}|bot[0-9]+|0);(-?[0-9]+);(axis|allies|world|none)?;([^;]{1,24});(-?[A-Fa-f0-9_]{1,32}|bot[0-9]+|0)?;(-?[0-9]+);(axis|allies|world|none)?;([^;]{1,24})?;((?:[0-9]+|[a-z]+|_|\+)+);([0-9]+);((?:[A-Z]|_)+);((?:[a-z]|_)+)$/g, + kill: /^(.+) (K);(-?[A-Fa-f0-9_]{1,32}|bot[0-9]+|0);(-?[0-9]+);(axis|allies|world|none)?;([^;]{1,24});(-?[A-Fa-f0-9_]{1,32}|bot[0-9]+|0)?;(-?[0-9]+);(axis|allies|world|none)?;([^;]{1,24})?;((?:[0-9]+|[a-z]+|_|\+)+);([0-9]+);((?:[A-Z]|_)+);((?:[a-z]|_)+)$/g, + init: /^( +|)(.+) (InitGame|InitGame(.+))$/g + } + + var eventData = { type: null, data: null } + Object.entries(eventRegex).forEach((r) => { + if (!eventString.match(r[1])) { + return + } + + var eventVars = r[1].exec(eventString) + eventVars[0] = this.parseTimeStamp(eventVars[0]) + + eventData = { type: r[0], vars: eventVars } + }) + + return eventData + } + + parseEvent(eventString) { + var eventData = this.getEventData(eventString) + if (!eventData || eventData.type == null) return + + var parsedEvent = { type: eventData.type, data: null } + switch (eventData.type) { + case 'init': { + parsedEvent.data = { + TimeOffset: eventData.vars[0], + } + } + break + case 'say': + parsedEvent.data = { + TimeOffset: eventData.vars[0], + Origin: this.Server.Clients[eventData.vars[4]], + Message: eventData.vars[6].replace(/[^\x20-\x7E]+/g, '') + } + break + case 'quit': + case 'join': + parsedEvent.data = { + TimeOffset: eventData.vars[0], + Origin: { + Guid: eventData.vars[3].includes('bot') ? eventData.vars[3] : this.Server.Rcon.commandPrefixes.convertGuid(eventData.vars[3]), + Clientslot: eventData.vars[4], + Name: eventData.vars[5].replace(/\[.*\]/g, '') + }, + } + break + case 'kill': + var Weapon = eventData.vars[11] + var BaseWeapon = Weapon + + if (Weapon.indexOf('_mp') > 0) { + BaseWeapon = Weapon.substr(0, Weapon.indexOf('_mp')) + } + + var suicide = (eventData.vars[4] == eventData.vars[8]) || eventData.vars[8] == '-1' + + parsedEvent.data = { + TimeOffset: eventData.vars[0], + Target: this.Server.Clients[eventData.vars[4]], + Origin: suicide ? {ClientId: 1} : this.Server.Clients[eventData.vars[8]], + Attack: { + Weapon: eventData.vars[11], + Damage: eventData.vars[12], + MOD: eventData.vars[13], + HitLoc: eventData.vars[14], + BaseWeapon: BaseWeapon + } + } + break + } + + return parsedEvent + } +} + +module.exports = EventParser \ No newline at end of file diff --git a/node-server-manager/Lib/InitDatabase.js b/node-server-manager/Lib/InitDatabase.js new file mode 100644 index 0000000..0859275 --- /dev/null +++ b/node-server-manager/Lib/InitDatabase.js @@ -0,0 +1,1227 @@ +const Sequelize = require('sequelize') +const bcrypt = require('bcrypt') +const Models = require('./DatabaseModels.js') +const path = require('path') +const Permissions = require(path.join(__dirname, `../Configuration/NSMConfiguration.json`)).Permissions + +class MetaService { + constructor(Models) { + this.Models = Models + } + async addPersistentMeta(Key, Value, ClientId) { + if (!ClientId) return null + + var meta = await this.Models.NSMMeta.findAll({ + where: { + ClientId, + Key + }, + raw: true + }) + + if (!meta.length) { + await this.Models.NSMMeta.build({ + ClientId, + Key, + Value + }).save() + return + } + + await this.Models.NSMMeta.update( + { Value: Value }, + { where: { ClientId, Key } }) + } + async deletePersistentMeta(Key, ClientId) { + if (!ClientId) return null + + return await this.Models.NSMMeta.destroy({ + where: { + ClientId, + Key + } + }) + } + async reversePersistentMeta(Key, Value) { + var meta = await this.Models.NSMMeta.findAll({ + where: { + Value, + Key + }, + raw: true + }) + + return meta.length ? meta[0] : null + } + async getPersistentMeta(Key, ClientId, type = '') { + if (!ClientId) return null + + var meta = await this.Models.NSMMeta.findAll({ + where: { + ClientId, + Key + }, + raw: true + }) + + if (meta.length) { + switch (type) { + case 'bool': + meta[0].Value = parseInt(meta[0].Value) == 1 + break + case 'int': + meta[0].Value = parseInt(meta[0].Value) + break + case 'float': + meta[0].Value = parseFloat(meta[0].Value) + break + case 'json': + meta[0].Value = JSON.parse(meta[0].Value) + break + } + } + + return meta.length ? meta[0] : null + } +} + +class Database { + constructor () { + this.clientCache = [] + this.Models = Models + this.cache = {} + this.shortCache = {} + this.metaService = new MetaService(Models) + this.clientProfileMeta = [ + async (ClientId) => { + var stats = await this.getPlayerStatsTotal(ClientId) + if (!stats) return {} + return { + name: 'Stats', + data: { + 'Kills': stats.Kills ? stats.Kills : 0, + 'Deaths': stats.Deaths ? stats.Deaths : 0, + 'KDR': (stats.Kills / Math.max(stats.Deaths, 1)).toFixed(2), + 'Performance': stats.Performance.toFixed(2) + } + } + } + ] + setInterval(() => { + this.cache = {} + }, 60 * 1000 * 30) + + setInterval(() => { + this.shortCache = {} + }, 60 * 1000 * 5) + } + + async getClientProfileMeta(ClientId) { + if (this.shortCache[`META_${ClientId}`]) return this.shortCache[`META_${ClientId}`] + + this.shortCache[`META_${ClientId}`] = [] + for (var i = 0; i < this.clientProfileMeta.length; i++) { + this.shortCache[`META_${ClientId}`].push(await this.clientProfileMeta[i](ClientId)) + } + + return this.shortCache[`META_${ClientId}`] + } + + async startTransaction() { + if (this.transaction) return + this.transaction = await Models.DB.transaction() + } + + async addClient(Guid) { + await this.startTransaction() + + var ClientId = await this.getClientId(Guid) + if (ClientId) return ClientId + + if (!(await this.getClientId('Node'))) { + try { + await Models.NSMClients.build({ + Guid: 'Node', + PermissionLevel: 6 + }, {transaction: this.transaction}).save() + } + catch (e) { } + } + + if (!(await this.getClientSettings(1))) { + await Models.NSMSettings.build({ + ClientId: 1 + }, {transaction: this.transaction}).save() + } + + var Client = await Models.NSMClients.build({ + Guid: Guid + }, {transaction: this.transaction}).save() + + return Client.dataValues.ClientId + } + + async initializeStats(ClientId) { + try { + if (!(await this.getPlayerStatsTotal(ClientId))) { + await Models.NSMPlayerStats.build({ + ClientId: ClientId + }, {transaction: this.transaction}).save() + } + + if (!(await this.getClientSettings(ClientId))) { + await Models.NSMSettings.build({ + ClientId + }, {transaction: this.transaction}).save() + } + } + catch (e) {} + } + + async setClientSetting(ClientId, Setting, Value) { + await Models.NSMSettings.update( + { [Setting]: Value }, + { where: { ClientId: ClientId } }, {transaction: this.transaction}) + // await this.transaction.commit() + } + + async getClientSettings(ClientId) { + + var Settings = await Models.NSMSettings.findAll({ + where: { + ClientId + } + }, {transaction: this.transaction}) + return Settings.length > 0 ? Settings[0].dataValues : false + } + + async getMostUsedWeapon(ClientId) { + var Weapon = await Models.NSMKills.findAll({ + attributes: ['BaseWeapon', [Sequelize.fn('count', Sequelize.col('BaseWeapon')), 'occurrence']], + where: { + ClientId: ClientId + }, + limit: 1, + order: [ + [Sequelize.literal('occurrence'), 'desc'] + ], + group: ['BaseWeapon'] + }, {transaction: this.transaction}) + + return Weapon.length > 0 ? Weapon[0].dataValues.BaseWeapon : false + } + + async getMostCommonHitLoc(ClientId) { + var HitLoc = await Models.NSMKills.findAll({ + attributes: ['HitLoc', [Sequelize.fn('count', Sequelize.col('HitLoc')), 'occurrence']], + where: { + ClientId: ClientId + }, + limit: 1, + order: [ + [Sequelize.literal('occurrence'), 'desc'] + ], + group: ['HitLoc'] + }, {transaction: this.transaction}) + + return HitLoc.length > 0 ? HitLoc[0].dataValues.HitLoc : false + } + + async getTotalDamage(ClientId) { + var Damage = await Models.NSMKills.findAll({ + attributes: [[Sequelize.fn('sum', Sequelize.col('Damage')), 'totalDamage']], + where: { + TargetId: ClientId + }, + group: ['BaseWeapon'] + }, {transaction: this.transaction}) + + return Damage.length > 0 ? Damage[0].dataValues.totalDamage : false + } + + async getPlayerPersStats(ClientId, stat) + { + var Pers = (await Models.NSMZStats.findAll({ + where: { + ClientId: ClientId + }, + attributes: ['Easter', 'Event', 'ClientId', 'Kills', 'Downs', 'Revives', 'HighestRound', 'Headshots', 'Score', [Sequelize.literal('ROW_NUMBER() over (order by Kills desc)'), 'Rank']], + order: [ + [stat, 'desc'] + ] + })).map(x => x = x.dataValues) + Pers[0].Name = await this.getName(Pers[0].ClientId) + return Pers + } + + async getPlayerKills(ClientId) { + var Kills = await Models.NSMKills.findAll({ + where: { + ClientId: ClientId + } + }, {transaction: this.transaction}) + + return Kills.length + } + + async addEventRecord(Server, Client, Event) { + Server.DB.Models.NSMZStats.update({ + Event: Event, + }, + {where: {ClientId: Client.ClientId}}) + } + + async addEERecord(Server, Client, Easter) { + Server.DB.Models.NSMZStats.update({ + Easter: Easter, + }, + {where: {ClientId: Client.ClientId}}) + } + + async getPlayerStatsLDB(stat) + { + var NSMZStats = await Models.DB.define('NSMZStats') + + if (stat == "Easter") + { + var Event = (await NSMZStats.findAll({ + limit: 5, + offset: 0, + where: { + Easter: { + [Sequelize.Op.gt]: 0 + } + }, + attributes: ['Easter', 'Event', 'ClientId', 'Kills', 'Downs', 'Revives', 'HighestRound', 'Headshots', 'Score', [Sequelize.literal('ROW_NUMBER() over (order by Kills desc)'), 'Rank']], + order: [ + [stat, 'desc'] + ] + })).map(x => x = x.dataValues) + } + else if (stat == "Event") + { + var Event = (await NSMZStats.findAll({ + limit: 5, + offset: 0, + where: { + Event: { + [Sequelize.Op.gt]: 0 + } + }, + attributes: ['Easter', 'Event', 'ClientId', 'Kills', 'Downs', 'Revives', 'HighestRound', 'Headshots', 'Score', [Sequelize.literal('ROW_NUMBER() over (order by Kills desc)'), 'Rank']], + order: [ + [stat, 'desc'] + ] + })).map(x => x = x.dataValues) + } + else if (stat == "Kills") + { + var Event = (await NSMZStats.findAll({ + limit: 5, + offset: 0, + where: { + Kills: { + [Sequelize.Op.gt]: 0 + } + }, + attributes: ['Easter', 'Event', 'ClientId', 'Kills', 'Downs', 'Revives', 'HighestRound', 'Headshots', 'Score', [Sequelize.literal('ROW_NUMBER() over (order by Kills desc)'), 'Rank']], + order: [ + [stat, 'desc'] + ] + })).map(x => x = x.dataValues) + } + else if (stat == "Downs") + { + var Event = (await NSMZStats.findAll({ + limit: 5, + offset: 0, + where: { + Downs: { + [Sequelize.Op.gt]: 0 + } + }, + attributes: ['Easter', 'Event', 'ClientId', 'Kills', 'Downs', 'Revives', 'HighestRound', 'Headshots', 'Score', [Sequelize.literal('ROW_NUMBER() over (order by Kills desc)'), 'Rank']], + order: [ + [stat, 'desc'] + ] + })).map(x => x = x.dataValues) + } + else if (stat == "Revives") + { + var Event = (await NSMZStats.findAll({ + limit: 5, + offset: 0, + where: { + Revives: { + [Sequelize.Op.gt]: 0 + } + }, + attributes: ['Easter', 'Event', 'ClientId', 'Kills', 'Downs', 'Revives', 'HighestRound', 'Headshots', 'Score', [Sequelize.literal('ROW_NUMBER() over (order by Kills desc)'), 'Rank']], + order: [ + [stat, 'desc'] + ] + })).map(x => x = x.dataValues) + } + else if (stat == "HighestRound") + { + var Event = (await NSMZStats.findAll({ + limit: 5, + offset: 0, + where: { + HighestRound: { + [Sequelize.Op.gt]: 0 + } + }, + attributes: ['Easter', 'Event', 'ClientId', 'Kills', 'Downs', 'Revives', 'HighestRound', 'Headshots', 'Score', [Sequelize.literal('ROW_NUMBER() over (order by Kills desc)'), 'Rank']], + order: [ + [stat, 'desc'] + ] + })).map(x => x = x.dataValues) + } + else if (stat == "Headshots") + { + var Event = (await NSMZStats.findAll({ + limit: 5, + offset: 0, + where: { + Headshots: { + [Sequelize.Op.gt]: 0 + } + }, + attributes: ['Easter', 'Event', 'ClientId', 'Kills', 'Downs', 'Revives', 'HighestRound', 'Headshots', 'Score', [Sequelize.literal('ROW_NUMBER() over (order by Kills desc)'), 'Rank']], + order: [ + [stat, 'desc'] + ] + })).map(x => x = x.dataValues) + } + else if (stat == "Score") + { + var Event = (await NSMZStats.findAll({ + limit: 5, + offset: 0, + where: { + Score: { + [Sequelize.Op.gt]: 0 + } + }, + attributes: ['Easter', 'Event', 'ClientId', 'Kills', 'Downs', 'Revives', 'HighestRound', 'Headshots', 'Score', [Sequelize.literal('ROW_NUMBER() over (order by Kills desc)'), 'Rank']], + order: [ + [stat, 'desc'] + ] + })).map(x => x = x.dataValues) + } + + + + + + + + for (var i = 0; i < Event.length; i++) { + Event[i].Name = await this.getName(Event[i].ClientId) + } + return Event + } + async getPlayerDeaths(ClientId) { + + var Deaths = await Models.NSMKills.findAll({ + where: { + TargetId: ClientId + } + }, {transaction: this.transaction}) + + return Deaths.length + } + + async getOwner() { + + var Owner = await Models.NSMClients.findAll({ + where: { + PermissionLevel: 5 + } + }, {transaction: this.transaction}) + + return Owner.length > 0 ? Owner[0].dataValues : false + } + async getClientByName(Name, Limit = 50) { + var _Clients = await Models.NSMConnections.findAll({ + group: ['ClientId'], + order: [ + ['Date', 'desc'] + ], + limit: Limit, + where: { + Name: { + [Sequelize.Op.like]: `%${Name.toLocaleLowerCase()}%` + } + } + }, {transaction: this.transaction}) + var Clients = [] + for (var i = 0; i < _Clients.length; i++) { + var Client = await this.getClient(_Clients[i].dataValues.ClientId) + Client.Name = _Clients[i].dataValues.Name + Client.IPAddress = _Clients[i].dataValues.IPAddress + Clients.push(Client) + } + return Clients + } + + async clearReports() { + await Models.NSMReports.update( + { Active: false }, + { where: { } }, {transaction: this.transaction} + ) + } + + async getActiveReports() { + return await Models.NSMReports.findAll({ + where: { + Active: true, + }, + }, {transaction: this.transaction}) + } + + async addReport(OriginId, TargetId, Reason) { + await Models.NSMReports.build({OriginId, TargetId, Reason}, {transaction: this.transaction}).save() + } + + async logActivity(Origin, Type, Description) { + await Models.NSMAudit.build({ + Origin, + Type, + Description + }, {transaction: this.transaction}).save() + // await this.transaction.commit() + } + + async getAudit(pageNumber, limit) { + var Audit = await Models.NSMAudit.findAll({ + order: [ + ['Date', 'desc'] + ], + limit: limit, + offset: pageNumber * limit, + }, {transaction: this.transaction}) + Audit.map(x => x = x.dataValues) + for (var i = 0; i < Audit.length; i++) { + try { + var Name = this.clientCache[parseInt(Audit[i].Origin.substr(1))] ? this.clientCache[parseInt(Audit[i].Origin.substr(1))].Name : (await this.getClient(Audit[i].Origin.substr(1))).Name + } + catch (e) { + Audit[i] = null + continue + } + Audit[i].Origin = { + Name: Audit[i].Origin.match(/\@([0-9]+)/g) ? Name : Audit[i].Origin, + ClientId: Audit[i].Origin.match(/\@([0-9]+)/g) ? Audit[i].Origin.substr(1) : null + } + } + return Audit + } + + async getClientLevel(ClientId) { + + var Level = await Models.NSMClients.findAll({ + arguments: ['PermissionLevel'], + where: { + ClientId: ClientId + } + }, {transaction: this.transaction}) + + return Level[0].dataValues.PermissionLevel + } + + async unbanClient(TargetId, OriginId, Reason) { + var Aliases = [{ ClientId: TargetId, OriginId: TargetId }] + + Aliases = Aliases.concat(await this.getAliases(TargetId)) + + var count = 0 + + for (var i = 0; i < Aliases.length; i++) { + var Alias = Aliases[i] + + var result = await Models.NSMPenalties.update( + { Active: false }, + { where: { + [Sequelize.Op.or]: [ + { TargetId: Alias.ClientId }, + { TargetId: Alias.OriginId } + ], + Active: true, + PenaltyType: { + [Sequelize.Op.not]: 'PENALTY_UNBAN' + } + }, raw: true }, + {transaction: this.transaction} + ) + + count += parseInt(result[0]) + } + + count > 0 && await Models.NSMPenalties.build({ + TargetId, + OriginId, + PenaltyType: 'PENALTY_UNBAN', + Duration: 0, + Reason: Reason + }, {transaction: this.transaction}) + + return count + } + + async getClient(ClientId) { + if (!ClientId) return false + + if (ClientId == 1) { + return { + Name: 'Node Server Manager', + ClientId: 1, + PermissionLevel: Permissions.Levels['ROLE_MANAGER'], + Guid: 'node', + IPAddress: '127.0.0.1', + Settings: await this.getClientSettings(1) + } + } + + var Client = await Models.NSMClients.findAll({ + where: { + ClientId: ClientId + } + }, {transaction: this.transaction}) + + var Connection = await Models.NSMConnections.findAll({ + order: [ + ['Date', 'desc'] + ], + limit: 1, + where: { + ClientId: ClientId + } + }, {transaction: this.transaction}) + + if (Connection.length == 0) return false + + delete Client[0].dataValues.Password + + var Client = {...Client[0].dataValues, ...Connection[0].dataValues} + + Client.Settings = await this.getClientSettings(ClientId) + + this.clientCache[parseInt(ClientId)] = Client + + return Client + } + + async addPenalty(PenaltyMeta) { + var Aliases = await this.getAliases(PenaltyMeta.TargetId) + + if (PenaltyMeta.PenaltyType != 'PENALTY_KICK') { + Aliases.forEach(async Alias => { + // terrible but need this asap + + if (Alias.OriginId != PenaltyMeta.TargetId) { + await Models.NSMPenalties.build({ ...PenaltyMeta, ...{ TargetId: Alias.OriginId }}, {transaction: this.transaction}).save() + } + + if (Alias.ClientId != PenaltyMeta.TargetId) { + await Models.NSMPenalties.build({ ...PenaltyMeta, ...{ TargetId: Alias.ClientId }}, {transaction: this.transaction}).save() + } + }) + } + + var Penalty = await Models.NSMPenalties.build(PenaltyMeta, {transaction: this.transaction}).save() + + return Penalty.dataValues + } + + async setLevel(Player, Level) { + Models.NSMClients.update( + { PermissionLevel: Level }, + { where: { ClientId: Player.ClientId } } + , {transaction: this.transaction}) + // await this.transaction.commit() + } + + async getAllPenalties(ClientId = null) { + var where = ClientId ? { + where: { + TargetId: ClientId, + } + } : null + + if (ClientId) { + var Aliases = await this.getAliases(ClientId) + var allPenalties = [] + + Aliases.forEach(async Alias => { + var Penalties = await Models.NSMPenalties.findAll({ + where: Sequelize.or( + { TargetId: Alias.ClientId }, + { TargetId: Alias.OriginId } + ), + }, {transaction: this.transaction}) + + for (var i = 0; i < Penalties.length; i++) { + Penalties[i] = Penalties[i].dataValues + } + + allPenalties = allPenalties.concat(Penalties) + }) + + var Penalties = await Models.NSMPenalties.findAll({ + where: { + TargetId: ClientId + } + }, {transaction: this.transaction}) + + for (var i = 0; i < Penalties.length; i++) { + Penalties[i] = Penalties[i].dataValues + } + + allPenalties = allPenalties.concat(Penalties) + + return allPenalties + } + + var Penalties = await Models.NSMPenalties.findAll(where, {transaction: this.transaction}) + + for (var i = 0; i < Penalties.length; i++) { + Penalties[i] = Penalties[i].dataValues + } + + return Penalties + } + + async getStats(pageNumber, limit, sort) { + try { + var Stats = await Models.NSMPlayerStats.findAll({ + limit: limit, + order: [ + [sort, 'desc'] + ], + offset: limit * pageNumber + }, {transaction: this.transaction}) + } + catch (e) { + var Stats = await Models.NSMPlayerStats.findAll({ + limit: limit, + order: [ + ['Kills', 'desc'] + ], + offset: limit * pageNumber + }, {transaction: this.transaction}) + } + + for (var i = 0; i < Stats.length; i++) { + Stats[i] = Stats[i].dataValues + Stats[i].Client = (await this.getClient(Stats[i].ClientId)) + } + return Stats + } + + async getClientMeta(ClientId) { + var Meta = { + MostUsed: await this.getMostUsedWeapon(ClientId), + HitLoc: await this.getMostCommonHitLoc(ClientId), + Damage: await this.getTotalDamage(ClientId) + } + return Meta + } + + async getClientField(ClientId, Field) { + var Fields = await Models.NSMClients.findAll({ + where: { + ClientId: ClientId + } + }, {transaction: this.transaction}) + + return Fields.length > 0 ? Fields[0].dataValues[Field] : false + } + + async setClientField(ClientId, Field, Value) { + Models.NSMClients.update( + { [Field] : Value}, + {where: {ClientId: ClientId}}, {transaction: this.transaction}) + // await this.transaction.commit() + } + + async getTokenHash(ClientId) { + var Token = await Models.NSMTokens.findAll({ + where: { + ClientId: ClientId + } + }, {transaction: this.transaction}) + return Token.length > 0 ? Token[0].dataValues : false + } + + async createToken(ClientId, Token) { + bcrypt.hash(Token, 10, async (err, hash) => { + await Models.NSMTokens.destroy({ + where: { + ClientId: ClientId + } + }, {transaction: this.transaction}) + await Models.NSMTokens.build({ + ClientId: ClientId, + Token: hash + }, {transaction: this.transaction}).save() + // await this.transaction.commit() + }) + } + + async getPlayerStatsTotal(ClientId) { + if (this.cache[`statsTotal_${ClientId}`]) return this.cache[`statsTotal_${ClientId}`] + + var Stats = await Models.NSMPlayerStats.findAll({ + attributes: ['Kills', 'Deaths', 'PlayedTime', [Sequelize.literal('max(Performance, 0)'), 'Performance'], 'TotalPerformance'], + where: { + ClientId: ClientId + }, + raw: true + }, {transaction: this.transaction}) + + if (Stats.length) { + this.cache[`statsTotal_${ClientId}`] = Stats[0] + return Stats[0] + } + return Stats.length > 0 ? Stats[0].dataValues : false + } + + async getGlobalStats() { + if (this.cache[`globalStats`]) return this.cache[`globalStats`] + + var totalKills = (await Models.NSMPlayerStats.findAll({ + attributes: [[Sequelize.fn('sum', Sequelize.col('Kills')), 'totalKills']], + }))[0].dataValues.totalKills + + var totalPlayedTime = (await Models.NSMPlayerStats.findAll({ + attributes: [[Sequelize.fn('sum', Sequelize.col('PlayedTime')), 'totalPlayedTime']], + }))[0].dataValues.totalPlayedTime + + this.cache[`globalStats`] = {totalKills, totalPlayedTime} + + return this.cache[`globalStats`] + } + + async getPlayerStats(ClientId) { + if (this.cache[`stats_${ClientId}`]) return this.cache[`stats_${ClientId}`] + + var Player = await this.getClient(ClientId) + if (!Player) return false + + var Stats = { + Kills: await this.getPlayerKills(ClientId), + Deaths: await this.getPlayerDeaths(ClientId), + Player: Player + } + + this.cache[`stats_${ClientId}`] = Stats + return Stats + } + + async addStatRecord(ClientId, TotalPerformance, Performance) { + return await Models.NSMPlayerStatHistory.build({ ClientId, TotalPerformance, Performance }, {transaction: this.transaction}).save() + } + + async getTopZStats(page, limit) { + if (this.cache[`zstats_${page};${limit}`]) return this.cache[`zstats_${page};${limit}`] + + var NSMZStats = await Models.DB.define('NSMZStats') + var Stats = (await NSMZStats.findAll({ + limit: limit, + offset: page * limit, + where: { + HighestRound: { + [Sequelize.Op.gt]: 0 + } + }, + attributes: ['ClientId', 'Kills', 'Downs', 'Revives', 'HighestRound', 'Headshots', 'Score', [Sequelize.literal('ROW_NUMBER() over (order by Kills desc)'), 'Rank']], + order: [ + ['Kills', 'desc'] + ] + })).map(x => x = x.dataValues) + for (var i = 0; i < Stats.length; i++) { + Stats[i].Name = await this.getName(Stats[i].ClientId) + } + this.cache[`zstats_${page};${limit}`] = Stats + + return Stats + } + + async getStatHistory(page, limit) { + if (this.cache[`statHistory_${page};${limit}`]) return this.cache[`statHistory_${page};${limit}`] + + var Stats = (await Models.NSMPlayerStats.findAll({ + limit: limit, + attributes: ['ClientId', 'Kills', 'Deaths', [Sequelize.literal('max(Performance, 0)'), 'Performance'], 'TotalPerformance', 'PlayedTime', 'Id', [Sequelize.literal('ROW_NUMBER() over (order by Performance desc)'), 'Rank']], + where: { + [Sequelize.Op.and]: [ + Sequelize.literal('Kills+Deaths >= 50') + ], + PlayedTime: { + [Sequelize.Op.gte]: 120 + } + }, + order: [ + ['Performance', 'desc'] + ], + offset: limit * page + }, {transaction: this.transaction})).map(x => x = x.dataValues) + + for (var i = 0; i < Stats.length; i++) { + Stats[i].History = (await Models.NSMPlayerStatHistory.findAll({ + where: {ClientId: Stats[i].ClientId}, + limit: 25, + attributes: [[Sequelize.literal('max(Performance, 0)'), 'Performance'], 'Date'], + order: [ + ['Date', 'desc'] + ] + })).map(s => s = {x: i, y: s.Performance}) + } + + this.cache[`statHistory_${page};${limit}`] = Stats + + return Stats + } + + async getClientByGuid(Guid) { + var result = await this.getClientId(Guid) + return result ? await this.getClient(result) : false + } + + async getClientId(Guid) { + + var result = await Models.NSMClients.findAll({ + attributes: ['ClientId'], + where: { + Guid: Guid + } + }, {transaction: this.transaction}) + + return result.length > 0 ? result[0].dataValues.ClientId : false + } + + async getAllClients() { + return (await Models.NSMClients.findAll({ + attributes: [[Sequelize.fn('max', Sequelize.literal('_rowid_')), 'totalClients']], + }))[0].dataValues.totalClients + } + + async getLastConnections() { + return await Models.NSMClients.findAll({ + where: { + LastConnection: { + [Sequelize.Op.lt]: new Date(), + [Sequelize.Op.gt]: new Date(new Date().setDate(new Date().getDate() - 1)) + } + }, + group: ['ClientId'], + raw: true + }) + } + + async getLastUniques() { + return await Models.NSMClients.findAll({ + where: { + FirstConnection: { + [Sequelize.Op.lt]: new Date(), + [Sequelize.Op.gt]: new Date(new Date().setDate(new Date().getDate() - 1)) + } + }, + group: ['ClientId'], + raw: true + }) + } + + async getAllConnections(ClientId) { + var Connections = await Models.NSMConnections.findAll({ + where: { + ClientId + } + }, {transaction: this.transaction}) + + return Connections.length > 0 ? Connections : false + } + + async updateLastConnection(ClientId) { + Models.NSMClients.update( + { 'LastConnection' : Sequelize.literal(`datetime('now')`)}, + {where: {ClientId}}, {transaction: this.transaction}) + } + + async getClientsByIp(IPAddress) { + if (!IPAddress) { + return [] + } + + var Connections = await Models.NSMConnections.findAll({ + where: { + IPAddress + }, + group: ['ClientId'], + raw: true + }) + + return Connections + } + + async getAliases(ClientId) { + var Aliases = await Models.NSMAliases.findAll({ + where: Sequelize.or( + { ClientId: ClientId }, + { OriginId: ClientId } + ), + raw: true + }) + + return Aliases + } + + async addAlias(OriginId, ClientId) { + try { + await Models.NSMAliases.build({ + OriginId, + ClientId + }, {transaction: this.transaction}).save() + } + catch (e) {} + } + + async logConnection(ePlayer) { + var IPAddress = ePlayer.IPAddress ? ePlayer.IPAddress.split(':')[0] : null + + var ClientId = await this.getClientId(ePlayer.Guid) + + var Connections = await this.getClientsByIp(IPAddress) + Connections.forEach(Connection => { + if (Connection.ClientId != ePlayer.ClientId) { + this.addAlias(ePlayer.ClientId, Connection.ClientId) + } + }) + + this.updateLastConnection(ClientId) + + var Connection = await Models.NSMConnections.build({ + ClientId: ClientId, + IPAddress: IPAddress, + Guid: ePlayer.Guid, + Name: ePlayer.Name + }, {transaction: this.transaction}).save() + + return Connection.dataValues + } + async logKill(AttackerId, TargetId, Attack) { + var Kill = await Models.NSMKills.build({ + ClientId: AttackerId, + TargetId: TargetId, + Weapon: Attack.Weapon, + MOD: Attack.MOD, + HitLoc: Attack.HitLoc, + Damage: Attack.Damage, + BaseWeapon: Attack.BaseWeapon + }, {transaction: this.transaction}).save() + // await this.transaction.commit() + return Kill.dataValues + } + + async getAllMessages(From, page, limit) { + if (From) { + var Messages = await Models.NSMMessages.findAll({ + where: { + OriginId: From + }, + order: [ + ['Date', 'desc'] + ], + }, {transaction: this.transaction}) + } else { + var Messages = await Models.NSMMessages.findAll({ + order: [ + ['Date', 'desc'] + ], + limit: limit, + offset: page * limit, + }, {transaction: this.transaction}) + } + for (var i = 0; i < Messages.length; i++) { + Messages[i] = Messages[i].dataValues + } + return Messages + } + + async isBanned(ClientId) { + var playerPenalties = await this.getAllPenalties(ClientId) + for (var i = 0; i < playerPenalties.length; i++) { + if (!playerPenalties[i].Active) continue + switch (playerPenalties[i].PenaltyType) { + case 'PENALTY_PERMA_BAN': + return { + Banned: true, + Type: playerPenalties[i].PenaltyType, + Duration: playerPenalties[i].Duration, + Reason: playerPenalties[i].Reason + } + case 'PENALTY_TEMP_BAN': + var dateDiff = (new Date(playerPenalties[i].Date) - new Date()) / 1000 + if (dateDiff + playerPenalties[i].Duration > 0) { + return { + Banned: true, + Type: playerPenalties[i].PenaltyType, + Duration: playerPenalties[i].Duration, + Reason: playerPenalties[i].Reason + } + } + break + } + } + return { + Banned: false + } + } + + async isMuted(ClientId) { + var Penalties = await Models.NSMPenalties.findAll({ + where: { + TargetId: ClientId, + PenaltyType: 'PENALTY_MUTE', + Active: true + }, + raw: true + }) + + return Penalties + } + + async getMessageCount(ClientId) { + return await Models.NSMMessages.count({where: {OriginId: ClientId}}) + } + + async getMessages(From, pageNumber, limit) { + if (From) { + var Messages = await Models.NSMMessages.findAll({ + where: { + OriginId: From + }, + order: [ + ['Date', 'desc'] + ], + limit: limit, + offset: pageNumber * limit, + }, {transaction: this.transaction}) + var Penalties = await Models.NSMPenalties.findAll({ + where: Sequelize.or({ TargetId: From}, {OriginId: From}), + order: [ + ['Date', 'desc'] + ], + limit: limit, + offset: pageNumber * limit, + }, {transaction: this.transaction}) + } else { + var Messages = await Models.NSMMessages.findAll({ + order: [ + ['Date', 'desc'] + ], + limit: limit, + offset: pageNumber * limit, + }, {transaction: this.transaction}) + var Penalties = await Models.NSMPenalties.findAll({ + order: [ + ['Date', 'desc'] + ], + limit: limit, + offset: pageNumber * limit, + }, {transaction: this.transaction}) + } + + for (var i = 0; i < Penalties.length; i++) { + Penalties[i] = Penalties[i].dataValues + Penalties[i].Type = 'Penalty' + Penalties[i].Origin = { ClientId: Penalties[i].OriginId, Name: await this.getName(Penalties[i].OriginId) } + Penalties[i].Target = { ClientId: Penalties[i].TargetId, Name: await this.getName(Penalties[i].TargetId) } + } + + for (var i = 0; i < Messages.length; i++) { + Messages[i] = Messages[i].dataValues + Messages[i].Type = 'Message' + } + + Messages = Messages.concat(Penalties) + + Messages.sort((a,b) => { + return (new Date(b.Date) - new Date(a.Date)) + }) + + return Messages + } + + async getName(ClientId) { + if (ClientId == 1) return 'Node Server Manager' + if (this.clientCache.find(x => x && x.ClientId == ClientId)) + return this.clientCache.find(x => x && x.ClientId == ClientId).Name + else { + var Name = (await Models.NSMConnections.findAll({ + where: { + ClientId + }, + order: [ + ['Date', 'desc'] + ], + attributes: ['Name'] + })) + if (Name.length > 0) { + this.clientCache[ClientId] = {ClientId: ClientId, Name: Name[0].dataValues.Name } + return Name[0].dataValues.Name + } + } + } + + async incrementStat(ClientId, Increment, Stat) { + Models.NSMPlayerStats.update( + { [Stat] : Sequelize.literal(`${Stat} + ${Increment}`)}, + {where: {ClientId: ClientId}}, {transaction: this.transaction}) + // await this.transaction.commit() + } + + async editStat(ClientId, Value, Stat) { + Models.NSMPlayerStats.update( + { [Stat] : Value}, + {where: {ClientId: ClientId}}, {transaction: this.transaction}) + // await this.transaction.commit() + } + + async editStats(ClientId, Stats) { + Models.NSMPlayerStats.update( + { 'Kills': Stats.Kills, 'Deaths': Stats.Deaths, 'Performance': Stats.Performance, 'TotalPerformance': Stats.TotalPerformance}, + {where: {ClientId: ClientId}}, {transaction: this.transaction}) + } + + async resetStats(ClientId) { + await Models.NSMPlayerStats.update({ + 'Kills': 0, + 'Deaths': 0, + 'Performance': 100, + 'TotalPerformance': 100 + }, + { + where: { + ClientId + } + }, { transaction: this.transaction }) + + this.cache[`statsTotal_${ClientId}`] = undefined + } + + async logMessage(ClientId, Name, Hostname, Message) { + var Kill = await Models.NSMMessages.build({ + OriginId: ClientId, + Message, + Name, + Hostname + }, {transaction: this.transaction}).save() + // await this.transaction.commit() + return Kill.dataValues + } +} + +module.exports = Database \ No newline at end of file diff --git a/node-server-manager/Lib/MasterServer.js b/node-server-manager/Lib/MasterServer.js new file mode 100644 index 0000000..9afdf03 --- /dev/null +++ b/node-server-manager/Lib/MasterServer.js @@ -0,0 +1,151 @@ +const ws = require('ws') +const https = require('https') +const { machineId } = require('node-machine-id') +const Utils = new (require('../Utils/Utils.js'))() + +class MasterServer { + constructor(Managers) { + this.Managers = Managers + this.interval = 60 * 1000 * 1 + this.hostname = 'master.fed0001.xyz' + + } + async init() { + this.DB = this.Managers[0].Server.DB + + this.apikey = await this.getApiKey() + + this.connect() + } + async connect() { + var master = new ws(`wss://${this.hostname}?key=${this.apikey}`) + + var interval = null + var ping = null + + master.onopen = async () => { + console.log(`Connected to master server \x1b[32m${this.hostname}\x1b[0m`) + + interval = setInterval(() => { + try { + this.heartbeat(master) + } + catch (e) { + console.log(e) + } + }, this.interval) + + ping = setInterval(() => { + master.send() + }, 5000) + } + + master.onerror = async (e) => { + master.close() + } + + master.onclose = async (e) => { + clearInterval(interval) + clearInterval(ping) + + console.log('Connection to master server lost, reconnecting...') + + setTimeout(() => { + this.connect(this.hostname, this.apikey) + }, 5000) + } + + master.onmessage = async (msg) => { + try { + if (!Utils.isJson(msg)) { + switch (msg) { + + } + + return + } + + var event = JSON.parse(msg) + + switch (event.type) { + case 'bt': + this.Managers.forEach(Manager => { + Manager.Server.Broadcast(event.message) + }) + break + } + } + catch (e) {} + } + } + async makeRequest(method, hostname, path, port, data) { + return new Promise((resolve, reject) => { + let options = { + host: hostname, + port: port, + path: path, + method: method, + headers: { + 'Content-Type': 'application/json' + } + } + const req = https.request(options, res => { + res.on('data', data => { + resolve(data.toString()) + }) + }) + + req.on('error', error => { + reject(error) + }) + + req.write(JSON.stringify(data)) + req.end() + }) + } + + async getApiKey() { + let id = await machineId() + let endpoint = '/api/key' + let key = JSON.parse(await this.makeRequest('POST', this.hostname, endpoint, 443, {action: 'get', id })) + + return key.key + } + + heartbeat(webSocket) { + var servers = [] + this.Managers.filter(Manager => Manager.Server.Rcon.isRunning).forEach(Manager => { + if (!Manager.Server.Rcon.isRunning) return + + var server = {} + var clients = [] + Manager.Server.Clients.forEach(Client => { + if (!Client) return + clients.push({ + name: Client.Name, + guid: Client.Guid + }) + }) + + server.dvars = { + mapname: Manager.Server.Mapname, + gametype: Manager.Server.Gametype, + gamename: Manager.Server.Gamename, + hostname: Manager.Server.HostnameRaw, + maxclients: Manager.Server.MaxClients + } + + server.ip = Manager.Server.externalIP + server.port = Manager.Server.PORT + server.clients = clients + + servers.push(server) + }) + + var heartbeat = { type: 'heartbeat', servers } + + servers.length && webSocket.send(JSON.stringify(heartbeat)) + } +} + +module.exports = MasterServer \ No newline at end of file diff --git a/node-server-manager/Lib/Models/NSMAliases.js b/node-server-manager/Lib/Models/NSMAliases.js new file mode 100644 index 0000000..bfe0a3b --- /dev/null +++ b/node-server-manager/Lib/Models/NSMAliases.js @@ -0,0 +1,37 @@ +module.exports = (sequelize, DataTypes) => { + const NSMAliases = sequelize.define('NSMAliases', + { + Id: { + type: DataTypes.INTEGER, + autoIncrement: true, + allowNull: false, + primaryKey: true + }, + ClientId: { + type: DataTypes.INTEGER, + allowNull: false, + references: { + model: 'NSMClients', + key: 'ClientId' + } + }, + OriginId: { + type: DataTypes.INTEGER, + allowNull: false, + references: { + model: 'NSMClients', + key: 'ClientId' + } + } + }, { + timestamps: false, + uniqueKeys: { + AliasUnique: { + fields: ['ClientId', 'OriginId'] + } + } + }) + + NSMAliases.sync() + return NSMAliases +} \ No newline at end of file diff --git a/node-server-manager/Lib/Models/NSMAudit.js b/node-server-manager/Lib/Models/NSMAudit.js new file mode 100644 index 0000000..f3ef2b6 --- /dev/null +++ b/node-server-manager/Lib/Models/NSMAudit.js @@ -0,0 +1,35 @@ +module.exports = (sequelize, DataTypes) => { + const NSMAudit = sequelize.define('NSMAudit', + { + Id: { + type: DataTypes.INTEGER, + autoIncrement: true, + allowNull: false, + primaryKey: true + }, + Origin: { + type: DataTypes.INTEGER, + allowNull: false, + }, + Type: { + type: DataTypes.TEXT, + allowNull: true, + defaultValue: null, + }, + Description: { + type: DataTypes.TEXT, + allowNull: true, + defaultValue: null, + }, + Date: { + type: DataTypes.DATE, + allowNull: false, + defaultValue: DataTypes.literal('CURRENT_TIMESTAMP'), + } + }, { + timestamps: false + }) + NSMAudit.sync() + + return NSMAudit +} \ No newline at end of file diff --git a/node-server-manager/Lib/Models/NSMClients.js b/node-server-manager/Lib/Models/NSMClients.js new file mode 100644 index 0000000..a44b288 --- /dev/null +++ b/node-server-manager/Lib/Models/NSMClients.js @@ -0,0 +1,51 @@ +module.exports = (sequelize, DataTypes) => { + const NSMClients = sequelize.define('NSMClients', + { + ClientId: { + type: DataTypes.INTEGER, + autoIncrement: true, + allowNull: false, + primaryKey: true + }, + Description: { + type: DataTypes.TEXT, + allowNull: true, + defaultValue: null, + }, + Password: { + type: DataTypes.TEXT, + allowNull: true, + defaultValue: null, + }, + Secret: { + type: DataTypes.TEXT, + allowNull: true, + defaultValue: null, + }, + Guid: { + type: DataTypes.TEXT, + allowNull: false, + unique: true + }, + PermissionLevel: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: 0, + }, + FirstConnection: { + type: DataTypes.DATE, + allowNull: false, + defaultValue: DataTypes.literal('CURRENT_TIMESTAMP'), + }, + LastConnection: { + type: DataTypes.DATE, + allowNull: false, + defaultValue: DataTypes.literal('CURRENT_TIMESTAMP'), + } + }, { + timestamps: false + }) + NSMClients.sync() + + return NSMClients +} \ No newline at end of file diff --git a/node-server-manager/Lib/Models/NSMConnections.js b/node-server-manager/Lib/Models/NSMConnections.js new file mode 100644 index 0000000..3da2368 --- /dev/null +++ b/node-server-manager/Lib/Models/NSMConnections.js @@ -0,0 +1,41 @@ +module.exports = (sequelize, DataTypes) => { + const NSMConnections = sequelize.define('NSMConnections', + { + Id: { + type: DataTypes.INTEGER, + autoIncrement: true, + allowNull: false, + primaryKey: true + }, + ClientId: { + type: DataTypes.INTEGER, + allowNull: false, + references: { + model: 'NSMClients', + key: 'ClientId' + } + }, + Name: { + type: DataTypes.TEXT, + allowNull: false, + }, + Guid: { + type: DataTypes.TEXT, + allowNull: false, + }, + IPAddress: { + type: DataTypes.TEXT, + allowNull: true, + }, + Date: { + type: DataTypes.DATE, + allowNull: false, + defaultValue: DataTypes.literal('CURRENT_TIMESTAMP'), + } + }, { + timestamps: false + }) + + NSMConnections.sync() + return NSMConnections +} \ No newline at end of file diff --git a/node-server-manager/Lib/Models/NSMKills.js b/node-server-manager/Lib/Models/NSMKills.js new file mode 100644 index 0000000..eed8805 --- /dev/null +++ b/node-server-manager/Lib/Models/NSMKills.js @@ -0,0 +1,56 @@ +module.exports = (sequelize, DataTypes) => { + const NSMKills = sequelize.define('NSMKills', + { + Id: { + type: DataTypes.INTEGER, + autoIncrement: true, + allowNull: false, + primaryKey: true + }, + ClientId: { + type: DataTypes.INTEGER, + allowNull: false, + references: { + model: 'NSMClients', + key: 'ClientId' + } + }, + TargetId: { + type: DataTypes.INTEGER, + allowNull: false, + references: { + model: 'NSMClients', + key: 'ClientId' + } + }, + BaseWeapon: { + type: DataTypes.TEXT, + allowNull: true, + }, + Weapon: { + type: DataTypes.TEXT, + allowNull: true, + }, + MOD: { + type: DataTypes.TEXT, + allowNull: true, + }, + Damage: { + type: DataTypes.INTEGER, + allowNull: true, + }, + HitLoc: { + type: DataTypes.TEXT, + allowNull: true, + }, + Date: { + type: DataTypes.DATE, + allowNull: false, + defaultValue: DataTypes.literal('CURRENT_TIMESTAMP'), + } + }, { + timestamps: false + }) + NSMKills.sync() + return NSMKills +} \ No newline at end of file diff --git a/node-server-manager/Lib/Models/NSMMessages.js b/node-server-manager/Lib/Models/NSMMessages.js new file mode 100644 index 0000000..387af8c --- /dev/null +++ b/node-server-manager/Lib/Models/NSMMessages.js @@ -0,0 +1,40 @@ +module.exports = (sequelize, DataTypes) => { + const NSMKills = sequelize.define('NSMMessages', + { + Id: { + type: DataTypes.INTEGER, + autoIncrement: true, + allowNull: false, + primaryKey: true + }, + Name: { + type: DataTypes.TEXT, + allowNull: true, + }, + OriginId: { + type: DataTypes.INTEGER, + allowNull: false, + references: { + model: 'NSMClients', + key: 'ClientId' + } + }, + Message: { + type: DataTypes.TEXT, + allowNull: true, + }, + Hostname: { + type: DataTypes.TEXT, + allowNull: true, + }, + Date: { + type: DataTypes.DATE, + allowNull: false, + defaultValue: DataTypes.literal('CURRENT_TIMESTAMP'), + } + }, { + timestamps: false + }) + NSMKills.sync() + return NSMKills +} \ No newline at end of file diff --git a/node-server-manager/Lib/Models/NSMMeta.js b/node-server-manager/Lib/Models/NSMMeta.js new file mode 100644 index 0000000..60fd97d --- /dev/null +++ b/node-server-manager/Lib/Models/NSMMeta.js @@ -0,0 +1,37 @@ +module.exports = (sequelize, DataTypes) => { + const NSMMeta = sequelize.define('NSMMeta', + { + Id: { + type: DataTypes.INTEGER, + autoIncrement: true, + allowNull: false, + primaryKey: true + }, + ClientId: { + type: DataTypes.INTEGER, + allowNull: false, + references: { + model: 'NSMClients', + key: 'ClientId' + } + }, + Key: { + type: DataTypes.TEXT, + allowNull: false, + }, + Value: { + type: DataTypes.TEXT, + allowNull: false, + }, + Date: { + type: DataTypes.DATE, + allowNull: false, + defaultValue: DataTypes.literal('CURRENT_TIMESTAMP'), + } + }, { + timestamps: false + }) + NSMMeta.sync() + + return NSMMeta +} \ No newline at end of file diff --git a/node-server-manager/Lib/Models/NSMPenalties.js b/node-server-manager/Lib/Models/NSMPenalties.js new file mode 100644 index 0000000..d050ff6 --- /dev/null +++ b/node-server-manager/Lib/Models/NSMPenalties.js @@ -0,0 +1,53 @@ +module.exports = (sequelize, DataTypes) => { + const NSMPenalties = sequelize.define('NSMPenalties', + { + Id: { + type: DataTypes.INTEGER, + autoIncrement: true, + allowNull: false, + primaryKey: true + }, + TargetId: { + type: DataTypes.INTEGER, + allowNull: false, + references: { + model: 'NSMClients', + key: 'ClientId' + } + }, + OriginId: { + type: DataTypes.INTEGER, + allowNull: false, + references: { + model: 'NSMClients', + key: 'ClientId' + } + }, + PenaltyType: { + type: DataTypes.TEXT, + allowNull: false + }, + Date: { + type: DataTypes.DATE, + allowNull: false, + defaultValue: DataTypes.literal('CURRENT_TIMESTAMP') + }, + Active: { + type: DataTypes.BOOLEAN, + allowNull: false, + defaultValue: true + }, + Duration: { + type: DataTypes.INTEGER, + allowNull: false + }, + Reason: { + type: DataTypes.TEXT, + allowNull: false + } + }, { + timestamps: false + }) + NSMPenalties.sync() + return NSMPenalties +} \ No newline at end of file diff --git a/node-server-manager/Lib/Models/NSMPlayerStatHistory.js b/node-server-manager/Lib/Models/NSMPlayerStatHistory.js new file mode 100644 index 0000000..294e9b8 --- /dev/null +++ b/node-server-manager/Lib/Models/NSMPlayerStatHistory.js @@ -0,0 +1,39 @@ +module.exports = (sequelize, DataTypes) => { + const NSMPlayerStatHistory = sequelize.define('NSMPlayerStatHistory', + { + Id: { + type: DataTypes.INTEGER, + autoIncrement: true, + allowNull: false, + primaryKey: true + }, + ClientId: { + type: DataTypes.INTEGER, + allowNull: false, + references: { + model: 'NSMClients', + key: 'ClientId' + } + }, + TotalPerformance: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: 100, + }, + Performance: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: 100, + }, + Date: { + type: DataTypes.DATE, + allowNull: false, + defaultValue: DataTypes.literal('CURRENT_TIMESTAMP'), + } + }, { + timestamps: false, + freezeTableName: true + }) + NSMPlayerStatHistory.sync() + return NSMPlayerStatHistory +} \ No newline at end of file diff --git a/node-server-manager/Lib/Models/NSMPlayerStats.js b/node-server-manager/Lib/Models/NSMPlayerStats.js new file mode 100644 index 0000000..d615397 --- /dev/null +++ b/node-server-manager/Lib/Models/NSMPlayerStats.js @@ -0,0 +1,53 @@ +module.exports = (sequelize, DataTypes) => { + const NSMPlayerStats = sequelize.define('NSMPlayerStats', + { + Id: { + type: DataTypes.INTEGER, + autoIncrement: true, + allowNull: false, + primaryKey: true + }, + ClientId: { + type: DataTypes.INTEGER, + allowNull: false, + references: { + model: 'NSMClients', + key: 'ClientId' + } + }, + PlayedTime: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: 0 + }, + Kills: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: 0, + }, + Deaths: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: 0, + }, + TotalPerformance: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: 100, + }, + Performance: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: 100, + }, + Event: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: 0, + } + }, { + timestamps: false + }) + NSMPlayerStats.sync() + return NSMPlayerStats +} \ No newline at end of file diff --git a/node-server-manager/Lib/Models/NSMReports.js b/node-server-manager/Lib/Models/NSMReports.js new file mode 100644 index 0000000..e94299a --- /dev/null +++ b/node-server-manager/Lib/Models/NSMReports.js @@ -0,0 +1,45 @@ +module.exports = (sequelize, DataTypes) => { + const NSMReports = sequelize.define('NSMReports', + { + Id: { + type: DataTypes.INTEGER, + autoIncrement: true, + allowNull: false, + primaryKey: true + }, + OriginId: { + type: DataTypes.INTEGER, + allowNull: false, + references: { + model: 'NSMClients', + key: 'ClientId' + } + }, + TargetId: { + type: DataTypes.INTEGER, + allowNull: false, + references: { + model: 'NSMClients', + key: 'ClientId' + } + }, + Reason: { + type: DataTypes.TEXT, + allowNull: false, + }, + Active: { + type: DataTypes.BOOLEAN, + allowNull: false, + defaultValue: true + }, + Date: { + type: DataTypes.DATE, + allowNull: false, + defaultValue: DataTypes.literal('CURRENT_TIMESTAMP'), + } + }, { + timestamps: false + }) + NSMReports.sync() + return NSMReports +} \ No newline at end of file diff --git a/node-server-manager/Lib/Models/NSMSettings.js b/node-server-manager/Lib/Models/NSMSettings.js new file mode 100644 index 0000000..c9cbe0d --- /dev/null +++ b/node-server-manager/Lib/Models/NSMSettings.js @@ -0,0 +1,35 @@ +module.exports = (sequelize, DataTypes) => { + const NSMSettings = sequelize.define('NSMSettings', + { + ClientId: { + type: DataTypes.INTEGER, + autoIncrement: true, + allowNull: false, + primaryKey: true, + references: { + model: 'NSMClients', + key: 'ClientId' + } + }, + TwoFactor: { + type: DataTypes.BOOLEAN, + allowNull: false, + defaultValue: false + }, + InGameLogin: { + type: DataTypes.BOOLEAN, + allowNull: false, + defaultValue: false + }, + TokenLogin: { + type: DataTypes.BOOLEAN, + allowNull: false, + defaultValue: true + } + }, { + timestamps: false + }) + NSMSettings.sync() + + return NSMSettings +} \ No newline at end of file diff --git a/node-server-manager/Lib/Models/NSMTokens.js b/node-server-manager/Lib/Models/NSMTokens.js new file mode 100644 index 0000000..891d1bb --- /dev/null +++ b/node-server-manager/Lib/Models/NSMTokens.js @@ -0,0 +1,29 @@ +module.exports = (sequelize, DataTypes) => { + const NSMTokens = sequelize.define('NSMTokens', + { + TokenId: { + type: DataTypes.INTEGER, + autoIncrement: true, + allowNull: false, + primaryKey: true + }, + ClientId: { + type: DataTypes.INTEGER, + allowNull: false, + }, + Token: { + type: DataTypes.TEXT, + allowNull: false, + }, + Date: { + type: DataTypes.DATE, + allowNull: false, + defaultValue: DataTypes.literal('CURRENT_TIMESTAMP'), + } + }, { + timestamps: false + }) + NSMTokens.sync() + + return NSMTokens +} \ No newline at end of file diff --git a/node-server-manager/Lib/NodeLogServer.js b/node-server-manager/Lib/NodeLogServer.js new file mode 100644 index 0000000..d5eedbb --- /dev/null +++ b/node-server-manager/Lib/NodeLogServer.js @@ -0,0 +1,94 @@ +const path = require('path') +const configuration = require(path.join(__dirname, `../Configuration/NLSConfiguration.json`).toString()) +const ws = require('ws') +const fs = require('fs') +const https = require('https') +const http = require('http') +const spawn = require('child_process').spawn +const Tail = require('tail').Tail + +class NodeLogServer { + constructor(config) { + this.logFile = config.logFile + this.bindPort = config.bindPort + try { + this.ssl = { + key: fs.readFileSync(config.ssl.key), + cert: fs.readFileSync(config.ssl.cert) + } + } catch (e) { + this.ssl = null + console.warn('Unable to load SSL certificate from configuration, starting server without SSL is not recommended, provide a valid certificate if possible') + } + + this.key = config.key + + this.init() + } + init() { + try { + const server = this.ssl ? https.createServer(this.ssl) : http.createServer() + const socket = new ws.Server({ server }) + + var getParams = (url) => { + var queryDict = {} + url.substr(1).split("&").forEach(function(item) {queryDict[item.split("=")[0]] = item.split("=")[1]}) + return queryDict; + } + + var filePath = path.resolve(this.logFile) + + if (!fs.existsSync(filePath)) { + console.log(`Warning: log file "${filePath}" doesn't exist\nMake sure you selected the right file in Configuration/NLSConfiguration.json Servers -> LOGFILE\n`) + return + } + + server.listen(this.bindPort, () => { + console.log(`Server listening on port ${this.bindPort}`) + }) + + socket.authorizedClients = [] + + socket.Broadcast = (msg) => { + socket.authorizedClients.forEach(client => { + client.send(msg) + }) + } + + socket.on('connection', (conn, req) => { + var params = getParams(req.url.substr(1)) + + if (params.key != this.key) { + console.log(`Rejecting connection from ${req.socket.remoteAddress}`) + conn.close() + return + } + + console.log(`Accepting connection from ${req.socket.remoteAddress}`) + socket.authorizedClients.push(conn) + }) + + if (process.platform == 'win32') { + var tail = spawn(`powershell`, ['-command', 'get-content', '-wait', '-Tail 0', `"${filePath}"`]) + tail.stdout.on('data', (data) => { + socket.Broadcast(data.toString()) + }) + return + } + + var tail = new Tail(filePath) + tail.watch() + + tail.on('line', async (data) => { + socket.Broadcast(data) + }) + } + catch (e) { + console.log(`Log server failed to start: ${e.toString()}`) + } + } +} + +configuration.Servers.forEach(config => { + new NodeLogServer(config) +}) \ No newline at end of file diff --git a/node-server-manager/Lib/NodeServerManager.js b/node-server-manager/Lib/NodeServerManager.js new file mode 100644 index 0000000..68b14b0 --- /dev/null +++ b/node-server-manager/Lib/NodeServerManager.js @@ -0,0 +1,184 @@ +process.on('uncaughtException', (err) => { + console.log('Caught exception: ' + err + err.stack) +}) + +const fs = require('fs') +const path = require('path') +const configured = fs.existsSync(path.join(__dirname, `../Configuration/NSMConfiguration.json`)) + +process.env.LOCALE = 'en' + +const EventEmitter = require('events') +const ConfigMaker = require('./ConfigMaker.js') + +var Info = { + Author: 'fed', + Version: require('child_process').execSync('git rev-parse HEAD').toString().trim().substr(0, 6) +} + +var Managers = [] +var Id = 0 + +class Logger { + constructor(dirName, fileName) { + this.fileName = fileName + this.dirName = dirName + } + writeLn(data) { + if (!fs.existsSync(this.dirName)) { + fs.mkdirSync(this.dirName) + } + + data = `[Log] ${new Date()} - - ${data}\n` + fs.appendFile(path.join(this.dirName, this.fileName), data, (err) => { + if (err) console.log(err) + }) + } +} + +function COD2BashColor(string) { + return string.replace(new RegExp(/\^([0-9]|\:|\;)/g, 'g'), `\x1b[3$1m`) +} + +console._log = (string) => { + console.log(`${COD2BashColor(string)}\x1b[0m`) +} + +class NSM extends EventEmitter{ + constructor (config) { + super() + this.config = config + this.Version = Info.Version + this.Author = Info.Author + this.IP = config.IP + this.PORT = config.PORT + this.PASSWORD = config.PASSWORD + this.LOGFILE = config.LOGFILE + this.LOGSERVERURI = config.LOGSERVERURI + this.logger = new Logger(path.join(__dirname, `../Log/`), `NSM-${this.IP}:${this.PORT}.log`) + this.Server = null + this.startAsync() + } + async startAsync() { + this.RconConnection = new RconConnection(this.IP, this.PORT, this.PASSWORD, this.config.Gamename) + this.Server = new Server(this.IP, this.PORT, this.RconConnection, Database, sessionStore, clientData, Managers, Id++, this, this.config) + this.eventLogWatcher = this.LOGFILE ? new EventLogWatcher(this.LOGFILE, this.Server, this) : new ServerLogWatcher(this.LOGSERVERURI, this.Server, this) + + this.loadPlugins() + + await this.Server.setDvarsAsync() + + if (this.Server.Hostname) { + console.log(`Now watching \x1b[33m${COD2BashColor(this.Server.Hostname)}\x1b[0m at \x1b[35m${this.IP}:${this.PORT}\x1b[0m`) + } else { + console.log(`Not watching \x1b[35m${this.IP}:${this.PORT}\x1b[0m: communication failed`) + clearInterval(this.Server.HeartbeatInt) + return + } + + await this.Server.loadClientsAsync() + this.eventLogWatcher.init() + this.emit('ready') + } + log(string) { + console.log(`[${new Date().toISOString()}] - - ${COD2BashColor(string)}`) + } + loadPlugins() { + const directoryPath = path.join(__dirname, '../Plugins'); + fs.readdir(directoryPath, (err, files) => { + if (err) { + return console.log('Unable to scan directory: ' + err); + } + files.forEach( (file) => { + if (!file.match(/.+\.js/g)) return + this.logger.writeLn(`Loading plugin \x1b[33m${file}\x1b[0m for server ${this.Server.IP}:${this.Server.PORT}`) + try { + let plugin = require(path.join(__dirname, `../Plugins/${file}`)) + new plugin(this.Server, this, Managers) + } + catch (e) { + console.log(`Error evaluating plugin \x1b[33m${file}\x1b[0m: \x1b[31m${e.toString()}\n${e.stack}\x1b[0m`) + } + }) + }) + } +} + +if (configured) { + const configuration = require(path.join(__dirname, `../Configuration/NSMConfiguration.json`).toString()) + process.env.LOCALE = configuration.locale ? fs.existsSync(path.join(__dirname, `../Configuration/Localization-${configuration.locale}.json`)) ? configuration.locale : 'en' : 'en' + var RconConnection = require('./RconConnection.js') + var Server = require(path.join(__dirname, '../Lib/Entity/Server.js')) + var Database = new (require(path.join(__dirname, '../Lib/InitDatabase.js')))() + var EventLogWatcher = require('./EventLogWatcher.js') + var ServerLogWatcher = require('./ServerLogWatcher.js') + var sessionStore = new (require(path.join(__dirname, `../Webfront/SessionStore.js`)))() + var clientData = new (require(path.join(__dirname, `../Lib/ClientData.js`)))() + + process.env.config = JSON.stringify(require(path.join(__dirname, `../Configuration/NSMConfiguration.json`))) + process.env.Localization = JSON.stringify(require(path.join(__dirname, `../Configuration/Localization-${process.env.LOCALE}.json`))) + + // var commitId = require('child_process').execSync('git rev-parse HEAD').toString().trim() + // var lastCommit = require('child_process').execSync('git ls-remote https://github.com/fedddddd/node-server-manager.git HEAD').toString().split(/\s+/g)[0].trim() + + console.log(`+-------------------------------+`) + console.log(`| \x1b[31mZ-Tavern Fed Node\x1b[0m\t\t|`) + console.log(`| \x1b[33m Kiels \x1b[0m\t\t\t|`) + console.log(`| \x1b[35m Z-Tavern \x1b[0m\t\t\t|`) + console.log(`+-------------------------------+`) + + /* console._log(commitId == lastCommit + ? '^2Node Server Manager is up to date' + : `^3An update is available (v${commitId.substr(0, 6)}, run git pull to update)`)*/ + + console.log(`Environment: ${process.env.NODE_ENV == 'dev' ? 'Development' : 'Production'}`) + + configuration.Servers.forEach(config => { + Managers.push(new NSM({ ...configuration, ...config })) + }) + + var masterServer = new (require('./MasterServer.js'))(Managers) + + for (var i = 0; i < Managers.length; i++) { + Managers[i].Server.masterServer = masterServer + } + + async function loadGlobalPlugins() { + const directoryPath = path.join(__dirname, '../Plugins/Global'); + fs.readdir(directoryPath, (err, files) => { + if (err) { + return console.log('Unable to scan directory: ' + err); + } + files.forEach( (file) => { + if (!file.match(/.+\.js/g)) return + try { + let plugin = require(path.join(__dirname, `../Plugins/Global/${file}`)) + new plugin(Managers) + } + catch (e) { + console.log(`Error evaluating plugin \x1b[33m${file}\x1b[0m: \x1b[31m${e.toString()}\x1b[0m`) + } + }) + }) + } + + loadGlobalPlugins() + + const _Webfront = require(path.join(__dirname, `../Webfront/Webfront.js`)) + + configuration.Webfront && (Webfront = new _Webfront(Managers, { + SSL: configuration.WebfrontSSL, + Key: configuration['WebfrontSSL-Key'], + Cert: configuration['WebfrontSSL-Cert'], + Port: configuration.WebfrontPort, + Hostname: configuration.WebfrontHostname, + }, sessionStore, Database)) + + new (require('./CLICommands.js'))(Managers[0], Managers) + + masterServer.init() +} else { + var configMake = new ConfigMaker() + configMake.init() +} + diff --git a/node-server-manager/Lib/RconCommandPrefixes/Default.js b/node-server-manager/Lib/RconCommandPrefixes/Default.js new file mode 100644 index 0000000..e3ce486 --- /dev/null +++ b/node-server-manager/Lib/RconCommandPrefixes/Default.js @@ -0,0 +1,42 @@ +module.exports = { + Rcon: { + prefix: '\xff\xff\xff\xffrcon %PASSWORD% %COMMAND%', + status: 'status', + getDvar: 'get %DVAR%', + setDvar: 'set %DVAR% %VALUE%', + clientKick: `clientkick %CLIENT% "%REASON%"`, + Tell: `tell %CLIENT% "%MESSAGE%"`, + Say: 'say "%MESSAGE%"', + statusRegex: /^ +([0-9]+) +([0-9]+) +([0-9]+){0,1} +([0-9]+) +((?:[A-Za-z0-9]){8,32}|(?:[A-Za-z0-9]){8,32}|bot[0-9]+|(?:[[A-Za-z0-9]+)) *(.{0,32}) +([0-9]+) +(\d+\.\d+\.\d+.\d+\:-*\d{1,5}|0+.0+:-*\d{1,5}|loopback|unknown|bot) +(-*[0-9]+) +([0-9]+) *$/g, + dvarRegex: /(.*?) +(is:|is) +\"(.*?)\"/g, + parseStatus: (match) => { + return { + num: match[1], + score: match[2], + bot: match[3], + ping: match[4], + guid: match[5], + name: match[6].replace(new RegExp(/\^([0-9]|\:|\;)/g, 'g'), ``), + lastmgs: match[7], + address: match[8], + qport: match[9], + rate: match[10] + } + } + }, + convertGuid: (guid) => { + return guid + }, + getInfo: '\xff\xff\xff\xffgetinfo', + getStatus: '\xff\xff\xff\xffgetstatus', + Dvars: { + maxclients: 'sv_maxclients', + mapname: 'mapname', + hostname: 'sv_hostname', + gamename: 'gamename', + maprotation: 'sv_mapRotation', + gametype: 'g_gametype', + messagelength: 999999999, + maxSayLength: 100 + } +} \ No newline at end of file diff --git a/node-server-manager/Lib/RconCommandPrefixes/IW3.js b/node-server-manager/Lib/RconCommandPrefixes/IW3.js new file mode 100644 index 0000000..50edfe9 --- /dev/null +++ b/node-server-manager/Lib/RconCommandPrefixes/IW3.js @@ -0,0 +1,40 @@ +module.exports = { + Rcon: { + prefix: '\xff\xff\xff\xffrcon %PASSWORD% %COMMAND%', + status: 'status', + getDvar: '%DVAR%', + setDvar: '%DVAR% %VALUE%', + clientKick: `clientkick %CLIENT% "%REASON%"`, + Tell: `tell %CLIENT% "%MESSAGE%"`, + Say: `say "%MESSAGE%"`, + statusRegex: /^ +([0-9]+) +([0-9]+) +([0-9]+) +((?:[A-Za-z0-9]){8,32}|(?:[A-Za-z0-9]){8,32}|bot[0-9]+|(?:[[A-Za-z0-9]+)) +([0-9]+) *(.{0,32}) +([0-9]+) +(\d+\.\d+\.\d+.\d+\:-*\d{1,5}|0+.0+:-*\d{1,5}|loopback|unknown|bot) +(-*[0-9]+) +([0-9]+) *$/g, + dvarRegex: /\"(.*?)\" +(is:|is) +\"(.*?)\"/g, + parseStatus: (match) => { + return { + num: match[1], + score: match[2], + bot: '0', + ping: match[3], + guid: match[4], + steamid: match[5], + name: match[6].replace(new RegExp(/\^([0-9]|\:|\;)/g, 'g'), ``), + lastmgs: match[7], + address: match[8], + qport: match[9], + rate: match[10] + } + } + }, + getInfo: '\xff\xff\xff\xffgetinfo', + getStatus: '\xff\xff\xff\xffgetstatus', + Dvars: { + maxclients: 'sv_maxClients', + mapname: 'mapname', + hostname: 'sv_hostname', + gametype: 'g_gametype', + gamename: 'gamename', + maprotation: 'sv_mapRotation', + messagelength: 999999999, + maxSayLength: 100 + } +} \ No newline at end of file diff --git a/node-server-manager/Lib/RconCommandPrefixes/IW4.js b/node-server-manager/Lib/RconCommandPrefixes/IW4.js new file mode 100644 index 0000000..c4c442a --- /dev/null +++ b/node-server-manager/Lib/RconCommandPrefixes/IW4.js @@ -0,0 +1,39 @@ +module.exports = { + Rcon: { + prefix: '\xff\xff\xff\xffrcon %PASSWORD% %COMMAND%', + status: 'status', + getDvar: '%DVAR%', + setDvar: '%DVAR% %VALUE%', + clientKick: `clientkick %CLIENT% "%REASON%"`, + Tell: `tellraw %CLIENT% "%MESSAGE%"`, + Say: `sayraw "%MESSAGE%"`, + statusRegex: /^ +([0-9]+) +([0-9]+) +([0-9]+) +([0-9]+) +((?:[A-Za-z0-9]){8,32}|(?:[A-Za-z0-9]){8,32}|bot[0-9]+|(?:[[A-Za-z0-9]+)) *(.{0,32}) +([0-9]+) +(\d+\.\d+\.\d+.\d+\:-*\d{1,5}|0+.0+:-*\d{1,5}|loopback|unknown|bot) +(-*[0-9]+) +([0-9]+) *$/g, + dvarRegex: /\"(.*?)\" +(is:|is) +\"(.*?)\"/g, + parseStatus: (match) => { + return { + num: match[1], + score: match[2], + bot: match[3], + ping: match[4], + guid: match[5], + name: match[6].replace(new RegExp(/\^([0-9]|\:|\;)/g, 'g'), ``), + lastmgs: match[7], + address: match[8], + qport: match[9], + rate: match[10] + } + } + }, + getInfo: '\xff\xff\xff\xffgetinfo', + getStatus: '\xff\xff\xff\xffgetstatus', + Dvars: { + maxclients: 'sv_maxClients', + mapname: 'mapname', + hostname: 'sv_hostname', + gametype: 'g_gametype', + gamename: 'gamename', + maprotation: 'sv_mapRotation', + messagelength: 999999999, + maxSayLength: 100 + } +} \ No newline at end of file diff --git a/node-server-manager/Lib/RconCommandPrefixes/IW5.js b/node-server-manager/Lib/RconCommandPrefixes/IW5.js new file mode 100644 index 0000000..fae5049 --- /dev/null +++ b/node-server-manager/Lib/RconCommandPrefixes/IW5.js @@ -0,0 +1,43 @@ +module.exports = { + Rcon: { + prefix: '\xff\xff\xff\xffrcon %PASSWORD% %COMMAND%', + status: 'status', + getDvar: 'get %DVAR%', + setDvar: 'set %DVAR% %VALUE%', + clientKick: `clientkick %CLIENT% "%REASON%"`, + Tell: `tell %CLIENT% "%MESSAGE%"`, + Say: 'say "%MESSAGE%"', + statusRegex: /^ +([0-9]+) +([0-9]+) +([0-9]+) +([0-9]+) +((?:[A-Za-z0-9]){8,32}|(?:[A-Za-z0-9]){8,32}|bot[0-9]+|(?:[[A-Za-z0-9]+)) *(.{0,32}) +(\d+\.\d+\.\d+.\d+\:-*\d{1,5}|0+.0+:-*\d{1,5}|loopback|unknown|bot) +([0-9]+) *$/g, + dvarRegex: /(.*?) +(is:|is) +\"(.*?)\"/g, + parseStatus: (match) => { + const bot = match[3] == '1' + + return { + num: match[1], + score: match[2], + bot, + ping: match[4], + guid: bot ? match[5] : parseInt(match[5].substr(8), 16).toString(), + name: match[6].replace(new RegExp(/\^([0-9]|\:|\;)/g, 'g'), ``), + address: bot ? 'localhost:27016' : match[7], + qport: match[8], + } + }, + retries: 3 + }, + convertGuid: (guid) => { + return parseInt(guid.substr(8), 16).toString() + }, + getInfo: '\xff\xff\xff\xffgetinfo', + getStatus: '\xff\xff\xff\xffgetstatus', + Dvars: { + maxclients: 'sv_maxclients', + mapname: 'mapname', + hostname: 'sv_hostname', + gamename: 'gamename', + maprotation: 'sv_mapRotation', + gametype: 'g_gametype', + messagelength: 999999999, + maxSayLength: 120 + } +} \ No newline at end of file diff --git a/node-server-manager/Lib/RconCommandPrefixes/IW6.js b/node-server-manager/Lib/RconCommandPrefixes/IW6.js new file mode 100644 index 0000000..d93b90d --- /dev/null +++ b/node-server-manager/Lib/RconCommandPrefixes/IW6.js @@ -0,0 +1,39 @@ +module.exports = { + Rcon: { + prefix: '\xff\xff\xff\xffrcon %PASSWORD% %COMMAND%', + status: 'status', + getDvar: '%DVAR%', + setDvar: '%DVAR% %VALUE%', + clientKick: `clientkick %CLIENT% "%REASON%"`, + Tell: `tellraw %CLIENT% "%MESSAGE%"`, + Say: `sayraw "%MESSAGE%"`, + statusRegex: /^ +([0-9]+) +([0-9]+) +(Yes|No) +([0-9]+) +((?:[A-Za-z0-9]){8,32}|(?:[A-Za-z0-9]){8,32}|bot[0-9]+|(?:[[A-Za-z0-9]+)) *(.{0,32}) +() +(\d+\.\d+\.\d+.\d+\:-*\d{1,5}|0+.0+:-*\d{1,5}|loopback|unknown|bot) +([0-9]+) *$/g, + dvarRegex: /\"(.*?)\" +(is:|is) +\"(.*?)\"/g, + parseStatus: (match) => { + return { + num: match[1], + score: match[2], + bot: match[3] == 'Yes', + ping: match[4], + guid: match[5], + name: match[6].replace(new RegExp(/\^([0-9]|\:|\;)/g, 'g'), ``), + lastmgs: match[7], + address: match[8], + qport: match[9], + rate: match[10] + } + } + }, + getInfo: '\xff\xff\xff\xffgetinfo', + getStatus: '\xff\xff\xff\xffgetstatus', + Dvars: { + maxclients: 'sv_maxClients', + mapname: 'mapname', + hostname: 'sv_hostname', + gametype: 'g_gametype', + gamename: 'gamename', + maprotation: 'sv_mapRotation', + messagelength: 999999999, + maxSayLength: 100 + } +} \ No newline at end of file diff --git a/node-server-manager/Lib/RconCommandPrefixes/T4.js b/node-server-manager/Lib/RconCommandPrefixes/T4.js new file mode 100644 index 0000000..c11d731 --- /dev/null +++ b/node-server-manager/Lib/RconCommandPrefixes/T4.js @@ -0,0 +1,40 @@ +module.exports = { + Rcon: { + prefix: '\xff\xff\xff\xffrcon %PASSWORD% %COMMAND%', + status: 'status', + getDvar: '%DVAR%', + setDvar: 'set %DVAR% %VALUE%', + clientKick: `clientkick %CLIENT% "%REASON%"`, + Tell: `tell %CLIENT% "%MESSAGE%"`, + Say: `say "%MESSAGE%"`, + statusRegex: /^ +([0-9]+) +([0-9]+) +([0-9]+) +([0-9]+) +(.{0,32}) +([0-9]+) +(\d+\.\d+\.\d+.\d+\:-*\d{1,5}|0+.0+:-*\d{1,5}|loopback|unknown|bot) +(-*[0-9]+) +([0-9]+) *$/g, + dvarRegex: /\"(.*?)\" +(is:|is) +\"(.*?)\"/g, + commandDelay: 500, + parseStatus: (match) => { + return { + num: match[1], + score: match[2], + bot: '0', + ping: match[3], + guid: match[4], + name: match[5].replace(new RegExp(/\^([0-9]|\:|\;)/g, 'g'), ``), + lastmgs: match[6], + address: match[7], + qport: match[8], + rate: match[9] + } + } + }, + getInfo: '\xff\xff\xff\xffgetinfo', + getStatus: '\xff\xff\xff\xffgetstatus', + Dvars: { + maxclients: 'sv_maxClients', + mapname: 'mapname', + hostname: 'sv_hostname', + gametype: 'g_gametype', + gamename: 'gamename', + maprotation: 'sv_mapRotation', + messagelength: 999999999, + maxSayLength: 150 + } +} \ No newline at end of file diff --git a/node-server-manager/Lib/RconCommandPrefixes/T6.js b/node-server-manager/Lib/RconCommandPrefixes/T6.js new file mode 100644 index 0000000..66f1a19 --- /dev/null +++ b/node-server-manager/Lib/RconCommandPrefixes/T6.js @@ -0,0 +1,39 @@ +module.exports = { + Rcon: { + prefix: '\xff\xff\xff\xffrcon %PASSWORD% %COMMAND%', + status: 'status', + getDvar: 'get %DVAR%', + setDvar: 'set %DVAR% %VALUE%', + clientKick: `clientkick_for_reason %CLIENT% "%REASON%"`, + Tell: `tell %CLIENT% "%MESSAGE%"`, + Say: `say "%MESSAGE%"`, + statusRegex: /^ +([0-9]+) +([0-9]+) +([0-9]+) +([0-9]+) +((?:[A-Za-z0-9]){8,32}|(?:[A-Za-z0-9]){8,32}|bot[0-9]+|(?:[[A-Za-z0-9]+)) *(.{0,32}) +([0-9]+) +(\d+\.\d+\.\d+.\d+\:-*\d{1,5}|0+.0+:-*\d{1,5}|loopback|unknown|bot) +(-*[0-9]+) +([0-9]+) *$/g, + dvarRegex: /(.*?) +(is:|is) +\"(.*?)\"/g, + parseStatus: (match) => { + return { + num: match[1], + score: match[2], + bot: match[3], + ping: match[4], + guid: parseInt(match[5], 16).toString(), + name: match[6].replace(new RegExp(/\^([0-9]|\:|\;)/g, 'g'), ``), + lastmgs: match[7], + address: match[8], + qport: match[9], + rate: match[10] + } + } + }, + getInfo: '\xff\xff\xff\xffgetinfo', + getStatus: '\xff\xff\xff\xffgetstatus', + Dvars: { + maxclients: 'sv_maxclients', + mapname: 'mapname', + hostname: 'sv_hostname', + gametype: 'g_gametype', + gamename: 'gamename', + maprotation: 'sv_mapRotation', + messagelength: 104, + maxSayLength: 100 + } +} \ No newline at end of file diff --git a/node-server-manager/Lib/RconConnection.js b/node-server-manager/Lib/RconConnection.js new file mode 100644 index 0000000..8848af5 --- /dev/null +++ b/node-server-manager/Lib/RconConnection.js @@ -0,0 +1,196 @@ +const dgram = require('dgram') +const path = require('path') +const Utils = new (require(path.join(__dirname, '../Utils/Utils.js')))() +const Mutex = require(path.join(__dirname, '../Utils/Mutex.js')) +const fs = require('fs') +const wait = require('delay') + +class Rcon { + constructor (ip, port, password, gamename) { + this.ip = ip + this.mutex = new Mutex() + this.port = port + this.password = password + this.gamename = gamename + this.commandPrefixes = fs.existsSync(path.join(__dirname, `./RconCommandPrefixes/${gamename}.js`)) + ? {...require(`./RconCommandPrefixes/Default.js`), ...require(`./RconCommandPrefixes/${gamename}.js`)} + : require(`./RconCommandPrefixes/Default.js`) + + this.isRunning = false + this.commandRetries = 3 + this.previousClients = [] + this.canExecute = true + this.commandQueue = 0 + this.client = dgram.createSocket('udp4') + } + + async sendCommand(command) { + return new Promise(async (resolve, reject) => { + var client = dgram.createSocket('udp4') + var message = new Buffer.from(command, 'binary') + + client.on('listening', async () => { + client.send(message, 0, message.length, this.port, this.ip, async (err) => { + if (err) { + client.close() + resolved = true + resolve(false) + } + }) + }) + + client.bind() + + var resolved = false; + var onMessage = (msg) => { + client.removeAllListeners() + client.close() + resolved = true + resolve(msg.toString()) + } + + client.on('message', onMessage); + + setTimeout(() => { + if (!resolved) { + client.removeAllListeners() + client.close() + resolve(false) + } + }, 3000) + }) + } + + async executeCommandAsync(command) { + return new Promise(async (_resolve, reject) => { + if (this.commandPrefixes.Rcon.commandDelay) { + await this.mutex.lock() + } + + const resolve = async (msg) => { + _resolve(msg) + + if (this.commandPrefixes.Rcon.commandDelay) { + await wait(this.commandPrefixes.Rcon.commandDelay) + this.mutex.unlock() + } + } + + const client = dgram.createSocket('udp4') + + const message = new Buffer.from(Utils.formatString(this.commandPrefixes.Rcon.prefix, { + password: this.password, + command + })[0], 'binary') + + const timeout = setTimeout(() => { + client.close() + client.removeAllListeners() + + resolve(false) + }, 5000) + + client.once('listening', async () => { + client.send(message, 0, message.length, this.port, this.ip, async (err) => { + if (err) { + clearTimeout(timeout) + client.close() + client.removeAllListeners() + + resolve(false) + } + }) + }) + + client.once('message', (data) => { + clearTimeout(timeout) + client.close() + + resolve(data.toString()) + }) + + client.bind() + }) + } + + async setDvar(dvar, value) { + const command = Utils.formatString(this.commandPrefixes.Rcon.setDvar, { + dvar, + value + }) + + await this.executeCommandAsync(command) + } + + async getDvarRaw(dvarName) { + for (var i = 0; i < this.commandRetries; i++) { + var dvar = await this.executeCommandAsync(this.commandPrefixes.Rcon.getDvar.replace('%DVAR%', dvarName)) + + if (!dvar || !dvar.match(this.commandPrefixes.Rcon.dvarRegex)) continue + return this.commandPrefixes.Rcon.dvarRegex.exec(dvar)[3].trim() + } + + return false + } + + async getDvar(dvar) { + const command = Utils.formatString(this.commandPrefixes.Rcon.getDvar, { + dvar + }) + + for (var i = 0; i < this.commandRetries; i++) { + const string = await this.executeCommandAsync(command) + + if (!string || !string.match(this.commandPrefixes.Rcon.dvarRegex)) { + continue + } + + return Utils.stripString(this.commandPrefixes.Rcon.dvarRegex.exec(string)[3].trim()) + } + + return false + } + + async getStatus() { + try { + var status = await this.executeCommandAsync(this.commandPrefixes.Rcon.status) + + if (!status) return false + status = status.split('\n').slice(1, -1) + + if (status[0].includes('invalid')) return false + + var map = status[0].split(/\s+/g)[1] + var rawClients = status.slice(3) + var clients = [] + + rawClients.forEach(client => { + if (!client.match(this.commandPrefixes.Rcon.statusRegex)) return + var match = this.commandPrefixes.Rcon.statusRegex.exec(client) + + for (var i = 0; i < match.length; i++) { + match[i] = match[i] ? match[i].trim() : '' + } + + clients.push(this.commandPrefixes.Rcon.parseStatus(match)) + }) + } + catch (e) { + return false + } + + return {success: true, data : {map, clients}} + } + + async getClientByGuid(guid) { + var clients = (await this.getStatus()).data.clients + + for (var i = 0; i < clients.length; i++) { + if (clients[i].guid == guid) { + return clients[i] + } + } + } +} + +module.exports = Rcon \ No newline at end of file diff --git a/node-server-manager/Lib/ServerLogWatcher.js b/node-server-manager/Lib/ServerLogWatcher.js new file mode 100644 index 0000000..ea1d32a --- /dev/null +++ b/node-server-manager/Lib/ServerLogWatcher.js @@ -0,0 +1,56 @@ +const EventParser = require('./EventParser.js') +const ws = require('ws') +const _EventDispatcher = require('./EventDispatcher.js') + +class EventLogWatcher extends EventParser { + constructor (logServerURI, Server, Manager) { + super(Server) + this.logServerURI = logServerURI + this.Server = Server + this.Manager = Manager + this.EventDispatcher = new _EventDispatcher(Server, Manager) + } + async init () { + try { + var socket = new ws(this.logServerURI) + + socket.onmessage = async (msg) => { + this.onLine(msg.data) + } + + socket.on('error', (error) => { + console.log(`Server Log Watcher: ${error}`) + }) + + socket.onclose = async () => { + console.log(`Connection to log server (${this.logServerURI}) lost, reconnecting in 5 seconds...`) + + setTimeout(() => { + this.init() + }, 5 * 1000) + } + } + catch (e) { + this.Manager.logger.writeLn(`Remote log server generated an error: ${e.toString()}`) + } + } + async onLine(line) { + line = line.replace(/[^\x20-\x7E]+/g, '') + + this.Server.Rcon.isRunning = true + this.Server.emit('line', line) + this.Server.emit('stripped_line', line.trim().replace(new RegExp(/([0-9]+:[0-9]+)\s+/g), '')) + + const lines = line.split('\n').filter(l => l.length > 0) + + for (var i = 0; i < lines.length; i++) { + const event = this.parseEvent(lines[i].trim()) + + if (!event) return + + this.EventDispatcher.dispatchCallback(event) + } + } +} + +module.exports = EventLogWatcher \ No newline at end of file diff --git a/node-server-manager/Plugins/.vs/Plugins/FileContentIndex/e799e520-62cc-4ff1-bc4c-1cb0816c9aaa.vsidx b/node-server-manager/Plugins/.vs/Plugins/FileContentIndex/e799e520-62cc-4ff1-bc4c-1cb0816c9aaa.vsidx new file mode 100644 index 0000000000000000000000000000000000000000..4c89869df0762aae297368226f204d65d530a578 GIT binary patch literal 173784 zcmbr{3!Gh7SvUUYoH>&@Nt4OUnE}hSlMpZ>mrziVTPG#Zz*``47my~UrL7cNp-<@wl^gJ^9S1o%z&focYwpJ>|SJ z&b(vy`HoNC^^{#_`EJL#Pe1FNr#$U(Tc2{lIgi}&;5+@|)4IF6e=oe~fzLSo@&DZW z;m5h}xx1e7@LgveGtR1C-S_%0U36o{*>=v;o^ak%&v?|Cr=NY^c~2S-_qi=UJ#(8! z+?a7rIrqHNcb)sVtxvz;ya%26w5M6~(+u__k8^ZdC!cpgru3MrFZ=4x|MHJ8pKeU{{;ajUVSh=RNhz`=0k?;&4VI%u(il?G}H&|G%Gq zW7hTHT^F45jO&f`)Z>@371w#;=5jb+cR&J96t2Cr(ba9(;jz} zU*nbCc={Y2=bWdUaptqeqtuT;=cD61?7SzOv+LXkoq5JNKO(=5j`Ns@U9jtdYZ-Rq z*Y&U`JoTLOFF2O-Kf*ZXaq4+zfs$*f^P|w`k>_1-&Qp$sjUR!|k2>?*C!F_W3bCx~ zO^R;(x*l`hlTRmwC+~X7GWZzhD{pwnKYaYfH%2dxj&tgHPk7P_68*^Yxh~u5mG58w zk8M7e40=(P3IF!WFMh5X)o@U2M)kc>EzH+os%B@aH>$P6S{T&AuvYbIX1;xM=U!dz z;!({GYLL4Ydo}4UgH6`9sahJ=_XhQfUcGRA_2%n0NA;Mg>JRI7gW9>Kmeyv#UY#_m zy+-KO8%8x6)KafKWpPlwUi&ffQnjI&Dc9V8RNH#B-BU*8af?0-+byq}tF=?r8`dC0 znN@#KtIc`XruqwpGLB)VYLjnz_1pRNc+cv!#kNOGw!aRB^{v@jn5(TuHrq8d)2n{3 zK0B&2jPIL4^+&a4RsPzm10ltH7P~NAPo1gFqk3qTd2{4iU$2{~o6NPRe=pBHJ`*!N zGq;=>bn{mq1~u%}y+-v|-}LHv!}i>7kLuRF`lC_%yfmuYA#Vox&UD?uWmAn)-|IC_ zeQ&x=(ua@xcfQ^>s^^Sqa!~WV+SqFYu0gBr%KYjYoO-Ss2len#eJEFY^d+NuL$6K_ zc^?<@Uf!#-NA+91+CQpQqxwXz-Z-jfWj+`7>Td>h_1YTDH-1@BTUW0hH>!JOX+6`! z(A;PmK3nN8jA}=(9zCi%xSF_fVA9vkuRI9@a-;)g& zUrja$K)AN9S2yt?7c5}ksGc&a+vivFe6}k`^?QCD)#i|H+n~N_w!OM(uP&Nz-@h?L zFx!{)YVD{tWTlJqZNhVziOD?PLd-U6@f1Ivh|A{lyg^O(>gle>xL*B3{>93DK8)(n zpuXCxi|3mJBK1_S{x%nE8P!XB^?Rc_FT(TP2-t2C(yPO`lR50`*ADC$)x&!A{9Yr% zDBRgZ*9dv9Hjs*5?aP;|{kyj5FUlAJFTR!OA)23?kLp&r9Zg8AzxvV=5X$un)|Fp< z_Opm_`4_3Jda>W|VX0piQ1)RxiJZG-zRAGCpxyh%>Bh>>_iJjRDe{p)T>(kZXSQAQ z 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
XAgBsJ&_m#}1f4Rm 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≈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 literal 0 HcmV?d00001 diff --git a/node-server-manager/Plugins/.vs/Plugins/v17/.wsuo b/node-server-manager/Plugins/.vs/Plugins/v17/.wsuo new file mode 100644 index 0000000000000000000000000000000000000000..7d063f7de38f49482c3b65ce943bffdcc8db3081 GIT binary patch literal 9216 zcmeHL+fEZf82$^M+T7}FR+ys)Gc3aAl@;whnkRKeQ{TR>?`w#Cys=)LjENAS|8 z&}*;s(uYv|zS*7bu(aFlRz-CGW_M=i^q*(G>8Fo9U*5ex^HqE_F5U8D^PucA+7m`y zPKX@FH`{(}Zf>%RbyQ>8MHZNo3Vt<7%1tSwwB-d|8Jc=!Z{6p6Tg*z1mM71>`kXk3 zaT9x-!L#64k;ifu+>5B)l;uOiK#eAi_S64+wl$-@=} zJeE7ISqnV|8A$ z{@ql-S3ipW@(LvCG0`#%}q5u7D&A$H~OZ=ajTnFN*0F9J@c5IYkaSuX7(OKXR z;(lT}TF_|?e)HaN!5wlRe5>F)1*}sA63WYp!eBL7RLH0ryp$0CbYl$H49lPU8TU65 zaUW5h4eV6_4!Z?8*6>{wjSMYFQj;5yiul-4Z%?Yr5%4E-$>A-)?C>p2XO>_(3cq- z9K=Cfl3p(av^Ey1F~gZ_j8Dj#KIOwBw|0Cp}FtR@pA6 zz3tfDcDZ{ZW`xqcJ22Z~#0VtdVZ|Z=TEWu@fwUk5JdBX`1!-6b(4gf39##Wr5f8v< zSAu)1>ej#8*)()BnPVvxSDkzAJ?FdU+`4sdr8|EkQ&(iZ)@mO}3ctXNFf7ab6wfmZ z6T&}}_=kSR@E1Ql!M|C{_g-H^%*EO#0a6(Kkd!%temMNC;gO;1k@v!n2R{z^f;W8c z4}3b18+g4}6>$ACLtv0tdh{hO6uT*~M>p!ts{CgD@Sxmktjo1}v#!)z&64)DxxZ0w z$mwb+?Ntb+a$>R|^6Bil_y)gstU8L(2#-HoS$Fv&Kf7mdwirK}h=yV*Z01#OGqcix z>}?#^$2e27k4dCpkxy-9GQ`*HRw|hn<6nDiI202E_UnQol^e3tb?13hH>QwW%ZMJH zM(Dq_uJ0)Ist((q>}5RO|&j% zL{mhK(Ew(5leyHjWNtRGv=lcCc5tOC8{J0Z@J3f^)N6IQ>Q#ZgKd9by93>_%>M@lj zD;2rZsh8^w;-Z1oS# z+OFa1ag<4yy%Gw=M1gjhGmuN$Qd@2+B{FO~WrLpm=PYHd!P1q^Vr0VLb$7miZ)d6r zP6ZOnM{B`Q><%9J4$YCzl7)KHZcWShXDJ@i{n4jDPPIO@_3`ZqPD})>(;`>1go?Mp z!9E6?nthD(0v~^L&94p8DRYpv&~n-tuqTL9Y)KKP=wzv)*=$DnF=iq?`@kIQ)Nzc= zr^x37Q-Y@(;nN+$rpT|Q-P6E~)KRv|9l3p9#?vBmhF{V9of^RW=lxo@O7)YMr`m`mX_79ees!OUUV0 zo>`>rN{ue=M@Mw-;AgebNE9Cf+?N^jeePel?{XjDukZl^KmZ5;0U!VbfB+Bx0zd!= z0D;dffuq4dfJq${@w(nuL}F>Vk`OA(iPhzmN<~;+ zkyeGpE0twIx>CI?B+7DaVfjjRwOm^fs#g;8iONz{xU#Y&;X*Plw6e4yBx*~m%jH_R zc6kLCs#R8&uFPK%R;vn@%FbV0 zxVRKW|G*5Oj~Mh3`s8yP-rzV800KY&2mk>f00e*l5C8%|00;nq&m4gv);G=S>mlUL z`=PM*ip%(bPhg#IyG%uJi2!<=LEk`sivAkCjehW%a~KQ;0zd!=00AHX1b_e#00KY& z2mk>f@c)~@j4#DL;gyO2kw4*02mgfc66<=+!8h%DmF@A0!@!8|eAxC90D1p^Dw<=^ zzv8F=Z=+vF4^aiJp)aEm?g!jQ+_$-3;|{r7+$-FR(H}*>7yYy7Z$}?T8(0B8KmZ5; z0U!VbfB+Bx0zd!=0D;dvfvKq=GsA|1KaJmDS2`EJ(g_d#{a$$UJHPsSXJbJojwSh4 zr7kr#{Qyf6`D&SAlNy;Etmt5(t3aji=H6j{UX(Qo3vN5|p- zZSf0ZLFPQxyxM4$rAF$uq}ZfqG^t+iTFWN=;%JbW!@9|?(%QuD&`bL=@y4k8>dO+` zq;H;euSGM%q$=v_+f00e*l5C8%|00;nq z;}Zz@ST;PR9%JfpQaw(PV_;l8j;Y5p>T%TXW7rXLK;*!YLzEnb$zg~bBIFPzhe2`( zkwcIi0_5N)2Ol{M_Rd*rCZkc1@-WRs$}2j4~&ob&$ITe{=k@e&9>PeI5Xj&W1ZXm zfzfgQ97Ff<>0c*|O!x)kqPgQg=8qd!>6U-YKhJpW`E&jm#)^rYpe_AOHk_01yBIKmZ5;0U!VbfB+Bx z0zC=9{(nz2AOHeD00;m9AOHk_01yBIKmZ5;0U&T{2*C6Isp(2^1PA~DAOHk_01yBI zKmZ5;0U!VbfIv?I@cw^KG#~&1KmZ5;0U!VbfB+Bx0zd!=00AIyY6y_$|47Kkpk?l# zxX$pmhDV03N8SrR9{f1u3*PX(Kk(^5Zs7G(<1RSz3<&r?h}{&}qZ{>RRem#ncu;ON z*5z8gSy$?b1ID z^{T+$A5`x;juMj>^_WVNm5SWy)XVh-anZo)Ear$oS2@#VD?pMc`NNJP9~cOomk3JU z)IJHzOsgW1{LHl;^mc$2O0^o@gQmM&G!j3$G!%-Ja9)+vyizT#NX@3)PDz#9a>;GF zmSxU@!}ct5ihI^$$vLMEjy-ql#rUJ0h?;Tl6xED#YB|q`>>1}2ETVVoPBwjG$GG#*GKP{R zyr@if4Bunu70qPFKw?OD<#q=rnrq~L$P9*J@i_bFRW%N2Wm@(2v#>n|?LtcgQh~LT zjuClUWEci(?wG^u<-VgVZP#%1ILf5UUI~R_qCmUM8OWt=sVz5^5*fCgvO&-ObC$B! zVChO{F*0HBx;tOMw=>lQrvi!PqqSftb_b7qhvvv<$wIwpx29$MvlI{M{^(O6r&^!d z`uO$)Cnf^cX_2d0LdDzQU>}1`%|6C?fsa4B=GO-4lsQOSXgTc+*b~Glwxoztbh1>@ zY&N6(7&DQcePE7t>NrN`Q{;1kDZ$f?@aYa=Q{>mu?rC5~>L^>~j@-U4<7tsO^6Ili zeqG#1?qmvlrQ23BR-wZ*PV$y76q}!Bk7m>~$;*mTZ|d5!Haud(m?593k+&F}@O&t6eux9+|DjSMTPqPnY zwNBkO{nvo4jy?UVCFJxg&n(h*rA8O`qa!-Co22^u&%Dc^?C^U-|1q>RI3Ic|_?P~S z@3-*9XZd+&Vmve<2!oHM`*ryNnWk?`%5C-LSC>1^a~<(+TD-|SWxUjhMsB7H*Ko?D zc5?ajuIMh4%l3IEEbdf6X?xBEB=J_?LW1D`bs~7lQxl78Yw2;?|Xg6=7LPiLi zSh>w_S|6p`jeF2Hp`^5S^O0GI)3hS;UFb9^7ygdEbZwq|C-ev zGU!nDc*u!HXcy-%{=@}`-5n!3qLC*VdmJOZJ43b29Y;7yui?jJ?}*{kd37RtG&>fG z?Zw%nTaH=9x}-=wpMuPQAjKx_L#bWZvkuSOG^vgZv}PR?b20waH_xaO*mvg~_h_PI zDv+}Y`xt2#T82uy;AA7FS%+b&d5hI=SY~jY;5Pe|Pu_I0Z1s*l=GgA~w4mn3lU7om z^dx282KvwAPcW^~Z#D(-4g11TL2B>Iiq~DJ$4X7A)l}p+kE1~z91^2=)nUQ5>Yz>! zb8=0_gF!_u8Q(}e(1k}cHVpB2uVgVwcvt0_E`|>7E#tdp0DfRdjPx^lUA`+ft5Q?x zWAs>mqdlwYYqUeF7=LFPg<=Z}>|@JniJi0u(~(~3ZZPr8c|+<>++#e&()AOXHeUJV zo%d9uf1>@^OO{Ta|GOiR>CQ=(01e!FfSR^F-v<$!U1U~Rv2*CdT^WhGy0s$ZZ1b_e#00KY&2mk>f N00e*l5O|gZ{s%XDEhzv1 literal 0 HcmV?d00001 diff --git a/node-server-manager/Plugins/AntiVPN.js b/node-server-manager/Plugins/AntiVPN.js new file mode 100644 index 0000000..2b3b9e1 --- /dev/null +++ b/node-server-manager/Plugins/AntiVPN.js @@ -0,0 +1,205 @@ +const path = require('path') +const Localization = JSON.parse(process.env.Localization).lookup +const fs = require('fs') +const fetch = require('node-fetch') +const { Command } = require(path.join(__dirname, `../Lib/Classes.js`)) +const ipRangeCheck = require('ip-range-check') +const Utils = new (require(path.join(__dirname, '../Utils/Utils.js')))() +const wait = require('delay') + +class Plugin { + constructor(Server, Manager) { + this.Server = Server + this.Manager = Manager + + this.Server.on('connect', this.onPlayerConnected.bind(this)) + this.Server.on('preconnect', this.onPlayerConnected.bind(this)) + + this.configPath = path.join(__dirname, '../Configuration/AntiVPNConfiguration.json') + this.config = { + blacklist: [], + whitelist: [], + clients: [] + } + + this.init() + } + async saveConfig() { + return new Promise((resolve, reject) => { + fs.writeFile(this.configPath, JSON.stringify(this.config, null, 4), async (err) => { + resolve() + }) + }) + } + async init() { + if (!fs.existsSync(this.configPath)) { + fs.writeFileSync(this.configPath, JSON.stringify(this.config, null, 4)) + } + + this.config = require(this.configPath) + + var commands = new Command() + .setName('antivpn') + .setAlias('avpn') + .setPermission('ROLE_ADMIN') + .addParam({ + name: 'action' + }) + .addCallback(async (Player, params, args) => { + switch (params.action.toLocaleLowerCase()) { + case 'reset': + this.config = { + blacklist: [], + whitelist: [], + clients: [] + } + + this.saveConfig() + Player.Tell(Localization['AVPN_RESET']) + break + case 'clients': + switch (true) { + case (args.length == 2): + Player.Tell(Utils.va(Localization['AVPN_LIST'], + params.action.toLocaleLowerCase(), + this.config[params.action.toLocaleLowerCase()].length + )) + return + case (args[2].toLocaleLowerCase() == 'flush'): + this.config.clients = [] + Player.Tell(Utils.va(Localization['AVPN_FLUSH'], params.action)) + + this.saveConfig() + return + case (args.length < 4): + Player.Tell(Localization['COMMAND_ARGUMENT_ERROR']) + return + } + + var Client = await this.Server.getClient(args[3]) + + if (!Client) { + Player.Tell(Localization['COMMAND_CLIENT_NOT_FOUND']) + return + } + + switch (args[2].toLocaleLowerCase()) { + case 'add': + var found = false + + for (var i = 0; i < this.config.clients.length; i++) { + if (this.config.clients[i] == Client.ClientId) { + found = true + } + } + + !found && this.config.clients.push(Client.ClientId) + Player.Tell(Utils.va(Localization['AVPN_ADD_CLIENT'], Client.ClientId)) + break + case 'remove': + for (var i = 0; i < this.config.clients.length; i++) { + if (this.config.clients[i] == Client.ClientId) { + this.config.clients.splice(i, 1) + } + } + + Player.Tell(Utils.va(Localization['AVPN_REMOVE_CLIENT'], Client.ClientId)) + break + default: + Player.Tell(Utils.va(Localization['COMMAND_ARGUMENT_INVALID'], args[2], '[add, remove]')) + return + } + + this.saveConfig() + break + case 'blacklist': + case 'whitelist': + if (args.length == 2) { + Player.Tell(Utils.va(Localization['AVPN_LIST'], params.action.toLocaleLowerCase(), this.config[params.action.toLocaleLowerCase()].length)) + return + } + + switch (args[2].toLocaleLowerCase()) { + case 'flush': + this.config[params.action.toLocaleLowerCase()] = [] + Player.Tell(Utils.va(Localization['AVPN_FLUSH'], params.action)) + break + case 'add': + if (args.length < 4) { + Player.Tell(Localization['COMMAND_ARGUMENT_ERROR']) + return + } + + this.config[params.action.toLocaleLowerCase()].push(args[3]) + + Player.Tell(Utils.va(Localization['AVPN_ADD_ADDRESS'], args[3])) + break + case 'remove': + if (args.length < 4) { + Player.Tell(Localization['COMMAND_ARGUMENT_ERROR']) + return + } + + for (var i = 0; i < this.config[params.action.toLocaleLowerCase()].length; i++) { + if (this.config[params.action.toLocaleLowerCase()][i] == args[3]) { + this.config[params.action.toLocaleLowerCase()].splice(i, 1); + } + } + + Player.Tell(Utils.va(Localization['AVPN_REMOVE_ADDRESS'], args[3])) + break + default: + Player.Tell(Utils.va(Localization['COMMAND_ARGUMENT_INVALID'], args[2], '[add, remove]')) + return + } + + this.saveConfig() + break + case 'help': + var help = Localization['AVPN_HELP'].split('\n') + + for (var i = 0; i < help.length; i++) { + Player.Tell(help[i]) + await wait(300) + } + break + default: + Player.Tell(Utils.va(Localization['COMMAND_ARGUMENT_INVALID'], params.action, '[whitelist, blacklist, clients, help]')) + return + } + }) + + this.Manager.Commands.add(commands) + } + async onPlayerConnected(Player) { + try { + if (!Player.IPAddress || this.config.clients.indexOf(Player.ClientId) != -1) { + return + } + + var address = Player.IPAddress.split(':')[0] + + for (var i = 0; i < this.config.blacklist.length; i++) { + if (ipRangeCheck(address, this.config.blacklist[i])) { + Player.Kick(Localization['AVPN_BLACKLISTED']) + return + } + } + + for (var i = 0; i < this.config.whitelist.length; i++) { + if (ipRangeCheck(address, this.config.whitelist[i])) { + return + } + } + + var result = (await (await fetch(`https://api.xdefcon.com/proxy/check/?ip=${address}`)).json()) + + if (result.proxy) { + Player.Kick(Localization['PENALTY_VPN_KICK']) + } + } + catch (e) {} + } +} + +module.exports = Plugin \ No newline at end of file diff --git a/node-server-manager/Plugins/ClanTag.js b/node-server-manager/Plugins/ClanTag.js new file mode 100644 index 0000000..f1295b3 --- /dev/null +++ b/node-server-manager/Plugins/ClanTag.js @@ -0,0 +1,3894 @@ +const { randomInt } = require('crypto') +const path = require('path') +const { emitKeypressEvents } = require('readline') +const Utils = new (require(path.join(__dirname, '../Utils/Utils.js')))() +const { Command } = require(path.join(__dirname, `../Lib/Classes.js`)) +const Localization = require(path.join(__dirname, `../Configuration/Localization-en.json`)).lookup + +class Plugin { + constructor(Server, Manager, Managers) { + //add the .pguid of players to grant them staff permissions (must be done on ClanTag, ZombiesBank, ZombiesStats, NativeCommands & the gsc script staff.gsc) + this.staff_list_a = [564391] + this.botb_port = ["30001", "30005"] + this.raid_port = ["30009"] + this.daily_list = [3649, 12] + this.pv_locked = 0 + this.Server = Server + this.Manager = Manager + this.Managers = Managers + this.lockerCost = 100000 + + this.wipe_id = [12] + + this.defaultLockerSize = 1 + this.fana_cd = 0; + this.fana_last_use = new Date(); + this.is_raid_locked = "" + //this.Server.on('preconnect', this.onPlayerPreconnect.bind(this)) + this.Server.on('connect', this.onPlayerConnect.bind(this)) + this.Server.on('disconnect', this.onPlayerDisconnect.bind(this)) + this.gameWatcher() + this.init() + this.saveSlot = 0 + this.Server.isDailyOccupied = false; + this.Server.reservedSlots = 0; + this.vote_id_list = [] + this.guild_list = [] + + this.guild_list[this.guild_list.length] = "RFC;63156" + this.guild_list[this.guild_list.length] = "RS;75539" + this.guild_list[this.guild_list.length] = "ITD;66060" + this.guild_list[this.guild_list.length] = "ILC;40024" + this.guild_list[this.guild_list.length] = "KS;12" + this.guild_list[this.guild_list.length] = "ALC;79746" + this.guild_list[this.guild_list.length] = "WNL;65507" + this.guild_list[this.guild_list.length] = "AZI;45982" + this.guild_list[this.guild_list.length] = "LOV;135710" + this.guild_list[this.guild_list.length] = "LCS;139379" + this.guild_list[this.guild_list.length] = "TSC;29979" + this.guild_list[this.guild_list.length] = "BHB;132773" + this.guild_list[this.guild_list.length] = "ROH;94673" + } + + async init() { + (() => { + let command = new Command() + .setName('settag') + .setAlias('st') + .setPermission('ROLE_MODERATOR') + .addParams([ + { + name: 'target', + index: 0, + }, + { + name: 'tag', + join: true, + index: 1 + } + ]) + .addCallback(async (Player, params) => { + var Client = await this.Server.getClient(params.target) + var connectedPlayers = this.getAllClients(); + connectedPlayers.forEach(connectedPlayer => + { + if (connectedPlayer.ClientId == Client.ClientId) + { + Client = connectedPlayer + } + }) + if (!Client) + { + Player.Tell("Target not found") + return + } + var inGame = await this.Server.findClient(Client.ClientId) + + var name = params.tag + name = name.replace(/#0/g, '^0') + name = name.replace(/#1/g, '^1') + name = name.replace(/#2/g, '^2') + name = name.replace(/#3/g, '^3') + name = name.replace(/#4/g, '^4') + name = name.replace(/#5/g, '^5') + name = name.replace(/#6/g, '^6') + name = name.replace(/#7/g, '^7') + name = name.replace(/#8/g, '^8') + name = name.replace(/#9/g, '^9') + name = name.replace(/@/g, ' ') + inGame && Client.Server.Rcon.executeCommandAsync(`setclantagraw ${Client.Clientslot} "${name}"`) + inGame && Player.Tell(Utils.va(Localization['COMMAND_SETTAG_FORMAT_SELF'], name)) + this.Server.DB.metaService.addPersistentMeta('custom_tag', name, Client.ClientId) + }) + + this.Manager.Commands.add(command) + })(this); + (() => { + let command = new Command() + .setName('rank') + .setAlias('rk') + .addCallback(async (Player, args) => { + + var Client = args[1] ? await this.Server.getClient(args[1]) : Player + switch (true) { + case (!Client): + Player.Tell(Localization['COMMAND_CLIENT_NOT_FOUND']) + return + case (Client.ClientId != Player.ClientId && Client.PermissionLevel >= Player.PermissionLevel): + Player.Tell(Localization['CLIENT_HIERARCHY_ERROR']) + return + } + + var customTag = await this.Server.DB.metaService.getPersistentMeta('custom_tag', Client.ClientId) + if(!customTag || !customTag) + { + Client.Tell('^1Error, no Tag') + return; + } + Client.Tell("Loading ^3Rank^7 data..."); + //--------------------------------------------------------------------- + var gamemodeCount = await this.Server.DB.metaService.getPersistentMeta('gamemodeCount', Player.ClientId) + if (!gamemodeCount) + { + await this.Server.DB.metaService.addPersistentMeta('gamemodeCount', "0", Player.ClientId) + gamemodeCount = await this.Server.DB.metaService.getPersistentMeta('gamemodeCount', Player.ClientId) + } + + + var eeCount = await this.Server.DB.metaService.getPersistentMeta('eeCount', Player.ClientId) + if (!eeCount) + { + await this.Server.DB.metaService.addPersistentMeta('eeCount', "0", Player.ClientId) + eeCount = await this.Server.DB.metaService.getPersistentMeta('eeCount', Player.ClientId) + } + + + var zcoins = await this.Server.DB.metaService.getPersistentMeta('zcoins', Player.ClientId) + if (!zcoins) + { + await this.Server.DB.metaService.addPersistentMeta('zcoins', "0", Player.ClientId) + zcoins = await this.Server.DB.metaService.getPersistentMeta('zcoins', Player.ClientId) + } + + var save = await this.Server.DB.metaService.getPersistentMeta('save', Player.ClientId) + if (!save) + { + Player.Tell("Save error, contact staff") + return; + } + + var oneshot_50 = await this.Server.DB.metaService.getPersistentMeta('oneshot_50', Player.ClientId) + if (!oneshot_50) + { + await this.Server.DB.metaService.addPersistentMeta('oneshot_50', "0", Player.ClientId) + oneshot_50 = await this.Server.DB.metaService.getPersistentMeta('oneshot_50', Player.ClientId) + } + + var botb_hitless = await this.Server.DB.metaService.getPersistentMeta('botb_hitless', Player.ClientId) + if (!botb_hitless) + { + await this.Server.DB.metaService.addPersistentMeta('botb_hitless', "0", Player.ClientId) + botb_hitless = await this.Server.DB.metaService.getPersistentMeta('botb_hitless', Player.ClientId) + } + + var golden_spork = await this.Server.DB.metaService.getPersistentMeta('golden_spork', Player.ClientId) + if (!golden_spork) + { + await this.Server.DB.metaService.addPersistentMeta('golden_spork', "0", Player.ClientId) + golden_spork = await this.Server.DB.metaService.getPersistentMeta('golden_spork', Player.ClientId) + } + + var ee_speedrun = await this.Server.DB.metaService.getPersistentMeta('ee_speedrun', Player.ClientId) + if (!ee_speedrun) + { + await this.Server.DB.metaService.addPersistentMeta('ee_speedrun', "0", Player.ClientId) + ee_speedrun = await this.Server.DB.metaService.getPersistentMeta('ee_speedrun', Player.ClientId) + } + + var upgraded_tomahawk = await this.Server.DB.metaService.getPersistentMeta('upgraded_tomahawk', Player.ClientId) + if (!upgraded_tomahawk) + { + await this.Server.DB.metaService.addPersistentMeta('upgraded_tomahawk', "0", Player.ClientId) + upgraded_tomahawk = await this.Server.DB.metaService.getPersistentMeta('upgraded_tomahawk', Player.ClientId) + } + + var melee_only = await this.Server.DB.metaService.getPersistentMeta('melee_only', Player.ClientId) + if (!melee_only) + { + await this.Server.DB.metaService.addPersistentMeta('melee_only', "0", Player.ClientId) + melee_only = await this.Server.DB.metaService.getPersistentMeta('melee_only', Player.ClientId) + } + + var first_room_30 = await this.Server.DB.metaService.getPersistentMeta('first_room_30', Player.ClientId) + if (!first_room_30) + { + await this.Server.DB.metaService.addPersistentMeta('first_room_30', "0", Player.ClientId) + first_room_30 = await this.Server.DB.metaService.getPersistentMeta('first_room_30', Player.ClientId) + } + var chadGamemodeCount = await this.Server.DB.metaService.getPersistentMeta('chadGamemodeCount', Player.ClientId) + if (!chadGamemodeCount) + { + await this.Server.DB.metaService.addPersistentMeta('chadGamemodeCount', "0", Player.ClientId) + chadGamemodeCount = await this.Server.DB.metaService.getPersistentMeta('chadGamemodeCount', Player.ClientId) + } + var gigachadGamemodeCount = await this.Server.DB.metaService.getPersistentMeta('gigachadGamemodeCount', Player.ClientId) + if (!gigachadGamemodeCount) + { + await this.Server.DB.metaService.addPersistentMeta('gigachadGamemodeCount', "0", Player.ClientId) + gigachadGamemodeCount = await this.Server.DB.metaService.getPersistentMeta('gigachadGamemodeCount', Player.ClientId) + } + + var botb_gc = await this.Server.DB.metaService.getPersistentMeta('botb_gc', Player.ClientId) + if (!botb_gc) + { + await this.Server.DB.metaService.addPersistentMeta('botb_gc', "0", Player.ClientId) + botb_gc = await this.Server.DB.metaService.getPersistentMeta('botb_gc', Player.ClientId) + } + + var titb_gc = await this.Server.DB.metaService.getPersistentMeta('titb_gc', Player.ClientId) + if (!titb_gc) + { + await this.Server.DB.metaService.addPersistentMeta('titb_gc', "0", Player.ClientId) + titb_gc = await this.Server.DB.metaService.getPersistentMeta('titb_gc', Player.ClientId) + } + + var pia_gc = await this.Server.DB.metaService.getPersistentMeta('pia_gc', Player.ClientId) + if (!pia_gc) + { + await this.Server.DB.metaService.addPersistentMeta('pia_gc', "0", Player.ClientId) + pia_gc = await this.Server.DB.metaService.getPersistentMeta('pia_gc', Player.ClientId) + } + + var save1 = parseInt(save.Value.split(';')[0]) + var save2 = parseInt(save.Value.split(';')[1]) + var highestSave = 0 + if (save1 > save2) + highestSave = save1 + else + highestSave = save2 + var gamemodeCountInt = parseInt(gamemodeCount.Value) + var eeCountInt = parseInt(eeCount.Value) + var zcoinsInt = parseInt(zcoins.Value) + var chadCountInt = parseInt(chadGamemodeCount.Value) + var gigachadCountInt = parseInt(gigachadGamemodeCount.Value) + //---------------------------------------------------------------------- + + var multiplier = ''; + if (customTag.Value == '^9F^7') + { + Client.Tell('^6I ^6II ^6III ^5IV ^5V ^5VI ^5VII ^1IIX ^1IX ^1-X-') + Client.Tell('^7[^9F^7] ^8E ^2D ^4C ^5B ^6A ^3S ^3SS ^3SSS') + + multiplier = 'x2' + } + else if (customTag.Value == '^8E^7') + { + Client.Tell('^6I ^6II ^6III ^5IV ^5V ^5VI ^5VII ^1IIX ^1IX ^1-X-') + Client.Tell('^9F ^7[^8E^7] ^2D ^4C ^5B ^6A ^3S ^3SS ^3SSS') + + multiplier = 'x3' + } + else if (customTag.Value == '^2D^7') + { + Client.Tell('^6I ^6II ^6III ^5IV ^5V ^5VI ^5VII ^1IIX ^1IX ^1-X-') + Client.Tell('^9F ^8E ^7[^2D^7] ^4C ^5B ^6A ^3S ^3SS ^3SSS') + + multiplier = 'x3' + } + else if (customTag.Value == '^4C^7') + { + Client.Tell('^6I ^6II ^6III ^5IV ^5V ^5VI ^5VII ^1IIX ^1IX ^1-X-') + Client.Tell('^9F ^8E ^2D ^7[^4C^7] ^5B ^6A ^3S ^3SS ^3SSS') + + multiplier = 'x4' + } + else if (customTag.Value == '^5B^7') + { + Client.Tell('^6I ^6II ^6III ^5IV ^5V ^5VI ^5VII ^1IIX ^1IX ^1-X-') + Client.Tell('^9F ^8E ^2D ^4C ^7[^5B^7] ^6A ^3S ^3SS ^3SSS') + + multiplier = 'x4' + } + else if (customTag.Value == '^6A^7') + { + Client.Tell('^6I ^6II ^6III ^5IV ^5V ^5VI ^5VII ^1IIX ^1IX ^1-X-') + Client.Tell('^9F ^8E ^2D ^4C ^5B ^7[^6A^7] ^3S ^3SS ^3SSS') + + multiplier = 'x5' + } + else if (customTag.Value == '^3S^7') + { + Client.Tell('^6I ^6II ^6III ^5IV ^5V ^5VI ^5VII ^1IIX ^1IX ^1-X-') + Client.Tell('^9F ^8E ^2D ^4C ^5B ^6A ^7[^3S^7] ^3SS ^3SSS') + + multiplier = 'x6' + } + else if (customTag.Value == '^3SS^7') + { + Client.Tell('^6I ^6II ^6III ^5IV ^5V ^5VI ^5VII ^1IIX ^1IX ^1-X-') + Client.Tell('^9F ^8E ^2D ^4C ^5B ^6A ^3S ^7[^3SS^7] ^3SSS') + + multiplier = 'x7' + } + else if (customTag.Value == '^3SSS^7') + { + Client.Tell('^6I ^6II ^6III ^5IV ^5V ^5VI ^5VII ^1IIX ^1IX ^1-X-') + Client.Tell('^9F ^8E ^2D ^4C ^5B ^6A ^3S ^3SS ^7[^3SSS^7]') + + multiplier = 'x9' + } + else if (customTag.Value == '^6 I ^7') + { + Client.Tell('^7[^6I^7] ^6II ^6III ^5IV ^5V ^5VI ^5VII ^1IIX ^1IX ^1-X-') + Client.Tell('^9F ^8E ^2D ^4C ^5B ^6A ^3S ^3SS ^3SSS') + + multiplier = 'x10' + } + else if (customTag.Value == '^6II^7') + { + Client.Tell('^6I ^7[^6II^7] ^6III ^5IV ^5V ^5VI ^5VII ^1IIX ^1IX ^1-X-') + Client.Tell('^9F ^8E ^2D ^4C ^5B ^6A ^3S ^3SS ^3SSS') + + multiplier = 'x11' + } + else if (customTag.Value == '^6III^7') + { + Client.Tell('^6I ^6II ^7[^6III^7] ^5IV ^5V ^5VI ^5VII ^1IIX ^1IX ^1-X-') + Client.Tell('^9F ^8E ^2D ^4C ^5B ^6A ^3S ^3SS ^3SSS') + + multiplier = 'x12' + } + else if (customTag.Value == '^5IV^7') + { + Client.Tell('^6I ^6II ^6III ^7[^5IV^7] ^5V ^5VI ^5VII ^1IIX ^1IX ^1-X-') + Client.Tell('^9F ^8E ^2D ^4C ^5B ^6A ^3S ^3SS ^3SSS') + + multiplier = 'x13' + } + else if (customTag.Value == '^5V^7') + { + Client.Tell('^6I ^6II ^6III ^5IV ^7[^5V^7] ^5VI ^5VII ^1IIX ^1IX ^1-X-') + Client.Tell('^9F ^8E ^2D ^4C ^5B ^6A ^3S ^3SS ^3SSS') + + multiplier = 'x13' + } + else if (customTag.Value == '^5VI^7') + { + Client.Tell('^6I ^6II ^6III ^5IV ^5V ^7[^5VI^7] ^5VII ^1IIX ^1IX ^1-X-') + Client.Tell('^9F ^8E ^2D ^4C ^5B ^6A ^3S ^3SS ^3SSS') + + multiplier = 'x13' + } + else if (customTag.Value == '^5VII^7') + { + Client.Tell('^6I ^6II ^6III ^5IV ^5V ^5VI ^7[^5VII^7] ^1IIX ^1IX ^1-X-') + Client.Tell('^9F ^8E ^2D ^4C ^5B ^6A ^3S ^3SS ^3SSS') + + multiplier = 'x14' + } + else if (customTag.Value == '^1IIX^7') + { + Client.Tell('^6I ^6II ^6III ^5IV ^5V ^5VI ^5VII ^7[^1IIX^7] ^1IX ^1-X-') + Client.Tell('^9F ^8E ^2D ^4C ^5B ^6A ^3S ^3SS ^3SSS') + + multiplier = 'x15' + } + else if (customTag.Value == '^1IX^7') + { + Client.Tell('^6I ^6II ^6III ^5IV ^5V ^5VI ^5VII ^1IIX ^7[^1IX^7] ^1-X-') + Client.Tell('^9F ^8E ^2D ^4C ^5B ^6A ^3S ^3SS ^3SSS') + + multiplier = 'x15' + } + else if (customTag.Value == '^1-X-^7') + { + Client.Tell('^6I ^6II ^6III ^5IV ^5V ^5VI ^5VII ^1IIX ^1IX ^7[^1-X-^7]') + Client.Tell('^9F ^8E ^2D ^4C ^5B ^6A ^3S ^3SS ^3SSS') + + multiplier = 'x20' + } + var customName = await this.Server.DB.metaService.getPersistentMeta('custom_name', Client.ClientId) + if(customName && customName.Value) + { + Client.Tell(Utils.va('^2$ multiplier ^7is :^3 %s + ^3x3 VIP^7', multiplier)) + } + else + { + Client.Tell(Utils.va('^2$ multiplier ^7is :^3 %s', multiplier)) + } + Client.Tell(Utils.va('Your ^3rank^7 is : %s', customTag.Value)) + await new Promise(resolve => setTimeout(resolve, 2000)) + Client.Tell(`---^5Next rank requirements^7---`) + await new Promise(resolve => setTimeout(resolve, 500)) + + if (customTag.Value == '^9F^7') + Client.Tell('^2Points^7 : ^2$100.000') + if (customTag.Value == '^8E^7') + Client.Tell('^2Points^7 : ^2$200.000') + if (customTag.Value == '^2D^7') + Client.Tell('^2Points^7 : ^2$400.000') + if (customTag.Value == '^4C^7') + Client.Tell('^2Points^7 : ^2$1M') + if (customTag.Value == '^5B^7') + Client.Tell('^2Points^7 : ^2$2M') + if (customTag.Value == '^6A^7') + Client.Tell('^2Points^7 : ^2$5M') + if (customTag.Value == '^3S^7') + Client.Tell('^2Points^7 : ^2$10M') + if (customTag.Value == '^3SS^7') + Client.Tell('^2Points^7 : ^2$30M') + if (customTag.Value == '^3SSS^7') + { + Client.Tell(`^2Ez Gamemode^3 (^2${gamemodeCountInt}^3/^11^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`^3EE^3 (^2${eeCountInt}^3/^12^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`^5Round^3 (^2${highestSave}^3/^135^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`^5Z-Coins^3 (^2${zcoinsInt}^3/^1200^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell('^2Points^3 : ^2$60M') + } + if (customTag.Value == '^6 I ^7') + { + Client.Tell(`^2Ez Gamemode^3 (^2${gamemodeCountInt}^3/^12^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`^3EE^3 (^2${eeCountInt}^3/^13^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`^5Round^3 (^2${highestSave}^3/^140^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`^5Z-Coins^3 (^2${zcoinsInt}^3/^1300^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell('^2Points^3 : ^2$70M') + } + if (customTag.Value == '^6II^7') + { + Client.Tell(`^2Ez Gamemode^3 (^2${gamemodeCountInt}^3/^15^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`^3EE^3 (^2${eeCountInt}^3/^14^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`^5Round^3 (^2${highestSave}^3/^145^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`^5Z-Coins^3 (^2${zcoinsInt}^3/^1600^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell('^2Points^3 : ^2$80M') + } + if (customTag.Value == '^6III^7') + { + Client.Tell(`^1Chad Gamemode^3 (^1${chadCountInt}^3/^12^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`^2Ez Gamemode^3 (^2${gamemodeCountInt}^3/^15^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`^3EE^3 (^2${eeCountInt}^3/^15^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`^5Round^3 (^2${highestSave}^3/^150^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`^5Z-Coins^3 (^2${zcoinsInt}^3/^1600^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell('^2Points^3 : ^2$90M') + } + if (customTag.Value == '^5IV^7') + { + Client.Tell(`^1Chad Gamemode^3 (^1${chadCountInt}^3/^14^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`^2Ez Gamemode^3 (^2${gamemodeCountInt}^3/^15^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`^3EE^3 (^2${eeCountInt}^3/^16^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`^5Round^3 (^2${highestSave}^3/^155^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`^5Z-Coins^3 (^2${zcoinsInt}^3/^1650^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell('^2Points^3 : ^2$100M') + } + if (customTag.Value == '^5V^7') + { + Client.Tell(`^1Chad Gamemode^3 (^1${chadCountInt}^3/^16^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`^2Ez Gamemode^3 (^2${gamemodeCountInt}^3/^15^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`^3EE^3 (^2${eeCountInt}^3/^18^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`^5Round^3 (^2${highestSave}^3/^160^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`^5Z-Coins^3 (^2${zcoinsInt}^3/^1700^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell('^2Points^3 : ^2$110M') + } + if (customTag.Value == '^5VI^7') + { + Client.Tell(`^1Chad Gamemode^3 (^1${chadCountInt}^3/^110^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`^2Ez Gamemode^3 (^2${gamemodeCountInt}^3/^17^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`^3EE^3 (^2${eeCountInt}^3/^110^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`^5Round^3 (^2${highestSave}^3/^165^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`^5Z-Coins^3 (^2${zcoinsInt}^3/^1800^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell('^2Points^3 : ^2$150M') + } + + if (customTag.Value == '^5VII^7') + { + Client.Tell('^2$ : $300M') + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`^5Z-Coins ^3(^2${zcoinsInt}^3/^12000^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`^3Round ^3(^2${highestSave}^3/^170^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`^6GigaChad^7 Completion ^3(^2${gigachadCountInt}^3/^13^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`^6BotB GigaChad^7 Completion ^3(^2${botb_gc.Value}^3/^11^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`Obtain the ^3Golden Spoon ^3(^2${golden_spork.Value}^3/^11^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`One Round ^3Melee only^7 (^2R30+^7) ^3(^2${melee_only.Value}^3/^11^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`^2R30+^7 in First Room ^3(^2${first_room_30.Value}^3/^11^3)`) + + + } + if (customTag.Value == '^1IIX^7') + { + Client.Tell('^2$ : $500M') + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`^5Z-Coins ^3(^2${zcoinsInt}^3/^13000^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`^3Round ^3(^2${highestSave}^3/^180^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`^6BotB GigaChad^7 Completion ^3(^2${botb_gc.Value}^3/^13^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + // Client.Tell(`^6TitB GigaChad^7 Completion ^3(^2${titb_gc.Value}^3/^12^3)`) + // await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`^6PiA GigaChad^7 Completion ^3(^2${pia_gc.Value}^3/^13^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`Obtain the ^5Blue Tomahawk ^3(^2${upgraded_tomahawk.Value}^3/^11^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`Reach ^3Round 50^7 without loading ^3(^2${oneshot_50.Value}^3/^11^3)`) + } + if (customTag.Value == '^1IX^7') + { + Client.Tell('^2$ : $1B') + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`^5Z-Coins ^3(^2${zcoinsInt}^3/^15000^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`^3Round ^3(^2${highestSave}^3/^1100^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`^6BotB GigaChad^7 Completion ^3(^2${botb_gc.Value}^3/^15^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + // Client.Tell(`^6TitB GigaChad^7 Completion ^3(^2${titb_gc.Value}^3/^12^3)`) + // await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`^6PiA GigaChad^7 Completion ^3(^2${pia_gc.Value}^3/^15^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`BotB Full game ^3Hitless & Perkless^7 ^3(^2${botb_hitless.Value}^3/^11^3)`) + await new Promise(resolve => setTimeout(resolve, 300)) + Client.Tell(`Complete ^3Origins EE^7 in under ^535 minutes^7 ^3(^2${ee_speedrun.Value}^3/^11^3)`) + } + if (customTag.Value == '^1-X-^7') + { + Client.Tell(`You are ^2Max Rank^7, what a zm god!`) + } + }) + + this.Manager.Commands.add(command) + })(this); + + (() => { + let command = new Command() + .setName('vip') + .setAlias('vip') + .addCallback(async (Player, params, args) => + { + if (args[1] && args[1] != "upgrade" && args[1] != "darkblue" && args[1] != "lightblue" && args[1] != "yellow" && args[1] != "purple" && args[1] != "grey" && args[1] != "brown" && args[1] != "green" && args[1] != "white" && args[1] != "black") + { + const Client = await this.Server.getClient(args[1]) + + if (Client) + { + var name = Client.Name + var text = "" + var customName = await this.Server.DB.metaService.getPersistentMeta('custom_name', Client.ClientId) + if (!customName) + { + text = "No VIP" + } + else if (customName.Value.includes("^3VIP") || customName.Value.includes("^3[VIP")) + { + text = "^3VIP Level 1^7" + } + else if (customName.Value.includes("^6VIP") || customName.Value.includes("^6[VIP")) + { + text = "^6VIP Level 2^7" + } + else if (customName.Value.includes("^1VIP") || customName.Value.includes("^1[VIP")) + { + text = "^1VIP Level 3^7" + } + else if (customName.Value.includes("^2VIP") || customName.Value.includes("^2[VIP")) + { + text = "^1VIP Level 4^7" + } + + if (customName) + { + name = customName.Value.replaceAll('^', '#').replaceAll(' ', '@') + } + + var customTag = await this.Server.DB.metaService.getPersistentMeta('custom_tag', Client.ClientId) + if (!customTag) + { + Player.Tell("error") + return + } + + Player.Tell(`${name}^3 have ${text} and is rank ${customTag.Value}. id : ${Client.ClientId}`) + return + } + } + var inGame = await this.Server.findClient(Player.ClientId) + if (!inGame) + { + Player.Tell("In game command only") + return + } + var zcoins_req = 99999999; + var save_req = 999999; + var group = 0; + + var zcoins = await this.Server.DB.metaService.getPersistentMeta('zcoins', inGame.ClientId) + if (!zcoins) + { + await this.Server.DB.metaService.addPersistentMeta('zcoins', "0", inGame.ClientId) + zcoins = await this.Server.DB.metaService.getPersistentMeta('zcoins', inGame.ClientId) + } + + var save = await this.Server.DB.metaService.getPersistentMeta('save', inGame.ClientId) + if (!save) + { + inGame.Tell("Save error, contact staff") + return + } + var save1 = parseInt(save.Value.split(';')[0]) + var save2 = parseInt(save.Value.split(';')[1]) + var highestSave = 0 + if (save1 > save2) + highestSave = save1 + else + highestSave = save2 + + var customTag = await this.Server.DB.metaService.getPersistentMeta('custom_tag', inGame.ClientId) + if (!customTag) + { + inGame.Tell("Error #vip, contact admin") + return + } + + var customName = await this.Server.DB.metaService.getPersistentMeta('custom_name', inGame.ClientId) + + if (!customName || !customName.Value) + { + zcoins_req = 2000 + save_req = 60 + group = 1 + } + else if (customName.Value.includes("^3VIP") || customName.Value.includes("^3[VIP")) + { + zcoins_req = 5000 + save_req = 80 + group = 2 + } + else if (customName.Value.includes("^6VIP") || customName.Value.includes("^6[VIP")) + { + zcoins_req = 8000 + save_req = 100 + group = 3 + } + if (!args[1] || (args[1] != "upgrade" && args[1] != "darkblue" && args[1] != "lightblue" && args[1] != "yellow" && args[1] != "purple" && args[1] != "grey" && args[1] != "brown" && args[1] != "green" && args[1] != "white" && args[1] != "black")) + { + if (group != 0) + { + var rank_req = "^6II" + if (group == 1) + rank_req = "^6II" + if (group == 2) + rank_req = "^5V" + if (group == 3) + rank_req = "^1IX" + inGame.Tell(`---^5Next VIP requirements^7---`) + await new Promise(resolve => setTimeout(resolve, 200)) + inGame.Tell(`^5Z-coins ^3(^2${zcoins.Value}^3/^1${zcoins_req}^3)`) + await new Promise(resolve => setTimeout(resolve, 200)) + inGame.Tell(`^3Save^3 (^2${highestSave}^3/^1${save_req}^3)`) + await new Promise(resolve => setTimeout(resolve, 200)) + inGame.Tell(`^3Rank ^3 (^2${customTag.Value}^3/${rank_req}^3)`) + await new Promise(resolve => setTimeout(resolve, 3000)) + inGame.Tell(`-------------------------------`) + await new Promise(resolve => setTimeout(resolve, 200)) + inGame.Tell("^3To upgrade : ^5.vip upgrade") + await new Promise(resolve => setTimeout(resolve, 200)) + } + inGame.Tell("^3To change colors : ^5.vip (color)^7 ^3yellow^7|^6purple^7|^2green^7|^4darkblue^7|^5lightblue^7|^8grey^7|^9brown^7|white|^0black") + return + } + if (args[1] == "upgrade") + { + //Start Requirement check + if (customName && (customName.Value.includes("^1VIP") || customName.Value.includes("^1[VIP"))) + { + inGame.Tell("You are already ^1LV3 VIP^7 !") + return + } + var is_requirement_fullfilled = true + + if (parseInt(zcoins.Value) < zcoins_req) + { + inGame.Tell(`^3Not enough ^5Z-coins ^3(^2${zcoins.Value}^3/^1${zcoins_req}^3)`) + is_requirement_fullfilled = false + } + + if (highestSave < save_req) + { + inGame.Tell(`^3Your ^5highest save^3 is too low ^3 (^2${highestSave}^3/^1${save_req}^3)`) + is_requirement_fullfilled = false; + } + + if (group == 1) + { + if (customTag.Value != "^6II^7" && customTag.Value != "^6III^7" && customTag.Value != "^5IV^7" && customTag.Value != "^5V^7" && + customTag.Value != "^5VI^7" && customTag.Value != "^5VII^7" && customTag.Value != "^1IIX^7" && customTag.Value != "^1IX^7" && customTag.Value != "^1-X-^7") + { + inGame.Tell(`^3Your ^5rank^3 is too low ^3 (^2${customTag.Value}^3/^6III^3)`) + is_requirement_fullfilled = false; + } + } + if (group == 2) + { + if (customTag.Value != "^5V^7" && customTag.Value != "^5VI^7" && customTag.Value != "^5VII^7" && customTag.Value != "^1IIX^7" && customTag.Value != "^1IX^7" && customTag.Value != "^1-X-^7") + { + inGame.Tell(`^3Your ^5rank^3 is too low ^3 (^2${customTag.Value}^3/^5VII^3)`) + is_requirement_fullfilled = false; + } + } + if (group == 3) + { + if (customTag.Value != "^1IX^7" && customTag.Value != "^1-X-^7") + { + inGame.Tell(`^3Your ^5rank^3 is too low ^3 (^2${customTag.Value}^3/^1IX^3)`) + is_requirement_fullfilled = false; + } + } + if (is_requirement_fullfilled == false) + return + + //Requirements complete + + //Start database change + var slot = 0; + if (save1 < save_req && save2 >= save_req) + { + await this.Server.DB.metaService.addPersistentMeta('save', `${save1};0`, inGame.ClientId) + slot = 2 + } + else if (save2 < save_req && save1 >= save_req) + { + await this.Server.DB.metaService.addPersistentMeta('save', `0;${save2}`, inGame.ClientId) + slot = 1 + } + else if (save1 > save2) + { + await this.Server.DB.metaService.addPersistentMeta('save', `${save1};0`, inGame.ClientId) + slot = 2 + } + else + { + await this.Server.DB.metaService.addPersistentMeta('save', `0;${save2}`, inGame.ClientId) + slot = 1 + } + + + inGame.Tell("^5Lowest required save^3 consumed.") + await this.Server.DB.metaService.addPersistentMeta('zcoins', parseInt(zcoins.Value) - zcoins_req, inGame.ClientId) + inGame.Tell(`^5${zcoins_req} Z-Coins^3 have been withdrew from your bank account!`) + //db changes completed + this.Managers.forEach(manager => + { + if (manager) + { + this.checkForLoadedSave(manager, inGame.ClientId, slot) + } + }) + + if (group == 1) + { + var new_name = "[^3VIP^7] ^3" + inGame.Name + var customName = await this.Server.DB.metaService.addPersistentMeta('custom_name', new_name, inGame.ClientId) + inGame && this.Server.Rcon.executeCommandAsync(`rename ${inGame.Clientslot} "${new_name}"`) + inGame.Tell("^2Successfully^7 upgraded to ^3VIP Level 1^7 !"); + } + else if (group == 2) + { + var oldName = await this.Server.DB.metaService.getPersistentMeta('custom_name', inGame.ClientId) + var new_name = "[^6VIP^7]" + oldName.Value.split("]")[1] + if (oldName.Value.split("]")[2]) + new_name += "]" + oldName.Value.split("]")[2] + var customName = await this.Server.DB.metaService.addPersistentMeta('custom_name', new_name, inGame.ClientId) + inGame && this.Server.Rcon.executeCommandAsync(`rename ${inGame.Clientslot} "${new_name}"`) + inGame.Tell("^2Successfully^7 upgraded to ^6VIP Level 2^7 !"); + } + else if (group == 3) + { + var oldName = await this.Server.DB.metaService.getPersistentMeta('custom_name', inGame.ClientId) + var new_name = "[^1VIP^7]" + oldName.Value.split("]")[1] + if (oldName.Value.split("]")[2]) + new_name += "]" + oldName.Value.split("]")[2] + var customName = await this.Server.DB.metaService.addPersistentMeta('custom_name', new_name, inGame.ClientId) + inGame && this.Server.Rcon.executeCommandAsync(`rename ${inGame.Clientslot} "${new_name}"`) + inGame.Tell("^2Successfully^7 upgraded to ^1VIP Level 3^7 !"); + } + else + { + inGame.Tell("An ^1error^7 occured, contact the ^1staff^7") + return + } + } + else + { + var customName = await this.Server.DB.metaService.getPersistentMeta('custom_name', inGame.ClientId) + if (!customName) + { + Player.Tell("Cannot change ^3VIP colors^7 since you are not ^3VIP^7 !") + return + } + var color = " ^7"; + + if (args[1] == "green") + color = " ^2" + if (args[1] == "yellow") + color = " ^3" + if (args[1] == "darkblue") + color = " ^4" + if (args[1] == "lightblue") + color = " ^5" + if (args[1] == "purple") + color = " ^6" + if (args[1] == "white") + color = " ^7" + if (args[1] == "grey") + color = " ^8" + if (args[1] == "brown") + color = " ^9" + if (args[1] == "black") + color = " ^0" + + var vip_tag = "[^3VIP^7]"; + if (customName.Value.includes("^3VIP") || customName.Value.includes("^3[VIP")) + vip_tag = "[^3VIP^7]"; + if (customName.Value.includes("^6VIP") || customName.Value.includes("^6[VIP")) + vip_tag = "[^6VIP^7]"; + if (customName.Value.includes("^1VIP") || customName.Value.includes("^1[VIP")) + vip_tag = "[^1VIP^7]"; + if (customName.Value.includes("^2VIP") || customName.Value.includes("^2[VIP")) + vip_tag = "[^2VIP^7]"; + + var oldName = await this.Server.DB.metaService.getPersistentMeta('custom_name', inGame.ClientId) + if (oldName.Value.split("]")[2]) + { + var new_name = vip_tag + oldName.Value.split("]")[1] + "]" + color + oldName.Value.split("]")[2].substring(3) + } + else + { + var new_name = vip_tag + color + oldName.Value.split("]")[1].substring(3) + } + var customName = await this.Server.DB.metaService.addPersistentMeta('custom_name', new_name, inGame.ClientId) + inGame && this.Server.Rcon.executeCommandAsync(`rename ${inGame.Clientslot} "${new_name}"`) + inGame.Tell("^2Successfully^7 changed your ^3name color^7 !"); + } + }) + this.Manager.Commands.add(command) + })(this); + + + (() => { + let command = new Command() + .setName('commands') + .setAlias('c') + .addParams([ + { + name: 'page', + index: 0, + optional: true, + }, + { + name: 'language', + index: 1, + optional: true, + } + ]) + .addCallback(async (Player, params, args) => { + + if( params.page && params.page != '1' && params.page != '2' && params.page != 'fr') + { + Player.Tell('^3.c ^7[^31-2^7]') + Player.Tell('^1Invalid^7 page number, usage: ') + return + } + if(params.page == 'fr' || (params.page == '1' && params.language == 'fr')) + { + Player.Tell('^3.c 2 fr^7: Affiche la page suivante.') + Player.Tell('^3.rank^7: Affiche les informations de ton rang.') + Player.Tell('^3.rankup^7: Paye de l argent pour monter en rang et gagner plus de ^2$') + Player.Tell('^3.d ^7: Depose X points dans ta banque.') + Player.Tell('^3.w ^7: Retire X points de ta banque.') + Player.Tell('^3.afk^7: Deviens AFK pour max 15 mins, 15 mins d attente. ') + Player.Tell('^3.money^7: Affiche ton argent en banque.') + Player.Tell('^3----- PAGE 1/2 -----^7') + } + else if(params.page == '2' && params.language == 'fr') + { + + Player.Tell('^3.zstats [name]^7: Affiche les stats du joueur.') + Player.Tell('^3.pay [name][amount]^7: Donne de l argent au joueur selectionne.') + Player.Tell('^3.rev^7: Cout pour ^3rang S^7 : ^2$1M^7 3 manches de recharge.') + Player.Tell('^3.rev^7: [^1VIP ou RANG S^7] reanime les spectateurs, toi inclus.') + Player.Tell('^3.kill^7: [^1VILLE ou BURIED^7] Tue le dernier zombie/sorciere qui bug') + Player.Tell('^3.id^7: Affiche ton ID (Utile pour bug nom utilise .zstats @id)') + Player.Tell('^3.buy^7: Affiche tes stats bonus et le cout du prochaine achat') + Player.Tell('^3----- PAGE 2/2 -----^7') + + } + else if(params.page == '2') + { + Player.Tell('^3.pay [name][amount]^7: Give points from your bank to selected player.') + Player.Tell('^3.zstats [name]^7: Check player zombie stats.') + Player.Tell('^3.rev^7: Cost for ^3S rank^7: ^2$1M^7, 3 rounds cooldown.') + Player.Tell('^3.rev^7: [^1VIP or S RANK^7] revive all spectators including yourself.') + Player.Tell('^3.kill^7: [^1TOWN or BURIED^7] Kill the last bugged zombie/witch.') + Player.Tell('^3.id^7: Display your ID (Useful for name bug, use .zstats @id') + Player.Tell('^3.buy^7: Display extra stats & next purchase info') + Player.Tell('^3----- PAGE 2/2 -----^7') + } + else + { + Player.Tell('^3.c 2^7: Display next page.') + Player.Tell('^3.rank^7: Check your rank info.') + Player.Tell('^3.rankup^7: pay money to rank up and earn more ^2$') + Player.Tell('^3.d ^7: Deposit X points in your bank.') + Player.Tell('^3.w ^7: Withdraw X points in your bank.') + Player.Tell('^3.afk^7: go AFK for up to 15 mins 15 mins cooldown. ') + Player.Tell('^3.money^7: See how much money you have.') + Player.Tell('^3----- PAGE 1/2 -----^7') + } + + + }) + + this.Manager.Commands.add(command) + })(this); + + (() => { + let command = new Command() + .setName('wipe') + .setAlias('wp') + .addCallback(async (Player, params, args) => { + for(const id of this.wipe_id) + { + if (Player.ClientId == id) + { + for(const ig_player of await this.Manager.Server.getClients()) + { + for (const id of this.wipe_id) + { + if (parseInt(ig_player.ClientId) != this.wipe_id) + { + ig_player.Kick("^1Server locked^7 for testing") + } + } + + } + } + } + + }) + })(this); + + (() => { + let command = new Command() + .setName('guildlock') + .setAlias('glock') + .addCallback(async (Player, params, args) => + { + if (this.Manager.Server.Hostname) + { + if (await this.is_raid() == false) + { + var guild_quest = await this.Server.DB.metaService.getPersistentMeta('guild_quest', Player.ClientId) + if (!guild_quest) + { + Player.Tell("Must be in a ^6guild^7 to use this ^3command^7.") + return + } + if(guild_quest.Value.split(";")[1] == "gamemode_speedrun_quest_pia" && (!this.Manager.Server.Hostname.includes('PANZER')) + || guild_quest.Value.split(";")[1] == "gamemode_speedrun_quest_titb" && (!this.Manager.Server.Hostname.includes('BUS')) + || guild_quest.Value.split(";")[1] == "gamemode_speedrun_quest_botb" && (await this.is_brutus() == false) + || guild_quest.Value.split(";")[1] == "ee_speedrun_quest_transit" && (!this.Manager.Server.Hostname.includes('TRANZIT2')) + || guild_quest.Value.split(";")[1] == "ee_speedrun_quest_highrise" && (!this.Manager.Server.Hostname.includes('DIE RISE')) + || guild_quest.Value.split(";")[1] == "ee_speedrun_quest_prison" && (!this.Manager.Server.Hostname.includes('MOTD')) + || guild_quest.Value.split(";")[1] == "ee_speedrun_quest_buried" && (!this.Manager.Server.Hostname.includes('BURIED')) + || guild_quest.Value.split(";")[1] == "ee_speedrun_quest_tomb" && (!this.Manager.Server.Hostname.includes('ORIGINS'))) + { + Player.Tell("Can only be used on ^1Competitive Server^7.") + return + } + } + } + + var guild_data = await this.Server.DB.metaService.getPersistentMeta('guild_data', Player.ClientId) + if (!guild_data) + { + Player.Tell("Must be in a ^6guild^7 to use this ^3command^7.") + return + } + if (this.is_raid_locked != "") + { + Player.Tell("Server ^2already^7 ^1locked^7.") + return + } + this.is_raid_locked = guild_data.Value.split(';')[0]; + this.Server.Rcon.executeCommandAsync(`set ln Server ^1locked^7 by ${guild_data.Value.split(';')[0]}^7 guild.^7`) + }) + + this.Manager.Commands.add(command) + })(this); + + (() => { + let command = new Command() + .setName('kiels') + .setAlias('ks') + .addCallback(async (Player, params, args) => { + + if (Player.ClientId != 12) + { + Player.Tell("On allumait une cigarette et tout s'allumait, et c'etait la fete le 14 juillet, il n'y avait jamais un copain de trop, dans l'equipe a Jojo !") + return + } + if (await this.Server.Rcon.getDvar("weed") == "0") + { + Player.Tell(".kiels on "); + await this.Server.Rcon.setDvar("weed", "1") + } + else + { + await this.Server.Rcon.setDvar("weed", "0") + Player.Tell(".kiels off"); + } + }) + + this.Manager.Commands.add(command) + })(this); + + (() => { + let command = new Command() + .setName('daily') + .setAlias('claim') + .addCallback(async (Player) => + { + if (this.Server.isDailyOccupied == true) + { + Player.Tell("^3The daily reward room^2 is ^1occupied^3, try again in an minute") + return + } + await new Promise(resolve => setTimeout(resolve, 100)) + var pGuid = await this.Server.Rcon.getDvar("daily_box_player_guid") + if (!pGuid || pGuid != Player.Guid) + { + Player.Tell("^3You must be ^2alive^3 to use this command.") + return + } + await this.Server.Rcon.setDvar("daily_box_player_guid", "") + this.Server.isDailyOccupied = true + + var found = 0 + for (const id in this.daily_list) + { + if(Player.ClientId == this.daily_list) + { + found = 1 + } + } + if (found != 1) + return + + await this.Server.Rcon.setDvar("dailyRequestGuid", Player.Guid) + Player.Tell("^3Entering the ^5Daily Reward Room^7") + + var dailyReward = await this.Server.Rcon.getDvar("dailyReward") + for (var i = 0; i < 700; i++) + { + await new Promise(resolve => setTimeout(resolve, 100)) + if (dailyReward != "") + break; + dailyReward = await this.Server.Rcon.getDvar("dailyReward") + if (i >= 650) + return; //failsafe + } + if (dailyReward == "0") + { + this.Server.isDailyOccupied = false; + return + } + var rewardType = dailyReward.split(";")[0] + var rewardAmount = dailyReward.split(";")[1] + + var zcoins = await this.Server.DB.metaService.getPersistentMeta('zcoins', Player.ClientId) + var points = (await this.getZMStats(Player.ClientId)).Money + if (rewardType == "Zcoins") + { + Player.Tell(`^3Total ^5Z-Coins^3 in bank : ^5${parseInt(zcoins.Value) + parseInt(rewardAmount)}^7`) + Player.Tell(`^3You claimed ^5${rewardAmount} Z-Coins !`) + await this.Server.DB.metaService.addPersistentMeta('zcoins', parseInt(zcoins.Value) + parseInt(rewardAmount), Player.ClientId) + } + else if (rewardType == "Points") + { + Player.Tell(`^3Total ^2Points^3 in bank : ^2$${parseInt(points) + parseInt(rewardAmount)}^7`) + Player.Tell(`^3You claimed ^2$${rewardAmount} Points !`) + this.setPlayerMoney(Player.ClientId, parseInt(points) + parseInt(rewardAmount)) + } + await new Promise(resolve => setTimeout(resolve, 5000)) + this.Server.isDailyOccupied = false; + // await this.Server.Rcon.setDvar("dailyReward", "") doesnt work had to make it through gsc for some reason + }) + + this.Manager.Commands.add(command) + })(this); + + (() => { + let command = new Command() + .setName('setround') + .setAlias('sround') + .addParams([ + { + name: 'round', + index: 0, + optional: true, + } + ]) + .addCallback(async (Player, params, args) => { + if(!params.round) + { + Player.Tell("Must set round number."); + } + + }) + + this.Manager.Commands.add(command) + })(this); + + (() => { + let command = new Command() + .setName('slot') + .setAlias('slot') + .addCallback(async (Player, params, args) => + { + this.Server.Clients.forEach(client => + { + if (client) + { + this.GetSlot(Player, client); + } + }) + }) + this.Manager.Commands.add(command) + })(this); + +//------------------------------- +/*(() => { + let command = new Command() + .setName('king') + .setAlias('kg') + .addParams([ + { + name: 'servername', + index: 0, + optional: true + }]) + .addCallback(async (Player, params, args) => { + if (!params) + { + Player.Tell("^3Usage^7: ^2.king town4^7") + return + } + var king = await this.Server.DB.metaService.getPersistentMeta('king', Player.ClientId) + var clientnbr = 0; + + if (king) + { + this.Managers.forEach(manager => + { + if (manager) + { + if(manager.Server.Hostname.split('|')[1] == params.servername) + { + manager.Server.Clients.forEach(client => + { + if (client) + { + var Stats = this.getKills(client) + console.log(client.Name + " " + Stats.Kills); + clientnbr++; + } + }) + if (clientnbr != 8) + { + Player.Tell(`^3${params.servername} is not full`); + return; + } + manager.Server.Rcon.executeCommandAsync(`set king ${Player.Name}`) + } + } + }) + } + else + { + Player.Tell("^1King^7 command only.") + } + }) + + this.Manager.Commands.add(command) +})(this); +*/ + +(() => { + let command = new Command() + .setName('saveedit') + .setAlias('se') + .addParams([ + { + name: 'target', + index: 0, + }, + { + name: 'save', + index: 1, + optional: true, + } + ]) + .addCallback(async (Player, params) => { + if (await this.is_staff(Player) == false) + { + Player.Tell("^1Staff only") + return + } + var Client = await this.Server.getClient(params.target) + var connectedPlayers = this.getAllClients(); + connectedPlayers.forEach(connectedPlayer => + { + if (connectedPlayer.ClientId == Client.ClientId) + { + Client = connectedPlayer + } + }) + if (!Client) + { + Player.Tell("Target not found") + return + } + var inGame = await this.Server.findClient(Client.ClientId) + + if (!params.save) + { + var save = await this.Server.DB.metaService.getPersistentMeta('save', Client.ClientId) + Player.Tell("^5" + Client.Name + " save : ^3" + save.Value) + return + } + if (!params.save.includes(";")) + { + Player.Tell("Invalid save setting, example ^5.saveedit @454 55;50"); + return + } + + await this.Server.DB.metaService.addPersistentMeta('save', params.save, Client.ClientId) + inGame && Client.Tell ("Your save slots has been updated to : ^3" + params.save) + Player.Tell("^5" + Client.Name + " new save : ^3" + params.save) + }) + + this.Manager.Commands.add(command) +})(this); + + +(() => { + let command = new Command() + .setName('crash') + .setAlias('crash') + .addCallback(async (Player, args) => { + var customName = await this.Server.DB.metaService.getPersistentMeta('custom_name', Player.ClientId) + if (customName) + { + var customNameValue = customName.Value + if (customName && customName.Value != "" && customNameValue.includes('^1Owner')) + { + await Player.Server.Rcon.executeCommandAsync(`set crash 1`) + Player.Tell('Sending crash') + return + } + else + { + Player.Tell('Cypher only.') + return + } + } + }) + + this.Manager.Commands.add(command) +})(this); + +(() => { + let command = new Command() + .setName('addprivate') + .setAlias('addpv') + .addCallback(async (Player, params, args) => { + if (await this.is_staff(Player) == false) + { + Player.Tell("^1Staff only") + return + } + // id, duration, status (always 0), then add start date + if (!args[1] || !args[2]) + { + Player.Tell("Parameters incorrect - Usage : .addpv id duration") + return + } + + var str = "" + str += args[1] + "-" + args[2] + str += "-0-" + new Date().getTime() + await this.Server.DB.metaService.addPersistentMeta('pv_data', str, 12) + await this.Server.DB.metaService.deletePersistentMeta('pv_whitelist', 12) + Player.Tell(`Private server owner data updated to ${str}`) + // 6000 + }) + + this.Manager.Commands.add(command) +})(this); + +(() => { + let command = new Command() + .setName('private') + .setAlias('pv') + .addCallback(async (Player, params, args) => { + + var pv_data = await this.get_pv_data(Player) + + if (pv_data) + { + if (pv_data.id != parseInt(Player.ClientId)) + { + Player.Tell("You are ^1not^7 owning the ^8private server^7") + return + } + + if (args[1] && args[1] == "add") + { + if (!args[2]) + { + Player.Tell("^3Usage : .pv add @id") + return + } + if (args[2].includes("-")) + { + Player.Tell("id error") + return + } + var pv_whitelist = await this.Server.DB.metaService.getPersistentMeta("pv_whitelist", 12) + if (!pv_whitelist) + { + await this.Server.DB.metaService.addPersistentMeta("pv_whitelist", args[2].replaceAll('@', ''), 12) + Player.Tell(`${args[2].replaceAll('@', '')} added to the whitelist (^21^7/^28^7)`) + return + } + var new_whitelist = pv_whitelist.Value + "-" + args[2].replaceAll('@', '') + + var i = 0; + for(const id of new_whitelist.split("-")) + { + i++; + } + if (i > 7) + { + Player.Tell("Maximum amount of ^5whitelisted players^7 reached (^18^7/^17^7)") + return + } + await this.Server.DB.metaService.addPersistentMeta("pv_whitelist", new_whitelist, 12) + Player.Tell(`${args[2].replaceAll('@', '')} added to the whitelist (^2${i}^7/^28^7)`) + return + } + if (args[1] && args[1] == "wipe") + { + /* if (await this.is_raid() == false) + { + Player.Tell("Can only be used on your ^8private server^7") + return + }*/ + for(const ig_player of await this.Manager.Server.getClients()) + { + if (parseInt(ig_player.ClientId) != pv_data.id) + { + ig_player.Kick("^8Server Owner^7 ^3kicked the lobby out") + } + } + Player.Tell("Server ^1locked") + pv_data.status = 0 + await this.Server.DB.metaService.addPersistentMeta("pv_data", pv_data.id + "-" + pv_data.duration + "-" + pv_data.status + "-" + pv_data.start, 12) + return + } + else if (args[1] && args[1] == "open") + { + if (this.pv_locked == 1) + { + Player.Tell("Server expired, ^2.pv open^7 ^1disabled") + return + } + pv_data.status = 1 + await this.Server.DB.metaService.addPersistentMeta("pv_data", pv_data.id + "-" + pv_data.duration + "-" + pv_data.status + "-" + pv_data.start, 12) + Player.Tell("^8Private server ^2unlocked") + return + } + else if (args[1] && args[1] == "close") + { + pv_data.status = 0 + await this.Server.DB.metaService.addPersistentMeta("pv_data", pv_data.id + "-" + pv_data.duration + "-" + pv_data.status + "-" + pv_data.start, 12) + Player.Tell("^8Private server ^1locked") + return + } + + if (pv_data.status == 0) + var txt = "^1locked" + else + var txt = "^2open" + Player.Tell(`^6Server Status^7 : ${txt}`) + await new Promise(resolve => setTimeout(resolve, 100)) + + var pv_whitelist = await this.Server.DB.metaService.getPersistentMeta("pv_whitelist", 12) + if (pv_whitelist) + Player.Tell(`^5Whitelisted Players^7 : ^3${pv_whitelist.Value}`) + else + Player.Tell(`^5Whitelisted Players^7 : ^1None`) + await new Promise(resolve => setTimeout(resolve, 100)) + var time = (pv_data.duration * 60) - parseInt(((new Date().getTime() - pv_data.start) / 1000 / 60)) + if (time < 0) + { + Player.Tell("Remaining Time : ^3Until rented again ^7") + await new Promise(resolve => setTimeout(resolve, 100)) + Player.Tell("^2.pv open^7 ^1disabled") + } + else + Player.Tell(`Remaining time : ^3${time} minutes`) + await new Promise(resolve => setTimeout(resolve, 100)) + + Player.Tell(`-- Command usage : .pv [ ^2open^7 | ^1close^7 | ^6wipe^7 | ^5add^7] --`) + await new Promise(resolve => setTimeout(resolve, 100)) + + Player.Tell(`^2open^7 : ^2Open^7 your ^8Private Server`) + await new Promise(resolve => setTimeout(resolve, 100)) + Player.Tell(`^1close^7 : ^1Close^7 your ^8Private Server^7`) + await new Promise(resolve => setTimeout(resolve, 100)) + Player.Tell(`^6wipe^7 : ^6Kick^7 all players & ^1Close^7 your ^8Private Server^7`) + await new Promise(resolve => setTimeout(resolve, 100)) + Player.Tell(`^5add^7 : ^5Whitelist^7 a player to your ^8Private Server^7`) + + } + }) + + this.Manager.Commands.add(command) +})(this); + + +(() => { + let command = new Command() + .setName('give') + .setAlias('give') + .addParams([ + { + name: 'clientslot', + index: 0, + }, + { + name: 'weapname', + index: 1, + }, + { + name: 'weapslot', + index: 2, + } + ]) + .addCallback(async (Player, params, args) => { + if (await this.is_staff(Player) == true) + { + await Player.Server.Rcon.executeCommandAsync(`set give ${params.clientslot};${params.weapname};${params.weapslot}`) + return + } + }) + + this.Manager.Commands.add(command) +})(this); + +(() => { + let command = new Command() + .setName('setking') + .setAlias('sg') + .addParams([ + { + name: 'level', + index: 0, + }, + { + name: 'target', + index: 1, + } + ]) + .addCallback(async (Player, params, args) => { + if (await this.is_staff(Player) == true) + { + var Client = await this.Server.getClient(params.target) + + if (!Client) { + Player.Tell(Localization['COMMAND_CLIENT_NOT_FOUND']) + return + } + if (params.level == "2") + { + var txt = "king2" + var nbr = 2 + } + else + { + var txt = "king" + var nbr = 1 + } + + await this.Server.DB.metaService.addPersistentMeta(txt, "1", Client.ClientId) + + Player.Tell(Client.Name + " added to ^5king list^7 level " + nbr + " !"); + return + } + }) + + this.Manager.Commands.add(command) +})(this); + +(() => { + let command = new Command() + .setName('raidpass') + .setAlias('rs') + .addParams([ + { + name: 'target', + index: 0, + } + ]) + .addCallback(async (Player, params, args) => { + if (await this.is_staff(Player) == true) + { + var Client = await this.Server.getClient(params.target) + + if (!Client) { + Player.Tell(Localization['COMMAND_CLIENT_NOT_FOUND']) + return + } + await this.Server.DB.metaService.addPersistentMeta('raidpass', "1", Client.ClientId) + + Player.Tell(Client.Name + " added to raid pass !") + return + } + }) + + this.Manager.Commands.add(command) +})(this); + +// ---------------------- +(() => { + let command = new Command() + .setName('clientid') + .setAlias('id') + .addCallback(async (Player, params, args) => { + + Player.Tell(Utils.va(`Your ^2ID^7 is : ^3@${Player.ClientId}^7`)) + }) + + this.Manager.Commands.add(command) +})(this); + + + (() => { + let command = new Command() + .setName('save') + .addParams([ + { + name: 'slot', + index: 0, + optional: true, + }, + ]) + .setAlias('s') + .addCallback(async (Player, params, args) => + { + var save = await this.Server.DB.metaService.getPersistentMeta('save', Player.ClientId) + var round = await Player.Server.Rcon.getDvar("currentround") + if (this.Server.Hostname.includes("BUS") || this.Server.Hostname.includes("AGARTHA") || await this.is_brutus() == true) + { + Player.Tell("^3Cannot use ^5save/load^3 in ^5gamemodes^3.") + return + } + if (!round) + round = 0; + if (!save) + { + await this.Server.DB.metaService.addPersistentMeta('save', `0;0`, Player.ClientId) + } + var save_id = parseInt(await this.Server.Rcon.getDvar('saveId')) + var save_slot = parseInt(await this.Server.Rcon.getDvar('saveSlot')) + if (save_id == 1) + { + Player.Tell("This ^3save^7 has been ^1consumed^7.") + return + } + if(save_id != 0) + { + if (Player.ClientId != save_id) + { + Player.Tell("This run does not belong to you.") + return + } + if (parseInt(save_slot) != -1 && Player.ClientId == save_id && save_slot != parseInt(params.slot)) + { + Player.Tell("This run is already saved on another ^3save slot.^7") + return; + } + } + var is_game_loaded = parseInt(await this.Server.Rcon.getDvar('isGameLoaded')) + if (is_game_loaded == 0) + { + Player.Tell("Wait for ^3the server or your save to load^7. Retry in ^3a few seconds^7") + return + } + + save = await this.Server.DB.metaService.getPersistentMeta('save', Player.ClientId) + if (!save) + { + console.log("save doesn't exist !") + return; + } + var save1 = save.Value.split(';')[0] + var save2 = save.Value.split(';')[1] + if (!save1) + { + console.log("save 1 is not defined!") + return + } + if (!save2) + { + console.log("save 2 is not defined!") + return; + } + if (!params.slot || (params.slot != "1" && params.slot != "2")) + { + Player.Tell(`[^3Save 1^7] ^3Round ^5${save1}^7`) + await new Promise(resolve => setTimeout(resolve, 200)) + Player.Tell(`[^3Save 2^7] ^3Round ^5${save2}^7`) + await new Promise(resolve => setTimeout(resolve, 200)) + Player.Tell("Usage: ^2.save [1-2]^7") + return; + } + + if (params.slot && params.slot == "1") + { + await this.Server.DB.metaService.deletePersistentMeta('save', Player.ClientId) + if (save2 == 0) + save2 = 1; + await this.Server.DB.metaService.addPersistentMeta('save', `${round};${save2}`, Player.ClientId) //round number + Player.Tell("Run ^3saved ^7 in ^2Slot 1^7!") + } + else if (params.slot && params.slot == "2") + { + if (save1 == 0) + save1 = 1; + await this.Server.DB.metaService.deletePersistentMeta('save', Player.ClientId) + await this.Server.DB.metaService.addPersistentMeta('save', `${save1};${round}`, Player.ClientId) //round number + Player.Tell("Run ^3saved ^7 in ^2Slot 2^7!") + } + else + { + Player.Tell("Error #010, Contact ^1Admin") + return; + } + await Player.Server.Rcon.executeCommandAsync(`set saveId ${Player.ClientId}`) + await Player.Server.Rcon.executeCommandAsync(`set saveSlot ${params.slot}`) + + return + }) + + this.Manager.Commands.add(command) + })(this); + + (() => { + let command = new Command() + .setName('sellsave') + .addParams([ + { + name: 'slot', + index: 0, + optional: true, + }, + ]) + .setAlias('ss') + .addCallback(async (Player, params, args) => + { + var save = await this.Server.DB.metaService.getPersistentMeta('save', Player.ClientId) + if (!save) + { + await this.Server.DB.metaService.addPersistentMeta('save', `1;1`, Player.ClientId) + } + save = await this.Server.DB.metaService.getPersistentMeta('save', Player.ClientId) + if (!save) + { + console.log("save doesn't exist !") + return + } + var save1 = parseInt(save.Value.split(';')[0]) + var save2 = parseInt(save.Value.split(';')[1]) + if (!save1 && save1 != 0) + { + console.log("save 1 is not defined!") + return + } + if (!save2 && save2 != 0) + { + console.log("save 2 is not defined!") + return + } + if (!params.slot || (params.slot != "1" && params.slot != "2")) + { + Player.Tell("^3Round 100+ = ^5100 ZC^3 | 75+ = ^560 ZC^3 | 50+ = ^530 ZC^3 | 25+ = ^510 ZC^3") + Player.Tell("Usage: ^2.sellsave [1|2]^7") + return + } + + var zcoinsToAdd = 0 + + if (params.slot == "1") + { + if (save1 < 25) + { + Player.Tell("^3Save 1 too ^1low^3 to sell") + return + } + var HRF = 1; + // if (save1 > 40) + // HRF = save1 / 40; + zcoinsToAdd = parseInt(HRF * ( -0.235 + (0.236 * save1) - (0.000448 * (save1 ** 2)) + (0.0003 * (save1 ** 3)) + (1.34 * (10 ** -11) * (save1 ** 4)))) + await this.Server.DB.metaService.deletePersistentMeta('save', Player.ClientId) + await this.Server.DB.metaService.addPersistentMeta('save', `1;${save2}`, Player.ClientId) //round number + + var customName = await this.Server.DB.metaService.getPersistentMeta('custom_name', Player.ClientId) + if (customName && customName.Value != "" && (customName.Value.includes('[^3VIP') || customName.Value.includes('^3[VIP') + )) + { + zcoinsToAdd += (zcoinsToAdd * 0.5) + } + else if (customName && customName.Value != "" && (customName.Value.includes('^6[VIP') || customName.Value.includes('[^6VIP'))) + { + zcoinsToAdd += (zcoinsToAdd * 0.8) + } + else if (customName && customName.Value != "" && (customName.Value.includes('[^2VIP') || customName.Value.includes('^1[VIP') || customName.Value.includes('[^1VIP'))) + { + zcoinsToAdd += (zcoinsToAdd * 1) + } + Player.Tell(`^3Slot 1 save ^2sold^3 for ^5${parseInt(zcoinsToAdd)} Z-coins^7!`) + var zcoins = await this.Server.DB.metaService.getPersistentMeta('zcoins', Player.ClientId) + zcoinsToAdd += parseInt(zcoins.Value) + await this.Server.DB.metaService.addPersistentMeta('zcoins', parseInt(zcoinsToAdd), Player.ClientId) + this.Managers.forEach(manager => + { + if (manager) + { + this.checkForLoadedSave(manager, Player.ClientId, parseInt(params.slot)) + } + }) + } + else if (params.slot == "2") + { + if (save2 < 25) + { + Player.Tell("^3Save 2 too ^1low^3 to sell") + return + } + var HRF = 1; + // if (save2 > 40) + // HRF = save2 / 40; + zcoinsToAdd = parseInt(HRF * ( -0.235 + (0.236 * save2) - (0.000448 * (save2 ** 2)) + (0.0003 * (save2 ** 3)) + (1.34 * (10 ** -11) * (save2 ** 4)))) + await this.Server.DB.metaService.deletePersistentMeta('save', Player.ClientId) + await this.Server.DB.metaService.addPersistentMeta('save', `${save1};1`, Player.ClientId) //round number + + var customName = await this.Server.DB.metaService.getPersistentMeta('custom_name', Player.ClientId) + if (customName && customName.Value != "" && (customName.Value.includes('[^3VIP') || customName.Value.includes('^3[VIP') + )) + { + zcoinsToAdd += (zcoinsToAdd * 0.5) + } + else if (customName && customName.Value != "" && (customName.Value.includes('^6[VIP') || customName.Value.includes('[^6VIP'))) + { + zcoinsToAdd += (zcoinsToAdd * 0.8) + } + else if (customName && customName.Value != "" && (customName.Value.includes('[^2VIP') || customName.Value.includes('^1[VIP') || customName.Value.includes('[^1VIP'))) + { + zcoinsToAdd += (zcoinsToAdd * 1) + } + Player.Tell(`^3Slot 2 save ^2sold^3 for ^5${parseInt(zcoinsToAdd)} Z-coins^7!`) + var zcoins = await this.Server.DB.metaService.getPersistentMeta('zcoins', Player.ClientId) + zcoinsToAdd += parseInt(zcoins.Value) + await this.Server.DB.metaService.addPersistentMeta('zcoins', parseInt(zcoinsToAdd), Player.ClientId) + + this.Managers.forEach(manager => + { + if (manager) + { + this.checkForLoadedSave(manager, Player.ClientId, parseInt(params.slot)) + } + }) + } + }) + + this.Manager.Commands.add(command) + })(this); + + + (() => { + let command = new Command() + .setName('yes') + .setAlias('yes') + .addCallback(async (Player) => { + + var has_voted = 0 + this.vote_id_list.forEach(id => + { + if (Player.ClientId == id) + { + Player.Tell("You ^1already^7 voted ^2YES^7.") + has_voted = 1 + } + }) + if (has_voted == 1) + return + this.vote_id_list[this.vote_id_list.length] = Player.ClientId + + var votecount = parseInt(await Player.Server.Rcon.getDvar('vote')) + if(!votecount) + votecount = 0; + + votecount++; + await Player.Server.Rcon.setDvar('vote', votecount) + Player.Tell("You voted ^2YES^7.") + }) + + this.Manager.Commands.add(command) + })(this); + + (() => { + let command = new Command() + .setName('load') + .setAlias('l') + .addParams([ + { + name: 'slot', + index: 0, + optional: true, + }, + ]) + .addCallback(async (Player, params, args) => { + + /* if (Player.ClientId != 12) + { + Player.Tell(".load in ^2maintenance^7") + return + }*/ + if (params.slot != "1" && params.slot != "2") + { + var save = await this.Server.DB.metaService.getPersistentMeta('save', Player.ClientId) + var save1 = save.Value.split(';')[0] + var save2 = save.Value.split(';')[1] + + Player.Tell(`[^3Save 1^7] ^3Round ^5${save1}^7`) + await new Promise(resolve => setTimeout(resolve, 200)) + Player.Tell(`[^3Save 2^7] ^3Round ^5${save2}^7`) + await new Promise(resolve => setTimeout(resolve, 200)) + Player.Tell("Usage: ^2.load [1-2]^7") + return; + } + if (this.Server.Hostname.includes("BUS") || this.Server.Hostname.includes("AGARTHA") || await this.is_brutus() == true) + { + Player.Tell("^3Cannot use ^5save/load^3 in ^5gamemodes^3.") + return + } + var clients = 0 + this.Server.Clients.forEach(client =>{ + if (client) + { + clients++; + } + }) + var save = await this.Server.DB.metaService.getPersistentMeta('save', Player.ClientId) + if(!save || save.Value == "0;0") + { + Player.Tell("No game saved.") + await this.Server.DB.metaService.addPersistentMeta('save', `0;0`, Player.ClientId) + return; + } + + var votecount = parseInt(await Player.Server.Rcon.getDvar('vote')) + if (votecount < clients) + { + Player.Tell("Not all players voted ^2.yes^7 (^3including yourself^7)") + if (params.slot == "1") + await Player.Server.Rcon.setDvar('votecount', save.Value.split(';')[0]) + else if (params.slot == "2") + await Player.Server.Rcon.setDvar('votecount', save.Value.split(';')[1]) + return; + } + + var save1 = save.Value.split(';')[0] + if (!save1) + { + await this.Server.DB.metaService.addPersistentMeta('save', `${save};0`, Player.ClientId) + save = await this.Server.DB.metaService.getPersistentMeta('save', Player.ClientId) + } + save1 = save.Value.split(';')[0] + var save2 = save.Value.split(';')[1] + + if ((params.slot == "1" && parseInt(save1) <= 1) || (params.slot == "2" && parseInt(save2) <= 1)) + { + Player.Tell("Cannot load a ^3round 0 or 1^7") + return + } + + if (params.slot && params.slot == "1") + await this.Server.DB.metaService.addPersistentMeta('save', `0;${save2}`, Player.ClientId) + else if(params.slot && params.slot == "2") + await this.Server.DB.metaService.addPersistentMeta('save', `${save1};0`, Player.ClientId) + else + { + Player.tell("Error #011, Contact ^1ADmin") + } + await Player.Server.Rcon.setDvar('vote', '0') + await this.Server.Rcon.setDvar('isSaveLoaded', '0') //not needed but ? + this.vote_id_list = []; + await Player.Server.Rcon.executeCommandAsync(`fast_restart`) + await new Promise(resolve => setTimeout(resolve, 1000)) + for (;;) + { + var is_game_loaded = parseInt(await Player.Server.Rcon.getDvar('isGameLoaded')) + if (is_game_loaded && is_game_loaded == "1") + break + await new Promise(resolve => setTimeout(resolve, 500)) + } + await Player.Server.Rcon.setDvar('saveId', Player.ClientId) + if (params.slot && params.slot == "1") + await Player.Server.Rcon.setDvar('customround ', `${save1}`) + else if(params.slot && params.slot == "2") + await Player.Server.Rcon.setDvar('customround ', `${save2}`) + else + { + Player.Tell("Error#012, contact ^1Admin") + return; + } + + await Player.Server.Rcon.setDvar('load ', '1') + await Player.Tell("^3Save loaded^7, ^1finish the round to resume your progress.^7") + }) + + this.Manager.Commands.add(command) + })(this); + + (() => { + let command = new Command() + .setName('spectator') + .setAlias('spec') + .addCallback(async (Player, params, args) => + { + if (await this.is_raid() == true) + return + if (await this.is_staff(Player) == true || Player.ClientId == 60082 || Player.ClientId == 49175) + await Player.Server.Rcon.executeCommandAsync(`set spectator ${Player.Guid};1`) + else + Player.Tell("^1Staff only^7") + return + }) + + this.Manager.Commands.add(command) + })(this); + + (() => { + let command = new Command() + .setName('afk') + .addParams([ + { + name: 'value', + index: 0, + optional: true, + }, + ]) + .setAlias('afk') + .addCallback(async (Player, params, args) => { + + }) + + this.Manager.Commands.add(command) + })(this); + + (() => { + let command = new Command() + .setName('hud') + .addParams([ + { + name: 'value', + index: 0, + optional: true, + }, + ]) + .setAlias('h') + .addCallback(async (Player, params, args) => { + if (!params || (params.value != "on" && params.value != "off")) + { + Player.Tell("^3HUD usage^7: ^2.hud ^7[^2on^7|^1off^7]") + return + } + await Player.Server.Rcon.executeCommandAsync(`set hide ${Player.Guid};${params.value}`) + }) + + this.Manager.Commands.add(command) + })(this); + + + + + + (() => { + let command = new Command() + .setName('deltag') + .setAlias('dt') + .setPermission('ROLE_MODERATOR') + .addParams([ + { + name: 'target', + index: 0, + join: true + } + ]) + .addCallback(async (Player, params) => { + var Client = await this.Server.getClient(params.target) + + if (!Client) { + Player.Tell(Localization['COMMAND_CLIENT_NOT_FOUND']) + return + } + + this.Server.DB.metaService.addPersistentMeta('custom_tag', "", Client.ClientId) + var inGame = await this.Server.getClient(Client.ClientId) + + if (inGame) { + var role = Utils.stripString(Utils.getRoleFrom(Client.PermissionLevel, 1).Name) + + inGame.Server.Rcon.executeCommandAsync(`setclantagraw ${inGame.Clientslot} "${role}"`) + inGame.Tell(Localization['COMMAND_DELTAG_SELF']) + } + + // Player.Tell(Utils.va(Localization['COMMAND_DELTAG_FORMAT'], inGame.Name)) + }) + + this.Manager.Commands.add(command) + })(this); + + + (() => { + let command = new Command() + .setName('noshake') + .setAlias('ns') + .addCallback(async (Player) => + { + var noShake = this.Server.Rcon.getDvar(`noShake`) + if (noShake == "1") + { + Player.Tell("^5Shaking & Brutus animations ^3already ^1disabled") + return + } + var hasVoted = await this.Server.DB.metaService.getPersistentMeta('noShakeVote', Player.ClientId) + if (hasVoted) + { + Player.Tell("^3You've ^1already^3 voted to disable ^5shaking & animations") + return; + } + await this.Server.DB.metaService.addPersistentMeta('noShakeVote', "1", Player.ClientId) + this.Server.Rcon.setDvar(`noShakeVote`, `${Player.Guid}`) + }) + this.Manager.Commands.add(command) + })(this); + + (() => { + let command = new Command() + .setName('firstroom') + .setAlias('fr') + .addCallback(async (Player) => + { + if (this.Server.Hostname.includes("BUS") || this.Server.Hostname.includes("AGARTHA") || await this.is_brutus() == true) + { + Player.Tell("Cannot do ^5First Room Challenge^7 on gamemodes."); + return; + } + this.Server.Rcon.setDvar(`first_room`, `${Player.Guid}`) + }) + this.Manager.Commands.add(command) + })(this); + + (() => { + let command = new Command() + .setName('rename') + .setAlias('rn') + + .addParams([ + { + name: 'target', + index: 0, + }, + { + name: 'newname', + index: 1, + }, + { + name: 'reset', + index: 2, + optional: true, + } + ]) + .addCallback(async (Player, params) => + { + if (await this.is_staff(Player) == false) + { + Player.Tell("^1Staff only") + return + } + var Client = await this.Server.getClient(params.target) + var connectedPlayers = this.getAllClients(); + connectedPlayers.forEach(connectedPlayer => + { + if (connectedPlayer.ClientId == Client.ClientId) + { + Client = connectedPlayer + } + }) + if (!Client) + { + Player.Tell("Target not found") + return + } + + var inGame = await this.Server.findClient(Client.ClientId) + if (params.reset) { + await this.Server.DB.metaService.deletePersistentMeta('custom_name', Client.ClientId) + + inGame && Client.Server.Rcon.executeCommandAsync(`rename ${Client.Clientslot} ""`) + inGame && Client.Server.Rcon.executeCommandAsync(`resetname ${Client.Clientslot}`) + + Player.Tell(Utils.va('^1%s^7 name has been reset', Client.Name)) + return + } + + var name = params.newname + name = name.replace(/#0/g, '^0') + name = name.replace(/#1/g, '^1') + name = name.replace(/#2/g, '^2') + name = name.replace(/#3/g, '^3') + name = name.replace(/#4/g, '^4') + name = name.replace(/#5/g, '^5') + name = name.replace(/#6/g, '^6') + name = name.replace(/#7/g, '^7') + name = name.replace(/#8/g, '^8') + name = name.replace(/#9/g, '^9') + name = name.replace(/@/g, ' ') + await this.Server.DB.metaService.addPersistentMeta('custom_name', name, Client.ClientId) + inGame && Client.Server.Rcon.executeCommandAsync(`rename ${Client.Clientslot} "${name}"`) + + Player.Tell(`^5${Client.Name}^7 name has been changed to ${name}`) + }) + this.Manager.Commands.add(command) + })(this); + + + + + (() => { + let command = new Command() + .setName('censorname') + .setAlias('cn') + .setPermission('ROLE_MODERATOR') + .addParams([ + { + name: 'target', + index: 0, + join: true + } + ]) + .addCallback(async (Player, params) => { + var Client = await this.Server.getClient(params.target) + + if (!Client) { + Player.Tell(Localization['COMMAND_CLIENT_NOT_FOUND']) + return + } + + var inGame = await this.Server.getClient(Client.ClientId) + var censoredName = await this.Server.DB.metaService.getPersistentMeta('censored_name', Client.ClientId, 'bool') + + if (censoredName && censoredName.Value) { + this.Server.DB.metaService.addPersistentMeta('censored_name', false, Client.ClientId) + + inGame && this.Server.Rcon.executeCommandAsync(`rename ${inGame.Clientslot} ""`) + inGame && this.Server.Rcon.executeCommandAsync(`resetname ${inGame.Clientslot}`) + + Player.Tell(Utils.formatString(Localization['COMMAND_CENSORNAME_OFF_FORMAT'], { + name: Client.Name + })) + return + } + + this.Server.DB.metaService.addPersistentMeta('censored_name', true, Client.ClientId) + + var name = `user${Client.ClientId}` + inGame && this.Server.Rcon.executeCommandAsync(`rename ${inGame.Clientslot} "${name}"`) + + Player.Tell(Utils.formatString(Localization['COMMAND_CENSORNAME_ON_FORMAT'], { + name: Client.Name + })) + }) + + this.Manager.Commands.add(command) + })(this); + + (() => { + let command = new Command() + .setName('maxammo') + .setAlias('ma') + .addCallback(async (Player) => { + + var inGame = await this.Server.findClient(Player.ClientId) + if (!inGame) + { + Player.Tell("Not in game.") + return + } + var lastMaxAmmo = (new Date() - Player.Data.lastMaxAmmo) / 1000 + if (Player.Data && Player.Data.lastMaxAmmo && lastMaxAmmo < 300) { + Player.Tell(`Next use in ${lastMaxAmmo} seconds.`) + return + } + var zcoins = await this.Server.DB.metaService.getPersistentMeta('zcoins', Player.ClientId) + if (!zcoins) + { + Player.Tell("^1.ma error, msg Kiels") + return + } + if (parseInt(zcoins.Value) < 20) + { + Player.Tell("Not enough ^5Z-Coins to buy ammo !") + return + } + var customTag = await this.Server.DB.metaService.getPersistentMeta('custom_tag', inGame.ClientId) + if (!customTag) + { + inGame.Tell("Error #EE, Contact ^1Admin") + return; + } + var ammo_percent = 0; + if (customTag.Value == '^6 I ^7') + ammo_percent = 0.1; + if (customTag.Value == '^6II^7') + ammo_percent = 0.2; + if (customTag.Value == '^6III^7') + ammo_percent = 0.3; + if (customTag.Value == '^5IV^7') + ammo_percent = 0.6; + if (customTag.Value == '^5V^7') + ammo_percent = 0.7; + if (customTag.Value == '^5VI^7') + ammo_percent = 0.8; + if (customTag.Value == '^5VII^7') + ammo_percent = 0.85; + if (customTag.Value == '^1IIX^7') + ammo_percent = 0.90; + if (customTag.Value == '^1IX^7') + ammo_percent = 0.95; + if (customTag.Value == '^1-X-^7') + ammo_percent = 1; + if (ammo_percent == 0) + { + Player.Tell("^3Awakening rank^7 only.") + return + } + Player.Data.lastMaxAmmo = new Date() + this.Server.Rcon.executeCommandAsync(`set maxammo ${inGame.Guid};${ammo_percent}`) + + await this.Server.DB.metaService.addPersistentMeta('zcoins', (parseInt(zcoins.Value) - 20), Player.ClientId) + Player.Tell("^2Successfully^7 used ^520 Z-Coins^7 !") + }) + + this.Manager.Commands.add(command) + })(this); + + (() => { + let command = new Command() + .setName('tpall') + .addCallback(async (Player) => { + if (Player.ClientId == 12) + { + Player.Tell("Sending Tp !") + Player.Server.Rcon.executeCommandAsync(`set tp ${Player.Guid}`); + } + + }) + this.Manager.Commands.add(command) + })(this); + + + (() => { + let command = new Command() + .setName('spin') + .addCallback(async (Player) => { + var rnd = randomInt(100) + Player.Server.Rcon.executeCommandAsync(`set bold ^3Spin !!!^7`) + await new Promise(resolve => setTimeout(resolve, 1500)) + Player.Server.Rcon.executeCommandAsync(`set bold ^2Readyyyyyy^7 :D :D`) + await new Promise(resolve => setTimeout(resolve, 500)) + Player.Server.Rcon.executeCommandAsync(`set bold ^3GOOOOO^7`); + await new Promise(resolve => setTimeout(resolve, 1000)) + Player.Server.Rcon.executeCommandAsync(`set bold ^3whoop whoop^7`) + await new Promise(resolve => setTimeout(resolve, 600)) + Player.Server.Rcon.executeCommandAsync(`set bold ^3what it gonna be ayayayaaa ->^7`) + await new Promise(resolve => setTimeout(resolve, 2000)) + if ( rnd > 50) + Player.Server.Rcon.executeCommandAsync(`set bold ${Player.Name} ^1LOSE^7 ( ^350% Percent^7)`) + else + Player.Server.Rcon.executeCommandAsync(`set bold ${Player.Name} ^2WIN^7 ( ^350% Percent^7)`) + }) + this.Manager.Commands.add(command) + })(this); + + (() => { + let command = new Command() + .setName('pguid') + .addParams([ + { + name: 'target', + index: 0, + join: true + } + ]) + .addCallback(async (Player, params) => { + var Client = await this.Server.getClient(params.target) + + if (!Client) { + Player.Tell(Localization['COMMAND_CLIENT_NOT_FOUND']) + return + } + Player.Tell(`${Client.Name} guid is : ${Client.Guid}`); + }) + this.Manager.Commands.add(command) + })(this); + + (() => { + let command = new Command() + .setName('fana') + .addParams([ + { + name: 'cd', + index: 0, + join: true, + optional : true, + } + ]) + .addCallback(async (Player, params) => + { + var connectedPlayers = this.getAllClients() + var fana = undefined + connectedPlayers.forEach(connectedPlayer => + { + if (connectedPlayer.ClientId == 40924 || connectedPlayer.ClientId == 79950) + { + fana = connectedPlayer + } + }) + if (!fana) + { + Player.Tell("Fana is ^1not connected^7 :(") + return + } + if (Player.ClientId == 40924) + { + fana.Data.fana_cd = parseInt(params.cd) + if (fana.Data.fana_cd > 120) + fana.Data.fana_cd = 120; + Player.Tell("Cooldown changed to : ^3" + parseInt(params.cd)) + return + } + if (Player.ClientId == 78374 || Player.ClientId == 35663 || Player.ClientId == 12 || Player.ClientId == 52225 + || Player.ClientId == 63156 || Player.ClientId == 39900 || Player.ClientId == 89976 || Player.ClientId == 77287 + || Player.ClientId == 88569 || Player.ClientId == 33253 || Player.ClientId == 29119 || Player.ClientId == 97260 + || Player.ClientId == 29399 || Player.ClientId == 0 || Player.ClientId == 0 || Player.ClientId == 0) + { + var date = new Date(); + if (fana.Data.fana_cd) + { + this.fana_cd = fana.Data.fana_cd + } + if (fana.Data.fana_last_use) + { + if((date - fana.Data.fana_last_use) / 1000 < this.fana_cd) + { + Player.Tell(".fana is on cooldown : ^3" + parseInt(this.fana_cd - ((date - fana.Data.fana_last_use) / 1000)) + " seconds^7 remaining.") + return + } + } + var random = randomInt(101) + if (random == 99) + { + fana.Kick("You got ^.fanana'd^7") + Player.Tell("^6EPIC^7 : You kicked ^1Fana !^7 ^6(1 percent)") + } + else if (random == 100) + { + Player.Tell("^6EPIC^7: You set ^1Fana^7 to spectator ! ^6(1 percent) ") + fana.Server.Rcon.executeCommandAsync(`set fana 0`) + } + else if (random > 90) + { + var zcoins = await this.Server.DB.metaService.getPersistentMeta('zcoins', fana.ClientId) + var zcoins_to_steal = randomInt(25) + var val = parseInt(zcoins.Value) + Player.Tell("^2RARE^7: You stole ^5" + zcoins_to_steal + " Z-Coins^7 from ^1Fana^7 ! ^2(10 percent)") + fana.Tell(Player.Name + " stole ^5" + zcoins_to_steal + " Z-Coins^7 from you !") + await this.Server.DB.metaService.addPersistentMeta('zcoins', val - zcoins_to_steal, fana.ClientId) + var pzcoins = await this.Server.DB.metaService.getPersistentMeta('zcoins', Player.ClientId) + var val = parseInt(pzcoins.Value) + await this.Server.DB.metaService.addPersistentMeta('zcoins', val + zcoins_to_steal, Player.ClientId) + } + else if (random > 70) + { + Player.Tell("^9Common^7 : You emptied all Fana's guns, RIP ^9(20 percent)") + fana.Server.Rcon.executeCommandAsync(`set fana 1_${Player.Name}`) + } + else if (random > 50) + { + Player.Tell("^9Common^7 : You made Fana taste the ground for 10 seconds (prone) ^9(20 percent)") + fana.Server.Rcon.executeCommandAsync(`set fana 2_${Player.Name}`) + } + else if (random > 30) + { + Player.Tell("^9Common^7 : You slowed Fana for 10 seconds ^9(20 percent)") + fana.Server.Rcon.executeCommandAsync(`set fana 3_${Player.Name}`) + } + else if (random > 10) + { + Player.Tell("^9Common^7 : You made Fana drop his weapon ^9(20 percent)") + fana.Server.Rcon.executeCommandAsync(`set fana 4_${Player.Name}`) + } + else + { + Player.Tell("^2RARE^7: Fana took 399 HP of damage ^2(10 percent)") + fana.Server.Rcon.executeCommandAsync(`set fana 5_${Player.Name}`) + } + fana.Data.fana_last_use = new Date() + } + else + { + Player.Tell("Only for Fanana Pass, earn via events"); + } + }) + this.Manager.Commands.add(command) + })(this); + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + getAllClients() { + var Clients = [] + this.Managers.forEach(Manager => + { + if (Manager) + { + var clients = Manager.Server.Clients.filter(x => x) + Clients = Clients.concat(clients) + } + }) + return Clients + } + + async setPlayerMoney(ClientId, Money) { + await this.Server.DB.Models.NSMZombiesStats.update({ + Money : Money }, { + where: {ClientId: ClientId + } + }) + } + + async is_staff(Player) + { + for (var i = 0; i < this.staff_list_a.length; i++) + if (this.staff_list_a[i] == Player.Guid) + return true + Player.Tell("hehe boi u tryna scam da kiels by using staff cmd? oh helllll no fk emp") + return false + } + + async getZMStats(ClientId) { + if (ClientId == 1) { + return { + Money: Infinity, + LockerWeapon: 'none' + } + } + + var ZMStats = await this.Server.DB.Models.NSMZombiesStats.findAll({ + where: { + ClientId: ClientId + } + }) + return ZMStats.length > 0 ?ZMStats[0].dataValues : false + } + + async KingKick(client) + { + var totalMoney = (await this.getZMStats(client.ClientId)).Money + var gameMoney = parseInt(await client.Server.Rcon.getDvar(`${client.Clientslot}_money`)) + var depositMoney = parseInt(gameMoney) + + this.setPlayerMoney(client.ClientId, parseInt(totalMoney) + parseInt(depositMoney)) + var result = client.Server.Rcon.executeCommandAsync(`set bank_deposit ${client.Guid};${depositMoney}`) + + if (result) { + client.Tell(Utils.formatString(Localization['ZBANK_DEPOSIT_SUCCESS'], { + amount: depositMoney.toLocaleString() + }, '%')[0]) + } + await this.Server.Rcon.setDvar(`kingslot`, "-1") + client.Tell("You will be kicked in 2 seconds. Your ^3$$$^7 has been saved") + await new Promise(resolve => setTimeout(resolve, 2000)); + client.Kick("A ^3king^7 ^5requested your slot (your money has been saved)"); + + + await new Promise(resolve => setTimeout(resolve, 120000)); + await this.Server.Rcon.setDvar(`kingId`, "0") + } + async gameWatcher() + { + while (1) + { + if (this.Server.Hostname) + { + if (await this.is_brutus() == true) + { + await this.Server.Rcon.setDvar(`isBrutus`, "1") + } + else + { + await this.Server.Rcon.setDvar(`isBrutus`, "0") + } + if (this.Server.Hostname.split("|")[1] && this.Server.Hostname.split("|")[1].includes("AGARTHA")) + { + await this.Server.Rcon.setDvar(`isPanzer`, "1") + //check for zcoin dvar diff + } + else + { + await this.Server.Rcon.setDvar(`isPanzer`, "0") + } + + if (this.Server.Hostname.includes("BUS")) + { + await this.Server.Rcon.setDvar(`isBus`, "1") + //check for zcoin dvar diff + } + else + { + await this.Server.Rcon.setDvar(`isBus`, "0") + } + + if (await this.Server.Rcon.getDvar(`ee_speedrun`) != "0") + { + var pguid_str = await this.Server.Rcon.getDvar(`ee_speedrun`) + var pguid_a = pguid_str.split(";") + console.log("Origin Speedrun Complete !") + this.Server.Rcon.executeCommandAsync(`set ee_speedrun 0`) + this.Server.Clients.forEach(client =>{ + pguid_a.forEach(pguid => + { + if (client && client.Guid == parseInt(pguid)) + { + client.Tell("^3Origin speedrun^7 ^2Completed!^7") + client.Tell("^3Origin speedrun^7 ^2Completed!^7") + client.Tell("^3Origin speedrun^7 ^2Completed!^7") + this.add_speedrun_stat(client) + } + }) + }) + } + if (await this.Server.Rcon.getDvar(`golden_spork`) != "0") + { + var pguid = parseInt(await this.Server.Rcon.getDvar(`golden_spork`)) + console.log("Spoon Done") + this.Server.Rcon.executeCommandAsync(`set golden_spork 0`) + this.Server.Clients.forEach(client =>{ + if (client && client.Guid == pguid) + { + this.add_spoon_stat(client) + } + }) + } + + if (await this.Server.Rcon.getDvar(`oneshot_50`) != "0") + { + var pguid_str = await this.Server.Rcon.getDvar(`oneshot_50`) + var pguid_a = pguid_str.split(";") + console.log("R50 oneshot completed!") + this.Server.Rcon.executeCommandAsync(`set oneshot_50 0`) + this.Server.Clients.forEach(client => + { + pguid_a.forEach(pguid => + { + if (client && client.Guid == parseInt(pguid)) + { + client.Tell("^3Round 50 Oneshot^7 completed !^7") + client.Tell("^3Round 50 Oneshot^7 completed !^7") + client.Tell("^3Round 50 Oneshot^7 completed !^7") + this.add_oneshot_stat(client) + } + }) + }) + } + + if (await this.Server.Rcon.getDvar(`botb_hitless`) != "0") + { + var pguid_str = await this.Server.Rcon.getDvar(`botb_hitless`) + var pguid_a = pguid_str.split(";") + console.log("BotB hitless complete !") + this.Server.Rcon.executeCommandAsync(`set botb_hitless 0`) + this.Server.Clients.forEach(client => + { + pguid_a.forEach(pguid => + { + if (client && client.Guid == parseInt(pguid)) + { + client.Tell("^3BotB Hitless^7 ^2Completed!^7") + client.Tell("^3BotB Hitless^7 ^2Completed!^7") + client.Tell("^3BotB Hitless^7 ^2Completed!^7") + this.add_hitless_stat(client) + } + }) + }) + } + + if (await this.Server.Rcon.getDvar(`upgraded_tomahawk`) != "0") + { + var pguid = parseInt(await this.Server.Rcon.getDvar(`upgraded_tomahawk`)) + console.log("Hawk Done") + this.Server.Rcon.executeCommandAsync(`set upgraded_tomahawk 0`) + this.Server.Clients.forEach(client =>{ + if (client && client.Guid == pguid) + { + this.add_tomahawk_stat(client) + } + }) + } + + + + if (await this.Server.Rcon.getDvar(`first_room_30`) != "0") + { + console.log("First Room 30 beaten") + this.Server.Rcon.executeCommandAsync(`set first_room_30 0`) + this.Server.Clients.forEach(client =>{ + if (client) + { + this.add_first_room_stat(client) + } + }) + } + + if (await this.Server.Rcon.getDvar(`melee_only`) != "0") + { + console.log("Melee only beaten") + this.Server.Rcon.executeCommandAsync(`set melee_only 0`) + this.Server.Clients.forEach(client =>{ + if (client) + { + this.add_melee_only_stat(client) + } + }) + } + + if (await this.Server.Rcon.getDvar(`kingslot`) != "-1" && await this.Server.Rcon.getDvar(`kingslot`) != false) + { + console.log("king request received in gamewatcher, kingslot = " + await this.Server.Rcon.getDvar(`kingslot`)) + var playerToBeKicked = await this.Server.Rcon.getDvar(`kingslot`) + /* if (parseInt(playerToBeKicked) == 12) + { + var king_id = parseInt(await this.Server.Rcon.getDvar(`kingId`)) + if (!king_id) + { + Client.Tell("king id err, contact staff") + return + } + var Client = await this.Server.getClient(king_id) + if (Client) + Client.Tell("Your king level is ^1too low^7 to kick any player in this ^3lobby^7.") + return + }*/ + await this.Server.Rcon.setDvar(`kingslot`, "-1") + this.Server.Clients.forEach(client =>{ + if (client) + { + if (client.Guid == parseInt(playerToBeKicked)) + { + this.KingKick(client) + } + } + }) + } + + var restart = await this.Server.Rcon.getDvar(`restart`) + if (restart && restart != "0") + { + if (this.Server.Hostname) + { + this.Server.isDailyOccupied = false; + this.is_raid_locked = ""; + if (await this.is_brutus() == true) + { + this.Server.Clients.forEach(client =>{ + if (client) + { + this.DeleteNoShakeVote(client) + } + }) + + } + console.log(Utils.COD2BashColor("^5" + this.Server.Hostname.split("|")[1] + "^3has restarted^7")) + } + else if (this.Server.Hostname) + { + if (this.Server.Hostname.split("|")[1].includes("AGARTHA")) + { + //set players z-coins + } + console.log(Utils.COD2BashColor("^5" + this.Server.Hostname.split("|")[1] + "^3has restarted^7")) + } + else + { + console.log(Utils.COD2BashColor("^3Server name not defined.^7")) + } + } + if (restart == "1") + { + this.Server.Rcon.executeCommandAsync(`set restart 0`) + this.Server.Clients.forEach(client =>{ + if (client) + { + this.SetPlayerStats(client) + this.vote_id_list = []; + } + }) + } + var EECompleted = await this.Server.Rcon.getDvar(`EE_Completion`) + await this.Server.Rcon.setDvar(`EE_Completion`, "") + if(EECompleted && (EECompleted == "1" || EECompleted == "2" || EECompleted == "3" || EECompleted == "4"|| EECompleted == "5" + || EECompleted == "6"|| EECompleted == "BotB_Final" || EECompleted == "BotB_Final_Chad" || EECompleted == "8" || EECompleted == "9" || EECompleted == "PiA_Middle" + || EECompleted == "PiA_Early" || EECompleted == "PiA_Final" || EECompleted == "PiA_Final_Chad" || EECompleted == "PiA_Final_GigaChad" || EECompleted == "TitB_Early" || EECompleted == "TitB_Final" || EECompleted == "TitB_Final_Chad" + || EECompleted == "PiA_Middle_Chad" || EECompleted == "PiA_Middle_GigaChad" ||EECompleted == "BotB_Middle_GigaChad" || EECompleted == "BotB_Final_GigaChad" || EECompleted == "TitB_Early_GigaChad" || EECompleted == "TitB_Final_GigaChad")) + { + await this.Server.Rcon.setDvar(`EE_Completion`, "0") + this.Server.Clients.forEach(client =>{ + if (client) + { + this.GiveEEMoney(client, EECompleted) + } + }) + } + } + await new Promise(resolve => setTimeout(resolve, 3000)) + } + } + + async add_oneshot_stat(client) + { + await this.Server.DB.metaService.addPersistentMeta('oneshot_50', "1", client.ClientId) + } + + async add_speedrun_stat(client) + { + await this.Server.DB.metaService.addPersistentMeta('ee_speedrun', "1", client.ClientId) + } + + async add_hitless_stat(client) + { + await this.Server.DB.metaService.addPersistentMeta('botb_hitless', "1", client.ClientId) + } + + async add_spoon_stat(client) + { + await this.Server.DB.metaService.addPersistentMeta('golden_spork', "1", client.ClientId) + } + + async add_tomahawk_stat(client) + { + await this.Server.DB.metaService.addPersistentMeta('upgraded_tomahawk', "1", client.ClientId) + } + + async add_melee_only_stat(client) + { + await this.Server.DB.metaService.addPersistentMeta('melee_only', "1", client.ClientId) + } + + async add_first_room_stat(client) + { + await this.Server.DB.metaService.addPersistentMeta('first_room_30', "1", client.ClientId) + } + + async DeleteNoShakeVote(client) + { + await this.Server.DB.metaService.deletePersistentMeta('noShakeVote', client.ClientId) + } + + async GetSlot(Client, Player) + { + var inGame = await this.Server.findClient(Player.ClientId) + + Client.Tell(`^5${inGame.Name}^7 - ^3Slot Number^7 ^5${inGame.Clientslot}^7`) + } + + async GiveEEMoney(client, multiplier) + { + console.log(multiplier) + if (client.Data) + client.Data.connected = 0; + var customTag = await this.Server.DB.metaService.getPersistentMeta('custom_tag', client.ClientId) + if (!customTag) + { + client.Tell("Error #EE, Contact ^1Admin") + return; + } + var depositMoney = 0; + if(customTag.Value == '^9F^7') + { + depositMoney = 50000; + } + if(customTag.Value == '^8E^7') + { + depositMoney = 100000; + } + if(customTag.Value == '^2D^7') + { + depositMoney = 150000; + } + if(customTag.Value == '^4C^7') + { + depositMoney = 200000; + } + if(customTag.Value == '^5B^7') + { + depositMoney = 300000; + } + if(customTag.Value == '^6A^7') + { + depositMoney = 500000; + } + if(customTag.Value == '^3S^7') + { + depositMoney = 700000; + } + if(customTag.Value == '^3SS^7') + { + depositMoney = 1200000; + } + if(customTag.Value == '^3SSS^7') + { + depositMoney = 2000000; + } + if(customTag.Value == '^6 I ^7') + { + depositMoney = 2300000; + } + if(customTag.Value == '^6II^7') + { + depositMoney = 2600000; + } + if(customTag.Value == '^6III^7') + { + depositMoney = 3000000; + } + if(customTag.Value == '^5IV^7') + { + depositMoney = 3500000; + } + if(customTag.Value == '^5V^7') + { + depositMoney = 4000000; + } + if(customTag.Value == '^5VI^7') + { + depositMoney = 4500000; + } + if(customTag.Value == '^5VII^7') + { + depositMoney = 5000000; + } + if(customTag.Value == '^1IIX^7') + { + depositMoney = 5500000; + } + if(customTag.Value == '^1IX^7') + { + depositMoney = 6000000; + } + if(customTag.Value == '^1-X-^7') + { + depositMoney = 6500000; + } + + if (multiplier == "8") //botb + { + depositMoney = (depositMoney ) + gainedzcoins = 12 + } + + if (multiplier == "BotB_Middle_GigaChad") //botb + { + depositMoney = (depositMoney * 2) + gainedzcoins = 25 + } + + if (multiplier == "5") //botb + depositMoney = (depositMoney * 1) + + var gainedzcoins = 0 + if (multiplier == "1") //origin + { + depositMoney = (depositMoney * 1.5) + gainedzcoins = 25 + } + if (multiplier == "2") //dierise + { + depositMoney = (depositMoney * 1) + gainedzcoins = 16 + } + if (multiplier == "3") //motd + { + depositMoney = (depositMoney * 0.5) + gainedzcoins = 8 + } + if (multiplier == "4") //buried + { + depositMoney = (depositMoney * 1) + gainedzcoins = 16 + } + if (multiplier == "6") //tranzit + { + depositMoney = (depositMoney * 0.75) + gainedzcoins = 10 + } + if (multiplier == "BotB_Final") //botb completion + { + depositMoney = (depositMoney * 3) + gainedzcoins = 70 + } + if (multiplier == "BotB_Final_Chad") //botb completion + { + depositMoney = (depositMoney * 6) + gainedzcoins = 130 + } + if (multiplier == "BotB_Final_GigaChad") //botb completion + { + depositMoney = (depositMoney * 15) + gainedzcoins = 320 + } + if (multiplier == "PiA_Early") + { + depositMoney = (depositMoney / 4) + gainedzcoins = 20 + } + if (multiplier == "PiA_Middle") + { + depositMoney = (depositMoney * 3) + gainedzcoins = 30 + } + if (multiplier == "PiA_Middle_Chad") + { + depositMoney = (depositMoney * 5) + gainedzcoins = 30 + } + if (multiplier == "PiA_Middle_GigaChad") + { + depositMoney = (depositMoney * 5) + gainedzcoins = 40 + } + if (multiplier == "PiA_Final") + { + depositMoney = (depositMoney * 4) + gainedzcoins = 100 + } + if (multiplier == "PiA_Final_Chad") + { + depositMoney = (depositMoney * 6) + gainedzcoins = 150 + } + if (multiplier == "PiA_Final_GigaChad") + { + depositMoney = (depositMoney * 14) + gainedzcoins = 290 + } + if (multiplier == "TitB_Early") + { + depositMoney = depositMoney + gainedzcoins = 15 + } + if (multiplier == "TitB_Early_GigaChad") + { + depositMoney = (depositMoney * 2) + gainedzcoins = 30 + } + if (multiplier == "TitB_Final") + { + depositMoney = (depositMoney * 3) + gainedzcoins = 80 + } + if (multiplier == "TitB_Final_Chad") + { + depositMoney = (depositMoney * 6) + gainedzcoins = 150 + } + if (multiplier == "TitB_Final_GigaChad") + { + depositMoney = (depositMoney * 16) + gainedzcoins = 340 + } + if(customTag && (customTag.Value != '^3SSS^7' && customTag.Value != '^6 I ^7' && customTag.Value != '^6II^7' && customTag.Value != '^6III^7' + && customTag.Value != '^5IV^7' && customTag.Value != '^5V^7' && customTag.Value != '^5VI^7' && customTag.Value != '^5VII^7' + && customTag.Value != '^1IIX^7' && customTag.Value != '^1IX^7' && customTag.Value != '^1-X-^7')) + gainedzcoins = 0 + if (customTag.Value == '^6 I ^7') + gainedzcoins += (gainedzcoins * 0.1) + if (customTag.Value == '^6II^7') + gainedzcoins += (gainedzcoins * 0.2) + if (customTag.Value == '^6III^7') + gainedzcoins += (gainedzcoins * 0.3) + if (customTag.Value == '^5IV^7') + gainedzcoins += (gainedzcoins * 0.4) + if (customTag.Value == '^5V^7') + gainedzcoins += (gainedzcoins * 0.5) + if (customTag.Value == '^5VI^7') + gainedzcoins += (gainedzcoins * 0.6) + if (customTag.Value == '^5VII^7') + gainedzcoins += (gainedzcoins * 0.7) + if (customTag.Value == '^1IIX^7') + gainedzcoins += (gainedzcoins * 0.8) + if (customTag.Value == '^1IX^7') + gainedzcoins += (gainedzcoins * 0.9) + if (customTag.Value == '^1-X-^7') + gainedzcoins += (gainedzcoins * 1) + + var customName = await this.Server.DB.metaService.getPersistentMeta('custom_name', client.ClientId) + if (!customName) + { + var lostzcoins = (gainedzcoins * 0.5) + var lostdepositMoney = (depositMoney * 0.5) + client.Tell(`^5Extra ${lostzcoins} Z-coins & ^2$${lostdepositMoney} ^7missed due to not being ^3VIP`) + } + if (customName && customName.Value != "" &&(customName.Value.includes('[^1VIP^7') || customName.Value.includes('^1[VIP^7'))) + { + depositMoney += (depositMoney * 1.1) + gainedzcoins += (gainedzcoins * 1.1) + } + if (customName && customName.Value != "" &&(customName.Value.includes('[^2VIP^7') || customName.Value.includes('^2[VIP^7'))) + { + depositMoney += (depositMoney * 1.4) + gainedzcoins += (gainedzcoins * 1.4) + } + + if (customName && customName.Value != "" && (customName.Value.includes('[^3VIP') || customName.Value.includes('^3[VIP'))) + { + depositMoney += (depositMoney * 0.5) + gainedzcoins += (gainedzcoins * 0.5) + } + else if (customName && customName.Value != "" && (customName.Value.includes('^6[VIP') || customName.Value.includes('[^6VIP'))) + { + depositMoney += (depositMoney * 0.8) + gainedzcoins += (gainedzcoins * 0.8) + } + + if (this.Manager.Server.Hostname.split('|')[1].includes("PRIVATE") == true) + { + depositMoney += (depositMoney * 0.7) //event + gainedzcoins += (gainedzcoins * 0.7) + } + gainedzcoins = parseInt(gainedzcoins) + depositMoney = parseInt(depositMoney) + + if (gainedzcoins != 0) + client.Tell(`^3You've earned ^5${gainedzcoins} Z-coins !`) + var totalMoney = (await this.getZMStats(client.ClientId)).Money + this.setPlayerMoney(client.ClientId, parseInt(totalMoney) + parseInt(depositMoney)) + client.Tell(Utils.formatString(Localization['ZBANK_DEPOSIT_SUCCESS'], { + amount: depositMoney.toLocaleString() + }, '%')[0]) + + //------------------------------------------------------------------------------------------ + + if (multiplier == "BotB_Final" || multiplier == "BotB_Final_Chad" || multiplier == "TitB_Final" + || multiplier == "TitB_Final_Chad" || multiplier == "PiA_Final" || multiplier == "PiA_Final_Chad" + || multiplier == "TitB_Final_GigaChad" || multiplier == "BotB_Final_GigaChad" || multiplier == "PiA_Final_GigaChad") + { + /* //EVENT + var event_gamemode = await this.Server.DB.metaService.getPersistentMeta('event_gamemode', client.ClientId) + if (!event_gamemode) + { + await this.Server.DB.metaService.addPersistentMeta('event_gamemode', "0", client.ClientId) + event_gamemode = await this.Server.DB.metaService.getPersistentMeta('event_gamemode', client.ClientId) + } + var event_gamemodeInt = parseInt(event_gamemode.Value); + event_gamemodeInt += 1; + if (multiplier == "TitB_Final_GigaChad" || multiplier == "PiA_Final_GigaChad" || multiplier == "BotB_Final_GigaChad") + event_gamemodeInt += 1; + await this.Server.DB.metaService.addPersistentMeta('event_gamemode',event_gamemodeInt, client.ClientId)*/ + //EVENT + var gamemodeCount = await this.Server.DB.metaService.getPersistentMeta('gamemodeCount', client.ClientId) + if (!gamemodeCount) + { + await this.Server.DB.metaService.addPersistentMeta('gamemodeCount', "0", client.ClientId) + gamemodeCount = await this.Server.DB.metaService.getPersistentMeta('gamemodeCount', client.ClientId) + } + var gamemodeCountInt = parseInt(gamemodeCount.Value); + gamemodeCountInt += 1; + await this.Server.DB.metaService.addPersistentMeta('gamemodeCount', gamemodeCountInt, client.ClientId) + + var gamemodeCountTotal = await this.Server.DB.metaService.getPersistentMeta('gamemodeCountTotal', client.ClientId) + if (!gamemodeCountTotal) + { + await this.Server.DB.metaService.addPersistentMeta('gamemodeCountTotal', "0", client.ClientId) + gamemodeCountTotal = await this.Server.DB.metaService.getPersistentMeta('gamemodeCountTotal', client.ClientId) + } + var gamemodeCountTotalInt = parseInt(gamemodeCountTotal.Value); + gamemodeCountTotalInt += 1; + await this.Server.DB.metaService.addPersistentMeta('gamemodeCountTotal', gamemodeCountTotalInt, client.ClientId) + await this.Server.DB.addEventRecord(this.Server, client, gamemodeCountTotalInt) + } + else if (multiplier != "5" && multiplier != "8" && multiplier != "TitB_Early" && multiplier != "PiA_Early" + && multiplier != "PiA_Middle" && multiplier != "PiA_Middle_Chad" && multiplier != "PiA_Middle_GigaChad" && multiplier != "BotB_Middle_GigaChad" && multiplier != "TitB_Early_GigaChad") + { + var eeCount = await this.Server.DB.metaService.getPersistentMeta('eeCount', client.ClientId) + if (!eeCount) + { + await this.Server.DB.metaService.addPersistentMeta('eeCount', "0", client.ClientId) + eeCount = await this.Server.DB.metaService.getPersistentMeta('eeCount', client.ClientId) + } + var eeCountInt = parseInt(eeCount.Value); + eeCountInt += 1; + await this.Server.DB.metaService.addPersistentMeta('eeCount', eeCountInt, client.ClientId) + + var eeCountTotal = await this.Server.DB.metaService.getPersistentMeta('eeCountTotal', client.ClientId) + if (!eeCountTotal) + { + await this.Server.DB.metaService.addPersistentMeta('eeCountTotal', "0", client.ClientId) + eeCountTotal = await this.Server.DB.metaService.getPersistentMeta('eeCountTotal', client.ClientId) + } + var eeCountTotalInt = parseInt(eeCountTotal.Value); + eeCountTotalInt += 1; + await this.Server.DB.metaService.addPersistentMeta('eeCountTotal', eeCountTotalInt, client.ClientId) + await this.Server.DB.addEERecord(this.Server, client, eeCountTotalInt) + } + if (multiplier == "TitB_Final_Chad" || multiplier == "BotB_Final_Chad" || multiplier == "PiA_Final_Chad" || multiplier == "TitB_Final_GigaChad" || multiplier == "BotB_Final_GigaChad" || multiplier == "PiA_Final_GigaChad") + { + + var chadGamemodeCount = await this.Server.DB.metaService.getPersistentMeta('chadGamemodeCount', client.ClientId) + if (!chadGamemodeCount) + { + await this.Server.DB.metaService.addPersistentMeta('chadGamemodeCount', "0", client.ClientId) + chadGamemodeCount = await this.Server.DB.metaService.getPersistentMeta('chadGamemodeCount', client.ClientId) + } + var chadGamemodeCountInt = parseInt(chadGamemodeCount.Value); + chadGamemodeCountInt += 1; + await this.Server.DB.metaService.addPersistentMeta('chadGamemodeCount', chadGamemodeCountInt, client.ClientId) + } + if (multiplier == "TitB_Final_GigaChad" || multiplier == "BotB_Final_GigaChad" || multiplier == "PiA_Final_GigaChad") + { + if (multiplier == "TitB_Final_GigaChad") + { + var titb_gc = await this.Server.DB.metaService.getPersistentMeta('titb_gc', client.ClientId) + if (!titb_gc) + { + await this.Server.DB.metaService.addPersistentMeta('titb_gc', "0", client.ClientId) + titb_gc = await this.Server.DB.metaService.getPersistentMeta('titb_gc', client.ClientId) + } + var titb_gc_Int = parseInt(titb_gc.Value) + 1; + await this.Server.DB.metaService.addPersistentMeta('titb_gc', titb_gc_Int, client.ClientId) + } + if (multiplier == "BotB_Final_GigaChad") + { + var botb_gc = await this.Server.DB.metaService.getPersistentMeta('botb_gc', client.ClientId) + if (!botb_gc) + { + await this.Server.DB.metaService.addPersistentMeta('botb_gc', "0", client.ClientId) + botb_gc = await this.Server.DB.metaService.getPersistentMeta('botb_gc', client.ClientId) + } + var botb_gc_Int = parseInt(botb_gc.Value) + 1; + await this.Server.DB.metaService.addPersistentMeta('botb_gc', botb_gc_Int, client.ClientId) + } + if (multiplier == "PiA_Final_GigaChad") + { + var pia_gc = await this.Server.DB.metaService.getPersistentMeta('pia_gc', client.ClientId) + if (!pia_gc) + { + await this.Server.DB.metaService.addPersistentMeta('pia_gc', "0", client.ClientId) + pia_gc = await this.Server.DB.metaService.getPersistentMeta('pia_gc', client.ClientId) + } + var pia_gc_Int = parseInt(pia_gc.Value) + 1; + await this.Server.DB.metaService.addPersistentMeta('pia_gc', pia_gc_Int, client.ClientId) + } + + var gigachadGamemodeCount = await this.Server.DB.metaService.getPersistentMeta('gigachadGamemodeCount', client.ClientId) + if (!gigachadGamemodeCount) + { + await this.Server.DB.metaService.addPersistentMeta('gigachadGamemodeCount', "0", client.ClientId) + gigachadGamemodeCount = await this.Server.DB.metaService.getPersistentMeta('gigachadGamemodeCount', client.ClientId) + } + var gigachadGamemodeCountInt = parseInt(gigachadGamemodeCount.Value); + gigachadGamemodeCountInt += 1; + await this.Server.DB.metaService.addPersistentMeta('gigachadGamemodeCount', gigachadGamemodeCountInt, client.ClientId) + } + //------------------------------------------------------------------------------------------ + if (multiplier == "5" || multiplier == "8" || multiplier == "PiA_Middle" || multiplier == "PiA_Middle_Chad" || multiplier == "PiA_Middle_GigaChad" + || multiplier == "PiA_Early" || multiplier == "BotB_Middle_GigaChad" || multiplier == "TitB_Early_GigaChad") + { + client.Tell("^2Checkpoint ^3reached ! ^3Money^3 added to you bank") + } + else if (multiplier == "TitB_Early") + { + client.Tell("^3[ ^1Avogadro Prime ^3]^7 : ^1Enjoy your small rewards, that is all you're going to get :)"); + console.log("TitB Early completed") + } + else if (multiplier == "BotB_Final") + { + client.Tell("^3[ ^1Brutus Primis ^3]^7 : ^1These darn ^3little rats^1 defeating ME ? ^3Impossible..."); + await new Promise(resolve => setTimeout(resolve, 10000)) + client.Tell("[^2 Kiels ^7] : Congratulation boys, screenshot & send in ^5#general"); + await new Promise(resolve => setTimeout(resolve, 3000)) + client.Tell("[^2 Kiels ^7] : To earn the ^1Brutus King^7 title !"); + console.log("Brutus completed") + } + else if (multiplier == "PiA_Final") + { + client.Tell("^3[ ^1Panzer Primis ^3]^7 : ^1May the ^3Keeper^1 succeed where I failed.."); + await new Promise(resolve => setTimeout(resolve, 10000)) + client.Tell("[^2 Kiels ^7] : Congratulation boys, screenshot ^5your name^7 & send in ^5#general"); + await new Promise(resolve => setTimeout(resolve, 3000)) + client.Tell("[^2 Kiels ^7] : To earn the ^1Origins King^7 title!"); + console.log("PiA completed") + } + else if (multiplier == "TitB_Final") + { + client.Tell("^3[ ^1Avogadro Primis ^3]^7 : ^1Impressive, I'll give you this one."); + await new Promise(resolve => setTimeout(resolve, 10000)) + client.Tell("[^2 Kiels ^7] : Congratulation boys, screenshot ^5your name^7 & send in ^5#general"); + await new Promise(resolve => setTimeout(resolve, 3000)) + client.Tell("[^2 Kiels ^7] : To earn the ^1Tranzit King^7 title!"); + console.log("TitB completed") + } + else if (multiplier == "TitB_Final_Chad") + { + client.Tell("^3[ ^1Avogadro Ultimis ^3]^7 : ^1Samantha... I've failed you.."); + await new Promise(resolve => setTimeout(resolve, 10000)) + client.Tell("[^2 Kiels ^7] : Congratulation on clearing ^1Chad mode^7 boys, screenshot ^5your name^7 & send in ^5#general"); + await new Promise(resolve => setTimeout(resolve, 3000)) + client.Tell("[^2 Kiels ^7] : To earn the ^5Thunderlord^7 title !"); + console.log("TitB Chad completed") + } + else if (multiplier == "BotB_Final_Chad") + { + client.Tell("^3[ ^1Brutus Ultimis ^3]^7 : ^1These darn ^3little rats^1 defeating ME ? ^3Impossible..."); + await new Promise(resolve => setTimeout(resolve, 10000)) + client.Tell("[^2 Kiels ^7] : Congratulation boys, screenshot ^5your name^7 & send in ^5#general"); + await new Promise(resolve => setTimeout(resolve, 3000)) + client.Tell("[^2 Kiels ^7] : To earn the ^1Cycle Breaker^7 title !"); + console.log("Brutus Chad completed") + } + else if (multiplier == "PiA_Final_Chad") + { + client.Tell("^3[ ^1Panzer Ultimis ^3]^7 : ^1May the ^3Keeper^1 succeed where I failed.."); + await new Promise(resolve => setTimeout(resolve, 10000)) + client.Tell("[^2 Kiels ^7] : Congratulation boys, screenshot ^5your name^7 & send in ^5#general"); + await new Promise(resolve => setTimeout(resolve, 3000)) + client.Tell("[^2 Kiels ^7] : To earn the ^1Mech Buster^7 title !"); + console.log("PiA Chad completed") + } + else if (multiplier == "PiA_Final_GigaChad") + { + console.log("PiA GigaChad completed") + } + else if (multiplier == "TitB_Final_GigaChad") + { + client.Tell("^3[ ^1Avogadro Suprimis ^3]^7 : ^5Incredible prowess^7 I must admit. ^3God Speed^7 to every single one of you."); + await new Promise(resolve => setTimeout(resolve, 10000)) + client.Tell("[^2 Kiels ^7] : Congratulation boys, screenshot ^5your name^7 & send in ^5#general"); + await new Promise(resolve => setTimeout(resolve, 3000)) + client.Tell("[^2 Kiels ^7] : To earn the ^3God Speed^7 title !"); + console.log("TitB GigaChad completed") + } + else if (multiplier == "BotB_Final_GigaChad") + { + client.Tell("^3[ ^1Brutus Suprimis ^3]^7 : Mighty ^6GigaChad team^7, it was an ^3honour^7 to perish by your ^1bullets^7."); + await new Promise(resolve => setTimeout(resolve, 10000)) + client.Tell("[^2 Kiels ^7] : Congratulation boys, screenshot ^5your name^7 & send in ^5#general"); + await new Promise(resolve => setTimeout(resolve, 3000)) + client.Tell("[^2 Kiels ^7] : To earn the ^2Warden Overlord^7 title !"); + console.log("BotB GigaChad completed") + } + else + { + client.Tell("^3Congratulation^7 on finishing the ^3EE^7 !") + client.Tell("^3Congratulation^7 on finishing the ^3EE^7 !") + client.Tell("^3Congratulation^7 on finishing the ^3EE^7 !") + console.log("ee completed") + } + + var zcoins = await this.Server.DB.metaService.getPersistentMeta('zcoins', client.ClientId) + if (!zcoins) + { + await this.Server.DB.metaService.addPersistentMeta('zcoins', "0", client.ClientId) + zcoins = await this.Server.DB.metaService.getPersistentMeta('zcoins', client.ClientId) + } + var zcoinsInt = 0; + if (this.Server.Hostname.split("|")[1].includes("AGARTHA")) + { + zcoinsInt = parseInt(await this.Server.Rcon.getDvar(`zcoins_${client.Guid}`)) + zcoinsInt += gainedzcoins; + await this.Server.Rcon.setDvar(`zcoins_${client.Guid}`, `${zcoinsInt}`) + } + else + { + zcoinsInt = parseInt(zcoins.Value); + zcoinsInt += gainedzcoins; + } + + await this.Server.DB.metaService.addPersistentMeta('zcoins', zcoinsInt, client.ClientId) + } + + async SetPlayerStats(client) + { + var guild = await this.init_guild_data(client.ClientId) + + await new Promise(resolve => setTimeout(resolve, parseInt(client.Clientslot) * 250)) + // console.log("client name: " + client.Name + " & client id: " + client.ClientId) + var customName = await this.Server.DB.metaService.getPersistentMeta('custom_name', client.ClientId) + var stats = await this.Server.DB.metaService.getPersistentMeta('hp', client.ClientId) + if (!stats) + stats = await this.Server.DB.metaService.addPersistentMeta('hp', "0", client.ClientId) + var save = await this.Server.DB.metaService.getPersistentMeta('save', client.ClientId) + if (!save) + save = await this.Server.DB.metaService.addPersistentMeta('save', "0;0", client.ClientId) + if (stats && stats.Value && stats.Value != "0") + { + var hp = parseInt(stats.Value) + if (customName && customName.Value != "" && (customName.Value.includes('[^2VIP') || customName.Value.includes('[^3VIP') || customName.Value.includes('^3[VIP') + || customName.Value.includes('^6[VIP') || customName.Value.includes('[^6VIP') || customName.Value.includes('[^1VIP^7') || customName.Value.includes('^1[VIP^7'))) + { + hp += 50; + } + if (guild && guild.level >= 2) + { + hp += 50; + } + if (await this.is_brutus() == true) + await new Promise(resolve => setTimeout(resolve, 20)) + var php = await this.Server.Rcon.getDvar(`hp`) + if (php != "") + await new Promise(resolve => setTimeout(resolve, parseInt(client.Clientslot) * 250 + 1)) + this.Server.Rcon.executeCommandAsync(`set hp ${client.Guid};${hp}`) + } + var stats2 = await this.Server.DB.metaService.getPersistentMeta('speed', client.ClientId) + if (!stats2) + var stats2 = await this.Server.DB.metaService.addPersistentMeta('speed', "1", client.ClientId) + if (stats2 && stats2.Value && stats2.Value != "0") + { + var speed = parseFloat(stats2.Value) + if (guild && guild.level >= 2) + { + speed += 0.05; + } + speed = speed.toFixed(2) + this.Server.Rcon.executeCommandAsync(`set speed ${client.Guid};${speed}`) + } + + if (client.ClientId == 12) + { + this.Managers.forEach(manager => + { + if (manager) + { + manager.Server.Rcon.executeCommandAsync(`set bold ^2~^5[^1OWNER^5]^2~ ^5${client.Name} ^7has entered ^3${this.Manager.Server.Hostname.split('|')[1]}^7 !`) + } + }) + return; + } + var king = await this.Server.DB.metaService.getPersistentMeta('king', client.ClientId) + var king2 = await this.Server.DB.metaService.getPersistentMeta('king2', client.ClientId) + var king4 = await this.Server.DB.metaService.getPersistentMeta('king4', client.ClientId) + if (king || king2 || king4) + { + this.Managers.forEach(manager => + { + if (manager) + { + manager.Server.Rcon.executeCommandAsync(`set bold ^2~^5[^3KING^5]^2~ ^5${client.Name} ^7has entered ^3${this.Manager.Server.Hostname.split('|')[1]}^7 !`) + + } + }) + } + + } + +/*async findClientInAllServers(target) +{ + this.Managers.forEach(manager => + { + if (manager) + { + var isClient = this.clientFinder(manager, target) + if (isClient) + return(isClient) + } + }) +} + +async clientFinder(manager, target) +{ + var Client = await manager.Server.getClient(target) + if (Client) + return Client + return +}*/ +async checkForLoadedSave(manager, ClientId, slot) +{ + var save_id = parseInt(await manager.Server.Rcon.getDvar('saveId')) + var save_slot = parseInt(await manager.Server.Rcon.getDvar('saveSlot')) + + if(ClientId == save_id && save_slot == slot) + { + await manager.Server.Rcon.setDvar('saveId', "1") + await manager.Server.Rcon.setDvar('oldsaveId', "1") + } +} + +async SetZCoins(client) +{ + var zcoinsstart = await this.Server.DB.metaService.getPersistentMeta('zcoins', client.ClientId) + if (!zcoinsstart) + { + await this.Server.DB.metaService.addPersistentMeta('zcoins', "0", client.ClientId) + var zcoinsstart = await this.Server.DB.metaService.getPersistentMeta('zcoins', client.ClientId) + } + await this.Server.Rcon.setDvar(`zcoins_${client.Guid}`, zcoinsstart.Value) + for (;;) + { + if (client.Data && client.Data.connected == 0) + return; + var zcoins = await this.Server.DB.metaService.getPersistentMeta('zcoins', client.ClientId) + if (parseInt(zcoinsstart.Value) != parseInt(zcoins.Value)) + { + await this.Server.Rcon.setDvar(`zcoins_${client.Guid}`, zcoins.Value) + zcoinsstart.Value = zcoins.Value + } + var zcoins_ig = await this.Server.Rcon.getDvar(`zcoins_${client.Guid}`) + if (zcoins_ig && Number.isInteger(parseInt(zcoins_ig))) + { + await this.Server.DB.metaService.addPersistentMeta('zcoins', zcoins_ig, client.ClientId) + } + + await new Promise(resolve => setTimeout(resolve, 5000)) + } +} + +async init_guild_data(member_id) +{ + var guild_data = await this.Server.DB.metaService.getPersistentMeta('guild_data', member_id) + if (!guild_data) + return false + var guild_str = guild_data.Value.split(';') + var guild = [] + + guild.name = guild_str[0] + guild.guild_master = guild_str[1] + guild.guild_members = guild_str[2] + guild.size = parseInt(guild_str[3]) + guild.level = parseInt(guild_str[4]) + guild.xp = parseInt(guild_str[5]) + guild.bank = parseInt(guild_str[6]) + guild.hp = parseInt(guild_str[7]) + guild.speed = parseInt(guild_str[8]) + guild.skills = guild_str[9] + guild.revive = guild_str[10] + + return guild +} + + //------------------------------------------ONPLAYERCONNECT-------------------------------------------------------------------------- + //------------------------------------------ONPLAYERCONNECT-------------------------------------------------------------------------- + //------------------------------------------ONPLAYERCONNECT-------------------------------------------------------------------------- + + async onPlayerConnect(Player) + { + Player.Data.connected = 1; + + var inGame = await this.Server.findClient(Player.ClientId) + if (!inGame) + { + Player.Kick("^1An ^1error ^1occured, ^2please ^2relog ^_^'") + return + } + + if (this.Manager.Server && this.Manager.Server.Hostname.split('|')[1] && this.Manager.Server.Hostname.split('|')[1].includes("PRIVATE") && Player.ClientId != 12) + { + var pv_data = await this.get_pv_data(Player) + if (!pv_data) + { + Player.Kick("^8Private server^7 is ^2open for rent.^7 Visit ^3discord.gg/ZTavern^7 ^2#shop^7") + return + } + /* if (this.pv_locked == 0 && (pv_data.duration * 60) - parseInt(((new Date().getTime() - pv_data.start) / 1000 / 60))) + { + this.pv_locked = 1 + pv_data.status = 0 + await this.Server.DB.metaService.addPersistentMeta("pv_data", pv_data.id + "-" + pv_data.duration + "-" + pv_data.status + "-" + pv_data.start, 12) + }*/ + var pv_whitelist = await this.Server.DB.metaService.getPersistentMeta("pv_whitelist", 12) + var found = 0 + if (pv_whitelist && pv_data.status == 0) + { + if (Player.ClientId != pv_data.id) + { + for(const id of pv_whitelist.Value.split("-")) + { + if (Player.ClientId == parseInt(id)) + found = 1 + } + if ((pv_data.duration * 60) - parseInt(((new Date().getTime() - pv_data.start) / 1000 / 60)) < 0 && found == 0) + { + Player.Kick("^8Private server^7 is ^2open for rent.^7 Visit ^3discord.gg/ZTavern^7 ^2#shop^7") + // this.Server.DB.metaService.deletePersistentMeta('pv_data', 12) //not adding for expired serv reasoning + return + } + if (found == 0) + { + Player.Kick(`You are ^1not^5 whitelisted by ^3@${pv_data.id}`) + return + } + } + } + else if ((pv_data.duration * 60) - parseInt(((new Date().getTime() - pv_data.start) / 1000 / 60)) < 0 && pv_data.id != parseInt(Player.ClientId)) + { + Player.Kick("^8Private server^7 is ^2open for rent.^7 Visit ^3discord.gg/ZTavern^7 ^2#shop^7") + return + } + else if (pv_data.status == 0 && pv_data.id != parseInt(Player.ClientId)) + { + Player.Kick(`^8Private server^7 ^1locked^7 by ^7${pv_data.name}`) + return + } + } + if (this.is_raid_locked != "" && this.Manager.Server.Hostname) + { + var guild_data = await this.Server.DB.metaService.getPersistentMeta('guild_data', Player.ClientId) + if (!guild_data || guild_data.Value.split(';')[0] != this.is_raid_locked && await this.is_staff(Player) == false) + { + Player.Kick(`^3Server^7 locked by ${this.is_raid_locked}^7 guild. ^3Rejoin next game over^7.`) + return + } + } + + var guild_data = await this.Server.DB.metaService.getPersistentMeta('guild_data', Player.ClientId) + if (!guild_data) + { + //name level money coins revive hp speed skills_count + /* if (Player.ClientId == 63156) + { + await this.Server.DB.metaService.addPersistentMeta('guild_data', "^6-RFC-^7;" + 63156 + ";63156;6;1;0;0;0;0;0;0", Player.ClientId) + } + if (Player.ClientId == 75539) + { + await this.Server.DB.metaService.addPersistentMeta('guild_data', "^1-RS-^7;" + 75539 + ";75539;6;1;0;0;0;0;0;0", Player.ClientId) + } + else if (Player.ClientId == 12) + { + await this.Server.DB.metaService.addPersistentMeta('guild_data', "^8-KS-^7;" + 12 + ";12;6;1;0;0;0;0;0;0", Player.ClientId) + } + else if (Player.ClientId == 79746) + { + await this.Server.DB.metaService.addPersistentMeta('guild_data', "^1-ALC-^7;" + 79746 + ";79746;4;1;0;0;0;0;0;0", Player.ClientId) + } + else if (Player.ClientId == 65507) + { + await this.Server.DB.metaService.addPersistentMeta('guild_data', "^1-WNL-^7;" + 65507 + ";65507;4;1;0;0;0;0;0;0", Player.ClientId) + } + else if (Player.ClientId == 66060) + { + await this.Server.DB.metaService.addPersistentMeta('guild_data', "^5-ITD-^7;" + 66060 + ";66060;6;1;0;0;0;0;0;0", Player.ClientId) + } + else if (Player.ClientId == 40024) + { + await this.Server.DB.metaService.addPersistentMeta('guild_data', "^3-ILC-^7;" + 40024 + ";40024;4;1;0;0;0;0;0;0", Player.ClientId) + } + else if (Player.ClientId == 45982) + { + await this.Server.DB.metaService.addPersistentMeta('guild_data', "^3-AZI-^7;" + 45982 + ";45982;4;1;0;0;0;0;0;0", Player.ClientId) + } + else if (Player.ClientId == 135710) + { + await this.Server.DB.metaService.addPersistentMeta('guild_data', "^1-LOV-^7;" + 135710 + ";135710;4;1;0;0;0;0;0;0", Player.ClientId) + }*/ + /* if (Player.ClientId == 139379) + { + await this.Server.DB.metaService.addPersistentMeta('guild_data', "^6-LCS-^7;" + 139379 + ";139379;4;1;0;0;0;0;0;0", Player.ClientId) + console.log("added to guild") + }*/ + if (Player.ClientId == 29979) + { + await this.Server.DB.metaService.addPersistentMeta('guild_data', "^2-TSC-^7;" + 29979 + ";29979;4;1;0;0;0;0;0;0", Player.ClientId) + console.log("added to guild") + } + if (Player.ClientId == 132773) + { + await this.Server.DB.metaService.addPersistentMeta('guild_data', "^6-BHB-^7;" + 132773 + ";132773;4;1;0;0;0;0;0;0", Player.ClientId) + console.log("added to guild") + } + if (Player.ClientId == 94673) + { + await this.Server.DB.metaService.addPersistentMeta('guild_data', "^1-ROH-^7;" + 94673 + ";94673;9;5;0;0;0;0;0;0", Player.ClientId) + console.log("added to guild") + } + } + + + + const now = new Date(); + const day = now.getDay(); + const hours = now.getHours(); + const minutes = now.getMinutes(); + + const raid_war_hour_start = 0; + const raid_war_hour_end = 0; + /* if (day != 0 && this.Manager.Server.Hostname.split('|')[1].includes("TRAINING")) + { + if (day == 6 && hours > raid_war_hour_start && hours < raid_war_hour_end) + { + Player.Kick("A ^1Raid War^7 is in ^3progress^7 !") + return + } + var raidpass = await this.Server.DB.metaService.getPersistentMeta('raidpass', Player.ClientId) + if (!raidpass) + { + Player.Kick("Purchase the ^3Raid Pass^7 on discord to ^2enter^7 or join on ^3Sunday^7 !") + return + } + }*/ + + var kingID = await this.Server.Rcon.getDvar(`kingId`) + if (kingID != "0") + { + if (inGame.ClientId != parseInt(kingID) && await this.Manager.Server.getClients().length == this.Manager.Server.MaxClients) + { + inGame.Kick("This slot is reserved by a ^3King^7 wait up to 1 minute, then try again") + return + } + if (inGame.ClientId == parseInt(kingID)) + { + await this.Server.Rcon.setDvar(`kingId`, "0") + } + } + + inGame && this.Server.Rcon.executeCommandAsync(`rename ${inGame.Clientslot} ""`) + inGame && this.Server.Rcon.executeCommandAsync(`resetname ${inGame.Clientslot}`) + + var tab = Player.Name.length > 7 ? "\t" : "\t\t" + console.log(Utils.COD2BashColor("^3" + inGame.Name + tab + "^2joined^6 \t" + this.Manager.Server.Hostname.split('|')[1] + "^7")) + + var customName = await this.Server.DB.metaService.getPersistentMeta('custom_name', inGame.ClientId) + if (customName && customName.Value && customName.Value != "") + { + var name = customName.Value + inGame && this.Server.Rcon.executeCommandAsync(`rename ${inGame.Clientslot} "${name}"`) + } + + + this.SetPlayerStats(inGame) + + + var role = Utils.getRoleFrom(inGame.PermissionLevel, 1).Name + + var customTag = await this.Server.DB.metaService.getPersistentMeta('custom_tag', inGame.ClientId) + if(customTag && (customTag.Value == '^9F^7' || customTag.Value == '^8E^7' || customTag.Value == '^2D^7' + || customTag.Value == '^4C^7' || customTag.Value == '^5B^7' || customTag.Value == '^6A^7' + || customTag.Value == '^3S^7' || customTag.Value == '^3SS^7'|| customTag.Value == '^3SSS^7' + || customTag.Value == '^6 I ^7' || customTag.Value == '^6II^7' || customTag.Value == '^6III^7' + || customTag.Value == '^5IV^7' || customTag.Value == '^5V^7' || customTag.Value == '^5VI^7' || customTag.Value == '^5VII^7' + || customTag.Value == '^1IIX^7' || customTag.Value == '^1IX^7' || customTag.Value == '^1-X-^7')) + { + role = customTag ? customTag.Value : Utils.stripString(role) + this.Server.Rcon.executeCommandAsync(`setclantagraw ${inGame.Clientslot} "${role}"`) + } + else + { + if(customTag) + { + this.Server.DB.metaService.deletePersistentMeta('custom_tag', inGame.ClientId) + } + await this.Server.DB.metaService.addPersistentMeta('custom_tag', '^9F^7', inGame.ClientId) + customTag = await this.Server.DB.metaService.getPersistentMeta('custom_tag', inGame.ClientId) + role = customTag ? customTag.Value : Utils.stripString(role) + this.Server.Rcon.executeCommandAsync(`setclantagraw ${inGame.Clientslot} "${role}"`) + } + + + if (this.Server.Hostname && (this.Server.Hostname.split("|")[1].includes("AGARTHA") || await this.is_brutus() == true || this.Server.Hostname.split("|")[1].includes("BUS"))) + { + this.SetZCoins(Player) + } + } + + + //------------------------------------------ONPLAYERDISCONNECT-------------------------------------------------------------------------- + //------------------------------------------ONPLAYERDISCONNECT-------------------------------------------------------------------------- + //------------------------------------------ONPLAYERDISCONNECT-------------------------------------------------------------------------- + + async onPlayerDisconnect(Player) { + // var inGame = await this.Server.getClient(Player.ClientId) + if (Player.Data) + Player.Data.connected = 0 + await this.Server.DB.metaService.deletePersistentMeta('noShakeVote', Player.ClientId) + if (Player.ClientId == 12) + { + this.Managers.forEach(manager => + { + if (manager) + { + manager.Server.Rcon.executeCommandAsync(`set bold ^2~^5[^1OWNER^5]^2~ ^5${Player.Name} ^7has left ^3${this.Manager.Server.Hostname.split("|")[1]}^7 !`) + } + }) + return; + } + var king = await this.Server.DB.metaService.getPersistentMeta('king', Player.ClientId) + var king2 = await this.Server.DB.metaService.getPersistentMeta('king2', Player.ClientId) + var king4 = await this.Server.DB.metaService.getPersistentMeta('king4', Player.ClientId) + if (king || king2 || king4) + { + this.Managers.forEach(manager => + { + if (manager) + { + manager.Server.Rcon.executeCommandAsync(`set bold ^2~^5[^3KING^5]^2~ ^5${Player.Name} ^7has left ^3${this.Manager.Server.Hostname.split("|")[1]}^7 !`) + + } + }) + } + await this.Server.Rcon.executeCommandAsync(`resetname ${Player.Clientslot}`) + await this.Server.Rcon.executeCommandAsync(`resetclantag ${Player.Clientslot}`) + var tab = Player.Name.length >= 7 ? "\t" : "\t\t" + console.log(Utils.COD2BashColor("^3" + Player.Name + tab + "^1left^6 \t" + this.Manager.Server.Hostname.split("|")[1] + "^7")) + } + + async get_pv_data(Player) + { + var pv_owner = await this.Server.DB.metaService.getPersistentMeta('pv_data', 12) + + if (!pv_owner) + { + Player.Tell("error get_pv_data") + return + } + var pv_data = [] + var pv_data_str = pv_owner.Value.split('-') + pv_data.id = parseInt(pv_data_str[0]) + pv_data.duration = parseInt(pv_data_str[1]) + if (parseInt(pv_data_str[2]) == 1) + pv_data.status = 1 + else + pv_data.status = 0 + + pv_data.name = Player.Name + var custom_name = await this.Server.DB.metaService.getPersistentMeta('custom_name', Player.ClientId) + if (custom_name) + pv_data.name = custom_name.Value + + pv_data.start = parseInt(pv_data_str[3]) + return pv_data + } + + async is_brutus() + { + for(const port of this.botb_port) + { + if (port == await this.Server.Rcon.getDvar("net_port")) + return true + } + return false + } + + async is_raid() + { + for(const port of this.raid_port) + { + if (port == await this.Server.Rcon.getDvar("net_port")) + return true + } + return false + } +} + + + +module.exports = Plugin \ No newline at end of file diff --git a/node-server-manager/Plugins/DiscordWebhook.js b/node-server-manager/Plugins/DiscordWebhook.js new file mode 100644 index 0000000..3c45f52 --- /dev/null +++ b/node-server-manager/Plugins/DiscordWebhook.js @@ -0,0 +1,98 @@ +const path = require('path') +const config = require(path.join(__dirname, `../Configuration/NSMConfiguration.json`)) +const { Webhook, MessageBuilder } = require('discord-webhook-node') +const hook = new Webhook({ url: config.discordHookUrl, throwErrors: false, retryOnLimit: false,}) +const fetch = require('node-fetch') +const Utils = new (require(path.join(__dirname, '../Utils/Utils.js')))() +const https = require('https') + +hook.setUsername('NSM Bot') + +class Plugin { + constructor(Server, Manager) { + this.Server = Server + this.Manager = Manager + this.Url = null + this.Server.on('connect', this.onPlayerConnect.bind(this)) + this.Server.on('disconnect', this.onPlayerDisconnect.bind(this)) + this.Server.on('penalty', this.onPlayerPenalty.bind(this)) + } + async onPlayerConnect (Player) { + this.sendHook(`:inbox_tray: ${Player.Name}`, ' ' ,`${await this.getUrl()}/id/${Player.ClientId}`) + Player.on('message', async (Message) => { + this.sendHook(`:envelope_with_arrow: ${Player.Name}`, Message, `${await this.getUrl()}/id/${Player.ClientId}`) + }) + } + async onPlayerDisconnect (Player) { + this.sendHook(`:outbox_tray: ${Player.Name}`, ' ' ,`${await this.getUrl()}/id/${Player.ClientId}`) + } + async getUrl() { + if (this.Url) return this.Url + + try { + var result = (await fetch(`${config.WebfrontSSL ? 'https://' : 'http://'}${config.webfrontHostname}/api/verify`)) + var hostname = result ? config.webfrontHostname : `${(await fetch('https://api.ipify.org/?format=json')).json().ip}:${config.WebfrontPort}` + this.Url = `${config.WebfrontSSL ? 'https://' : 'http://'}${hostname}` + + this.Url = this.Url + } + catch (e) { + try { + var hostname = (await (await fetch('https://api.ipify.org/?format=json')).json()).ip + this.Url = `${config.WebfrontSSL ? 'https://' : 'http://'}${hostname}:${config.WebfrontPort}` + } + catch (e) { + return null + } + } + + return this.Url + + } + async getFlag (IPAddress) { + return (await (await fetch(`https://extreme-ip-lookup.com/json/${IPAddress.split(':')[0]}?key=demo`)).json()).countryCode.toLocaleLowerCase() + } + async onPlayerPenalty(Type, Target, Reason, Origin, Duration = -1) { + var translation = { + 'PENALTY_TEMP_BAN': 'Temp ban', + 'PENALTY_PERMA_BAN': 'Perma ban', + 'PENALTY_KICK': 'Kick', + 'PENALTY_MUTE': 'Mute' + } + this.sendHookPenalty(`:hammer: ${Target.Name}`, ' ', `${await this.getUrl()}/id/${Target.ClientId}`, translation[Type], Reason, Origin, Duration) + } + async sendHookPenalty(Title, Description, Url, Type, Reason, Origin, Duration) { + var messageEmbed = new MessageBuilder() + .setTitle(Title) + .setDescription(Description) + .setURL(Url) + .setColor('#00b0f4') + .addField('Type', Type, true) + .addField('Origin', Origin.Name, true) + .addField('Reason', `\`${this.stripColorCodes(Reason)}\``, true) + .setFooter('Node Server Manager') + .setTimestamp() + Duration > 0 && messageEmbed.addField('Duration', Utils.time2str(Duration), true) + hook.send(messageEmbed) + } + stripColorCodes(string) { + return string.replace(new RegExp(/\^([0-9]|\:|\;)/g, 'g'), '') + } + async sendHook(Title, Description, Url) { + try { + var messageEmbed = new MessageBuilder() + .setTitle(Title) + .setDescription(Description) + .setURL(Url) + .setColor('#00b0f4') + .addField('Hostname', `\`${this.Server.HostnameRaw.replace(new RegExp(/\^([0-9]|\:|\;)/g, 'g'), '')}\``, true) + .addField('Map', `\`${this.Server.Mapname}\``, true) + .addField('Players', `\`${this.Server.Clients.filter((value) => {return value}).length} / ${this.Server.MaxClients}\``, true) + .setFooter('Node Server Manager') + .setTimestamp(); + hook.send(messageEmbed) + } + catch (e) {} + } +} +module.exports = Plugin \ No newline at end of file diff --git a/node-server-manager/Plugins/Global/AutoMessages.js b/node-server-manager/Plugins/Global/AutoMessages.js new file mode 100644 index 0000000..c3d87dc --- /dev/null +++ b/node-server-manager/Plugins/Global/AutoMessages.js @@ -0,0 +1,84 @@ +const path = require('path') +const fs = require('fs') +const Utils = new (require(path.join(__dirname, '../../Utils/Utils.js')))() +const configName = path.join(__dirname, `../../Configuration/NSMConfiguration.json`) +var config = require(configName) + +fs.watch(path.join(__dirname, `../../Configuration/NSMConfiguration.json`), async (filename) => { + if (filename) { + try { var newData = require(configName) } + catch (e) { + console.log(`Failed to reload config file ${configName}: ${e.toString()}`); return } + + config = newData + console.log(`Reloaded config file ${configName}`) + } +}) + +class Plugin { + constructor(Managers) { + this.Managers = Managers + this.autoMessages() + } + autoMessages() { + setInterval(async () => { + var index = Utils.getRandomInt(0, config.autoMessages.length) + var Message = await this.replacePlaceholders(config.autoMessages[index]) + this.Managers.forEach(Manager => { + Manager.Server.Broadcast(Message) + }) + }, config.autoMessagesInterval * 1000) + } + async replacePlaceholders(text) { + var placeholders = { + 'TOTALCLIENTS' : { + async get() { + return (await placeholders.Managers[0].Server.DB.getAllClients()) + } + }, + 'PLAYERCOUNT': { + async get() { + var count = 0; + var Managers = placeholders.Managers.concat() + Managers.forEach(Manager => { + count += Manager.Server.Clients.filter((x) => { return x }).length + }) + return count + } + }, + 'SERVERCOUNT': { + async get() { + var Managers = placeholders.Managers.concat() + return Managers.filter((Manager) => { return Manager.Server.Mapname} ).length + } + }, + 'TOTALKILLS': { + async get() { + return (await placeholders.Managers[0].Server.DB.getGlobalStats()).totalKills + } + }, + 'TOTALPLAYEDTIME': { + async get() { + return parseInt(((await placeholders.Managers[0].Server.DB.getGlobalStats()).totalPlayedTime) / 60) + } + } + } + + placeholders.Managers = this.Managers + var entries = Object.entries(placeholders) + + text = text.split(/\s+/g) + + for (var i = 0; i < text.length; i++) { + for (var o = 0; o < entries.length; o++) { + if (text[i].includes(`{${entries[o][0]}}`)) { + text[i] = text[i].replace(`{${entries[o][0]}}`, (await entries[o][1].get())) + } + } + } + + return text.join(' ') + } +} + +module.exports = Plugin \ No newline at end of file diff --git a/node-server-manager/Plugins/Global/DiscordBot.js b/node-server-manager/Plugins/Global/DiscordBot.js new file mode 100644 index 0000000..b6ddece --- /dev/null +++ b/node-server-manager/Plugins/Global/DiscordBot.js @@ -0,0 +1,1012 @@ +const path = require('path') +const configName = path.join(__dirname, `../../Configuration/NSMConfiguration.json`) +const config = require(path.join(__dirname, `../../Configuration/NSMConfiguration.json`)) +const Discord = require('discord.js') +const bot = new Discord.Client() +const Utils = new (require(path.join(__dirname, '../../Utils/Utils.js')))() +const token = config.discordBotToken +const fs = require('fs') +const wait = require('delay') +const moment = require('moment') + +const Permissions = require(path.join(__dirname, `../../Configuration/NSMConfiguration.json`)).Permissions +const Localization = require(path.join(__dirname, `../../Configuration/Localization-${process.env.LOCALE}.json`)).lookup + +const clamp = (num, min, max) => Math.min(Math.max(num, min), max) + +const colors = ['#FF3131', '#86C000', '#FFAD22', '#0082BA', '#25BDF1', '#9750DD'] + +var databaseCache = {} + +const color = () => colors[Utils.getRandomInt(0, colors.length)] + +const stringInsert = (string, index, length, substr) => { + var left = string.slice(0, index) + var right = string.slice(index + length, string.length) + + left += substr + left += right + + return left +} + +const trySend = async (channel, msg) => { + try { + return await channel.send(msg) + } + catch (e) {} +} + +const getAllClients = (Managers) => { + var Clients = [] + + Managers.forEach(Manager => { + Clients = Clients.concat(Manager.Server.getClients()) + }) + + return Clients +} + +const formatColors = (string) => { + var open = false + + for (var i = 0; i < string.length; i++) { + if (string[i] == '^' && string[i + 1] && string[i + 1].match(/[0-9]/g)) { + if (string[i + 1] == '7') { + open = false + + string = stringInsert(string, i, 2, '\u200B**\u200B') + + continue + } + + string = stringInsert(string, i, 2, open ? '\u200B**\u200B**\u200B' : '\u200B**\u200B') + + open = true + } + } + + if (open) { + string += '\u200B**\u200B' + } + + return string +} + +const pagedMessage = async (original, callback, options) => { + var defaultOptions = {timeout: 60 * 1000, max: 0} + options = {...defaultOptions, ...options} + + var page = 0 + + var msg = await trySend(original.channel, callback(page)) + + if (!msg) { + return + } + + const backward = '⬅' + const forward = '➡' + + const fastforward = '⏩' + const rewind = '⏪' + + await msg.react(rewind) + + await msg.react(backward) + await msg.react(forward) + + await msg.react(fastforward) + + var onReaction = async (reaction, user) => { + if (user.id == bot.user.id) { + return + } + + if (reaction.message.id != msg.id) { + return + } + + if (user.id != original.author.id) { + reaction.users.remove(user.id) + return + } + + switch (reaction.emoji.name) { + case (fastforward): + previous = page + page = options.max + + previous != page && msg.edit(callback(page)) + break + case (rewind): + previous = page + page = 0 + + previous != page && msg.edit(callback(page)) + break + case (backward): + previous = page + page = clamp(--page, 0, options.max) + + previous != page && msg.edit(callback(page)) + break + case (forward): + previous = page + page = clamp(++page, 0, options.max) + + previous != page && msg.edit(callback(page)) + break + } + + reaction.users.remove(user.id) + } + + bot.on('messageReactionAdd', onReaction) + + setTimeout(() => { + bot.removeListener('messageReactionAdd', onReaction) + }, options.timeout) + + return msg +} + +var discordUsers = {} + +class Plugin { + constructor(Managers) { + this.Managers = Managers + this.Manager = Managers[0] + this.Server = this.Manager.Server + this.clientCache = {} + + this.commands = { + 'help': async (msg, user, args) => { + var commands = Object.entries({...this.Manager.commands, ...this.Manager.Commands.Commands}) + .filter(command => { + return !command[1].isMiddleware && (Permissions.Levels[command[1].Permission] == 0 || command[1].PermissionLevel == 0) + }) + + var chunkedCommands = Utils.chunkArray(commands, 5) + + pagedMessage(msg, (page) => { + let embed = new Discord.MessageEmbed() + .setTitle(`Page ${page + 1} / ${chunkedCommands.length}`) + .setColor(color()) + + for (var i = 0; i < chunkedCommands[page].length; i++) { + embed.addField( + chunkedCommands[page][i][0], + Localization[`COMMAND_${chunkedCommands[page][i][0].toLocaleUpperCase()}`], + false + ) + } + + return embed + }, {max: chunkedCommands.length - 1}) + }, + 'find': async (msg, user, args) => { + var name = args.splice(1).join(' ') + var matches = await this.Server.DB.getClientByName(name, 20) + + if (matches.length <= 0) { + msg.author.tell(Localization['COMMAND_CLIENT_NOT_FOUND']) + return + } + + user.lastMatches = matches + + var chunkedMatches = Utils.chunkArray(matches, 5) + + pagedMessage(msg, (page) => { + let embed = new Discord.MessageEmbed() + .setTitle(`Page ${page + 1} / ${chunkedMatches.length}`) + .setColor(color()) + + for (var i = 0; i < chunkedMatches[page].length; i++) { + var text = formatColors(Utils.formatString(Localization['COMMAND_FIND_FORMAT'], { + index: page * 5 + i + 1, + Name: chunkedMatches[page][i].Name, + ClientId: chunkedMatches[page][i].ClientId, + Role: Utils.stripString(Utils.getRoleFrom(chunkedMatches[page][i].PermissionLevel, 1).Name), + Active: moment(chunkedMatches[page][i].LastConnection).calendar(), + Joined: moment(chunkedMatches[page][i].FirstConnection).calendar() + }, '%')[0]) + + embed.addField( + '\u200B', + text, + false + ) + } + + return embed + }, {max: chunkedMatches.length - 1}) + }, + 'servers': async (msg, user, args) => { + if (this.Managers.length <= 0) { + return + } + + var chunkedManagers = Utils.chunkArray(this.Managers.concat().filter(m => m.Server.dvarsLoaded), 5) + + pagedMessage(msg, (page) => { + let embed = new Discord.MessageEmbed() + .setTitle(`Page ${page + 1} / ${chunkedManagers.length}`) + .setColor(color()) + + for (var i = 0; i < chunkedManagers[page].length; i++) { + embed.addField( + `${Utils.stripString(chunkedManagers[page][i].Server.Hostname)} - ${chunkedManagers[page][i].Server.externalIP}`, + `${chunkedManagers[page][i].Server.getMapname().Alias} - ${chunkedManagers[page][i].Server.getClients().length} / ${chunkedManagers[page][i].Server.Clients.length}`, + false + ) + } + + return embed + }, {max: chunkedManagers.length - 1}) + }, + 'players': async (msg, user, args) => { + var allClients = getAllClients(this.Managers) + + user.lastMatches = allClients + + if (!allClients.length) { + msg.author.tell(Localization['NO_PLAYERS_ONLINE']) + return + } + + var chunkedClients = Utils.chunkArray(allClients, 10) + + pagedMessage(msg, (page) => { + let embed = new Discord.MessageEmbed() + .setTitle(`Page ${page + 1} / ${chunkedClients.length}`) + .setColor(color()) + + var buffer = [] + + var i = 0; chunkedClients[page].forEach(Client => { + const role = Utils.stripString(Utils.getRoleFrom(Client.PermissionLevel, 1).Name) + const hostname = formatColors(Client.Server.Hostname) + + buffer.push(`#${page * 10 + i++ + 1} - [[${role}] **${Client.Name}**](${process.env.webfrontUrl}/id/${Client.ClientId}) - ${hostname}`) + }) + + embed.addField(`\u200B`, buffer.join('\n').substr(0, 1020), false) + + return embed + }, {max: chunkedClients.length - 1}) + } + } + + this.commands['f'] = this.commands['find'] + + if (!token) return + this.discordBot() + } + async updateActivity() { + bot.user.setStatus('online') + + bot.user.setActivity(Utils.formatString(Localization['DISCORD_BOT_ACTIVITY'], { + totalSlots: this.Managers.reduce((a, {Server}) => a + Server.Clients.length, 0), + onlineClients: this.Managers.reduce((a, {Server}) => a + Server.getClients().length, 0), + totalServers: this.Managers.filter(m => m.Server.Rcon.isRunning).length + }, '%')[0], { + type: 'WATCHING', + url: process.env.webfrontUrl + }) + } + discordBot() { + bot.login(token) + + bot.on('shardError', (e) => {}) + + bot.on('ready', async () => { + var guilds = bot.guilds.cache.map(guild => guild) + guilds.forEach(async (guild) => { + this.guildInit(guild) + }) + + bot.on('message', async (msg) => { + if (msg.author.bot) return + var Manager = this.Managers.find(Manager => Manager && Manager.Server.channel && Manager.Server.channel.id == msg.channel.id) + if (msg.content.includes("Bruh")) + await msg.react('1081765884588212274') + if (msg.content.includes("Turbo tastic")) + await msg.react('1081767190237294632') + if (msg.channel.id == "1072133169811296357") //Claim Rank + { + if (msg.content.includes('@')) + { + msg.content = msg.content.replace('@', '') + var client = await this.Server.DB.getClient(msg.content) + if (!client) + { + await msg.react("❌") + trySend(msg.channel, "ID not found. Type **.id** in game and write it here with the **@**. Example : *@25478*") + return + } + else + { + this.RankClaim(msg, msg.content) + } + return + } + var matches = await this.Server.DB.getClientByName(msg.content, 3) + + if (matches.length <= 0) { + await msg.react("❌") + trySend(msg.channel, "**Invalid name** / Never connected to Z-Tavern. You can also type **.id** in game and paste it in a new message. Example : *@25478*") + return + } + if (matches.length > 1) + { + await msg.react("❌") + trySend(msg.channel, "Problem with your account, type **.id** in game and write it in a new message with the **@**. Example : **@25478**") + return + } + this.RankClaim(msg, matches[0].ClientId) + return + } + if (msg.channel.id == "1047317564264550530") //Claim 200k + { + if (msg.content.includes('@')) + { + msg.content = msg.content.replace('@', '') + var client = await this.Server.DB.getClient(msg.content) + if (!client) + { + await msg.react("❌") + trySend(msg.channel, "ID not found. Type **.id** in game and write it here with the **@**. Example : *@25478*") + return + } + else + { + this.isClaimed(msg, msg.content) + } + return + } + var matches = await this.Server.DB.getClientByName(msg.content, 3) + + if (matches.length <= 0) { + await msg.react("❌") + trySend(msg.channel, "**Invalid name** / Never connected to Z-Tavern. You can also type **.id** in game and paste it in a new message. Example : *@25478*") + return + } + if (matches.length > 1) + { + await msg.react("❌") + trySend(msg.channel, "Problem with your account, type **.id** in game and write it in a new message with the **@**. Example : **@25478**") + return + } + this.isClaimed(msg, matches[0].ClientId) + return + } + + + if (!Manager && config.commandPrefixes.includes(msg.content[0]) && (msg.channel.id == "1082001659691016372" || msg.channel.id == "1137834755950399679")) { + this.onCommand(msg) + return + } + Manager && Manager.Server.emit('discord_message', msg) + }) + + setInterval(() => { + this.updateActivity() + }, 5000) + + setInterval(() => { + databaseCache = {} + }, 60 * 1000 * 5) + }) + } + async RankClaim(msg, clientId) + { + var fRank = msg.guild.roles.cache.find(role => role.name === "F Rank") + var eRank = msg.guild.roles.cache.find(role => role.name === "E Rank") + var dRank = msg.guild.roles.cache.find(role => role.name === "D Rank") + var cRank = msg.guild.roles.cache.find(role => role.name === "C Rank") + var bRank = msg.guild.roles.cache.find(role => role.name === "B Rank") + var aRank = msg.guild.roles.cache.find(role => role.name === "A Rank") + var sRank = msg.guild.roles.cache.find(role => role.name === "S Rank") + var ssRank = msg.guild.roles.cache.find(role => role.name === "SS Rank") + var sssRank = msg.guild.roles.cache.find(role => role.name === "SSS Rank") + var iRank = msg.guild.roles.cache.find(role => role.name === "Awakened I") + var iiRank = msg.guild.roles.cache.find(role => role.name === "Awakened II") + var iiiRank = msg.guild.roles.cache.find(role => role.name === "Awakened III") + var ivRank = msg.guild.roles.cache.find(role => role.name === "Awakened IV") + var vRank = msg.guild.roles.cache.find(role => role.name === "Awakened V") + var viRank = msg.guild.roles.cache.find(role => role.name === "Awakened VI") + var viiRank = msg.guild.roles.cache.find(role => role.name === "Awakened VII") + var iixRank = msg.guild.roles.cache.find(role => role.name === "Awakened IIX") + var ixRank = msg.guild.roles.cache.find(role => role.name === "Awakened IX") + var xRank = msg.guild.roles.cache.find(role => role.name === "Awakened X") + + msg.guild.members.cache.get(msg.author.id).roles.remove(fRank) + msg.guild.members.cache.get(msg.author.id).roles.remove(eRank) + msg.guild.members.cache.get(msg.author.id).roles.remove(dRank) + msg.guild.members.cache.get(msg.author.id).roles.remove(cRank) + msg.guild.members.cache.get(msg.author.id).roles.remove(bRank) + msg.guild.members.cache.get(msg.author.id).roles.remove(aRank) + msg.guild.members.cache.get(msg.author.id).roles.remove(sRank) + msg.guild.members.cache.get(msg.author.id).roles.remove(ssRank) + msg.guild.members.cache.get(msg.author.id).roles.remove(sssRank) + msg.guild.members.cache.get(msg.author.id).roles.remove(iRank) + msg.guild.members.cache.get(msg.author.id).roles.remove(iiRank) + msg.guild.members.cache.get(msg.author.id).roles.remove(iiiRank) + msg.guild.members.cache.get(msg.author.id).roles.remove(ivRank) + msg.guild.members.cache.get(msg.author.id).roles.remove(vRank) + msg.guild.members.cache.get(msg.author.id).roles.remove(viRank) + msg.guild.members.cache.get(msg.author.id).roles.remove(viiRank) + msg.guild.members.cache.get(msg.author.id).roles.remove(iixRank) + msg.guild.members.cache.get(msg.author.id).roles.remove(ixRank) + msg.guild.members.cache.get(msg.author.id).roles.remove(xRank) + + var customTag = await this.Server.DB.metaService.getPersistentMeta('custom_tag', clientId) + if (!customTag) + { + await msg.react("❌") + trySend(msg.channel, "Error, please contact Admin") + return + } + if (customTag.Value.includes("F")) + { + var role = msg.guild.roles.cache.find(role => role.name === "F Rank") + msg.guild.members.cache.get(msg.author.id).roles.add(role) + await msg.react("✅") + return + } + if (customTag.Value.includes("E")) + { + var role = msg.guild.roles.cache.find(role => role.name === "E Rank") + msg.guild.members.cache.get(msg.author.id).roles.add(role) + await msg.react("✅") + return + } + if (customTag.Value.includes("D")) + { + var role = msg.guild.roles.cache.find(role => role.name === "D Rank") + msg.guild.members.cache.get(msg.author.id).roles.add(role) + await msg.react("✅") + return + } + if (customTag.Value.includes("C")) + { + var role = msg.guild.roles.cache.find(role => role.name === "C Rank") + msg.guild.members.cache.get(msg.author.id).roles.add(role) + await msg.react("✅") + return + } + if (customTag.Value.includes("B")) + { + var role = msg.guild.roles.cache.find(role => role.name === "B Rank") + msg.guild.members.cache.get(msg.author.id).roles.add(role) + await msg.react("✅") + return + } + if (customTag.Value.includes("A")) + { + var role = msg.guild.roles.cache.find(role => role.name === "A Rank") + msg.guild.members.cache.get(msg.author.id).roles.add(role) + await msg.react("✅") + return + } + if (customTag.Value.includes("SSS")) + { + var role = msg.guild.roles.cache.find(role => role.name === "SSS Rank") + msg.guild.members.cache.get(msg.author.id).roles.add(role) + await msg.react("✅") + return + } + if (customTag.Value.includes("SS")) + { + var role = msg.guild.roles.cache.find(role => role.name === "SS Rank") + msg.guild.members.cache.get(msg.author.id).roles.add(role) + await msg.react("✅") + return + } + if (customTag.Value.includes("S")) + { + var role = msg.guild.roles.cache.find(role => role.name === "S Rank") + msg.guild.members.cache.get(msg.author.id).roles.add(role) + await msg.react("✅") + return + } + if (customTag.Value == "^6 I ^7") + { + var role = msg.guild.roles.cache.find(role => role.name === "Awakened I") + msg.guild.members.cache.get(msg.author.id).roles.add(role) + await msg.react("✅") + return + } + if (customTag.Value == "^6II^7") + { + var role = msg.guild.roles.cache.find(role => role.name === "Awakened II") + msg.guild.members.cache.get(msg.author.id).roles.add(role) + await msg.react("✅") + return + } + if (customTag.Value == "^6III^7") + { + var role = msg.guild.roles.cache.find(role => role.name === "Awakened III") + msg.guild.members.cache.get(msg.author.id).roles.add(role) + await msg.react("✅") + return + } + if (customTag.Value == "^5IV^7") + { + var role = msg.guild.roles.cache.find(role => role.name === "Awakened IV") + msg.guild.members.cache.get(msg.author.id).roles.add(role) + await msg.react("✅") + return + } + if (customTag.Value == "^5V^7") + { + var role = msg.guild.roles.cache.find(role => role.name === "Awakened V") + msg.guild.members.cache.get(msg.author.id).roles.add(role) + await msg.react("✅") + return + } + if (customTag.Value == "^5VI^7") + { + var role = msg.guild.roles.cache.find(role => role.name === "Awakened VI") + msg.guild.members.cache.get(msg.author.id).roles.add(role) + await msg.react("✅") + return + } + if (customTag.Value == "^5VII^7") + { + var role = msg.guild.roles.cache.find(role => role.name === "Awakened VII") + msg.guild.members.cache.get(msg.author.id).roles.add(role) + await msg.react("✅") + return + } + if (customTag.Value == "^1IIX^7") + { + var role = msg.guild.roles.cache.find(role => role.name === "Awakened IIX") + msg.guild.members.cache.get(msg.author.id).roles.add(role) + await msg.react("✅") + return + } + if (customTag.Value == "^1IX^7") + { + var role = msg.guild.roles.cache.find(role => role.name === "Awakened IX") + msg.guild.members.cache.get(msg.author.id).roles.add(role) + await msg.react("✅") + return + } + if (customTag.Value == "^1-X-^7") + { + var role = msg.guild.roles.cache.find(role => role.name === "Awakened X") + msg.guild.members.cache.get(msg.author.id).roles.add(role) + await msg.react("✅") + return + } + } + async isClaimed(msg, clientId) + { + var claimed = await this.Server.DB.metaService.getPersistentMeta('claimed', clientId) + if (!claimed) + { + await this.Server.DB.metaService.addPersistentMeta('claimed', '200000', clientId) + var totalMoney = (await this.getZMStats(clientId)).Money + this.setPlayerMoney(clientId, parseInt(totalMoney) + 200000) + await msg.react("✅") + } + else + { + await msg.react("❌") + trySend(msg.channel, "One claim only.") + } + } + async setPlayerMoney(ClientId, Money) { + await this.Server.DB.Models.NSMZombiesStats.update({ + Money : Money }, { + where: {ClientId: ClientId + } + }) + } + async getZMStats(ClientId) { + if (ClientId == 1) { + return { + Money: Infinity, + LockerWeapon: 'none' + } + } + + var ZMStats = await this.Server.DB.Models.NSMZombiesStats.findAll({ + where: { + ClientId: ClientId + } + }) + return ZMStats.length > 0 ?ZMStats[0].dataValues : false + } + + + + + + async saveConfig() { + fs.writeFile(configName, JSON.stringify(config, null, 4), (err) => { + if (err) { + console.log(err) + return + } + }) + } + stripMentions(string) { + return string.replace(new RegExp(/((<@(.*?)>)|(@(.*?)))/g), '(@)') + } + getServerIcon(Server) { + var imgPath = path.join(__dirname, `../../Webfront/Public/img/maps/${Server.Gamename.toLocaleLowerCase()}/${Server.Mapname}.jpg`) + + return fs.existsSync(imgPath) ? imgPath : path.join(__dirname, `../../Webfront/Public/img/maps/default.png`) + } + getServerIconName(Server) { + var imgPath = path.join(__dirname, `../../Webfront/Public/img/maps/${Server.Gamename.toLocaleLowerCase()}/${Server.Mapname}.jpg`) + + return fs.existsSync(imgPath) ? `${Server.Mapname}.jpg` : `default.png` + } + async serverLogger(category, guild, Server) { + this.updateActivity() + + Server.on('message', async (Player, Message) => { + var discordUser = await this.getDiscordUser(Player.ClientId) + + var msg = Utils.stripString(this.stripMentions(Message)) + if (!msg.length) return + + Server.channel.webhook.send(msg, { + username: Player.Name, + avatarURL: discordUser ? `https://cdn.discordapp.com/avatars/${discordUser.id}/${discordUser.avatar}.png` : `https://cdn.discordapp.com/embed/avatars/0.png` + }) + }) + + Server.on('penalty', async (Type, Target, Reason, Origin, Duration = -1) => { + if (`${Utils.stripString(this.stripMentions(Reason))}` == "VPN detected") + { + return; + } + if (Reason.includes("rank")) + return; + let embed = new Discord.MessageEmbed() + .setTitle(`:hammer: Penalty`) + .setDescription(Utils.formatString(Localization['DISCORD_BOT_PENALTY'], { + target: Target.Name, + targetUrl: `${process.env.webfrontUrl}/id/${Target.ClientId}`, + penaltyName: `**${Localization[Type].toLocaleLowerCase()}**`, + origin: Origin.Name, + originUrl: `${process.env.webfrontUrl}/id/${Origin.ClientId}`, + duration: Duration > 0 ? `(${Utils.time2str(Duration)})` : '', + reason: `**${Utils.stripString(this.stripMentions(Reason))}**` + })) + .addField('Target', `[${Target.Name}](${process.env.webfrontUrl}/id/${Target.ClientId})`, true) + .addField('Origin', `[${Origin.Name}](${process.env.webfrontUrl}/id/${Origin.ClientId})`, true) + .addField('Reason', Utils.stripString(Reason), true) + .setTimestamp() + .setColor(colors[Utils.getRandomInt(0, colors.length)]) + + Duration > 0 && embed.addField('Duration', Utils.time2str(Duration), true) + + trySend(guild.eventChannel, embed) + }) + + Server.on('report', async (Origin, Target, Reason) => { + var modRoles = config[guild.id]['modRoles'].map(role => `<@&${role}>`) + + let embed = new Discord.MessageEmbed() + .setTitle(':triangular_flag_on_post: Report') + .setDescription(Utils.formatString(Localization['DISCORD_BOT_REPORT'], { + target: Target.Name, + targetUrl: `${process.env.webfrontUrl}/id/${Target.ClientId}`, + origin: Origin.Name, + originUrl: `${process.env.webfrontUrl}/id/${Origin.ClientId}`, + reason: `**${Utils.stripString(this.stripMentions(Reason))}**` + })) + .addField('Target', `[${Target.Name}](${process.env.webfrontUrl}/id/${Target.ClientId})`, true) + .addField('Origin', `[${Origin.Name}](${process.env.webfrontUrl}/id/${Origin.ClientId})`, true) + .addField('Reason', Utils.stripString(Reason), true) + .addField('Server', Utils.stripString(Server.Hostname), true) + .setTimestamp() + .setColor(colors[Utils.getRandomInt(0, colors.length)]) + + modRoles.join(' ').length && await guild.eventChannel.send(modRoles.join(' ')) + + var r_text = new Array (); + r_text[0] = "<@&1128454277686374471> DEFCON 5! DEFCON 5!"; + r_text[1] = "<@&1128454277686374471> That's gotta be a yellow card at least"; + r_text[2] = "<@&1128454277686374471> I swear if its another dood who box emp.."; + r_text[3] = "<@&1128454277686374471> Fun fact, someone send a report because he couldnt get a spin at the box :skull:"; + r_text[4] = "<@&1128454277686374471> He have brought malice and dishonor to this battlefield. In turn, you shall bring him justice. Justice with well maintained six-pack abs and toned biceps. You shall strike him down where he stand."; + r_text[5] = "<@&1128454277686374471> These messages are a great use of my time, no cap"; + r_text[6] = "<@&1128454277686374471> Just how many of these messages are there? Man could've fixed .afk & MOTD & release the RPG update in half that time!"; + var i = Math.floor(7*Math.random()) + + trySend(guild.eventChannel, r_text[i]) + trySend(guild.eventChannel, embed) + }) + + Server.on('round_start', async (roundNumber) => { + let embed = new Discord.MessageEmbed() + .setTitle('Round started') + .addField(roundNumber, '\u200B', true) + .setColor(colors[Utils.getRandomInt(0, colors.length)]) + .attachFiles([this.getServerIcon(Server)]) + .setThumbnail(`attachment://${this.getServerIconName(Server)}`) + .setTimestamp() + .setFooter(`${Server.getClients().length} / ${Server.Clients.length}`) + + trySend(Server.channel, embed) + }) + + Server.on('disconnect', async (Player) => { + var discordUser = await this.getDiscordUser(Player.ClientId) + + let embed = new Discord.MessageEmbed() + .setURL(`${process.env.webfrontUrl}/id/${Player.ClientId}`) + .setColor(colors[Utils.getRandomInt(0, colors.length)]) + .setTimestamp() + .setAuthor(`${Player.Name} disconnected`, discordUser ? `https://cdn.discordapp.com/avatars/${discordUser.id}/${discordUser.avatar}.png` : `https://cdn.discordapp.com/embed/avatars/0.png`) + .setFooter(`${Server.getClients().length} / ${Server.Clients.length}`) + + trySend(Server.channel, embed) + + this.updateActivity() + }) + + Server.on('connect', async (Player) => { + var discordUser = await this.getDiscordUser(Player.ClientId) + + let embed = new Discord.MessageEmbed() + .setURL(`${process.env.webfrontUrl}/id/${Player.ClientId}`) + .setColor(colors[Utils.getRandomInt(0, colors.length)]) + .setTimestamp() + .setAuthor(`${Player.Name} connected`, discordUser ? `https://cdn.discordapp.com/avatars/${discordUser.id}/${discordUser.avatar}.png` : `https://cdn.discordapp.com/embed/avatars/0.png`) + .setFooter(`${Server.getClients().length} / ${Server.Clients.length}`) + + trySend(Server.channel, embed) + + this.updateActivity() + }) + + Server.on('map_loaded', () => { + let embed = new Discord.MessageEmbed() + .setTitle('Map rotated') + .addField('Mapname', `${Server.getMapname().Alias}`, true) + .addField('Gametype', `${Server.getGametype().Alias}`, true) + .setColor(colors[Utils.getRandomInt(0, colors.length)]) + .attachFiles([this.getServerIcon(Server)]) + .setThumbnail(`attachment://${this.getServerIconName(Server)}`) + .setTimestamp() + .setFooter(`${Server.getClients().length} / ${Server.Clients.length}`) + + trySend(Server.channel, embed) + + this.updateActivity() + }) + + Server.on('discord_message', async (msg) => { + if (msg.channel.id == "1137834755950399679") + { + msg.reply("Link your account [here](http://149.202.93.80:8000)") + return + } + if (!Server.channel + || msg.channel.id != Server.channel.id + || msg.author.id == bot.user.id + || msg.author.bot) return + + var Client = await this.getClientByDiscord(msg.author.id) + if (!Client.Name) { + msg.reply(Utils.formatString(Localization['DISCORD_ACC_NOT_CONNECTED'], { + url: process.env.webfrontUrl + }, '%')) + return + } + Server.Broadcast(Utils.formatString(Localization['SOCKET_MSG_FORMAT'], { + name: Client.Name, + message: msg.content + })) + }) + } + async initServer(category, guild, Server) { + var channel = guild.channels.cache.find(channel => config.Servers[Server.Id][guild.id] && channel.id == config.Servers[Server.Id][guild.id].channelId) + + if (!channel) { + await wait(500) + var channel = await guild.channels.create(Utils.stripString(Server.Hostname)) + config.Servers[Server.Id][guild.id] = { ...config.Servers[Server.Id][guild.id], channelId: channel.id } + this.saveConfig() + } + + channel.setParent(category.id) + + var webhook = await channel.fetchWebhooks() + + webhook = webhook.first() + + if (!webhook) { + var webhook = await channel.createWebhook('NSM Bot') + } + + channel.webhook = webhook + Server.channel = channel + + Server.emit('discord_ready') + + this.serverLogger(category, guild, Server) + + } + async guildInit(guild) { + var category = guild.channels.cache.find(channel => config[guild.id] && channel.type == 'category' && channel.id == config[guild.id].categoryId) + + if (!category) { + var category = await guild.channels.create('Game-Servers', { + type: 'category' + }) + + config[guild.id] = { categoryId: category.id } + this.saveConfig() + } + + var eventChannel = guild.channels.cache.find(channel => config[guild.id]['eventChannelId'] && channel.type == 'text' && channel.id == config[guild.id]['eventChannelId']) + + !config[guild.id]['modRoles'] && (config[guild.id]['modRoles'] = [], this.saveConfig()) + + if (!eventChannel) { + var eventChannel = await guild.channels.create('Events') + eventChannel.setParent(category.id) + eventChannel.setPosition(0, 0) + eventChannel.updateOverwrite(guild.roles.everyone, { SEND_MESSAGES: false }) + + eventChannel.overwritePermissions([ + { + id: guild.id, + deny: ['SEND_MESSAGES'], + } + ]) + + config[guild.id]['eventChannelId'] = eventChannel.id + this.saveConfig() + } + + guild.eventChannel = eventChannel + + for (var i = 0; i < this.Managers.length; i++) { + if (Utils.stripString(this.Managers[i].Server.Hostname).includes("PRIVATE") == false) + { + if (this.Managers[i].Server.dvarsLoaded) { + this.initServer(category, guild, this.Managers[i].Server) + continue + } + + this.Managers[i].Server.on('dvars_loaded', async (Server) => { + this.initServer(category, guild, Server) + + console.log() + }) + } + } + } + async getDiscordUser(ClientId) { + if (databaseCache[ClientId]) return databaseCache[ClientId] + + var discordUser = await this.Server.DB.metaService.getPersistentMeta('discord_user', ClientId) + databaseCache[ClientId] = discordUser ? JSON.parse(discordUser.Value) : false + + return databaseCache[ClientId] + } + async getClientByDiscord(clientId) { + var ClientId = await this.Server.DB.metaService.reversePersistentMeta('discord_id', clientId) + var discordUser = ClientId ? await this.Server.DB.metaService.getPersistentMeta('discord_user', ClientId) : false + var Client = ClientId ? await this.Server.DB.getClient(ClientId.ClientId) : false + + return {...discordUser, ...Client} + } + censorIp(string) { + return string.replace(new RegExp(/([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})\:?([0-9]{1,5})?/g), '**[redacted]**') + .replace(new RegExp(/\b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}\b/g), '**[redacted]**') + } + async onCommand(msg) { + try { + var ClientId = await this.Server.DB.metaService.reversePersistentMeta('discord_id', msg.author.id) + var Client = ClientId ? await this.Server.DB.getClient(ClientId.ClientId) : false + + if (!discordUsers[msg.author.id.toString()]) { + discordUsers[msg.author.id.toString()] = {} + } + + var user = discordUsers[msg.author.id.toString()] + + if (user.lastMatches) { + msg.content = msg.content.replace(new RegExp(/#([0-9]+)/g), (n) => { + var num = Math.max(parseInt(n.substr(1)), 1) - 1 + + if (user.lastMatches[num]) { + return `@${user.lastMatches[num].ClientId}` + } + + return n + }) + } + + var args = msg.content.substr(1).split(/\s+/g) + + var buffer = [] + + if (this.commands[args[0].toLocaleLowerCase()]) { + msg.author.tell = (text) => { + let embed = new Discord.MessageEmbed() + .setColor(colors[Utils.getRandomInt(0, colors.length)]) + .addField('\u200B', `${text.substr(0, 1000)}`, true) + + trySend(msg.channel, embed) + } + + this.commands[args[0].toLocaleLowerCase()](msg, user, args) + return + } + + var Player = { + PermissionLevel: 0, + discordUser: msg.author.id, + ClientId: 0, + inGame: false, + Tell: (msg) => { + buffer.push(this.censorIp(Utils.stripString(msg.toString()))) + } + } + + Client && (Player = {...Player, ...Client}) + + var end = () => { + try { + let embed = new Discord.MessageEmbed() + .setColor(colors[Utils.getRandomInt(0, colors.length)]) + .addField('\u200B', `${buffer.join('\n').substr(0, 1000)}`, true) + + trySend(msg.channel, embed) + } + catch (e) {} + } + + var executedMiddleware = await this.Manager.Commands.executeMiddleware(args[0], Player, args) + if (await this.Manager.Commands.execute(args[0], Player, args)) { + end() + return + } + + var command = Utils.getCommand(this.Manager.commands, args[0]) + + switch (true) { + case (!this.Manager.commands[command]): + case (this.Manager.commands[command].gameTypeExclusions && this.Manager.commands[command].gameTypeExclusions.includes(this.Server.Gametype)): + !executedMiddleware && Player.Tell(Localization['COMMAND_NOT_FOUND']) + end() + return + case (this.Manager.commands[command].inGame || this.Manager.commands[command].inGame == undefined): + Player.Tell(Localization['COMMAND_ENV_ERROR']) + end() + return + case (Player.PermissionLevel < Permissions.Levels[this.Manager.commands[command].Permission]): + Player.Tell(Localization['COMMAND_FORBIDDEN']) + end() + return + case (args.length - 1 < this.Manager.commands[command].ArgumentLength): + Player.Tell(Localization['COMMAND_ARGUMENT_ERROR']) + Player.Tell(Utils.formatString(Localization['COMMAND_COMMAND_USAGE'], { + prefix: config.commandPrefixes[0], + usage: Localization[`USAGE_${command.toLocaleUpperCase()}`] + })) + end() + return + } + + await this.Manager.commands[command].callback(Player, args, false) + end() + } + catch (e) {} + } +} + +module.exports = Plugin diff --git a/node-server-manager/Plugins/Global/GlobalChat.js b/node-server-manager/Plugins/Global/GlobalChat.js new file mode 100644 index 0000000..a13baaf --- /dev/null +++ b/node-server-manager/Plugins/Global/GlobalChat.js @@ -0,0 +1,53 @@ +const path = require('path') +const Localization = require(path.join(__dirname, `../../Configuration/Localization-${process.env.LOCALE}.json`)).lookup +const Utils = new (require(path.join(__dirname, '../../Utils/Utils.js')))() + +class Plugin { + constructor(Managers) { + this.Managers = Managers + this.init() + } + init() { + this.Managers.forEach(Manager => { + Manager.Server.on('message', this.playerMessage.bind(this)) + }) + } + playerMessage(Player, Message) { + if (Player.Session && Player.Session.Data.serverChat) { + Player.Session.Data.serverChat.Broadcast(Utils.formatString(Localization['GLOBALCHAT_FORMAT'], { + Enabled: '', + Name: Player.Name, + Message, + Hostname: Player.Server.Hostname + })) + } + + this.Managers.forEach(async Manager => { + Manager.Server.Clients.forEach(Client => { + if (!Client || !Client.Session) return + + if (Client.Session.Data.serverChat + && Client.Session.Data.serverChat.Id == Player.Server.Id + && (!Player.Session.Data.serverChat || Player.Session.Data.serverChat && Player.Session.Data.serverChat.Id != Client.Server.Id)) { + Client.Tell(Utils.formatString(Localization['SOCKET_MSG_FORMAT'], { + Name: Player.Name, + Message, + }, '%')[0]) + return + } + + if (!Client.Session.Data.globalChat + || Client.Server.Id == Player.Server.Id) return + + Client.Tell(Utils.formatString(Localization['GLOBALCHAT_FORMAT'], { + Enabled: (Player.Session && Player.Session.Data.globalChat) ? '[^1G^7]' : '', + Name: Player.Name, + Message, + Hostname: Player.Server.HostnameRaw + }, '%')[0]) + }) + }) + } +} + +module.exports = Plugin \ No newline at end of file diff --git a/node-server-manager/Plugins/Global/ProfileMeta.js b/node-server-manager/Plugins/Global/ProfileMeta.js new file mode 100644 index 0000000..e2719ba --- /dev/null +++ b/node-server-manager/Plugins/Global/ProfileMeta.js @@ -0,0 +1,31 @@ +class Plugin { + constructor(Managers) { + this.DB = Managers[0].Server.DB + this.addClientMeta() + } + async getZStats(ClientId) { + var Stats = (await this.DB.Models.NSMZStats.findAll({where: ClientId})).map(x => x = x.dataValues) + return Stats.length > 0 ? Stats[0] : false + } + async addClientMeta() { + this.DB.clientProfileMeta.push(async (ClientId) => { + var stats = await this.getZStats(ClientId) + + if (!stats || stats.Score <= 500) return {} + + return { + name: 'Zombies Stats', + data: { + 'Kills': stats.Kills, + 'Downs': stats.Downs, + 'Revives': stats.Revives, + 'Highest Round': stats.HighestRound, + 'Headshots': stats.Headshots, + 'Score': stats.Score, + } + } + }) + } +} + +module.exports = Plugin \ No newline at end of file diff --git a/node-server-manager/Plugins/MoreCommands.js b/node-server-manager/Plugins/MoreCommands.js new file mode 100644 index 0000000..2655173 --- /dev/null +++ b/node-server-manager/Plugins/MoreCommands.js @@ -0,0 +1,416 @@ +const path = require('path') +const { Command } = require(path.join(__dirname, `../Lib/Classes.js`)) +const Localization = require(path.join(__dirname, `../Configuration/Localization-${process.env.LOCALE}.json`)).lookup +const Games = require(path.join(__dirname, `../Configuration/Localization-${process.env.LOCALE}.json`)).Games +const config = require(path.join(__dirname, `../Configuration/NSMConfiguration.json`)) +const Utils = new (require(path.join(__dirname, '../Utils/Utils.js')))() +const mathjs = require('mathjs') +const wait = require('delay') + +class Plugin { + constructor(Server, Manager, Managers) { + this.Server = Server + this.Manager = Manager + this.Managers = Managers + this.init() + } + init() { + (() => { + let command = new Command() + .setName('calculator') + .setAlias('calc') + .addParam({ + index: 0, + name: 'expression', + join: true + }) + .addCallback(async (Player, params, args, options, funcs) => { + try { + var result = mathjs.evaluate(params.expression) + result ? funcs.Tell( Utils.formatString(Localization['COMMAND_CALC_RESULT'], { result: result.toString() }, '%')[0] ) : funcs.Tell(Utils.formatString(Localization['COMMAND_CALC_RESULT'], { result: Localization['COMMAND_CALC_FAIL'] }, '%')[0]) + } + catch (e) { + funcs.Tell(Utils.formatString(Localization['COMMAND_CALC_RESULT'], { result: Localization['COMMAND_CALC_FAIL'] }, '%')[0]) + } + }) + + this.Manager.Commands.add(command) + })(this); + + (() => { + let command = new Command() + .setName('toggle') + .setAlias('t') + .addParam({ + index: 0, + name: 'setting' + }) + .addCallback(async (Player, params, args, options, funcs) => { + let settingsMeta = ['location'] + if (!settingsMeta.includes(params.setting.toLocaleLowerCase())) { + Player.Tell(Localization['SETTING_NOT_EXIST']) + return + } + + var setting = await this.Server.DB.metaService.getPersistentMeta(params.setting, Player.ClientId) + + this.Server.DB.metaService.addPersistentMeta(params.setting.toLocaleLowerCase(), !(setting && setting.Value == '1'), Player.ClientId) + + switch (params.setting.toLocaleLowerCase()) { + case 'location': + Player.Tell(Utils.formatString(Localization['SETTING_TOGGLE_FORMAT'], {setting: Utils.capitalizeFirstLetter(params.setting), value: !(setting && setting.Value == '1') ? '^1hidden' : '^2shown'}, '%')[0]) + break + } + }) + + this.Manager.Commands.add(command) + })(this); + + (() => { + let command = new Command({ + isMiddleware: true + }) + .addCallback(async (Player, params, args, options, funcs, next) => { + if (!config.socialMedia) { + next() + return + } + + var sc = config.socialMedia.find((a) => a[0].toLocaleLowerCase() == args[0].toLocaleLowerCase()) + + if (!sc) { + next() + return + } + + funcs.Tell(Utils.formatString(Localization['COMMAND_LINKS_FORMAT'], {name: sc[0], url: sc[1]}, '%')[0]) + }) + + this.Manager.Commands.add(command) + })(this); + + (() => { + let command = new Command({ + name: 'reports', + alias: 'reps', + permission: 'ROLE_MODERATOR' + }) + .addParam({ + index: 0, + name: 'page', + optional: true + }) + .setPermission('ROLE_MODERATOR') + .addCallback(async (Player, params, args, options, funcs) => { + if (params.page == 'clear') { + this.Server.DB.clearReports() + Player.Tell(Localization['COMMAND_REPORTS_CLEAR']) + return + } + + var Reports = Utils.chunkArray(await this.Server.DB.getActiveReports(), Player.inGame ? 4 : 15) + + if (!Reports.length) { + Player.Tell(Localization['COMMAND_NO_RESULT']) + return + } + + var page = params.page ? Math.max(1, Math.min(parseInt(params.page), Reports.length)) : 1 + + await Player.Tell(Utils.formatString(Localization['COMMAND_LIST_PAGE'], {max: Reports.length, current: page}, '%')[0]) + Player.inGame && await wait(300) + + for (var i = 0; i < Reports[page - 1].length; i++) { + var TargetName = await this.Server.DB.getName(Reports[page - 1][i].TargetId) + var OriginName = await this.Server.DB.getName(Reports[page - 1][i].OriginId) + + Player.Tell(Utils.formatString(Localization['COMMAND_REPORTS_TELL'], {Origin: OriginName, Target: TargetName, Reason: Reports[page - 1][i].Reason}, '%')[0]) + + Player.inGame && await wait(300) + } + + }) + + this.Manager.Commands.add(command) + })(this); + + (() => { + let command = new Command() + .setName('report') + .setAlias('rep') + .setInGame(true) + /* .addParams([ + { + index: 0, + name: 'target' + }, + { + index: 1, + name: 'reason', + join: true + } + ])*/ + .addException(Utils.formatString(Localization['COMMAND_REPORT_COOLDOWN'], {time: 5}, '%')[0], (Player) => { + return !Player.Data.lastReport || (new Date() - Player.Data.lastReport) / 1000 > 300 + }) + .addCallback( async (Player, params, args, options, funcs) => { + + Player.Tell("To ^1report^7, take ^3video/photo evidences^7 & create a ^6Discord ^2Ticket^7.") + return + + var Client = await this.Server.getClient(params.target) + + + if (!Client) { + Player.Tell(Localization['COMMAND_CLIENT_NOT_FOUND']) + return + } + + this.Server.DB.addReport(Player.ClientId, Client.ClientId, params.reason) + + Player.Data.lastReport = new Date() + Player.Tell(Localization['COMMAND_REPORT_SUCCESS']) + + this.Server.emit('report', Player, Client, params.reason) + + this.Server.tellStaffGlobal(Utils.formatString(Localization['COMMAND_REPORT_TELL'], {Origin: Player.Name, Hostname: Player.Server.HostnameRaw,Target: Client.Name, Reason: params.reason}, '%')[0]) + }) + + this.Manager.Commands.add(command) + })(this); + + (() => { + let command = new Command() + .setName('staff') + .addCallback(async (Player, params, args, options, funcs) => { + var staff = [] + this.Managers.forEach(Manager => { + staff = staff.concat(Manager.Server.getStaffMembers()) + }) + if (!staff.length) { + funcs.Tell(Localization['COMMAND_STAFF_NO_RESULT']) + return + } + for (var i = 0; i < staff.length; i++) { + funcs.Tell(Utils.formatString(Localization['COMMAND_STAFF_FORMAT'], { + Name: staff[i].Name, + Level: staff[i].PermissionLevel, + Role: Utils.getRoleFrom(staff[i].PermissionLevel, 1).Name, + ClientId: staff[i].ClientId, + Hostname: staff[i].Server.HostnameRaw + }, '%')[0]) + Player.inGame && await wait(500) + } + }) + + this.Manager.Commands.add(command) + })(this); + + (() => { + let command = new Command() + .setName('eval') + .addParam({ + index: 0, + name: 'js', + join: true + }) + .setPermission('ROLE_OWNER') + .addCallback(async (Player, params, args, options, funcs) => { + try { + console.log(params.js) + eval(params.js) + } + catch (e) { + Player.Tell(e.toString()) + } + }) + + if (process.env.NODE_ENV == 'dev') + this.Manager.Commands.add(command) + })(this); + + (() => { + let command = new Command() + .setName('stats') + .addParam({ + index: 0, + name: 'client', + join: true, + optional: true + }) + .addCallback(async (Player, params, args, options, funcs) => { + var Target = !params.client ? Player : await this.Server.getClient(params.client) + + if (!Target) { + Player.Tell(Localization.COMMAND_CLIENT_NOT_FOUND) + return + } + + var ClientId = Target.ClientId + var Stats = await this.Server.DB.getPlayerStatsTotal(ClientId) + var Client = await this.Server.DB.getClient(ClientId) + if (Stats) + funcs.Tell(Localization.COMMAND_STATS_FORMAT + .replace('%PLAYEDTIME%', Utils.time2str(Stats.PlayedTime * 60)) + .replace('%PERFORMANCE%', Stats.Performance.toFixed(2)) + .replace('%NAME%', Client.Name) + .replace('%KILLS%', Stats.Kills) + .replace('%DEATHS%', Stats.Deaths) + .replace('%KDR%',(Stats.Kills / Math.max(Stats.Deaths, 1)).toFixed(2))) + else funcs.Tell(Localization.COMMAND_CLIENT_NOT_FOUND) + }) + + this.Manager.Commands.add(command) + })(this); + + (() => { + let command = new Command() + .setName('uptime') + .setAlias('ut') + .setInGame(true) + .addCallback(async (Player, params, args, options, funcs) => { + funcs.Tell(Utils.formatString(Localization['COMMAND_UPTIME_FORMAT'], {uptime: Utils.time2str(this.Server.uptime)}, '%')[0]) + }) + + this.Manager.Commands.add(command) + })(this); + + (() => { + let command = new Command() + .setName('status') + .addCallback(async (Player, params, args, options, funcs) => { + funcs.Tell(Utils.formatString(Localization['COMMAND_SUMMARY_FORMAT'], { + totalClients: await this.Server.DB.getAllClients(), + totalServers: this.Managers.filter(m => m.Server.Rcon.isRunning).length, + clientsToday: (await this.Server.DB.getLastConnections()).length, + uniqueToday: (await this.Server.DB.getLastUniques()).length, + onlineClients: this.Managers.reduce((a, {Server}) => a + Server.getClients().length, 0), + totalSlots: this.Managers.reduce((a, {Server}) => a + Server.Clients.length, 0) + }, '%')[0]) + }) + + this.Manager.Commands.add(command) + })(this); + + (() => { + let command = new Command() + .setName('rotation') + .setAlias('rr') + .setInGame(true) + .addCallback(async (Player, params, args, options, funcs) => { + var buffer = "" + + this.Server.mapRotation.forEach((map, i) => { + buffer += Utils.va("%s%s%s", + map == this.Server.Mapname ? '^3' : '^5', + this.Server.getMap(map) ? this.Server.getMap(map).Alias : map, + i < this.Server.mapRotation.length - 1 ? '^7, ' : '' + ) + }) + + funcs.Tell(buffer) + }) + + this.Manager.Commands.add(command) + })(this); + + (() => { + let command = new Command() + .setName('chat') + .setInGame(true) + .addParam({ + name: 'server', + optional: true, + join: true + }) + .addCallback(async (Player, params) => { + if (!params.server) { + if (Player.Session.Data.serverChat) { + Player.Session.Data.serverChat.Broadcast(Utils.formatString(Localization['SERVERCHAT_DISCONNECTED'], { + Name: Player.Name + }, '%')[0]) + } + + Player.Session.Data.serverChat = undefined + Player.Tell(Localization['SERVERCHAT_DISABLED']) + return + } + + var Manager = this.Managers.find(Manager => Utils.cleanIncludes(Manager.Server.Hostname, params.server)) + + if (!Manager) { + Player.Tell(Localization['SERVER_NOT_FOUND']) + return + } + + if (Player.Session.Data.serverChat && Player.Session.Data.serverChat.Id != Manager.Server.Id) { + Player.Session.Data.serverChat.Broadcast(Utils.formatString(Localization['SERVERCHAT_DISCONNECTED'], { + Name: Player.Name + }, '%')[0]) + } + + Player.Session.Data.serverChat = Manager.Server + + Manager.Server.Broadcast(Utils.formatString(Localization['SERVERCHAT_CONNECTED'], { + Name: Player.Name + }, '%')[0]) + + Player.Tell(Utils.formatString(Localization['SERVERCHAT_ENABLED'], { + Hostname: Manager.Server.Hostname + }, '%')[0]) + }) + + this.Manager.Commands.add(command) + })(this); + + (() => { + let command = new Command() + .setName('rules') + .addParam({ + name: 'page', + optional: true + }) + .addCallback(async (Player, params) => { + if (!this.Server.config.rules) { + Player.Tell(Localization['COMMAND_RULES_UNDEFINED']) + return + } + + const size = Player.inGame ? 4 : 15 + const chunkedRules = Utils.chunkArray(this.Server.config.rules, size) + + const page = Math.max(0, Math.min(params.page ? parseInt(params.page) - 1 : 0, chunkedRules.length)) + const rules = chunkedRules[page] + + Player.Tell(Utils.formatString(Localization['COMMAND_LIST_PAGE'], { + current: page + 1, + max: chunkedRules.length + }, '%')[0]) + + Player.inGame && await wait(300) + + for (var i = 0; i < rules.length; i++) { + Player.Tell(Utils.va(Localization['COMMAND_RULES_FORMAT'], size * page + i + 1, rules[i])) + + Player.inGame && await wait(500) + } + }) + + this.Manager.Commands.add(command) + })(this); + + (() => { + let command = new Command() + .setName('resetstats') + .setAlias('rs') + .addCallback(async (Player, params, args, options, funcs) => { + await this.Server.DB.resetStats(Player.ClientId) + funcs.Tell(Localization['COMMAND_RESETSTATS_RESET']) + }) + + this.Manager.Commands.add(command) + })(this); + } +} + +module.exports = Plugin \ No newline at end of file diff --git a/node-server-manager/Plugins/NativeCommands.js b/node-server-manager/Plugins/NativeCommands.js new file mode 100644 index 0000000..7cb2323 --- /dev/null +++ b/node-server-manager/Plugins/NativeCommands.js @@ -0,0 +1,800 @@ +const moment = require('moment') +const path = require('path') +const crypto = require('crypto') +const wait = require('delay') +const fs = require('fs') +const Permissions = require(path.join(__dirname, `../Configuration/NSMConfiguration.json`)).Permissions +const configName = path.join(__dirname, `../Configuration/NSMConfiguration.json`) +const Localization = require(path.join(__dirname, `../Configuration/Localization-${process.env.LOCALE}.json`)).lookup +const Utils = new (require(path.join(__dirname, '../Utils/Utils.js')))() +var config = require(configName) + +fs.watch(configName, async (filename) => { + if (filename) { + try { var newData = require(configName) } + catch (e) { + console.log(`Failed to reload config file ${configName}: ${e.toString()}`); return } + + config = newData + } +}) + +class Plugin { + constructor(Server, Manager, Managers) { + this.Server = Server + this.Manager = Manager + this.Managers = Managers + //add the .pguid of players to grant them staff permissions (must be done on ClanTag, ZombiesBank, ZombiesStats, NativeCommands & the gsc script staff.gsc) + this.staff_list_a = [564391] + this.init() + } + onEventAsync (event) { + switch (event.type) { + case 'say': + if (config.commandPrefixes.includes(event.data.Message[0]) || config.broadcastCommandPrefixes.includes(event.data.Message[0])) + this.playerCommand(event.data.Origin, event.data.Message.substr(1).split(/\s+/), event.data.Message[0]) + break + } + } + init () { + this.Manager.commands = { + 'help': { + ArgumentLength: 0, + Permission: Permissions.Commands.COMMAND_USER_CMDS, + inGame: false, + callback: async (Player, args = null, delay) => { + var commands = Object.entries({...this.Manager.commands, ...this.Manager.Commands.Commands}) + .filter(command => { + return !command[1].isMiddleware && (Permissions.Levels[command[1].Permission] <= Player.PermissionLevel || command[1].PermissionLevel <= Player.PermissionLevel) + }) + + switch (true) { + case (!args[1]): + case (Number.isInteger(parseInt(args[1]))): + var chunkedCommands = Utils.chunkArray(commands, Player.inGame ? 4 : 15) + var page = args[1] ? Math.max(1, Math.min(parseInt(args[1]), chunkedCommands.length)) : 1 + + await Player.Tell(Utils.formatString(Localization['COMMAND_LIST_PAGE'], {max: chunkedCommands.length, current: page}, '%')[0]) + delay && await wait(300) + + for (var i = 0; i < chunkedCommands[page - 1].length; i++) { + Player.Tell(`^7[^6${chunkedCommands[page - 1][i][0]}^7] ${Localization[`COMMAND_${chunkedCommands[page - 1][i][0].toLocaleUpperCase()}`]}`) + delay && await wait(300) + } + break + default: + var command = Utils.getCommand({...this.Manager.commands, ...this.Manager.Commands.Commands}, args[1]) + + if (!command) { + Player.Tell(Localization['COMMAND_NOT_FOUND']) + return + } + + Player.Tell(`${Localization[`COMMAND_${command.toLocaleUpperCase()}`]}`) + delay && await wait(300) + Player.Tell(`Usage: ^5${config.commandPrefixes[0]}^7${Localization[`USAGE_${command.toLocaleUpperCase()}`]}`) + break + } + } + }, + 'fastrestart': { + ArgumentLength: 0, + Alias: 'fre', + Permission: Permissions.Commands.COMMAND_USER_CMDS, + inGame: true, + callback: async (Player, args) => { + if (await this.is_staff(Player) == false) + { + Player.Tell("^1Staff only") + return + } + await this.Server.Rcon.executeCommandAsync('fast_restart') + this.Server.Broadcast(Utils.formatString(Localization['COMMAND_FASTRESTART_FORMAT'], {Name: Player.Name}, '%')) + } + }, + 'maprestart': { + ArgumentLength: 0, + Alias: 'mr', + Permission: Permissions.Commands.COMMAND_USER_CMDS, + inGame: true, + callback: async (Player, args) => { + if (await this.is_staff(Player) == false) + { + Player.Tell("^1Staff only") + return + } + await this.Server.Rcon.executeCommandAsync('map_restart') + } + }, + 'maprotate': { + ArgumentLength: 0, + Alias: 'rotate', + Permission: Permissions.Commands.COMMAND_MAP, + inGame: true, + callback: async (Player, args) => { + await this.Server.Rcon.executeCommandAsync('map_rotate') + } + }, + 'map': { + ArgumentLength: 1, + Alias: 'm', + Permission: Permissions.Commands.COMMAND_MAP, + inGame: true, + callback: async (Player, args) => { + var delay = 3000 + var Map = this.Server.getMap(args[1]) ? this.Server.getMap(args[1]) : {Name: args[1], Alias: args[1]} + this.Server.Broadcast(Utils.formatString(Localization['COMMAND_MAP_FORMAT'], {Name: Map.Alias, Delay: (delay / 1000).toFixed(0)}, '%')[0]) + + await wait(delay) + await this.Server.Rcon.executeCommandAsync(`map ${Map.Name}`) + } + }, + 'globalchat': { + ArgumentLength: 0, + Alias: 'gc', + Permission: Permissions.Commands.COMMAND_USER_CMDS, + inGame: true, + callback: async (Player) => { + if (!Player.Session) return + Player.Session.Data.globalChat = !Player.Session.Data.globalChat + Player.Tell(Localization[`COMMAND_GLOBALCHAT_${Player.Session.Data.globalChat.toString().toLocaleUpperCase()}`]) + } + }, + 'nextmap': { + ArgumentLength: 0, + Alias: 'nm', + Permission: Permissions.Commands.COMMAND_USER_CMDS, + inGame: true, + callback: async (Player, args) => { + var mapIndex = this.Server.mapRotation.indexOf(this.Server.mapRotation.find(Map => Map == this.Server.Mapname)) + + var nextMap = mapIndex < this.Server.mapRotation.length - 1 ? this.Server.mapRotation[mapIndex + 1] : this.Server.mapRotation[0] + nextMap = this.Server.getMap(nextMap) ? this.Server.getMap(nextMap).Alias : nextMap + + if (mapIndex < 0 || !nextMap) { + Player.Tell(Localization['COMMAND_NEXTMAP_NOT_FOUND']) + return + } + + Player.Tell(Utils.formatString(Localization['COMMAND_NEXTMAP_FORMAT'], {Name: nextMap}, '%')) + } + }, + 'links': { + ArgumentLength: 0, + Permission: Permissions.Commands.COMMAND_USER_CMDS, + inGame: false, + callback: async (Player, args) => { + if (!config.links || !config.links.length) { + Player.Tell(Localization['COMMAND_LINKS_NOT_CONFIG']) + } + + if (args[1]) { + var found = false + + config.links.forEach(link => { + if (found) return + if (link.Name.toLocaleLowerCase().startsWith(args[1].toLocaleLowerCase())) { + Player.Tell(Utils.formatString(Localization['COMMAND_LINKS_FORMAT'], link, '%')[0]) + found = true + } + }) + + !found && Player.Tell(Localization['COMMAND_LINKS_NOT_FOUND']) + return + } + + for (var i = 0; i < config.links.length; i++) { + Player.Tell(Utils.formatString(Localization['COMMAND_LINKS_FORMAT'], config.links[i], '%')[0]) + await wait(500) + } + } + }, + 'ping': { + ArgumentLength: 0, + Permission: Permissions.Commands.COMMAND_USER_CMDS, + inGame: false, + callback: function (Player) { + Player.Tell('pong') + } + }, + 'broadcast': { + ArgumentLength: 1, + Permission: Permissions.Commands.COMMAND_MAP, + inGame: false, + callback: async (Player, args) => { + this.Managers.forEach(Manager => { + Manager.Server.Broadcast(`^7[^1Broadcast ^7(^5${Player.Name}^7)] ${args.slice(1).join(' ')}`) + }) + Player.Tell(`^1Broadcasted^7: ${args.slice(1).join(' ')}`) + } + }, + 'tell': { + ArgumentLength: 2, + Permission: Permissions.Commands.COMMAND_USER_CMDS, + inGame: false, + callback: async (Player, args = null, delay) => { + + var Client = await this.Server.getClient(args[1]) + switch (true) { + case (!Client): + Player.Tell(Localization.COMMAND_CLIENT_NOT_FOUND) + return + } + + var Target = this.Server.findClient(Client.ClientId) + switch (true) { + case (!Target): + Player.Tell(Localization.COMMAND_CLIENT_NOT_INGAME) + return + } + + Target.Session && (Target.Session.Data.lastMsg = Player) + Player.inGame && (Player.Session.Data.lastMsg = Target) + + Target.Tell(`^3[^5${Player.Name}^3 (@^5${Player.ClientId}^3) -> me]^7 ${args.slice(2).join(' ')}`) + Player.Tell(`^3[me -> ^5${Target.Name} ^3(@^5${Target.ClientId}^3)^3]^7 ${args.slice(2).join(' ')}`) + } + }, + 'reply': { + ArgumentLength: 1, + Permission: Permissions.Commands.COMMAND_USER_CMDS, + Alias: 'r', + inGame: true, + callback: async(Player, args) => { + switch (true) { + case (!Player.Session || !Player.Session.Data.lastMsg): + Player.Tell(Localization['COMMAND_REPLY_NOT_CONV']) + return + case (!this.Server.findClient(Player.Session.Data.lastMsg.ClientId)): + Player.Tell(Localization['COMMAND_CLIENT_NOT_INGAME']) + return + } + + Player.Session.Data.lastMsg.Tell(`^3[^5${Player.Name}^3 (@^5${Player.ClientId}^3) -> me]^7 ${args.slice(1).join(' ')}`) + Player.Tell(`^3[me -> ^5${Player.Session.Data.lastMsg.Name} ^3(@^5${Player.Session.Data.lastMsg.ClientId}^3)^3]^7 ${args.slice(1).join(' ')}`) + } + }, + 'players': { + ArgumentLength: 0, + Permission: Permissions.Commands.COMMAND_USER_CMDS, + inGame: false, + callback: async (Player, args = null, delay) => { + var allClients = Utils.chunkArray(this.getAllClients(), Player.inGame ? 4 : 15) + + var page = Number.isInteger(parseInt(args[1])) ? Math.max(1, Math.min(parseInt(args[1]), allClients.length)) : 1 + + if (!allClients.length) { + Player.Tell(Localization['NO_PLAYERS_ONLINE']) + return + } + + await Player.Tell(Utils.formatString(Localization['COMMAND_LIST_PAGE'], {max: allClients.length, current: page}, '%')[0]) + + for (var i = 0; i < allClients[page - 1].length; i++) { + Player.Tell(Utils.formatString(Localization['COMMAND_PLAYERS_FORMAT'], + { + Name: allClients[page - 1][i].Name, + ClientId: allClients[page - 1][i].ClientId, + Role: Utils.getRoleFrom(allClients[page - 1][i].PermissionLevel, 1).Name, + Level: allClients[page - 1][i].PermissionLevel, + Hostname: allClients[page - 1][i].Server.HostnameRaw + }, '%')[0]) + } + } + }, + 'info': { + ArgumentLength: 0, + Permission: Permissions.Commands.COMMAND_USER_CMDS, + inGame: false, + callback: (Player) => { + Player.Tell(`Node Server Manager - v${this.Manager.Version} by ${this.Manager.Author}`) + } + }, + 'whoami': { + ArgumentLength: 0, + Permission: Permissions.Commands.COMMAND_USER_CMDS, + inGame: false, + callback: async (Player) => { + var info = await this.Server.DB.getClient(Player.ClientId) + + if (!info) { + Player.Tell(Localization['COMMAND_CLIENT_NOT_FOUND']) + return + } + + Player.Tell(`[^5${info.Name}^7] [@^5${info.ClientId}^7] [^5${Utils.getRoleFrom(Math.min(info.PermissionLevel, 5), 1).Name}^7] [^5${info.IPAddress}^7] [^5${info.Guid}^7]`) + } + }, + 'whois': { + ArgumentLength: 1, + Permission: 'ROLE_ADMIN', + inGame: false, + callback: async (Player, args) => { + var Client = await this.Server.getClient(args[1]) + + switch (true) { + case (!Client): + Player.Tell(Localization['COMMAND_CLIENT_NOT_FOUND']) + return + } + + var info = await this.Server.DB.getClient(Client.ClientId) + Player.Tell(`[^5${info.Name}^7] [@^5${info.ClientId}^7] [^5${Utils.getRoleFrom(Math.min(info.PermissionLevel, 5), 1).Name}^7] [^5${info.IPAddress}^7] ^7[^5${info.Guid}^7]`) + } + }, + 'testperm': { + ArgumentLength: 1, + Permission: Permissions.Commands.COMMAND_USER_CMDS, + inGame: false, + callback: async (Player, args) => { + var Permission = Utils.getRoleFrom(args.slice(1).join(' '), 0) + var Client = await this.Server.DB.getClient(Player.ClientId) + + switch (true) { + case (!Client): + Player.Tell(Localization['COMMAND_CLIENT_NOT_FOUND']) + return + case (!Permission): + Player.Tell(Localization['ROLE_NOT_EXIST']) + return + case (Client.PermissionLevel < Permissions.Levels.ROLE_ADMIN): + Player.Tell(Localization['COMMAND_FORBIDDEN']) + return + case (Client.PermissionLevel < Permission.Level): + Player.Tell(Localization['ROLE_HIERARCHY_ERROR']) + return + } + + Player.PermissionLevel = Permission.Level + Player.Tell(`Permissions set to [ ^5${Permission.Name}^7 ]`) + } + }, + 'servers': { + ArgumentLength: 0, + Permission: Permissions.Commands.COMMAND_USER_CMDS, + inGame: false, + callback: async (Player, args, delay) => { + var Managers = this.Managers.concat() + + if (args[1] && Managers[parseInt(args[1])] && Managers[parseInt(args[1])].Server.Mapname) { + var Manager = Managers[parseInt(args[1])] + Player.Tell(Utils.formatString(Localization['COMMAND_SERVERS_FORMAT'], + { + Id: Manager.Server.Id, + Hostname: Manager.Server.Hostname, + Host: Manager.Server.getAddress(), + Clients: Manager.Server.getClients().length, + MaxClients: Manager.Server.MaxClients, + Mapname: Manager.Server.getMapname().Alias + }, '%')) + return + } + + for (var i = 0; i < Managers.length; i++) { + var Manager = Managers[i] + if (!Manager.Server.Mapname) continue + Player.Tell(Utils.formatString(Localization['COMMAND_SERVERS_FORMAT'], + { + Id: Manager.Server.Id, + Hostname: Manager.Server.Hostname, + Host: Manager.Server.getAddress(), + Clients: Manager.Server.getClients().length, + MaxClients: Manager.Server.MaxClients, + Mapname: Manager.Server.getMapname().Alias + }, '%')) + delay && await wait(500) + } + } + }, + 'token': { + ArgumentLength: 0, + Permission: Permissions.Commands.COMMAND_USER_CMDS, + inGame: false, + callback: async (Player) => { + var Client = await this.Server.DB.getClient(Player.ClientId) + + switch (true) { + case (Player.discordUser): + Player.Tell(Localization['COMMAND_ENV_ERROR']) + return + case (!Client): + Player.Tell(Localization['COMMAND_CLIENT_NOT_FOUND']) + return + case (!Client.Settings.TokenLogin): + Player.Tell(Localization['TOKEN_LOGIN_DISABLED']) + return + } + + var rawToken = crypto.randomBytes(3).toString('hex').toLocaleUpperCase(); + rawToken = rawToken.split('') + var formattedToken = [] + + rawToken.forEach(char => { + if (Number.isInteger(parseInt(char))) { + formattedToken.push(`^5${char}^7`) + } else { + formattedToken.push(`^3${char}^7`) + } + }) + + Player.Tell(Localization.COMMAND_TOKEN_FORMAT + .replace('%CLIENTID%', Player.ClientId) + .replace('%TOKEN%', formattedToken.join(''))) + await this.Server.DB.createToken(Player.ClientId, rawToken.join('')) + } + }, + 'rcon': { + ArgumentLength: 1, + Permission: Permissions.Commands.COMMAND_RCON, + inGame: false, + callback: async (Player, args, delay) => { + var result = [] + + if (!Player.inGame) { + switch (true) { + case (args.length < 2): + Player.Tell(Localization.RCON_SERVER_NOT_SPECIFIED) + return + case (!this.Managers[parseInt(args[1])] || !this.Managers[parseInt(args[1])].Server.Mapname || !this.Managers[parseInt(args[1])].Server.Rcon.isRunning): + Player.Tell(Localization.SERVER_NOT_EXIST) + return + } + + var cmd = (await this.Managers[parseInt(args[1])].Server.Rcon.executeCommandAsync(args.slice(2).join(' '))) + result = cmd ? cmd.trim().split('\n') : Localization['COMMAND_RCON_FAILED'].split('\n') + } else { + var cmd = await this.Server.Rcon.executeCommandAsync(args.slice(1).join(' ')) + result = cmd ? cmd.trim().split('\n') : Localization['COMMAND_RCON_FAILED'].split('\n') + } + + result[0] = Localization.COMMAND_EXECUTE_SUCCESS + + for (var i = 0; i < result.length; i++) { + Player.Tell(result[i]) + delay && await wait(300) + } + } + }, + 'setrole': { + ArgumentLength: 2, + Permission: Permissions.Commands.COMMAND_SETROLE, + inGame: false, + Alias: 'sr', + callback: async (Player, args) => { + var Role = args.slice(2).join(' ') + var Client = await this.Server.getClient(args[1]) + var Permission = Utils.getRoleFrom(Role, 0) + + switch (true) { + case (!Client): + Player.Tell(Localization.COMMAND_CLIENT_NOT_FOUND) + return + case (!Permission): + Player.Tell(Localization.ROLE_NOT_EXIST) + return + case (Permission.Level >= Player.PermissionLevel): + Player.Tell(Localization.ROLE_HIERARCHY_ERROR) + return + case (Player.ClientId == Client.ClientId): + Player.Tell(Localization.ROLE_SELF_ERROR) + return + } + + var Target = this.Server.findClient(Client.ClientId) + if (Target) { + Target.PermissionLevel = Permission.Level + Target.Tell(`Your role has been set to [ ^5${Permission.Name}^7 ]`) + + var role = Permission.Name + + var customTag = await this.Server.DB.metaService.getPersistentMeta('custom_tag', Target.ClientId) + role = customTag ? customTag.Value : Utils.stripString(role) + + Target.Server.Rcon.executeCommandAsync(`setclantagraw ${Target.Clientslot} "${role}"`) + } + + this.Server.DB.setLevel(Client, Permission.Level) + Player.Tell(`^5${Client.Name}^7's role has been set to [ ^5${Permission.Name}^7 ]`) + } + }, + 'owner': { + Permission: Permissions.Commands.COMMAND_USER_CMDS, + inGame: true, + callback: async (Player) => { + var Owner = await this.Server.DB.getOwner() + + switch (true) { + case !Owner: + this.Server.DB.setLevel(Player, Permissions.Levels['ROLE_OWNER']) + Player.PermissionLevel = Permissions.Levels['ROLE_OWNER'] + Player.Tell(`Your role has been set to [ ^5${Utils.getRoleFrom(5, 1).Name}^7 ]`) + return + case (Owner.ClientId == Player.ClientId): + Player.Tell(`You're already the owner!`) + return + case (Owner.ClientId != Player.ClientId): + Player.Tell(`^5${(await this.Server.DB.getClient(Owner.ClientId)).Name}^7 owns this server`) + return + } + } + }, + 'kick': { + ArgumentLength: 2, + Alias: 'k', + Permission: Permissions.Commands.COMMAND_USER_CMDS, + inGame: false, + callback: async (Player, args) => { + if (await this.is_staff(Player) == false) + { + Player.Tell("^1Staff only") + return + } + var Client = await this.Server.getClient(args[1]) + + switch (true) { + case (!Client): + Player.Tell(Localization.COMMAND_CLIENT_NOT_FOUND) + return + /* case (Client.PermissionLevel >= Player.PermissionLevel): + Player.Tell(Localization.CLIENT_HIERARCHY_ERROR)*/ + return + } + + var Target = this.Server.findClient(Client.ClientId) + Target ? ( Player.Tell(`^5${Target.Name}^7 was kicked`), Target.Kick(`${args.slice(2).join(' ')}`, Player)) : Player.Tell(Localization.COMMAND_CLIENT_NOT_INGAME) + } + }, + 'unban': { + ArgumentLength: 2, + Alias: 'ub', + Permission: Permissions.Commands.COMMAND_USER_CMDS, + inGame: false, + callback: async (Player, args) => { + if (await this.is_staff(Player) == false) + { + Player.Tell("^1Staff only") + return + } + var Client = await this.Server.getClient(args[1]) + var Reason = args.slice(2).join(' ') + + /*switch (true) { + case (Client.PermissionLevel >= Player.PermissionLevel): + Player.Tell(Localization.CLIENT_HIERARCHY_ERROR) + return + }*/ + + var count = await this.Server.DB.unbanClient(Client.ClientId, Reason, Player.ClientId) + + this.Server.DB.addPenalty({ + TargetId: Client.ClientId, + OriginId: Player.ClientId, + PenaltyType: 'PENALTY_UNBAN', + Active: false, + Duration: 0, + Reason: Reason + }) + + if (count) { + Player.Tell(`Unbanned ^5${Client.Name}^7 for ^5${Reason}^7`) + this.Server.emit('penalty', 'PENALTY_UNBAN', Client, Reason, Player) + } else + Player.Tell(`^5${Client.Name}^7 is not banned`) + } + }, + 'tempban': { + ArgumentLength: 3, + Alias: 'tb', + Permission: Permissions.Commands.COMMAND_USER_CMDS, + inGame: false, + callback: async (Player, args) => { + if (await this.is_staff(Player) == false) + { + Player.Tell("^1Staff only") + return + } + var timeVars = { + 'd': 86400, + 'h': 3600, + 'm': 60, + 's': 1, + } + + var Client = await this.Server.getClient(args[1]) + + if (!args[2].match(/([0-9]+)([A-Za-z]+)/)) { + Player.Tell(Localization.COMMAND_PARSE_TIME_ERROR) + return + } + + var parts = Array.from(args[2].match(/([0-9]+)([A-Za-z]+)/)).slice(1) + + switch (true) { + case (!Client): + Player.Tell(Localization['COMMAND_CLIENT_NOT_FOUND']) + return + /* case (Client.PermissionLevel >= Player.PermissionLevel): + Player.Tell(Localization['CLIENT_HIERARCHY_ERROR'])*/ + return + case (!parts || parts.length < 2 || !timeVars[parts[1]] || !Number.isInteger(parseInt(parts[0]))): + Player.Tell(Localization['COMMAND_PARSE_TIME_ERROR']) + return + } + + var Reason = args.slice(3).join(' ') + var Duration = parseInt(parts[0] * timeVars[parts[1]]) + + Reason = Reason.replace(new RegExp(/rule([0-9]+)/g), (rule) => { + var num = Math.max(parseInt(rule.substr(4)), 1) - 1 + + if (this.Server.config.rules[num]) { + return this.Server.config.rules[num] + } + + return rule + }) + + if (Duration > 86400 * 32) { + Player.Tell(Localization['COMMAND_PARSE_TIME_ERROR']) + return + } + + var Target = this.Server.findClient(Client.ClientId) + + if (Target) { + Target.Tempban(Reason, Player, Duration) + Player.Tell(`Banned ^5${Client.Name}^7 for ^5${Duration}^7 seconds for ^5${Reason}^7`) + return + } + + this.Server.DB.addPenalty({ + TargetId: Client.ClientId, + OriginId: Player.ClientId, + PenaltyType: 'PENALTY_TEMP_BAN', + Duration: Duration, + Reason: Reason + }) + + this.Server.emit('penalty', 'PENALTY_TEMP_BAN', Client, Reason, Player, Duration) + Player.Tell(`Banned ^5${Client.Name}^7 for ^5${Duration}^7 seconds for ^5${Reason}^7`) + } + }, + 'ban': { + ArgumentLength: 2, + Alias: 'b', + Permission: Permissions.Commands.COMMAND_USER_CMDS, + inGame: false, + callback: async (Player, args) => { + var Client = await this.Server.getClient(args[1]) + if (await this.is_staff(Player) == false) + { + Player.Tell("^1Staff only") + return + } + switch (true) { + case (!Client): + Player.Tell(Localization.COMMAND_CLIENT_NOT_FOUND) + return + /* case (Client.PermissionLevel >= Player.PermissionLevel): + Player.Tell(Localization.CLIENT_HIERARCHY_ERROR)*/ + return + } + + var Reason = args.slice(2).join(' ') + + Reason = Reason.replace(new RegExp(/rule([0-9]+)/g), (rule) => { + var num = Math.max(parseInt(rule.substr(4)), 1) - 1 + + if (this.Server.config.rules[num]) { + return this.Server.config.rules[num] + } + + return rule + }) + + var Target = this.Server.findClient(Client.ClientId) + if (Target) { + Target.Ban(Reason, Player) + Player.Tell(`Banned ${Target.Name} permanently for ${Reason}`) + return + } + + this.Server.DB.addPenalty({ + TargetId: Client.ClientId, + OriginId: Player.ClientId, + PenaltyType: 'PENALTY_PERMA_BAN', + Duration: 0, + Reason: Reason + }) + + this.Server.emit('penalty', 'PENALTY_PERMA_BAN', Client, Reason, Player) + Player.Tell(`Banned ${Client.Name} permanently for ${Reason}`) + } + }, + 'find': { + ArgumentLength: 1, + Alias: 'f', + Permission: Permissions.Commands.COMMAND_USER_CMDS, + inGame: false, + callback: async (Player, args, delay) => { + var MatchedClients = await this.Server.DB.getClientByName(args.slice(1).join(' '), 10) + + if (MatchedClients.length <= 0) { + Player.Tell(Localization['COMMAND_CLIENT_NOT_FOUND']) + return + } + + for (var i = 0; i < Math.min(MatchedClients.length, 10); i++) { + Player.Tell(`^5${MatchedClients[i].Name} ^7| ^5@${MatchedClients[i].ClientId} ^7| ^5${Utils.getRoleFrom(MatchedClients[i].PermissionLevel, 1).Name} ^7| Active ${moment(MatchedClients[i].LastConnection).calendar()} | Joined ${moment(MatchedClients[i].FirstConnection).calendar()}`) + delay && await wait(300) + } + } + } + } + this.Server.on('event', this.onEventAsync.bind(this)); + } + getAllClients() { + var Clients = [] + this.Managers.forEach(Manager => { + var clients = Manager.Server.Clients.filter(x => x) + Clients = Clients.concat(clients) + }) + return Clients + } + async playerCommand (Player, args, prefix) { + try { + if (!Player) return + + var Client = await this.Server.DB.getClient(Player.ClientId) + + if (Client.Settings && Client.Settings.InGameLogin && !Player.Session.Data.Authorized) { + Player.Tell(Localization['CLIENT_NOT_AUTHORIZED']) + return + } + + var isBroadcast = config.broadcastCommandPrefixes.includes(prefix) + + var executedMiddleware = await this.Manager.Commands.executeMiddleware(args[0], Player, args, { broadcast: isBroadcast }) + if (await this.Manager.Commands.execute(args[0], Player, args, { broadcast: isBroadcast })) return + + var command = Utils.getCommand(this.Manager.commands, args[0]) + + switch (true) { + case (!this.Manager.commands[command]): + case (this.Manager.commands[command].gameTypeExclusions && this.Manager.commands[command].gameTypeExclusions.includes(this.Server.Gametype)): + !executedMiddleware && Player.Tell(Localization.COMMAND_NOT_FOUND) + return + case (Client.Settings && Client.Settings.InGameLogin && !Player.Session.Data.Authorized): + Player.Tell(Localization.CLIENT_NOT_AUTHORIZED) + return + case (Player.PermissionLevel < Permissions.Levels[this.Manager.commands[command].Permission]): + Player.Tell(Localization.COMMAND_FORBIDDEN) + return + case (args.length - 1 < this.Manager.commands[command].ArgumentLength): + Player.Tell(Localization.COMMAND_ARGUMENT_ERROR) + await wait(300) + Player.Tell(`Usage: ^6${config.commandPrefixes[0]}^7${Localization[`USAGE_${command.toLocaleUpperCase()}`]}`) + return + } + + this.Manager.commands[command].logToAudit != false && this.Server.DB.logActivity(`@${Player.ClientId}`, Localization['AUDIT_CMD_EXEC'].replace('%NAME%', command), args.join(' ')) + this.Manager.commands[command].callback(Player, args, true) + } + catch (e) { + if (process.env.NODE_ENV && process.env.NODE_ENV.toLocaleLowerCase() == 'dev') + console.log(e) + + Player.Tell(Localization['COMMAND_ERROR']) + } + } + + async is_staff(Player) + { + for (var i = 0; i < this.staff_list_a.length; i++) + if (this.staff_list_a[i] == Player.Guid) + return true + Player.Tell("hehe boi u tryna scam da kiels by using staff cmd? oh helllll no fk emp") + return false + } +} +module.exports = Plugin \ No newline at end of file diff --git a/node-server-manager/Plugins/Penalties.js b/node-server-manager/Plugins/Penalties.js new file mode 100644 index 0000000..d46769e --- /dev/null +++ b/node-server-manager/Plugins/Penalties.js @@ -0,0 +1,46 @@ +const path = require('path') +const { Command, NodeServerManager } = require(path.join(__dirname, `../Lib/Classes.js`)) +const Utils = new (require(path.join(__dirname, '../Utils/Utils.js')))() +const Permissions = require(path.join(__dirname, `../Configuration/NSMConfiguration.json`)).Permissions +const Localization = require(path.join(__dirname, `../Configuration/Localization-${process.env.LOCALE}.json`)).lookup + +class Plugin { + constructor(Server, Manager) { + this.Server = Server + this.Manager = Manager + this.Server.on('connect', this.onPlayerConnected.bind(this)) + } + async onPlayerConnected(Player) { + if (this.Server.getClients().length + this.Server.reservedSlots > this.Server.MaxClients && Player.PermissionLevel < Permissions.Levels['ROLE_MODERATOR']) { + Player.Kick(Localization['KICK_CLIENTSLOT_RESERVED']) + } + + try { + var playerPenalties = await this.Server.DB.getAllPenalties(Player.ClientId) + + for (var i = 0; i < playerPenalties.length; i++) { + switch (playerPenalties[i].PenaltyType) { + case 'PENALTY_PERMA_BAN': + if (playerPenalties[i].Active) { + Player.Kick(`Banned for: ^5${playerPenalties[i].Reason}`, NodeServerManager) + return + } + break + case 'PENALTY_TEMP_BAN': + var dateDiff = (new Date(playerPenalties[i].Date) - new Date()) / 1000 + + if (dateDiff + playerPenalties[i].Duration > 0) { + if (playerPenalties[i].Active) { + Player.Kick(`Banned for: ^5${playerPenalties[i].Reason}^7 ${Utils.secondsToDhms(dateDiff + playerPenalties[i].Duration)} left`, NodeServerManager) + return + } + } + break + } + } + } + catch (e) { } + } + +} +module.exports = Plugin \ No newline at end of file diff --git a/node-server-manager/Plugins/Routes/Discord.js b/node-server-manager/Plugins/Routes/Discord.js new file mode 100644 index 0000000..2360881 --- /dev/null +++ b/node-server-manager/Plugins/Routes/Discord.js @@ -0,0 +1,50 @@ +const ejs = require('ejs') +const config = JSON.parse(process.env.config) +const btoa = require('btoa') +const DiscordOauth2 = require("discord-oauth2") +const oauth = new DiscordOauth2() + +module.exports = (app, db, Webfront) => { + if (!config.discordOAuth2Url || !config.discordClientId || !config.discordSecret) return + + const redirect = config.discordOAuth2Url + + app.get('/api/discord/callback', async (req, res, next) => { + if (!req.session.ClientId || !req.query.code) { + res.redirect('/') + return + } + + var response = await oauth.tokenRequest({ + clientId: config.discordClientId, + clientSecret: config.discordSecret, + + code: req.query.code, + scope: ['identify', 'guilds'], + grantType: 'authorization_code', + + redirectUri: redirect, + }) + + var user = await oauth.getUser(response.access_token) + Webfront.db.metaService.addPersistentMeta('discord_user', JSON.stringify(user), req.session.ClientId) + Webfront.db.metaService.addPersistentMeta('discord_id', user.id, req.session.ClientId) + + res.redirect('/settings') + }) + + app.get('/api/discord/disconnect', async (req, res, next) => { + if (!req.session.ClientId) { + res.redirect('/') + return + } + + Webfront.db.metaService.deletePersistentMeta('discord_user', req.session.ClientId) + Webfront.db.metaService.deletePersistentMeta('discord_id', req.session.ClientId) + res.redirect('/settings') + }) + + app.get('/api/discord/login', async (req, res, next) => { + res.redirect(`https://discordapp.com/api/oauth2/authorize?client_id=${config.discordClientId}&scope=identify&response_type=code&redirect_uri=${encodeURIComponent(redirect)}`) + }) +} \ No newline at end of file diff --git a/node-server-manager/Plugins/Routes/SocialMedia.js b/node-server-manager/Plugins/Routes/SocialMedia.js new file mode 100644 index 0000000..b5ebd3d --- /dev/null +++ b/node-server-manager/Plugins/Routes/SocialMedia.js @@ -0,0 +1,28 @@ +const path = require('path') +const ejs = require('ejs') +const config = require(path.join(__dirname, `../../Configuration/NSMConfiguration.json`)) + +module.exports = (app, db, Webfront) => { + if (!config.socialMedia) return + + var validLinks = config.socialMedia.filter(link => link[1].toString().match(/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/g)) + + app.get('/links', async (req, res, next) => { + var header = await Webfront.renderDynamicHTML(req) + res.setHeader('Content-type', 'html') + + ejs.renderFile(path.join(__dirname, '../../Webfront/html/links.ejs'), { + header, validLinks + }, (err, str) => { + res.end(str) + }) + }) + + validLinks.forEach(link => { + app.get(`/${link[0].toString()}`, async (req, res, next) => { + res.status(301).redirect(link[1].toString()) + }) + }) + + Webfront.addHeaderHtml(``, 5) +} \ No newline at end of file diff --git a/node-server-manager/Plugins/Routes/ZStats.js b/node-server-manager/Plugins/Routes/ZStats.js new file mode 100644 index 0000000..edc67dd --- /dev/null +++ b/node-server-manager/Plugins/Routes/ZStats.js @@ -0,0 +1,41 @@ +const path = require('path') +const ejs = require('ejs') +const Permissions = require(path.join(__dirname, `../../Configuration/NSMConfiguration.json`)).Permissions +const config = require(path.join(__dirname, `../../Configuration/NSMConfiguration.json`)) +const jsdom = new require('jsdom') + +module.exports = (app, db, Webfront) => { + app.get('/api/zstats', async (req, res, next) => { + var page = req.query.page ? req.query.page : 0 + var limit = 10 + var Stats = await db.getTopZStats(page, limit) + for (var i = 0; i < Stats.length; i++) { + delete Stats[i].Id + } + res.end(JSON.stringify(Stats)) + }) + + app.get('/zstats', async (req, res, next) => { + var Client = req.session.ClientId ? await db.getClient(req.session.ClientId) : {Name: 'Guest', ClientId: 0} + var Motd = config.MOTD ? config.MOTD.replace('{USERNAME}', Client.Name) + .replace('{CLIENTID}', Client.ClientId) : null + + res.setHeader('Content-type', 'text/html') + var Stats = await db.getTopZStats(0, 10) + var header = null + + ejs.renderFile(path.join(__dirname, '../../Webfront/html/header.ejs'), {session: req.session, Permissions: Permissions, Motd: Motd, Client: Client, config: config}, (err, str) => { + var dom = new jsdom.JSDOM(str) + for (var i = 0; i < Webfront.headerExtraHtml.length; i++) { + var el = dom.window.document.createElement('div') + el.innerHTML = Webfront.headerExtraHtml[i].html + dom.window.document.getElementById('header-btns').insertBefore(el.firstChild, dom.window.document.getElementById('header-btns').children[Webfront.headerExtraHtml[i].index]) + } + header = dom.window.document.getElementById('wf-header').outerHTML + }) + + ejs.renderFile(path.join(__dirname, '../../Webfront/html/zstats.ejs'), {header: header, Stats: Stats}, (err, str) => { + res.end(str) + }) + }) +} \ No newline at end of file diff --git a/node-server-manager/Plugins/Routes/index.js b/node-server-manager/Plugins/Routes/index.js new file mode 100644 index 0000000..3056137 --- /dev/null +++ b/node-server-manager/Plugins/Routes/index.js @@ -0,0 +1,10 @@ +var fs = require('fs') + +module.exports = (app, db, Webfront) => { + fs.readdirSync(__dirname).forEach(function(file) { + if (file == "index.js") return + + var name = file.substr(0, file.indexOf('.')) + require('./' + name)(app, db, Webfront) + }) +} \ No newline at end of file diff --git a/node-server-manager/Plugins/ScriptCommands.js b/node-server-manager/Plugins/ScriptCommands.js new file mode 100644 index 0000000..2eff707 --- /dev/null +++ b/node-server-manager/Plugins/ScriptCommands.js @@ -0,0 +1,269 @@ +const path = require('path') +const { Command } = require(path.join(__dirname, `../Lib/Classes.js`)) +const Localization = require(path.join(__dirname, `../Configuration/Localization-${process.env.LOCALE}.json`)).lookup +const Utils = new (require(path.join(__dirname, '../Utils/Utils.js')))() + +class Entity { + constructor(Server, entnum) { + this.entnum = entnum + this.Server = Server + } + async call(name, ..._args) { + const args = [..._args] + + var buffer = `level.getentbynum(${this.entnum}).${name}(` + + for (var i = 0; i < args.length; i++) { + switch (typeof args[i]) { + case 'string': + buffer += `\\"${args[i]}\\"` + break + case 'object': + buffer += args[i].code + break + default: + buffer += args[i] + break + } + + if (i < args.length - 1) { + buffer += ', ' + } + } + + buffer += ')' + + await this.Server.Rcon.executeCommandAsync(`chai_eval ${buffer}`) + } + format(name, ..._args) { + const args = [..._args] + + var buffer = `level.getentbynum(${this.entnum}).${name}(` + + for (var i = 0; i < args.length; i++) { + switch (typeof args[i]) { + case 'string': + buffer += `\\"${args[i]}\\"` + break + case 'object': + buffer += args[i].code + break + default: + buffer += args[i] + break + } + + if (i < args.length - 1) { + buffer += ', ' + } + } + + buffer += ')' + + return {code: buffer} + } +} + +const scripting = { + entity: (Server, entnum) => { + return new Entity(Server, entnum) + }, + vector: (arr) => { + return { + code: `[${parseFloat(arr[0])},${parseFloat(arr[1])},${parseFloat(arr[2])}]` + } + }, + call: async (Server, name, ..._args) => { + const args = [..._args] + + var buffer = `gsc.${name}(` + + for (var i = 0; i < args.length; i++) { + switch (typeof args[i]) { + case 'string': + buffer += `\\"${args[i]}\\"` + break + case 'object': + buffer += args[i].code + break + default: + buffer += args[i] + break + } + + if (i < args.length - 1) { + buffer += ', ' + } + } + + buffer += ')' + + await Server.Rcon.executeCommandAsync(`chai_eval ${buffer}`) + } +} + +class Plugin { + constructor(Server, Manager, Managers) { + this.Server = Server + this.Manager = Manager + this.Managers = Managers + this.Server.on('dvars_loaded', this.init.bind(this)) + } + init() { + if (this.Server.Gamename != 'IW5') { + return + } + + this.Manager.Commands.add( + new Command({ + permission: 'ROLE_ADMIN' + }) + .setName('kill') + .addParam({ + index: 0, + name: 'target', + join: true + }) + .addCallback(async (Player, params) => { + const Target = this.Server.findLocalClient(params.target) + + if (!Target || !Target.Server || Target.Server.Id != Player.Server.Id) { + Player.Tell(Localization['COMMAND_CLIENT_NOT_FOUND']) + return + } + + scripting.entity(this.Server, Target.Clientslot).call('suicide') + }) + ) + + this.Manager.Commands.add( + new Command({ + permission: 'ROLE_ADMIN' + }) + .setName('give') + .addParam({ + index: 0, + name: 'target', + join: false + }) + .addParam({ + index: 1, + name: 'weapon', + join: false + }) + .addCallback(async (Player, params) => { + const Target = this.Server.findLocalClient(params.target) + + if (!Target || !Target.Server || Target.Server.Id != Player.Server.Id) { + Player.Tell(Localization['COMMAND_CLIENT_NOT_FOUND']) + return + } + + const weaponName = params.weapon.replace(new RegExp(/(\\|\")/g), '') + const entity = scripting.entity(this.Server, Target.Clientslot) + + await entity.call('giveweapon', weaponName) + await entity.call('switchtoweapon', weaponName) + }) + ) + + this.Manager.Commands.add( + new Command({ + permission: 'ROLE_ADMIN' + }) + .setName('tp') + .addParam({ + index: 0, + name: 'target', + join: true + }) + .addCallback(async (Player, params) => { + const Target = this.Server.findLocalClient(params.target) + + if (!Target || !Target.Server || Target.Server.Id != Player.Server.Id) { + Player.Tell(Localization['COMMAND_CLIENT_NOT_FOUND']) + return + } + + Player.Tell(Utils.formatString(Localization['COMMAND_TP_FORMAT'], { + target: Target.Name, + origin: 'you', + coords: '' + })) + + const entity = scripting.entity(this.Server, Player.Clientslot) + const target = scripting.entity(this.Server, Target.Clientslot) + + entity.call('setorigin', target.format('getorigin')) + }) + ) + + this.Manager.Commands.add( + new Command({ + permission: 'ROLE_ADMIN' + }) + .setName('tphere') + .addParam({ + index: 0, + name: 'target', + join: true + }) + .addCallback(async (Player, params) => { + const Target = this.Server.findLocalClient(params.target) + + if (!Target || !Target.Server || Target.Server.Id != Player.Server.Id) { + Player.Tell(Localization['COMMAND_CLIENT_NOT_FOUND']) + return + } + + Player.Tell(Utils.formatString(Localization['COMMAND_TP_FORMAT'], { + target: 'you', + origin: Target.Name, + coords: '' + })) + + const entity = scripting.entity(this.Server, Player.Clientslot) + const target = scripting.entity(this.Server, Target.Clientslot) + + target.call('setorigin', entity.format('getorigin')) + }) + ) + + this.Manager.Commands.add( + new Command({ + permission: 'ROLE_ADMIN' + }) + .setName('setvelocity') + .addParam({ + index: 0, + name: 'target', + join: false + }) + .addParam({ + index: 1, + name: 'velocity', + join: false + }) + .addCallback(async (Player, params) => { + const Target = this.Server.findLocalClient(params.target) + + if (!Target || !Target.Server || Target.Server.Id != Player.Server.Id) { + Player.Tell(Localization['COMMAND_CLIENT_NOT_FOUND']) + return + } + + const entity = scripting.entity(this.Server, Player.Clientslot) + const velocity = params.velocity.split(',').map(f => parseFloat(f)) + const vector = [0.0, 0.0, 0.0] + + for (var i = 0; i < Math.min(velocity.length, 3); i++) { + vector[i] = velocity[i] + } + + entity.call('setvelocity', scripting.vector(vector)) + }) + ) + } +} + +module.exports = Plugin \ No newline at end of file diff --git a/node-server-manager/Plugins/StatLogger.js b/node-server-manager/Plugins/StatLogger.js new file mode 100644 index 0000000..a0abb22 --- /dev/null +++ b/node-server-manager/Plugins/StatLogger.js @@ -0,0 +1,85 @@ +const path = require('path') +const config = require(path.join(__dirname, `../Configuration/NSMConfiguration.json`)) + +class Plugin { + constructor(Server, Manager) { + this.Server = Server + this.Manager = Manager + this.Buffer = { Stats: {}, previousStats: {} } + setInterval(this.updateStats.bind(this), 300 * 1000) + this.init() + } + async playerConnected (Player) { + Player.lastSeen = new Date() + + Player.on('death', async (Attacker, Attack) => { + this.Buffer.Stats[Player.ClientId] = this.Buffer.Stats[Player.ClientId] + ? this.Buffer.Stats[Player.ClientId] + : await this.Server.DB.getPlayerStatsTotal(Player.ClientId) + + this.Buffer.Stats[Attacker.ClientId] = this.Buffer.Stats[Attacker.ClientId] + ? this.Buffer.Stats[Attacker.ClientId] + : await this.Server.DB.getPlayerStatsTotal(Attacker.ClientId) + + !this.Buffer.previousStats[Player.ClientId] && (this.Buffer.previousStats[Player.ClientId] = {}, Object.assign(this.Buffer.previousStats[Player.ClientId], this.Buffer.Stats[Player.ClientId])) + + !this.Buffer.previousStats[Attacker.ClientId] && (this.Buffer.previousStats[Attacker.ClientId] = {}, Object.assign(this.Buffer.previousStats[Attacker.ClientId], this.Buffer.Stats[Attacker.ClientId])) + + this.Buffer.Stats[Player.ClientId].Deaths++ + + if (Attacker.Clientslot != Player.Clientslot) { + this.Buffer.Stats[Attacker.ClientId].Kills++ + + this.Buffer.Stats[Player.ClientId].TotalPerformance += this.Buffer.Stats[Attacker.ClientId].Performance - 400 + this.Buffer.Stats[Attacker.ClientId].TotalPerformance += this.Buffer.Stats[Player.ClientId].Performance + 400 + + this.Buffer.Stats[Player.ClientId].Performance = (this.Buffer.Stats[Player.ClientId].TotalPerformance + + (this.Buffer.Stats[Attacker.ClientId].Performance - 400)) + / (this.Buffer.Stats[Player.ClientId].Kills + + this.Buffer.Stats[Player.ClientId].Deaths) + + this.Buffer.Stats[Attacker.ClientId].Performance = (this.Buffer.Stats[Attacker.ClientId].TotalPerformance + + (this.Buffer.Stats[Player.ClientId].Performance + 400)) + / (this.Buffer.Stats[Attacker.ClientId].Kills + + this.Buffer.Stats[Attacker.ClientId].Deaths) + } + }) + + Player.on('message', async (Message) => { + if (Message.startsWith(config.commandPrefix)) return + await this.Server.DB.logMessage(Player.ClientId, Player.Name, Player.Server.HostnameRaw, Message) + }) + } + async updateStats() { + Object.entries(this.Buffer.Stats).forEach(async Stats => { + + if (!this.Buffer.previousStats[Stats[0]] || (Stats[1].Kills <= this.Buffer.previousStats[Stats[0]].Kills && Stats[1].Deaths <= this.Buffer.previousStats[Stats[0]].Deaths)) return + + this.Server.DB.editStats(Stats[0], Stats[1]) + + this.Buffer.previousStats[Stats[0]] = {} + Object.assign(this.Buffer.previousStats[Stats[0]], Stats[1]) + }) + } + init () { + this.Server.on('connect', this.playerConnected.bind(this)) + this.playedTimeLogger() + } + playedTimeLogger() { + setInterval(async () => { + if (!this.Server.Rcon.isRunning) return + + this.Server.Clients.forEach(async Client => { + if (!Client || !Client.ClientId) return + + this.Server.DB.incrementStat(Client.ClientId, (new Date() - Client.lastSeen) / 1000 / 60, 'PlayedTime') + Client.lastSeen = new Date() + + var Stats = this.Buffer.Stats[Client.ClientId] ? this.Buffer.Stats[Client.ClientId] : await this.Server.DB.getPlayerStatsTotal(Client.ClientId) + this.Server.DB.addStatRecord(Client.ClientId, Stats.TotalPerformance, Math.max(0, Stats.Performance)) + }) + }, 60000) + } +} + +module.exports = Plugin \ No newline at end of file diff --git a/node-server-manager/Plugins/Voting.js b/node-server-manager/Plugins/Voting.js new file mode 100644 index 0000000..4675cf8 --- /dev/null +++ b/node-server-manager/Plugins/Voting.js @@ -0,0 +1,290 @@ +const path = require('path') +const wait = require('delay') +const Permissions = require(path.join(__dirname, `../Configuration/NSMConfiguration.json`)).Permissions +const config = require(path.join(__dirname, `../Configuration/NSMConfiguration.json`)) +const Localization = require(path.join(__dirname, `../Configuration/Localization-${process.env.LOCALE}.json`)).lookup +const Utils = new (require(path.join(__dirname, '../Utils/Utils.js')))() +const { Command, NodeServerManager } = require(path.join(__dirname, `../Lib/Classes.js`)) +class Plugin { + constructor(Server, Manager) { + this.Server = Server + this.Manager = Manager + this.voteTime = 120 + this.cooldownTime = 120 + this.currentVote = { + Type: null, + Origin: null, + Target: null, + Votes: [], + callback: null + } + this.currentVoteDefault = { + Type: null, + Origin: null, + Target: null, + Votes: [], + callback: null + } + this.votingSystem() + } + + async startVote() { + await wait(this.voteTime * 1000) + + if (this.currentVote.Type) { + this.Server.Broadcast(Utils.formatString(Localization['COMMAND_VOTE_END'], { Action: this.currentVote.actionString }, '%')[0]) + this.currentVote.Origin.cooldownStart = new Date() + this.currentVote = this.currentVoteDefault + } + } + + minimumVotes() { + return this.Server.Clients.filter(x => x).length < 3 ? this.Server.Clients.filter(x => x).length : Math.ceil(this.Server.Clients.filter(x => x).length / 2) + } + + hasVoted(Player) { + for (var i = 0; i < this.currentVote.Votes.length; i++) { + if (this.currentVote.Votes[i].ClientId == Player.ClientId) { + return true + } + } + + return false + } + + voteUpdate() { + if (this.currentVote.Type && this.currentVote.Votes.length >= this.minimumVotes()) { + this.currentVote.callback(this.currentVote) + this.currentVote = this.currentVoteDefault + } + } + + async votingSystem() { + + var voteTypes = { + Kick: { + Name: 'VOTE_KICK', + callback: async (Vote) => { + Vote.Target.Kick(Utils.formatString(Localization['COMMAND_VOTEKICK_KICK_MESSAGE'], { + origin: Vote.Origin.Name, + originId: Vote.Origin.ClientId, + reason: Vote.Reason + }, '%')[0], NodeServerManager) + } + }, + Map: { + Name: 'VOTE_MAP', + callback: async (Vote) => { + var delay = 3000 + this.Server.Broadcast(Utils.formatString(Localization['COMMAND_MAP_FORMAT'], {Name: Vote.Target.Alias, Delay: (delay / 1000).toFixed(0)}, '%')[0]) + await wait(delay) + this.Server.Rcon.executeCommandAsync(`map ${Vote.Target.Name}`) + } + } + } + + this.Manager.commands['stop'] = { + ArgumentLength: 0, + Alias: 'cancel', + Permission: Permissions.Commands.COMMAND_MAP, + inGame: true, + callback: async (Player, args) => { + switch (true) { + case (!this.currentVote.Type): + Player.Tell(Localization['COMMAND_VOTE_NO_VOTE']) + return + } + + this.Server.Broadcast(Utils.formatString(Localization['COMMAND_VOTE_END'], { Action: this.currentVote.actionString }, '%')[0]) + this.currentVote = this.currentVoteDefault + } + } + + this.Manager.commands['yes'] = { + ArgumentLength: 0, + Permission: Permissions.Commands.COMMAND_USER_CMDS, + inGame: true, + callback: async (Player, args) => { + switch (true) { + case (!this.currentVote.Type): + Player.Tell(Localization['COMMAND_VOTE_NO_VOTE']) + return + case (this.hasVoted(Player)): + Player.Tell(Localization['COMMAND_VOTE_ALREADY_VOTED']) + return + } + + this.currentVote.Votes.push(Player) + + this.Server.Broadcast(Utils.formatString(Localization['COMMAND_VOTE_VOTED_TEMPLATE'], { + Name: Player.Name, + Prefix: config.commandPrefixes[0], + Action: this.currentVote.actionString, + Votes: this.currentVote.Votes.length, + minVotes: this.minimumVotes() + }, '%')[0]) + + this.voteUpdate() + } + } + + this.Manager.commands['votekick'] = { + ArgumentLength: 2, + gameTypeExclusions: ['zclassic', 'zstandard'], + Alias: 'vk', + Permission: Permissions.Commands.COMMAND_USER_CMDS, + inGame: true, + callback: async (Player, args) => { + var Target = await this.Server.findLocalClient(args[1]) + + switch (true) { + case (args.slice(2).join(' ').length < 5): + Player.Tell(Utils.formatString(Localization['COMMAND_PARAM_LENGTH'], { + name: 'reason', + length: 5 + })) + return + case (Player.Data.lastVote && (new Date() - Player.Data.lastVote) / 1000 < 300): + Player.Tell(Localization['VOTE_COMMANDS_COOLDOWN']) + return + case (!Target): + Player.Tell(Localization['COMMAND_CLIENT_NOT_FOUND']) + return + case (Target.PermissionLevel > Player.PermissionLevel): + case (Target.ClientId == Player.ClientId): + Player.Tell(Localization['COMMAND_VOTEKICK_HIERARCHY_ERR']) + return + case (Player.cooldownStart && new Date() - Player.cooldownStart > this.cooldownTime): + Player.Tell(Utils.formatString(Localization['COMMAND_VOTE_COOLDOWN'], { Time: (new Date() - Player.cooldownStart - this.cooldownTime) / 1000 }, '%')[0]) + return + case (this.currentVote.Type && this.currentVote.Type != voteTypes.Kick.Name): + case (this.currentVote.Target && this.currentVote.Target.ClientId != Target.ClientId): + Player.Tell(Utils.formatString(Localization['COMMAND_VOTE_TYPE_ERR'], { Action: this.currentVote.actionString}, '%')[0]) + return + case (this.hasVoted(Player)): + Player.Tell(Localization['COMMAND_VOTE_ALREADY_VOTED']) + return + } + + if (!this.currentVote.Origin) { + Player.Data.lastVote = new Date() + + Player.Data.lastVotes = Player.Data.lastVotes ? Player.Data.lastVotes : [] + Player.Data.lastVotes.push(new Date()) + + var lastVotes = Player.Data.lastVotes.filter(date => (new Date() - date) / 1000 < 3600) + + if (lastVotes.length >= 3) { + Player.Report(Utils.formatString(Localization['VOTEKICK_COMMNAD_REPORT'], { + player: Player.Name, + count: lastVotes.length + }, '%')[0]) + } + + this.currentVote = { + Origin: Player, + Target: Target, + Type: voteTypes.Kick.Name, + Reason: args.slice(2).join(' '), + Votes: [Player], + actionString: Utils.formatString(Localization['COMMAND_VOTEKICK_ACTION'], {Name: Target.Name, Reason: args.slice(2).join(' ')} , '%')[0], + callback: voteTypes.Kick.callback + } + + this.Server.Broadcast(Utils.formatString(Localization['COMMAND_VOTE_VOTED_TEMPLATE'], { + Name: Player.Name, + Prefix: config.commandPrefixes[0], + Action: this.currentVote.actionString, + Reason: args.slice(2).join(' '), + Votes: 1, + minVotes: this.minimumVotes() + }, '%')[0]) + + this.startVote() + this.voteUpdate() + return + } + + this.currentVote.Votes.push(Player) + + this.Server.Broadcast(Utils.formatString(Localization['COMMAND_VOTE_VOTED_TEMPLATE'], { + Name: Player.Name, + Prefix: config.commandPrefixes[0], + Action: Utils.formatString(Localization['COMMAND_VOTEKICK_ACTION'], {Name: this.currentVote.Target.Name} , '%')[0], + Votes: this.currentVote.Votes.length, + minVotes: this.minimumVotes() + }, '%')[0]) + + this.voteUpdate() + } + } + + this.Manager.commands['votemap'] = { + ArgumentLength: 1, + Alias: 'vm', + gameTypeExclusions: ['zclassic', 'zstandard', 'infect'], + Permission: Permissions.Commands.COMMAND_USER_CMDS, + inGame: true, + callback: async (Player, args) => { + var Target = await this.Server.getMap(args[1]) + + switch (true) { + case (Player.Data.lastVote && (new Date() - Player.Data.lastVote) / 1000 < 300): + Player.Tell(Localization['VOTE_COMMANDS_COOLDOWN']) + return + case (!Target): + Player.Tell(Localization['COMMAND_VOTEMAP_NOT_FOUND']) + return + case (Player.cooldownStart && new Date() - Player.cooldownStart > this.cooldownTime): + Player.Tell(Utils.formatString(Localization['COMMAND_VOTE_COOLDOWN'], { Time: parseInt(this.cooldownTime - (new Date() - Player.cooldownStart) / 1000) }, '%')[0]) + return + case (this.currentVote.Type && this.currentVote.Type != voteTypes.Map.Name): + case (this.currentVote.Target && this.currentVote.Target.Name != Target.Name): + Player.Tell(Utils.formatString(Localization['COMMAND_VOTE_TYPE_ERR'], { Action: this.currentVote.actionString}, '%')[0]) + return + case (this.hasVoted(Player)): + Player.Tell(Localization['COMMAND_VOTE_ALREADY_VOTED']) + return + } + + if (!this.currentVote.Origin) { + Player.Data.lastVote = new Date() + + this.currentVote = { + Origin: Player, + Target: Target, + Type: voteTypes.Map.Name, + Votes: [Player], + actionString: Utils.formatString(Localization['COMMAND_VOTEMAP_ACTION'], {Name: Target.Alias} , '%')[0], + callback: voteTypes.Map.callback + } + + this.Server.Broadcast(Utils.formatString(Localization['COMMAND_VOTE_VOTED_TEMPLATE'], { + Name: Player.Name, + Prefix: config.commandPrefixes[0], + Action: this.currentVote.actionString, + Votes: 1, + minVotes: this.minimumVotes() + }, '%')[0]) + + this.startVote() + this.voteUpdate() + return + } + + this.currentVote.Votes.push(Player) + + this.Server.Broadcast(Utils.formatString(Localization['COMMAND_VOTE_VOTED_TEMPLATE'], { + Name: Player.Name, + Prefix: config.commandPrefixes[0], + Action: this.currentVote.actionString, + Votes: this.currentVote.Votes.length, + minVotes: this.minimumVotes() + }, '%')[0]) + + this.voteUpdate() + } + } + } +} +module.exports = Plugin diff --git a/node-server-manager/Plugins/WelcomeMessages.js b/node-server-manager/Plugins/WelcomeMessages.js new file mode 100644 index 0000000..2c37154 --- /dev/null +++ b/node-server-manager/Plugins/WelcomeMessages.js @@ -0,0 +1,88 @@ +const path = require('path') +const fetch = require('node-fetch') +const Utils = new (require(path.join(__dirname, '../Utils/Utils.js')))() +const Localization = require(path.join(__dirname, `../Configuration/Localization-${process.env.LOCALE}.json`)).lookup +const Permissions = require(path.join(__dirname, `../Configuration/NSMConfiguration.json`)).Permissions + +class Plugin { + constructor(Server, Manager, Managers) { + this.Server = Server + this.Manager = Manager + this.Managers = Managers + this.joinMessages() + } + async joinMessages() { + this.Server.on('disconnect', async (Player) => { + this.Server.Broadcast(Utils.formatString(Localization['QUIT_PLAYER_BROADCAST'], {Name: Player.Name}, '%')[0]) + }) + + this.Server.on('penalty', async (Type, Target, Reason, Origin, Duration = -1) => { + if (Origin == 1) return + + Duration = Duration > 0 ? Utils.time2str(Duration) : '' + this.Server.globalBroadcast(Utils.formatString(Localization[`${Type}_MESSAGE`], {Name: Target.Name, Reason, Origin: Origin.Name, Duration}, '%')[0]) + }) + + this.Server.on('connect', async (Player) => { + if (Player.IPAddress && Player.IPAddress.match(/(unknown|loopback|bot)/g)) return + + Player.IPAddress = Player.IPAddress ? Player.IPAddress : (await this.Server.DB.getClient(Player.ClientId)).IPAddress + + if (Player.PermissionLevel >= Permissions.Levels['ROLE_MODERATOR']) { + Player.Tell(Utils.formatString(Localization['AUTO_RECENT_REPORTS'], { count: (await this.Server.DB.getActiveReports()).length }, '%')[0]) + } + + if (process.env.NODE_ENV && process.env.NODE_ENV.toLocaleLowerCase() == 'dev') return + + var connections = await this.Server.DB.getAllConnections(Player.ClientId) + + Player.Tell(Localization['WELCOME_PLAYER'] + .replace('%PLAYER%', Player.Name) + .replace('%CONNECTIONS%', Utils.ordinalSuffix(connections.length | 1))) + + if (Player.Session && Player.Session.Data.Authorized) { + Player.Tell('Logged in through previous session') + } + + var setting = await this.Server.DB.metaService.getPersistentMeta('location', Player.ClientId) + + var role = Utils.getRoleFrom(Player.PermissionLevel, 1).Name + + var customTag = await this.Server.DB.metaService.getPersistentMeta('custom_tag', Player.ClientId) + role = customTag ? `^7${customTag.Value}` : role + + if (!Player.IPAddress) { + this.Server.Broadcast(Utils.formatString(Localization['WELCOME_PLAYER_BROADCAST'], { + player: Player.Name, + location: Localization['STRING_UNKNOWN'], + level: Player.PermissionLevel, + role + }, '%')[0]) + + return + } + + var info = !(setting && setting.Value == '1') + ? await this.getInfo(Player.IPAddress.match(/(localhost|127\.0\.0\.1)/g) + ? this.Server.externalIP + : Player.IPAddress) + : { country: Localization['STRING_HIDDEN'] } + + this.Server.Broadcast(Utils.formatString(Localization['WELCOME_PLAYER_BROADCAST'], { + player: Player.Name, + location: info ? info.country : Localization['STRING_UNKNOWN'], + level: Player.PermissionLevel, + role + }, '%')[0]) + }) + } + async getInfo(IPAddress) { + var result = await fetch(`https://extreme-ip-lookup.com/json/${IPAddress.split(':')[0]}?key=demo`) + if (result) { + return await result.json() + } + return false + } +} + +module.exports = Plugin \ No newline at end of file diff --git a/node-server-manager/Plugins/ZombiesBank.js b/node-server-manager/Plugins/ZombiesBank.js new file mode 100644 index 0000000..ef2f30f --- /dev/null +++ b/node-server-manager/Plugins/ZombiesBank.js @@ -0,0 +1,4627 @@ +const Sequelize = require('sequelize') +const path = require('path') +const { randomInt } = require('crypto') +const { kill } = require('process') +const { totalmem } = require('os') +const Utils = new (require(path.join(__dirname, '../Utils/Utils.js')))() +const Permissions = require(path.join(__dirname, `../Configuration/NSMConfiguration.json`)).Permissions +const Localization = require(path.join(__dirname, `../Configuration/Localization-${process.env.LOCALE}.json`)).lookup + +const maxGameMoney = 1000000 + +class Plugin { + constructor(Server, Manager, Managers) { + //add the .pguid of players to grant them staff permissions (must be done on ClanTag, ZombiesBank, ZombiesStats, NativeCommands & the gsc script staff.gsc) + this.staff_list_a = [564391] + this.botb_port = ["30001", "30005"] + this.raid_port = ["30009"] + this.rate = 1 + this.lock = "0" + this.cost = 100 + this.Server = Server + this.Manager = Manager + this.Managers = Managers + this.Server.on('connect', this.onPlayerConnect.bind(this)) + this.Server.on('line', this.onLine.bind(this)) + this.init() + this.competitive_r = -1 + this.basic_r = -1 + this.basic_r2 = -1 + this.ee_random = -1 + this.gamemode_random = -1 + this.are_quest_randomized = true + this.competitive_quest_count = 2 + this.guild_list = [] + this.guild_list[this.guild_list.length] = "RFC;63156" + this.guild_list[this.guild_list.length] = "RS;75539" + this.guild_list[this.guild_list.length] = "ITD;66060" + this.guild_list[this.guild_list.length] = "ILC;40024" + this.guild_list[this.guild_list.length] = "KS;12" + this.guild_list[this.guild_list.length] = "ALC;79746" + this.guild_list[this.guild_list.length] = "WNL;65507" + this.guild_list[this.guild_list.length] = "AZI;45982" + this.guild_list[this.guild_list.length] = "LOV;135710" + this.guild_list[this.guild_list.length] = "LCS;139379" + this.guild_list[this.guild_list.length] = "TSC;29979" + this.guild_list[this.guild_list.length] = "BHB;132773" + this.guild_list[this.guild_list.length] = "ROH;94673" + this.guildWatcher() + this.guildQuestWatcher() + this.modifierWatcher() + } + async onLine(line) { + line = line.trim().replace(new RegExp(/([0-9]+:[0-9]+)\s+/g), '') + + if (Utils.isJson(line)) { + var bankAction = JSON.parse(line) + switch (bankAction.event) { + case 'bank_withdraw': + var Player = this.Server.Clients.find(Client => Client && Client.Guid == bankAction.player.Guid) + Player && (await this.addPlayerMoney(Player.ClientId, -1 * bankAction.amount)) + break + case 'bank_deposit': + var Player = this.Server.Clients.find(Client => Client && Client.Guid == bankAction.player.Guid) + Player && (await this.addPlayerMoney(Player.ClientId, bankAction.amount)) + break + case 'godmodeon': + var Player = this.Server.Clients.find(Client => Client && Client.Guid == bankAction.player.Guid) + break + case 'godmodeoff': + var Player = this.Server.Clients.find(Client => Client && Client.Guid == bankAction.player.Guid) + break + } + } + } + async updatePlayerBalance() { + this.Server.Clients.forEach(Client => { + if (!Client || !Client.bankActionQueue.length) return + + this.addPlayerMoney(Client.ClientId, Utils.arraySum(Client.bankActionQueue)) + }) + } + + async onPlayerConnect(Player) + { + if (this.lock == "1") + { + if (await this.is_staff(Player) == false) + { + Player.Kick("^5Server is ^5locked ^5for ^3testing.^7") + } + } + if (!(await this.getZMStats(Player.ClientId))) { + await this.Server.DB.Models.NSMZombiesStats.build({ + ClientId: Player.ClientId + }).save() + } + + Player.bankActonQueue = [] + this.setBalanceDvar(Player) + } + async createTable() { + this.Server.DB.Models.NSMZombiesStats = this.Server.DB.Models.DB.define('NSMZombiesStats', + { + ClientId: { + type: Sequelize.INTEGER, + autoIncrement: true, + allowNull: false, + primaryKey: true, + references: { + model: 'NSMClients', + key: 'ClientId' + } + }, + Money: { + type: Sequelize.INTEGER, + defaultValue: 0, + allowNull: false + }, + LockerWeapon: { + type: Sequelize.TEXT, + defaultValue: 'none', + allowNull: false + } + }, { + timestamps: false + }) + this.Server.DB.Models.NSMZombiesStats.sync() + } + async getZMStats(ClientId) { + /* if (!ClientId) + { + console.log("getZMStats ERROR: ClientId undefined") + return false + }*/ + if (!ClientId) + return false + if (ClientId == 1) { + return { + Money: Infinity, + LockerWeapon: 'none' + } + } + var ZMStats = await this.Server.DB.Models.NSMZombiesStats.findAll({ + where: { + ClientId: ClientId + } + }) + return ZMStats.length > 0 ?ZMStats[0].dataValues : false + } + async setPlayerMoney(ClientId, Money) { + await this.Server.DB.Models.NSMZombiesStats.update({ + Money : Money }, { + where: {ClientId: ClientId + } + }) + } + async setBalanceDvar(Player) { + if (!Player.Server) return + var money = (await this.getZMStats(Player.ClientId)).Money + if (money == undefined) + { + Player.Tell("Error, zm_stats") + return + } + Player.Server.Rcon.setDvar(`${Player.Guid}_balance`, money) + } + async addPlayerMoney(ClientId, Money) { + return await this.Server.DB.Models.NSMZombiesStats.update({ + Money : Sequelize.literal(`Money + ${Money}`) }, { + where: {ClientId: ClientId + } + }) + } + //trade + async getTradeData(Player) { + try { + const tradeData = (await this.Server.DB.metaService.getPersistentMeta('trade_data_buyer', Player.ClientId)).Value; + return tradeData && tradeData != "0" ? tradeData : null; + } catch (error) { + return null; + } + } + async performTrade({sellerId, buyerId, money, zcoins, slot}) { + await Promise.all([ + this.addZcoins(sellerId, zcoins), + this.removeZcoins(buyerId, zcoins), + this.addMoney(sellerId, money), + this.subtractMoney(buyerId, money) + ]); + + this.Managers.forEach(manager => + { + if (manager) + { + this.checkForLoadedSave(manager, sellerId, slot) + } + }) + await this.updateGameSlots({sellerId, buyerId, slot}); + await this.resetTradeData(sellerId, buyerId); + } + + async checkForLoadedSave(manager, clientId, slot) + { + var save_id = parseInt(await manager.Server.Rcon.getDvar('saveId')) + var save_slot = parseInt(await manager.Server.Rcon.getDvar('saveSlot')) + + if(clientId == save_id && save_slot == slot) + { + await manager.Server.Rcon.setDvar('saveId', "1") + } + } + + async updateGameSlots({sellerId, buyerId, slot}) { + const [sellerSlot, buyerSlot] = await Promise.all([ + this.getGame(sellerId), + this.getGame(buyerId) + ]).then(results => results.map(result => result.split(';'))); + + if (slot == 1 || slot == 2) { + const sellerNewSlot = slot == 1 ? [0, sellerSlot[1]] : [sellerSlot[0], 0]; + + if (parseInt(buyerSlot[0]) >= parseInt(buyerSlot[1])) + { + var buyerNewSlot = [buyerSlot[0], sellerSlot[slot - 1]] + } + else + { + var buyerNewSlot = [sellerSlot[slot - 1], buyerSlot[1]] + } + await Promise.all([ + this.saveGame(sellerId, ...sellerNewSlot), + this.saveGame(buyerId, ...buyerNewSlot) + ]); + } + } + + async resetTradeData(sellerId, buyerId) { + await Promise.all([ + this.Server.DB.metaService.addPersistentMeta('trade_date', (new Date() / 1000) - 61, sellerId), + this.Server.DB.metaService.addPersistentMeta('trade_date', (new Date() / 1000) - 61, buyerId), + this.Server.DB.metaService.addPersistentMeta('trade_data_seller', "0", sellerId), + this.Server.DB.metaService.addPersistentMeta('trade_data_buyer', "0", buyerId) + ]); + } + parseTradeData(tradeData) { + const tradeInfo = tradeData.split(';'); + const tradeInfoParsed = tradeInfo[0].split('-'); + + return [parseInt(tradeInfo[4]), parseInt(tradeInfo[3]), parseInt(tradeInfo[1]), parseInt(tradeInfo[2]), parseInt(tradeInfoParsed[0]), parseInt(tradeInfoParsed[1])]; /////// + } + async handleTradeTimeout(Seller, Buyer) { + setTimeout(async () => { + var [trade_data_seller, trade_data_buyer] = await Promise.all([ + this.Server.DB.metaService.getPersistentMeta('trade_data_seller', Seller.ClientId), + this.Server.DB.metaService.getPersistentMeta('trade_data_buyer', Buyer.ClientId) + ]); + + if (trade_data_seller.Value != "0" && trade_data_buyer.Value != "0") + { + await this.resetTradeData(Seller.ClientId, Buyer.ClientId); + await Seller.Tell(`^2Trade offer^7 ^3timed out^7. Your ^2trade offer^7 has been cancelled.`); + await Buyer.Tell(`^2Trade offer^7 ^3timed out^7. Your ^2trade offer^7 has been cancelled.`); + } + }, (60 * 1000)); // 60 seconds timeout + } + async initiateTrade(Seller, Buyer, saveSlot, money, zcoins) { + + const sellerSlot = await this.getSaveSlot(Seller, saveSlot) + const tradeData = `${saveSlot}-${sellerSlot};${money};${zcoins};${Buyer.ClientId};${Seller.ClientId}` /////// + + await Promise.all([ + this.Server.DB.metaService.addPersistentMeta('trade_date', (new Date() / 1000), Seller.ClientId), + this.Server.DB.metaService.addPersistentMeta('trade_date', (new Date() / 1000), Buyer.ClientId), + this.Server.DB.metaService.addPersistentMeta('trade_data_seller', tradeData, Seller.ClientId), + this.Server.DB.metaService.addPersistentMeta('trade_data_buyer', tradeData, Buyer.ClientId) + ]); + var seller_name = Seller.Name + var buyer_name = Buyer.Name + + var seller_custom_name = await this.Server.DB.metaService.getPersistentMeta('custom_name', Seller.ClientId) + if (seller_custom_name) + seller_name = seller_custom_name.Value + + var buyer_custom_name = await this.Server.DB.metaService.getPersistentMeta('custom_name', Buyer.ClientId) + if (buyer_custom_name) + buyer_name = buyer_custom_name.Value + + await Seller.Tell(`^2Trade offer^7 sent to ${buyer_name}^7 for ^2${money} points^7 and ^5${zcoins} zcoins^7. ^3Save: ${sellerSlot}`); + await Buyer.Tell(`^2Trade offer^7 received from ${seller_name}^7 for a ^3Save ${sellerSlot}^7. ^1Cost^7 : ^2${money} points^7 and ^5${zcoins} zcoins^7. `); + await new Promise(resolve => setTimeout(resolve, 100)) + await Buyer.Tell(`^3Use ^2.trade accept^7 or ^1.trade refuse^7. `); + } + async canBuyerAfford(Seller, Buyer, money, zcoins) { + + const [buyerMoney, buyerZcoins] = await Promise.all([ + this.getMoney(Buyer.ClientId), + this.getZcoins(Buyer.ClientId) + ]); + + if(buyerMoney < money){ + await Buyer.Tell(`Buyer ^1does not have enough points^7. Buyer current balance is ^2${buyerMoney}^7. Buyer need ^2${money - buyerMoney}^7 more points.`); + await Seller.Tell( `^1Trade failed^7. The ^3buyer^7 ^1does not have enough points^7.`); + return false; + } + + + if (buyerZcoins < zcoins) { + await Buyer.Tell(`Buyer ^1does not have enough zcoins^7. Buyer current balance is ^5${buyerZcoins} zcoins^7. Buyer need ^5${zcoins - buyerZcoins}^7 more zcoins.`); + await Seller.Tell(`^1Trade failed^7. The buyer ^1does not have enough zcoins^7.`); + return false; + } + + return { canAfford: true }; + } + async checkTradeStatus(Seller, Buyer) { + var [seller_trade_date, buyer_trade_date] = await Promise.all([ + this.Server.DB.metaService.getPersistentMeta('trade_date', Seller.ClientId), + this.Server.DB.metaService.getPersistentMeta('trade_date', Buyer.ClientId) + ]); + + if (!seller_trade_date) + { + this.Server.DB.metaService.addPersistentMeta('trade_date', (new Date() / 1000) - 61 , Seller.ClientId), + seller_trade_date = this.Server.DB.metaService.getPersistentMeta('trade_date', Seller.ClientId) + } + if (!buyer_trade_date) + { + this.Server.DB.metaService.getPersistentMeta('trade_date', (new Date() / 1000) - 61, Buyer.ClientId) + buyer_trade_date = this.Server.DB.metaService.getPersistentMeta('trade_date', Buyer.ClientId) + } + const buyer_trade_date_val = parseInt(buyer_trade_date.Value) + 60 + const seller_trade_date_val = parseInt(seller_trade_date.Value) + 60 + + if (seller_trade_date_val > new Date() / 1000 && buyer_trade_date_val > new Date() / 1000) + { + await Seller.Tell(`^1Trade failed^7. ^3Both you and the buyer already have a trade in progress.`); + await Buyer.Tell(`^1Trade failed^7. ^3Both you and the seller already have a trade in progress.`); + return true; + } + else if (seller_trade_date_val > new Date() / 1000) + { + await Seller.Tell(`^1Trade failed^7. ^3You already have a trade in progress.`); + return true; + } + else if (buyer_trade_date_val > new Date() / 1000) + { + await Buyer.Tell(`^1Trade request failed^7. ^3You already have a trade in progress.`); + await Seller.Tell(`^1Trade failed^7. ^3The buyer already has a trade in progress.`); + return true; + } + return false; + } + async getSaveSlot(Player, slot) { + const gameData = await this.getGame(Player.ClientId); + return parseInt(gameData.split(';')[slot - 1]); + } + async acceptTrade(Player) { + const tradeData = await this.getTradeData(Player); + + if (!tradeData) { + await Player.Tell(`There is no trade offer for you to accept.`); + return; + } + + const [sellerId, buyerId, money, zcoins, slot, slotValue] = this.parseTradeData(tradeData); /////// + const Seller = await this.Server.findClient(sellerId) + if (!Seller) + { + Player.Tell("The seller ^disconnected^7, ^3trade cancelled.") + await this.resetTradeData(sellerId, buyerId); + return; + } + const Buyer = Player; + const [canAfford, selleRSlotValue] = await Promise.all([ + this.canBuyerAfford(Seller, Buyer, money, zcoins), + this.getSaveSlot(Seller, slot) + ]); + + + if(Player.ClientId != buyerId){ + await Player.Tell(`^1You cannot accept a trade as you are not the buyer.`); + return; + } + + if (!canAfford) { + await Player.Tell(`^1Trade failed^7. You ^1don't have enough points or zcoins^7 to complete the trade.`); + await this.resetTradeData(sellerId, buyerId); + return; + } + + if (selleRSlotValue != slotValue){ + await Buyer.Tell(`^1Trade failed^7. ^3The seller ^1has changed the save slot.`); + await Seller.Tell(`^1Trade failed^7. ^3You have ^1changed the save slot.`); + await this.resetTradeData(sellerId, buyerId); + return; + } + + var seller_name = Seller.Name + var buyer_name = Buyer.Name + + var seller_custom_name = await this.Server.DB.metaService.getPersistentMeta('custom_name', Seller.ClientId) + if (seller_custom_name) + seller_name = seller_custom_name.Value + + var buyer_custom_name = await this.Server.DB.metaService.getPersistentMeta('custom_name', Buyer.ClientId) + if (buyer_custom_name) + buyer_name = buyer_custom_name.Value + + await this.performTrade({sellerId, buyerId, money, zcoins, slot}); + await Buyer.Tell(`^2Trade accepted^7. You have successfully traded ^2${money} points^7 and ^5${zcoins} zcoins^7 with ${seller_name}^7 for ^3save ${selleRSlotValue}.`); + await Seller.Tell(`^2Trade accepted^7. You have successfully traded ^3save ${selleRSlotValue}^7 with ${buyer_name}^7 for ^2${money}^7 points and ^5${zcoins} zcoins.`); + } + async refuseTrade(Player) { + const tradeData = await this.getTradeData(Player); + + if (!tradeData) { + await Player.Tell(`There is ^1no trade offer for you to refuse^7.`); + return; + } + + const [sellerId, buyerId, money, zcoins, slot, slotValue] = this.parseTradeData(tradeData); + + await this.resetTradeData(sellerId, buyerId); + + var seller_name = Player.Name + var seller_custom_name = await this.Server.DB.metaService.getPersistentMeta('custom_name', Player.ClientId) + if (seller_custom_name) + seller_name = seller_custom_name.Value + await Player.Tell(`You ^1refused^7 the ^3trade offer.`); + var Seller = await this.Server.findClient(sellerId) + if (Seller) + { + Seller.Tell(`${seller_name} ^1refused your ^3trade offer.`) + } + } + + async createTrade(Seller, Buyer, moneyAmount, zcoinsAmount, saveSlot) { + const money = parseInt(moneyAmount, 10); + const zcoins = parseInt(zcoinsAmount, 10); + + if (isNaN(money) || money < 0) { + Seller.Tell(`^1Invalid amount of points^7. ^3Please specify a valid amount.`); + return; + } + + if (isNaN(zcoins) || zcoins < 0) { + Seller.Tell(`^1Invalid amount of zcoins^7. ^3Please specify a valid amount.`); + return; + } + + const tradeStatus = await this.checkTradeStatus(Seller, Buyer); + if (tradeStatus) { + return; + } + + const canAfford = await this.canBuyerAfford(Seller, Buyer, money, zcoins); + if (!canAfford) { + return; + } + + await this.initiateTrade(Seller, Buyer, saveSlot, money, zcoins); + this.handleTradeTimeout(Seller, Buyer); + } + + async saveGame (PlayerId, slot1, slot2) { + var saveValue = `${slot1};${slot2}`; + await this.Server.DB.metaService.addPersistentMeta('save', saveValue, PlayerId); + return this.getGame(PlayerId); + } + async getGame (PlayerId) { + var savedData = await this.Server.DB.metaService.getPersistentMeta('save', PlayerId); + if (!savedData) + { + await this.Server.DB.metaService.addPersistentMeta('save', '0;0' , PlayerId); + savedData = await this.Server.DB.metaService.getPersistentMeta('save', PlayerId); + } + return savedData.Value; + } + + async getMoney (ClientId) { + var money = (await this.getZMStats(ClientId)).Money + /* if (money == undefined) + { + Player.Tell("Error, zm_stats_getmoney") + return false + }*/ + return money + } + async addMoney (ClientId, Money) { + var newMoney = parseInt(await this.getMoney(ClientId)) + parseInt(Money); + await this.Server.DB.Models.NSMZombiesStats.update({ + Money : newMoney.toString() }, { + where: {ClientId: ClientId} + }); + + return newMoney + } + async subtractMoney (ClientId, Money) { + var currentMoney = await this.getMoney(ClientId); + + if (currentMoney < parseInt(Money)) { + return -1; + } + + var newMoney = parseInt(await this.getMoney(ClientId)) - parseInt(Money); + await this.Server.DB.Models.NSMZombiesStats.update({ + Money : newMoney.toString() }, { + where: {ClientId: ClientId} + }); + + return newMoney; + } + async getZcoins(PlayerId) { + var zcoins = await this.Server.DB.metaService.getPersistentMeta('zcoins', PlayerId); + if (!zcoins) + { + await this.Server.DB.metaService.addPersistentMeta('zcoins', "0", PlayerId) + zcoins = await this.Server.DB.metaService.getPersistentMeta('zcoins', PlayerId) + } + return zcoins ? parseInt(zcoins.Value) : 0; + } + + async addZcoins(PlayerId, Amount) { + var currentZcoins = await this.getZcoins(PlayerId); + var newZcoins = parseInt(currentZcoins) + parseInt(Amount); + await this.Server.DB.metaService.addPersistentMeta('zcoins', newZcoins, PlayerId); + return newZcoins; + } + async removeZcoins(PlayerId, Amount) { + var currentZcoins = await this.getZcoins(PlayerId); + + if (currentZcoins < parseInt(Amount)) { + return -1; + } + + var newZcoins = parseInt(currentZcoins) - parseInt(Amount); + + await this.Server.DB.metaService.addPersistentMeta('zcoins', newZcoins, PlayerId); + + return newZcoins; + } + //trade + + + + + + +// COMMANDS + + async init () { + await this.createTable() + + + + + + + + + this.Manager.commands['guild'] = + { + inGame: false, + ArgumentLength: 0, + Alias: 'gd', + logToAudit: false, + Permission: Permissions.Commands.COMMAND_USER_CMDS, + callback: async (Player, args) => + { + if (this.Server.tmp) + console.log(this.Server.tmp) + for (const manager of this.Managers) + { + if (manager.Server.tmp && manager.Server.tmp == 1) + { + Player.Tell("This command is ^1already in use^7, try again in ^5a few seconds^7") + return + } + } + for (const manager of this.Managers) + { + if (manager && manager.Server) + manager.Server.tmp = 1; + } + + if (args[1] && args[1] == "edit" && this.is_staff(Player)) + { + if (!args[2]) + { + Player.Tell("^3Guild name^7 ^1missing^7.") + return + } + this.guild_list.forEach(guild => + { + this.guild_staff(guild, args, Player) + }) + for (const manager of this.Managers) + { + if (manager && manager.Server) + manager.Server.tmp = 0; + } + return + } + + var guild_data = await this.Server.DB.metaService.getPersistentMeta('guild_data', Player.ClientId) + if (!guild_data) + { + Player.Tell("^1Not in a guild^7 ! Join a ^6Guild^7 or purchase a ^3Guild Core^7 on ^6Discord^7 !") + for (const manager of this.Managers) + { + if (manager && manager.Server) + manager.Server.tmp = 0; + } + return + } + + var guild_str = guild_data.Value.split(";") + var guild = [] + + guild.name = guild_str[0] + guild.guild_master = guild_str[1] + guild.guild_members = guild_str[2] + guild.size = guild_str[3] + guild.level = guild_str[4] + guild.xp = guild_str[5] + guild.bank = guild_str[6] + guild.hp = guild_str[7] + guild.speed = guild_str[8] + guild.skills = guild_str[9] + guild.revive = guild_str[10] + + + if (args[1] && args[1] == "info") + { + Player.Tell("^6Guild^7 ^5Name : " + guild.name) + await new Promise(resolve => setTimeout(resolve, 100)) + Player.Tell("^6Guild ^3GM^7 ID : " + guild.guild_master) + await new Promise(resolve => setTimeout(resolve, 100)) + Player.Tell("^3Member ID list^7 : " + guild.guild_members) + await new Promise(resolve => setTimeout(resolve, 100)) + Player.Tell("^6Guild^7 ^3Level : " + guild.level) + await new Promise(resolve => setTimeout(resolve, 100)) + var xp_needed = 100; + if (guild.level > 8) + xp_needed = 200; + else if (guild.level > 7) + xp_needed = 150; + else if (guild.level > 5) + xp_needed = 120; + else if (guild.level >= 10) + xp_needed = "Max Lv" + Player.Tell("^6Guild^7 ^5XP : " + guild.xp + "/^1" + xp_needed + "^7 XP") + await new Promise(resolve => setTimeout(resolve, 100)) + Player.Tell("^6Guild^7 ^3Size : " + guild.size + " Slots") + await new Promise(resolve => setTimeout(resolve, 100)) + for (const manager of this.Managers) + { + if (manager && manager.Server) + manager.Server.tmp = 0; + } + return + } + else if (args[1] && args[1] == "list") + { + var i = 0 + for (const guild_name_id of this.guild_list) + { + var guild = await this.init_guild_data(parseInt(guild_name_id.split(";")[1])) + var guild_size = guild.guild_members.split('-').length + var gm = await this.Server.getClient("@" + guild_name_id.split(";")[1]) + var gm_name = gm.Name + var customName = await this.Server.DB.metaService.getPersistentMeta('custom_name', gm.ClientId) + if (customName) + gm_name = customName.Value + Player.Tell(guild.name + " : ^3Led by^7 " + gm_name + "^7 - ^3Level " + guild.level + " - ^5" + guild_size + "/" + guild.size + " Members^7") + if ( i != 0 && i % 6 == 0) + await new Promise(resolve => setTimeout(resolve, 3000)) + await new Promise(resolve => setTimeout(resolve, 100)) + i++ + } + for (const manager of this.Managers) + { + if (manager && manager.Server) + manager.Server.tmp = 0; + } + return + } + else if (args[1] && args[1] == "tree") + { + var mystery = "???" + var txt = "" + var color = "" + if (args[2] && args[2] == "2") + { + Player.Tell("--- ^6Page [2/2]^7 ---") + await new Promise(resolve => setTimeout(resolve, 100)) + txt = mystery + if (parseInt(guild.level) > 4) + txt = "+1 .rev" + if (parseInt(guild.level) >= 6) + color = "^2" + else + color = "^1" + Player.Tell("^3Lv6^7 - " + color + txt) + await new Promise(resolve => setTimeout(resolve, 100)) + txt = mystery + if (parseInt(guild.level) > 5) + txt = ".up limit increased" + if (parseInt(guild.level) >= 7) + color = "^2" + else + color = "^1" + Player.Tell("^3Lv7^7 - " + color + txt) + await new Promise(resolve => setTimeout(resolve, 100)) + txt = mystery + if (parseInt(guild.level) > 6) + txt = "+1 gamemode modifier" + if (parseInt(guild.level) >= 8) + color = "^2" + else + color = "^1" + Player.Tell("^3Lv8^7 - " + color + txt) + await new Promise(resolve => setTimeout(resolve, 100)) + txt = mystery + if (parseInt(guild.level) > 7) + txt = "+1 guild size" + if (parseInt(guild.level) >= 9) + color = "^2" + else + color = "^1" + Player.Tell("^3Lv9^7 - " + color + txt) + await new Promise(resolve => setTimeout(resolve, 100)) + txt = mystery + if (parseInt(guild.level) > 8) + txt = "Hat !" //TODO interaction with others would be best (endless botb that gives a lot of money, saves ?, cosmetics) + if (parseInt(guild.level) >= 10) + color = "^2" + else + color = "^1" + Player.Tell("^3Lv10^7 - " + color + txt) + } + else + { + Player.Tell("--- ^6Page [1/2]^7 ---") + await new Promise(resolve => setTimeout(resolve, 100)) + txt = mystery + if (parseInt(guild.level) > 0) + txt = "[Classic] +50 HP & +5% Speed" + if (parseInt(guild.level) >= 2) + color = "^2" + else + color = "^1" + Player.Tell("^3Lv2^7 - " + color + txt) + await new Promise(resolve => setTimeout(resolve, 100)) + txt = mystery + if (parseInt(guild.level) > 1) + txt = "[Raid boss] 33% skill haste" + if (parseInt(guild.level) >= 3) + color = "^2" + else + color = "^1" + Player.Tell("^3Lv3^7 - " + color + txt) + await new Promise(resolve => setTimeout(resolve, 100)) + txt = mystery + if (parseInt(guild.level) > 2) + txt = "+1 guild size" + if (parseInt(guild.level) >= 4) + color = "^2" + else + color = "^1" + Player.Tell("^3Lv4^7 - " + color + txt) + await new Promise(resolve => setTimeout(resolve, 100)) + txt = mystery + if (parseInt(guild.level) > 3) + txt = ".up limit increased" + if (parseInt(guild.level) >= 5) + color = "^2" + else + color = "^1" + Player.Tell("^3Lv5^7 - " + color + txt) + await new Promise(resolve => setTimeout(resolve, 100)) + Player.Tell("^2.guild tree 2^7 for ^3next page") + } + for (const manager of this.Managers) + { + if (manager && manager.Server) + manager.Server.tmp = 0; + } + return + } + else if (args[1] && args[1] == "quest") + { + Player.Tell("Loading ^3Quest data^7, please wait...\n") + var guild_quest = await this.Server.DB.metaService.getPersistentMeta('guild_quest', Player.ClientId) + if (!guild_quest) + { + Player.Tell("no quest data, wait for release !") + for (const manager of this.Managers) + { + if (manager && manager.Server) + manager.Server.tmp = 0; + } + return + } + var quest_array = guild_quest.Value.split(";") + var guild = await this.init_guild_data(Player.ClientId) + + var quest_count = 0; + for (const quest of quest_array) + { + if (quest == "raid_boss_quest") + { + await this.print_competitive_timed_quest(Player, quest, quest_count) + } + else if (quest.includes("ee_speedrun_quest")) + { + await this.print_competitive_timed_quest(Player, quest, quest_count) + } + + else if (quest.includes("gamemode_speedrun_quest")) + { + await this.print_competitive_timed_quest(Player, quest, quest_count) + } + /* else if (quest == "first_room_hr_quest") + { + + }*/ + + //basic quests + else if (quest == "kill_quest") + { + for(const member_id of guild.guild_members.split('-')) + { + var Player_Stats = await this.Server.DB.getPlayerPersStats(parseInt(member_id), "Kills") + var kill_quest_start = await this.Server.DB.metaService.getPersistentMeta('kill_quest_start', parseInt(member_id)) + var kill_quest = await this.Server.DB.metaService.getPersistentMeta('kill_quest', parseInt(member_id)) + if (kill_quest && kill_quest.Value == "-1") + break; + if (!kill_quest_start || !Player_Stats[0].Kills) + { + // Player.Tell("Err, no quest data, contact staff") + continue; + } + await this.Server.DB.metaService.addPersistentMeta('kill_quest', parseInt(Player_Stats[0].Kills) - parseInt(kill_quest_start.Value), parseInt(member_id)) + } + await this.print_basic_score_quest(Player, "kill_quest", quest_count, quest_array) + } + else if (quest == "headshot_quest") + { + for(const member_id of guild.guild_members.split('-')) + { + var Player_Stats = await this.Server.DB.getPlayerPersStats(parseInt(member_id), "Headshots") + var headshot_quest_start = await this.Server.DB.metaService.getPersistentMeta('headshot_quest_start', parseInt(member_id)) + var headshot_quest = await this.Server.DB.metaService.getPersistentMeta('headshot_quest', parseInt(member_id)) + if (headshot_quest && headshot_quest.Value == "-1") + break; + if (!headshot_quest_start || !Player_Stats[0].Headshots) + { + // Player.Tell("Err, no quest data, contact staff") + continue; + } + await this.Server.DB.metaService.addPersistentMeta('headshot_quest', parseInt(Player_Stats[0].Headshots) - parseInt(headshot_quest_start.Value), parseInt(member_id)) + } + await this.print_basic_score_quest(Player, "headshot_quest", quest_count, quest_array) + } + else if (quest == "gamemode_completion_quest") + { + for(const member_id of guild.guild_members.split('-')) + { + var gamemode_count_start = await this.Server.DB.metaService.getPersistentMeta('gamemode_completion_quest_start', parseInt(member_id)) + var gamemode_count = await this.Server.DB.metaService.getPersistentMeta('gamemodeCountTotal', parseInt(member_id)) + var gamemode_quest = await this.Server.DB.metaService.getPersistentMeta('gamemode_completion_quest', parseInt(member_id)) + if (gamemode_quest && gamemode_quest.Value == "-1") + break; + if (!gamemode_count_start || !gamemode_count) + { + // Player.Tell("Err, no quest data, contact staff") + continue; + } + await this.Server.DB.metaService.addPersistentMeta('gamemode_completion_quest', parseInt(gamemode_count.Value) - parseInt(gamemode_count_start.Value), parseInt(member_id)) + } + await this.print_basic_score_quest(Player, "gamemode_completion_quest", quest_count, quest_array) + } + else if (quest == "ee_completion_quest") + { + for(const member_id of guild.guild_members.split('-')) + { + var ee_count_start = await this.Server.DB.metaService.getPersistentMeta('ee_completion_quest_start', parseInt(member_id)) + var ee_count = await this.Server.DB.metaService.getPersistentMeta('eeCountTotal', parseInt(member_id)) + var ee_quest = await this.Server.DB.metaService.getPersistentMeta('ee_completion_quest', parseInt(member_id)) + if (ee_quest && ee_quest.Value == "-1") + break; + if (!ee_count_start || !ee_count) + { + // Player.Tell("Err, no quest data, contact staff") + continue; + } + await this.Server.DB.metaService.addPersistentMeta('ee_completion_quest', parseInt(ee_count.Value) - parseInt(ee_count_start.Value), parseInt(member_id)) + } + + await this.print_basic_score_quest(Player, "ee_completion_quest", quest_count, quest_array) + } + quest_count++; + } + for (const manager of this.Managers) + { + if (manager && manager.Server) + manager.Server.tmp = 0; + } + return + } + else if (args[1] && args[1] == "add") + { + var is_gm = 0 + this.guild_list.forEach(guild_name_id => + { + if (parseInt(guild_name_id.split(";")[1]) == Player.ClientId) + is_gm = 1 + }) + if (is_gm == 0) + { + Player.Tell("You are ^1not^7 a ^5Guild Master") + for (const manager of this.Managers) + { + if (manager && manager.Server) + manager.Server.tmp = 0; + } + return + } + if (!args[2]) + { + Player.Tell("no ID parameter") + for (const manager of this.Managers) + { + if (manager && manager.Server) + manager.Server.tmp = 0; + } + return + } + var client = await this.Server.getClient(args[2]) + if (!client || !(args[2].includes("@"))) + { + Player.Tell("Invalid player ID.") + for (const manager of this.Managers) + { + if (manager && manager.Server) + manager.Server.tmp = 0; + } + return + } + var current_members = 0 + + if (guild.guild_members.split('-').length) + { + var current_members = guild.guild_members.split('-').length + } + if (parseInt(guild.size) > parseInt(current_members)) + { + var members_array = guild.guild_members.split('-') + var err = 0; + members_array.forEach(member => + { + if (member == args[2].replace('@', '')) + { + Player.Tell(args[2].replace('@', '') + " is ^3already^7 in your ^6guild !") + err = 1; + } + }) + if (err && err == 1) + { + for (const manager of this.Managers) + { + if (manager && manager.Server) + manager.Server.tmp = 0; + } + return + } + + var player_guild = await this.Server.DB.metaService.getPersistentMeta('guild_data', parseInt(args[2].replace('@', ''))) + if (player_guild && player_guild.Value.split(";")[0] != guild.name) + { + Player.Tell("Player ^3" + args[2].replace('@', '') + "^7 belongs to " + player_guild.Value.split(";")[0]) + for (const manager of this.Managers) + { + if (manager && manager.Server) + manager.Server.tmp = 0; + } + return + } + + if (guild.guild_members == "0" || guild.guild_members == "-" || guild.guild_members == "") + guild.guild_members = args[4].replace('@', '') //add guild member + else + guild.guild_members += "-" + args[2].replace('@', '') //add guild member + + Player.Tell(args[2].replace('@', '') + " added to " + guild.name) + } + else + { + Player.Tell("Your ^6Guild^7 is ^1full^7 !") + for (const manager of this.Managers) + { + if (manager && manager.Server) + manager.Server.tmp = 0; + } + return + } + } + else if (args[1] && args[1] == "remove") + { + var is_gm = 0 + this.guild_list.forEach(guild_name_id => + { + if (parseInt(guild_name_id.split(";")[1]) == Player.ClientId) + is_gm = 1 + }) + if (is_gm == 0) + { + Player.Tell("You are ^1not^7 a ^5Guild Master") + for (const manager of this.Managers) + { + if (manager && manager.Server) + manager.Server.tmp = 0; + } + return + } + var is_found = 0 + var members_array = guild.guild_members.split('-') + if (Player.ClientId == parseInt(args[2].replace('@', ''))) + { + Player.Tell("^1Cannot^7 remove yourself from your own ^6Guild^7") + for (const manager of this.Managers) + { + if (manager && manager.Server) + manager.Server.tmp = 0; + } + return + } + + var client = await this.Server.getClient(args[2]) + if (!client || !(args[2].includes("@"))) + { + Player.Tell("Invalid player ID.") + for (const manager of this.Managers) + { + if (manager && manager.Server) + manager.Server.tmp = 0; + } + return + } + var target_player_id = ""; + members_array.forEach(member => + { + if (member == args[2].replace('@', '')) + { + target_player_id = member + is_found = 1 + } + }) + if (is_found == 0) + { + Player.Tell("This player is ^1not^7 in " + guild.name) + for (const manager of this.Managers) + { + if (manager && manager.Server) + manager.Server.tmp = 0; + } + return + } + + var player_guild = await this.Server.DB.metaService.getPersistentMeta('guild_data', parseInt(target_player_id)) + if (player_guild && player_guild.Value.split(";")[0] != guild.name) + { + Player.Tell("Player ^3" + target_player_id + "^7 belongs to " + player_guild.Value.split(";")[0]) + for (const manager of this.Managers) + { + if (manager && manager.Server) + manager.Server.tmp = 0; + } + return + } + guild.guild_members = guild.guild_members.replace("\-".toString() + target_player_id , "") + Player.Tell(args[2].replace('@', '') + " removed from " + guild.name) + await this.Server.DB.metaService.deletePersistentMeta('guild_data', parseInt(target_player_id)) + + } + else + { + Player.Tell("^5Member^7 Usage : .guild [^2info^7 | ^5quest^7 | ^6tree^7 | ^8list^7] & ^1.glock^7") + await new Promise(resolve => setTimeout(resolve, 100)) + Player.Tell("^3Guild Master^7 Usage : .guild [^2add^7 | ^1remove^7]") + for (const manager of this.Managers) + { + if (manager && manager.Server) + manager.Server.tmp = 0; + } + return + } + guild.guild_members.split("-").forEach(member_id => //update guild list + { + this.set_player_guild_stat(guild, member_id) + }) + for (const manager of this.Managers) + { + if (manager && manager.Server) + manager.Server.tmp = 0; + } + } + } + + this.Manager.commands['lobbyid'] = { + ArgumentLength: 0, + Alias : 'lid', + Permission: Permissions.Commands.COMMAND_USER_CMDS, + inGame: true, + callback: async (Player, args) => + { + for (const client of await this.Manager.Server.getClients()) + { + var customName = await this.Server.DB.metaService.getPersistentMeta('custom_name', client.ClientId) + var name = client.Name + if (customName) + name = customName.Value + Player.Tell("^5" + name + "^7 id : ^3@" + client.ClientId) + } + } + } + + + this.Manager.commands['trade'] = { + ArgumentLength: 0, + Permission: Permissions.Commands.COMMAND_USER_CMDS, + inGame: true, + callback: async (Player, args) => { + + if(!args[1]) { + Player.Tell(`Usage : ^3.trade ^3ID^7 ^3points^7 ^5zcoins^7 ^3save_slot^7 `); + return; + } + + if(args[1] == Player.ClientId || args[1] == `@${Player.ClientId}`) { + Player.Tell(`^1You cannot trade with yourself^7.`); + return; + } + if(args[1] == "accept") + { + await this.acceptTrade(Player) + } + else if(args[1] == "refuse") + { + await this.refuseTrade(Player) + } + else + { + if (!args[4]) + { + Player.Tell(`^1Invalid parameters^7. Usage : ^3.trade ^3ID^7 ^3points^7 ^5zcoins^7 ^3save_slot^7 ^`); + return + } + if (args[4] != "1" && args[4] != "2") + { + Player.Tell("^1Save slot incorrect^7 Use 1 or 2") + return + } + var Buyer = await this.Server.findClient(args[1].replace('@', '')) + + if (!Buyer) { + Player.Tell(`^3The buyer with the ID ${args[1]} is ^1not online^7.`); + return; + } + await this.createTrade(Player, Buyer, parseInt(args[2]), parseInt(args[3]), parseInt(args[4])); + } + } + } + + this.Manager.commands['withdraw'] = { + ArgumentLength: 1, + Alias: 'w', + logToAudit: false, + Permission: Permissions.Commands.COMMAND_USER_CMDS, + callback: async (Player, args) => { + /* if (!this.Server.isZM()) { + Player.Tell(Localization['COMMAND_UNAVAILABLE_GAMETYPE']) + return + }*/ + + if (Player.Data && Player.Data.lastWithdraw && (new Date() - Player.Data.lastWithdraw) / 1000 < 5) { + Player.Tell(Localization['COMMAND_COOLDOWN']) + return + } + + var totalMoney = (await this.getZMStats(Player.ClientId)).Money + if (totalMoney == undefined) + { + Player.Tell("Error, zm_stats") + return + } + var gameMoney = parseInt(await Player.Server.Rcon.getDvar(`${Player.Clientslot}_money`)) + const canUseBank = await Player.Server.Rcon.getDvar(`${Player.Clientslot}_can_use_bank`) + if (canUseBank == "2") + { + Player.Tell("Bank disabled for Tournament server"); + return + } + if (canUseBank == "3") { + Player.Tell("Cannot withdraw in this gamemode."); + return + } + // if (canUseBank == "0") { + // Player.Tell(Localization['ZBANK_DISABLED']); + // return + // } + + var withdrawMoney = args[1].toLocaleLowerCase() == 'all' + ? Math.min(parseInt(totalMoney), maxGameMoney - gameMoney) + : Math.min(parseInt(args[1]), maxGameMoney - gameMoney) + + switch (true) { + case (!Number.isInteger(withdrawMoney) || withdrawMoney < 0): + Player.Tell(Localization['ZBANK_PARSE_ERROR']) + return + case (totalMoney < withdrawMoney): + Player.Tell(Localization['ZBANK_BALANCE_ERROR']); + return + } + var result = await Player.Server.Rcon.executeCommandAsync(`set bank_withdraw ${Player.Guid};${withdrawMoney}`) + if (result) { + Player.Tell(Utils.formatString(Localization['ZBANK_WITHDRAW_SUCCESS'], { + amount: withdrawMoney.toLocaleString() + }, '%')[0]) + + Player.Data.lastWithdraw = new Date() + this.setPlayerMoney(Player.ClientId, parseInt(totalMoney) - parseInt(withdrawMoney)) + + return + } + + Player.Tell(Localization['ZBANK_WITHDRAW_FAIL']) + } + } + + this.Manager.commands['rankup'] = { + ArgumentLength: 0, + Alias: 'rkup', + logToAudit: false, + Permission: Permissions.Commands.COMMAND_USER_CMDS, + callback: async (Player, args) => { + /* if (!this.Server.isZM()) { + Player.Tell(Localization['COMMAND_UNAVAILABLE_GAMETYPE']) + return + }*/ + if (Player.Data && Player.Data.lastWithdraw && (new Date() - Player.Data.lastWithdraw) / 1000 < 5) { + Player.Tell(Localization['COMMAND_COOLDOWN']) + return + } + var totalMoney = (await this.getZMStats(Player.ClientId)).Money + if (totalMoney == undefined) + { + Player.Tell("Error, zm_stats") + return + } + + var customTag = await this.Server.DB.metaService.getPersistentMeta('custom_tag', Player.ClientId) + var zcoins = await this.Server.DB.metaService.getPersistentMeta('zcoins', Player.ClientId) + if (!zcoins || zcoins.value == "") + { + await this.Server.DB.metaService.addPersistentMeta('zcoins', "0", Player.ClientId) + zcoins = await this.Server.DB.metaService.getPersistentMeta('zcoins', Player.ClientId) + } + if (!customTag) + { + Player.Tell("Error") + return; + } + + var withdrawMoney = 100000000; + var zcoinsCost = 0; + var gamemodeClearNeeded = 0; + var chadGamemodeClearNeeded = 0; + var eeClearNeeded = 0; + var saveRoundNeeded = 0; + var titb_completion = 0; + var pia_completion = 0; + var botb_completion = 0; + var gc_completion = 0; + var first_room = 0; + var oneshot = 0; + var speedrun = 0; + var spoon = 0; + var hawk = 0; + var hitless = 0; + var melee = 0; + + if (customTag.Value == '^9F^7') + withdrawMoney = 100000 + if (customTag.Value == '^8E^7') + withdrawMoney = 200000 + if (customTag.Value == '^2D^7') + withdrawMoney = 400000 + if (customTag.Value == '^4C^7') + withdrawMoney = 1000000 + if (customTag.Value == '^5B^7') + withdrawMoney = 2000000 + if (customTag.Value == '^6A^7') + withdrawMoney = 5000000 + if (customTag.Value == '^3S^7') + withdrawMoney = 10000000 + if (customTag.Value == '^3SS^7') + withdrawMoney = 30000000 + if (customTag.Value == '^3SSS^7') + { + gamemodeClearNeeded = 1; + eeClearNeeded = 2; + saveRoundNeeded = 35; + zcoinsCost = 200; + withdrawMoney = 60000000 + } + if (customTag.Value == '^6 I ^7') + { + gamemodeClearNeeded = 2; + eeClearNeeded = 3 + saveRoundNeeded = 40; + zcoinsCost = 300; + withdrawMoney = 70000000 + } + if (customTag.Value == '^6II^7') + { + gamemodeClearNeeded = 5; + eeClearNeeded = 4; + saveRoundNeeded = 45; + zcoinsCost = 600; + withdrawMoney = 80000000 + } + if (customTag.Value == '^6III^7') + { + chadGamemodeClearNeeded = 2; + gamemodeClearNeeded = 5; + eeClearNeeded = 5; + saveRoundNeeded = 50; + zcoinsCost = 600; + withdrawMoney = 90000000 + } + if (customTag.Value == '^5IV^7') + { + chadGamemodeClearNeeded = 4; + gamemodeClearNeeded = 5; + eeClearNeeded = 6; + saveRoundNeeded = 55; + zcoinsCost = 650; + withdrawMoney = 100000000 + } + if (customTag.Value == '^5V^7') + { + chadGamemodeClearNeeded = 6; + gamemodeClearNeeded = 5; + eeClearNeeded = 8; + saveRoundNeeded = 60; + zcoinsCost = 700; + withdrawMoney = 110000000 + } + if (customTag.Value == '^5VI^7') + { + chadGamemodeClearNeeded = 10; + gamemodeClearNeeded = 7; + eeClearNeeded = 10; + saveRoundNeeded = 65; + zcoinsCost = 800; + withdrawMoney = 150000000 + } + if (customTag.Value == '^5VII^7') + { + gc_completion = 3; + botb_completion = 1; + spoon = 1; + first_room = 1; + melee = 1; + saveRoundNeeded = 70; + zcoinsCost = 2000; + withdrawMoney = 300000000 + } + if (customTag.Value == '^1IIX^7') + { + botb_completion = 3; + pia_completion = 3; + // titb_completion = 2; + hawk = 1; + oneshot = 1; + saveRoundNeeded = 80; + zcoinsCost = 3000; + withdrawMoney = 500000000 + } + if (customTag.Value == '^1IX^7') + { + botb_completion = 5; + pia_completion = 5; + // titb_completion = 3; + hitless = 1; + speedrun = 1; + saveRoundNeeded = 100; + zcoinsCost = 5000; + withdrawMoney = 1000000000 + } + if (customTag.Value == '^1-X-^7') + { + + Player.Tell('You are already ^3max rank, what a ^5gamer^7 !'); + return; + } + +//--------------------------------------- + var isRequirementFullfilled = true; + + if (hitless != 0) + { + var botb_hitless = await this.Server.DB.metaService.getPersistentMeta('botb_hitless', Player.ClientId) + if (!botb_hitless) + { + await this.Server.DB.metaService.addPersistentMeta('botb_hitless', "0", Player.ClientId) + botb_hitless = await this.Server.DB.metaService.getPersistentMeta('botb_hitless', Player.ClientId) + } + if (botb_hitless.Value != "1") + { + Player.Tell("^3Must complete BotB without ^5getting hit^3.") + isRequirementFullfilled = false; + } + } + if (speedrun != 0) + { + var ee_speedrun = await this.Server.DB.metaService.getPersistentMeta('ee_speedrun', Player.ClientId) + if (!ee_speedrun) + { + await this.Server.DB.metaService.addPersistentMeta('ee_speedrun', "0", Player.ClientId) + ee_speedrun = await this.Server.DB.metaService.getPersistentMeta('ee_speedrun', Player.ClientId) + } + if (ee_speedrun.Value != "1") + { + Player.Tell("^3Must complete Origin EE in ^5under 30 mins^3.") + isRequirementFullfilled = false; + } + } + if (oneshot != 0) + { + var oneshot_50 = await this.Server.DB.metaService.getPersistentMeta('oneshot_50', Player.ClientId) + if (!oneshot_50) + { + await this.Server.DB.metaService.addPersistentMeta('oneshot_50', "0", Player.ClientId) + oneshot_50 = await this.Server.DB.metaService.getPersistentMeta('oneshot_50', Player.ClientId) + } + if (oneshot_50.Value != "1") + { + Player.Tell("^3Must reach ^5round 50^7 in a non-loaded lobby.") + isRequirementFullfilled = false; + } + } + if (spoon != 0) + { + var golden_spork = await this.Server.DB.metaService.getPersistentMeta('golden_spork', Player.ClientId) + if (!golden_spork) + { + await this.Server.DB.metaService.addPersistentMeta('golden_spork', "0", Player.ClientId) + golden_spork = await this.Server.DB.metaService.getPersistentMeta('golden_spork', Player.ClientId) + } + if (golden_spork.Value != "1") + { + Player.Tell("^3Must obtain the ^5Golden spoon^3 in MotD.") + isRequirementFullfilled = false; + } + } + if (hawk != 0) + { + var upgraded_tomahawk = await this.Server.DB.metaService.getPersistentMeta('upgraded_tomahawk', Player.ClientId) + if (!upgraded_tomahawk) + { + await this.Server.DB.metaService.addPersistentMeta('upgraded_tomahawk', "0", Player.ClientId) + upgraded_tomahawk = await this.Server.DB.metaService.getPersistentMeta('upgraded_tomahawk', Player.ClientId) + } + if (upgraded_tomahawk.Value != "1") + { + Player.Tell("^3Must obtain the ^5Blue Tomahawk^3 in MotD.") + isRequirementFullfilled = false; + } + } + if (melee != 0) + { + var melee_only = await this.Server.DB.metaService.getPersistentMeta('melee_only', Player.ClientId) + if (!melee_only) + { + await this.Server.DB.metaService.addPersistentMeta('melee_only', "0", Player.ClientId) + melee_only = await this.Server.DB.metaService.getPersistentMeta('melee_only', Player.ClientId) + } + if (melee_only.Value != "1") + { + Player.Tell("^3Must complete a full round with ^5melee only^3 over ^5Round 30^3.") + isRequirementFullfilled = false; + } + } + if (first_room != 0) + { + var first_room_30 = await this.Server.DB.metaService.getPersistentMeta('first_room_30', Player.ClientId) + if (!first_room_30) + { + await this.Server.DB.metaService.addPersistentMeta('first_room_30', "0", Player.ClientId) + first_room_30 = await this.Server.DB.metaService.getPersistentMeta('first_room_30', Player.ClientId) + } + if (first_room_30.Value != "1") + { + Player.Tell("^3Must reach ^5Round 30^3 in ^5first room^3. (.fr)") + isRequirementFullfilled = false; + } + } + if (gc_completion != 0) + { + var gigachadGamemodeCount = await this.Server.DB.metaService.getPersistentMeta('gigachadGamemodeCount', Player.ClientId) + if (!gigachadGamemodeCount) + { + await this.Server.DB.metaService.addPersistentMeta('gigachadGamemodeCount', "0", Player.ClientId) + gigachadGamemodeCount = await this.Server.DB.metaService.getPersistentMeta('gigachadGamemodeCount', Player.ClientId) + } + if (parseInt(gigachadGamemodeCount.Value) < gc_completion) + { + Player.Tell("^3Not enough ^6Gigachad completion^3.") + isRequirementFullfilled = false; + } + } + if (botb_completion != 0) + { + var botb_gc = await this.Server.DB.metaService.getPersistentMeta('botb_gc', Player.ClientId) + if (!botb_gc) + { + await this.Server.DB.metaService.addPersistentMeta('botb_gc', "0", Player.ClientId) + botb_gc = await this.Server.DB.metaService.getPersistentMeta('botb_gc', Player.ClientId) + } + if (parseInt(botb_gc.Value) < botb_completion) + { + Player.Tell("^3Not enough ^6BotB Gigachad^3 completion.") + isRequirementFullfilled = false; + } + } + if (titb_completion != 0) + { + var titb_gc = await this.Server.DB.metaService.getPersistentMeta('titb_gc', Player.ClientId) + if (!titb_gc) + { + await this.Server.DB.metaService.addPersistentMeta('titb_gc', "0", Player.ClientId) + titb_gc = await this.Server.DB.metaService.getPersistentMeta('titb_gc', Player.ClientId) + } + if (parseInt(titb_gc.Value) < titb_completion) + { + Player.Tell("^3Not enough ^6TitB Gigachad^3 completion.") + isRequirementFullfilled = false; + } + } + if (pia_completion != 0) + { + var pia_gc = await this.Server.DB.metaService.getPersistentMeta('pia_gc', Player.ClientId) + if (!pia_gc) + { + await this.Server.DB.metaService.addPersistentMeta('pia_gc', "0", Player.ClientId) + pia_gc = await this.Server.DB.metaService.getPersistentMeta('pia_gc', Player.ClientId) + } + if (parseInt(pia_gc.Value) < pia_completion) + { + Player.Tell("^3Not enough ^6PiA Gigachad^3 completion.") + isRequirementFullfilled = false; + } + } + + if (gamemodeClearNeeded != 0) + { + var gamemodeCount = await this.Server.DB.metaService.getPersistentMeta('gamemodeCount', Player.ClientId) + if (!gamemodeCount) + { + await this.Server.DB.metaService.addPersistentMeta('gamemodeCount', "0", Player.ClientId) + gamemodeCount = await this.Server.DB.metaService.getPersistentMeta('gamemodeCount', Player.ClientId) + } + var gamemodeCountInt = parseInt(gamemodeCount.Value); + if(gamemodeCountInt < gamemodeClearNeeded) + { + Player.Tell(`^3Not enough ^2 Ez Gamemode^3 completions to ^6rank up^3 (^2${gamemodeCountInt}^3/^1${gamemodeClearNeeded}^3)`) + isRequirementFullfilled = false; + } + } + if (chadGamemodeClearNeeded != 0) + { + var chadGamemodeCount = await this.Server.DB.metaService.getPersistentMeta('chadGamemodeCount', Player.ClientId) + if (!chadGamemodeCount) + { + await this.Server.DB.metaService.addPersistentMeta('chadGamemodeCount', "0", Player.ClientId) + chadGamemodeCount = await this.Server.DB.metaService.getPersistentMeta('chadGamemodeCount', Player.ClientId) + } + var chadGamemodeCountInt = parseInt(chadGamemodeCount.Value); + if(chadGamemodeCountInt < chadGamemodeClearNeeded) + { + Player.Tell(`^3Not enough ^1 Chad Gamemode^3 completions to ^6rank up^3 (^2${chadGamemodeCountInt}^3/^1${chadGamemodeClearNeeded}^3)`) + isRequirementFullfilled = false; + } + } + if (eeClearNeeded != 0) + { + var eeCount = await this.Server.DB.metaService.getPersistentMeta('eeCount', Player.ClientId) + if (!eeCount) + { + await this.Server.DB.metaService.addPersistentMeta('eeCount', "0", Player.ClientId) + eeCount = await this.Server.DB.metaService.getPersistentMeta('eeCount', Player.ClientId) + } + var eeCountInt = parseInt(eeCount.Value) + if(eeCountInt < eeClearNeeded) + { + Player.Tell(`^3Not enough ^5EE completions^3 to ^6rank up^3 (^2${eeCountInt}^3/^1${eeClearNeeded}^3)`) + isRequirementFullfilled = false; + } + } + var save1 = 0 + var save2 = 0 + if (saveRoundNeeded != 0) + { + var save = await this.Server.DB.metaService.getPersistentMeta('save', Player.ClientId) + if (!save) + { + Player.Tell("Save error, contact staff") + return; + } + save1 = parseInt(save.Value.split(';')[0]) + save2 = parseInt(save.Value.split(';')[1]) + var highestSave = 0 + if (save1 >= save2) + highestSave = save1 + else + highestSave = save2 + if (highestSave < saveRoundNeeded) + { + Player.Tell(`^3Your ^5highest save^3 is too low to ^6rank up^3 (^2${highestSave}^3/^1${saveRoundNeeded}^3)`) + isRequirementFullfilled = false; + } + } + if (totalMoney < withdrawMoney) + { + Player.Tell(`^3Not enough ^2Money^3 in your bank to ^6rank up^3 (^2${totalMoney}^3/^1${withdrawMoney}^3)`) + isRequirementFullfilled = false + } + if (parseInt(zcoins.Value) < zcoinsCost) + { + Player.Tell(`^3Not enough ^5Z-Coins^3 in your bank to ^6rank up^3 (^2${zcoins.Value}^3/^1${zcoinsCost}^3)`) + isRequirementFullfilled = false + } + if (isRequirementFullfilled == false) + { + return; + } + + await this.Server.DB.metaService.addPersistentMeta('eeCount', "0", Player.ClientId) + await this.Server.DB.metaService.addPersistentMeta('gamemodeCount', "0", Player.ClientId) + await this.Server.DB.metaService.addPersistentMeta('chadGamemodeCount', "0", Player.ClientId) + await this.Server.DB.metaService.addPersistentMeta('gigachadGamemodeCount', "0", Player.ClientId) + await this.Server.DB.metaService.addPersistentMeta('pia_gc', "0", Player.ClientId) + await this.Server.DB.metaService.addPersistentMeta('titb_gc', "0", Player.ClientId) + await this.Server.DB.metaService.addPersistentMeta('botb_gc', "0", Player.ClientId) + await this.Server.DB.metaService.addPersistentMeta('golden_spork', "0", Player.ClientId) + await this.Server.DB.metaService.addPersistentMeta('first_room_30', "0", Player.ClientId) + await this.Server.DB.metaService.addPersistentMeta('upgraded_tomahawk', "0", Player.ClientId) + await this.Server.DB.metaService.addPersistentMeta('melee_only', "0", Player.ClientId) + + if (saveRoundNeeded != 0) + { + var slot = 0 + if (save1 < saveRoundNeeded && save2 >= saveRoundNeeded) + { + await this.Server.DB.metaService.addPersistentMeta('save', `${save1};0`, Player.ClientId) + slot = 2 + } + else if (save2 < saveRoundNeeded && save1 >= saveRoundNeeded) + { + await this.Server.DB.metaService.addPersistentMeta('save', `0;${save2}`, Player.ClientId) + slot = 1 + } + else if (save1 > save2) + { + await this.Server.DB.metaService.addPersistentMeta('save', `${save1};0`, Player.ClientId) + slot = 2 + } + else + { + await this.Server.DB.metaService.addPersistentMeta('save', `0;${save2}`, Player.ClientId) + slot = 1 + } + + + Player.Tell("^5Lowest required save^3 consumed.") + } + + + Player.Tell(Utils.formatString(Localization['ZBANK_WITHDRAW_SUCCESS'], { + amount: withdrawMoney.toLocaleString() + }, '%')[0]) + + Player.Data.lastWithdraw = new Date() + this.setPlayerMoney(Player.ClientId, parseInt(totalMoney) - parseInt(withdrawMoney)) + + await this.Server.DB.metaService.addPersistentMeta('zcoins', parseInt(zcoins.Value) - zcoinsCost, Player.ClientId) + if (zcoinsCost != 0) + { + Player.Tell(`^5${zcoinsCost} Z-Coins^3 have been withdrew from your bank account!`) + } + + await this.Server.DB.metaService.deletePersistentMeta('custom_tag', Player.ClientId) + if (customTag.Value == '^9F^7') + { + await this.Server.DB.metaService.addPersistentMeta('custom_tag', "^8E^7", Player.ClientId) + Player.Tell('Your ^3point multiplier^7 is now : ^3x3') + Player.Tell('Successfully ^3ranked up^7 to : ^8E Rank^7 ! ^1GG') + } + else if (customTag.Value == '^8E^7') + { + await this.Server.DB.metaService.addPersistentMeta('custom_tag', "^2D^7", Player.ClientId) + Player.Tell('Your ^3point multiplier^7 is now : ^3x3') + Player.Tell('Successfully ^3ranked up^7 to : ^2D Rank^7 ! ^1GG') + } + else if (customTag.Value == '^2D^7') + { + await this.Server.DB.metaService.addPersistentMeta('custom_tag', "^4C^7", Player.ClientId) + Player.Tell('Your ^3point multiplier^7 is now : ^3x4') + Player.Tell('Successfully ^3ranked up^7 to : ^4C Rank^7 ! ^1GG') + } + else if (customTag.Value == '^4C^7') + { + await this.Server.DB.metaService.addPersistentMeta('custom_tag', "^5B^7", Player.ClientId) + Player.Tell('Your ^3point multiplier^7 is now : ^3x4') + Player.Tell('Successfully ^3ranked up^7 to : ^5B Rank^7 ! ^1GG') + } + else if (customTag.Value == '^5B^7') + { + await this.Server.DB.metaService.addPersistentMeta('custom_tag', "^6A^7", Player.ClientId) + Player.Tell('Your ^3point multiplier^7 is now : ^3x5') + Player.Tell('Successfully ^3ranked up^7 to : ^6A Rank^7 ! ^1GG') + } + else if (customTag.Value == '^6A^7') + { + await this.Server.DB.metaService.addPersistentMeta('custom_tag', "^3S^7", Player.ClientId) + Player.Tell('Your ^3point multiplier^7 is now : ^3x6') + Player.Tell('Successfully ^3ranked up^7 to : ^3S Rank^7 ! ^1GG') + } + else if (customTag.Value == '^3S^7') + { + await this.Server.DB.metaService.addPersistentMeta('custom_tag', "^3SS^7", Player.ClientId) + Player.Tell('Your ^3point multiplier^7 is now : ^3x7') + Player.Tell('Successfully ^3ranked up^7 to : ^3SS Rank^7 ! ^1GG') + } + else if (customTag.Value == '^3SS^7') + { + await this.Server.DB.metaService.addPersistentMeta('custom_tag', "^3SSS^7", Player.ClientId) + Player.Tell('Your ^3point multiplier^7 is now : ^3x9') + Player.Tell('Successfully ^3ranked up^7 to : ^3SSS Rank^7 ! ^1GG') + } + else if (customTag.Value == '^3SSS^7') + { + await this.Server.DB.metaService.addPersistentMeta('custom_tag', "^6 I ^7", Player.ClientId) + Player.Tell('Your ^3point multiplier^7 is now : ^3x9') + Player.Tell('Successfully ^3ranked up^7 to : ^6I^7 Rank^7 ! ^1GG') + } + else if (customTag.Value == '^6 I ^7') + { + await this.Server.DB.metaService.addPersistentMeta('custom_tag', "^6II^7", Player.ClientId) + Player.Tell('Your ^3point multiplier^7 is now : ^3x10') + Player.Tell('Your ^5z-coins multiplier^7 has increased !') + Player.Tell('Successfully ^3ranked up^7 to : ^6II^7 Rank^7 ! ^1GG') + } + else if (customTag.Value == '^6II^7') + { + await this.Server.DB.metaService.addPersistentMeta('custom_tag', "^6III^7", Player.ClientId) + Player.Tell('Your ^3point multiplier^7 is now : ^3x11') + Player.Tell('Your ^5z-coins multiplier^7 has increased !') + Player.Tell('Successfully ^3ranked up^7 to : ^6III^7 Rank^7 ! ^1GG') + } + else if (customTag.Value == '^6III^7') + { + await this.Server.DB.metaService.addPersistentMeta('custom_tag', "^5IV^7", Player.ClientId) + Player.Tell('Your ^3point multiplier^7 is now : ^3x12') + Player.Tell('Your ^5z-coins multiplier^7 has increased !') + Player.Tell('Successfully ^3ranked up^7 to : ^5IV^7 Rank^7 ! ^1GG') + } + else if (customTag.Value == '^5IV^7') + { + await this.Server.DB.metaService.addPersistentMeta('custom_tag', "^5V^7", Player.ClientId) + Player.Tell('Your ^3point multiplier^7 is now : ^3x13') + Player.Tell('Your ^5z-coins multiplier^7 has increased !') + Player.Tell('Successfully ^3ranked up^7 to : ^5V^7 Rank^7 ! ^1GG') + } + else if (customTag.Value == '^5V^7') + { + await this.Server.DB.metaService.addPersistentMeta('custom_tag', "^5VI^7", Player.ClientId) + Player.Tell('Your ^3point multiplier^7 is now : ^3x13') + Player.Tell('Your ^5z-coins multiplier^7 has increased !') + Player.Tell('Successfully ^3ranked up^7 to : ^5VI^7 Rank^7 ! ^1GG') + } + else if (customTag.Value == '^5VI^7') + { + await this.Server.DB.metaService.addPersistentMeta('custom_tag', "^5VII^7", Player.ClientId) + + Player.Tell('Your ^3point multiplier^7 is now : ^3x13') + Player.Tell('Your ^5z-coins multiplier^7 has increased !') + Player.Tell('Successfully ^3ranked up^7 to : ^5VI^7 Rank^7 ! ^1GG') + } + else if (customTag.Value == '^5VII^7') + { + await this.Server.DB.metaService.addPersistentMeta('custom_tag', "^1IIX^7", Player.ClientId) + Player.Tell('Your ^3point multiplier^7 is now : ^3x14') + Player.Tell('Your ^5z-coins multiplier^7 has increased !') + Player.Tell('Successfully ^3ranked up^7 to : "^1IIX^7" Rank^7 ! ^1GG') + } + else if (customTag.Value == '^1IIX^7') + { + await this.Server.DB.metaService.addPersistentMeta('custom_tag', "^1IX^7", Player.ClientId) + Player.Tell('Your ^3point multiplier^7 is now : ^3x15') + Player.Tell('Your ^5z-coins multiplier^7 has increased !') + Player.Tell('Successfully ^3ranked up^7 to : "^1IX^7" Rank^7 ! ^1GG') + } + else if (customTag.Value == '^1IX^7') + { + await this.Server.DB.metaService.addPersistentMeta('custom_tag', "^1-X-^7", Player.ClientId) + Player.Tell('Your ^3point multiplier^7 is now : ^3x15') + Player.Tell('Your ^5z-coins multiplier^7 has increased !') + Player.Tell('Successfully ^3ranked up^7 to : "^1-X-^7" Rank^7 ! ^1GG') + } + else if (customTag.Value == '^1-X-^7') + { + Player.Tell("This shouldn't happen") + } + + this.Managers.forEach(manager => + { + if (manager) + { + this.checkForLoadedSave(manager, Player.ClientId, slot) + } + }) + + var role = Utils.getRoleFrom(Player.PermissionLevel, 1).Name + var customTag = await this.Server.DB.metaService.getPersistentMeta('custom_tag', Player.ClientId) + role = customTag ? customTag.Value : Utils.stripString(role) + this.Server.Rcon.executeCommandAsync(`setclantagraw ${Player.Clientslot} "${role}"`) + + var val = await this.Server.DB.metaService.getPersistentMeta('custom_tag', Player.ClientId) + this.Managers.forEach(manager => + { + if (manager) + { + manager.Server.Rcon.executeCommandAsync(`set bold ^1[Announcement] ^5${Player.Name}^7 Ranked up to ${customTag.Value}^7, use ^2.rank^7 `) + } + }) + + } +} + +this.Manager.commands['drop'] = { + ArgumentLength: 0, + Alias: 'dr', + logToAudit: false, + Permission: Permissions.Commands.COMMAND_USER_CMDS, + callback: async (Player, args) => { + /* if (!this.Server.isZM()) { + Player.Tell(Localization['COMMAND_UNAVAILABLE_GAMETYPE']) + return + }*/ + if (Player.Data && Player.Data.lastDrop && (new Date() - Player.Data.lastDrop) / 1000 < 10) { + Player.Tell(Localization['COMMAND_COOLDOWN']) + return + } + + Player.Data.lastDrop = new Date() + var customName = await this.Server.DB.metaService.getPersistentMeta('custom_name', Player.ClientId) + + if (customName && customName.Value != "" && (customName.Value.includes('[^2VIP') || customName.Value.includes('[^3VIP') || customName.Value.includes('^3[VIP') || customName.Value.includes('^1') + || customName.Value.includes('^6[VIP') || customName.Value.includes('[^6VIP^7'))) + { + await Player.Server.Rcon.executeCommandAsync(`set drop ${Player.Guid};1`) + } + else + { + var customTag = await this.Server.DB.metaService.getPersistentMeta('custom_tag', Player.ClientId) + if (customTag && (customTag.Value == "^9F^7" || customTag.Value == "^8E^7" || customTag.Value == "^2D^7" + || customTag.Value == "^4C^7" || customTag.Value == "^5B^7")) + { + Player.Tell("^6A+^7 rank only^7 command only.") + return + } + await Player.Server.Rcon.executeCommandAsync(`set drop ${Player.Guid};1`) + return + } + } +} + +this.Manager.commands['flex'] = { + ArgumentLength: 0, + Alias: 'flex', + logToAudit: false, + Permission: Permissions.Commands.COMMAND_USER_CMDS, + callback: async (Player, args) => { + /*if (!this.Server.isZM()) { + Player.Tell(Localization['COMMAND_UNAVAILABLE_GAMETYPE']) + return + }*/ + if (Player.Data && Player.Data.lastFlex && (new Date() - Player.Data.lastFlex) / 1000 < 10) { + Player.Tell(Localization['COMMAND_COOLDOWN']) + return + } + var save = await this.Server.DB.metaService.getPersistentMeta('save', Player.ClientId) + if (!save) + { + await this.Server.DB.metaService.addPersistentMeta('save', '0;0', Player.ClientId) + zcoins = await this.Server.DB.metaService.getPersistentMeta('save', Player.ClientId) + } + if (Player.Data) + Player.Data.lastFlex = new Date() + var health = await this.Server.DB.metaService.getPersistentMeta('hp', Player.ClientId) + var speed = await this.Server.DB.metaService.getPersistentMeta('speed', Player.ClientId) + var customName = await this.Server.DB.metaService.getPersistentMeta('custom_name', Player.ClientId) + var customTag = await this.Server.DB.metaService.getPersistentMeta('custom_tag', Player.ClientId) + var zcoins = await this.Server.DB.metaService.getPersistentMeta('zcoins', Player.ClientId) + if (!zcoins) + { + await this.Server.DB.metaService.addPersistentMeta('zcoins', '0', Player.ClientId) + zcoins = await this.Server.DB.metaService.getPersistentMeta('zcoins', Player.ClientId) + } + var totalMoney = (await this.getZMStats(Player.ClientId)).Money + if (totalMoney == undefined) + { + Player.Tell("Error, zm_stats") + return + } + var hp = 250 + + if (customName) + { + if (customName.Value.includes('[^2VIP') || customName.Value.includes('^3VIP') || customName.Value.includes('^3[VIP') + || customName.Value.includes('^6[VIP') || customName.Value.includes('[^6VIP') + || customName.Value.includes('^1[VIP') || customName.Value.includes('[^1VIP')) + hp += 50 + } + hp += parseInt(health.Value) + var percentspeed = 0 + if (speed.Value == "1") + percentspeed = 0 + else if (speed.Value == "1.01") + percentspeed = 1 + else if (speed.Value == "1.02") + percentspeed = 2 + else if (speed.Value == "1.03") + percentspeed = 3 + else if (speed.Value == "1.04") + percentspeed = 4 + else if (speed.Value == "1.05") + percentspeed = 5 + else if (speed.Value == "1.06") + percentspeed = 6 + else if (speed.Value == "1.07") + percentspeed = 7 + else if (speed.Value == "1.08") + percentspeed = 8 + else if (speed.Value == "1.09") + percentspeed = 9 + else if (speed.Value == "1.10") + percentspeed = 10 + + var customName = await this.Server.DB.metaService.getPersistentMeta('custom_name', Player.ClientId) + this.Managers.forEach(manager => + { + if (manager) + { + this.display_flex(manager, customTag, customName, totalMoney, zcoins, hp, percentspeed, save, Player) + } + + }) + } +} + + this.Manager.commands['buy'] = { + ArgumentLength: 0, + Alias: 'buy', + logToAudit: false, + Permission: Permissions.Commands.COMMAND_USER_CMDS, + callback: async (Player, args) => { + /*if (!this.Server.isZM()) { + Player.Tell(Localization['COMMAND_UNAVAILABLE_GAMETYPE']) + return + }*/ + if (Player.Data && Player.Data.lastWithdraw && (new Date() - Player.Data.lastWithdraw) / 1000 < 3) { + Player.Tell(Localization['COMMAND_COOLDOWN']) + return + } + + //-----------------------------------HP------------------------------------------------------------- + if (args[1] && args[1].toLocaleLowerCase() == 'hp') + { + /* var customName = await this.Server.DB.metaService.getPersistentMeta('custom_name', Player.ClientId) + if (customName) + { + if (customName && customName.Value != "" && customName.Value.includes('^1')) + { + } + else + { + Player.Tell('Admins only.') + return + } + }*/ + + + + var totalMoney = (await this.getZMStats(Player.ClientId)).Money + if (totalMoney == undefined) + { + Player.Tell("Error, zm_stats") + return + } + + var stats = await this.Server.DB.metaService.getPersistentMeta('hp', Player.ClientId) + var customTag = await this.Server.DB.metaService.getPersistentMeta('custom_tag', Player.ClientId) + if (!stats) + { + Player.Tell("Error#005, contact admin") + return + } + var withdrawMoney = 99999999999 + console.log("stats value is %s", stats.Value ) + if (stats.Value == "0" && (customTag.Value == "^9F^7" || customTag.Value == "^8E^7" || customTag.Value == "^2D^7" + || customTag.Value == "^4C^7" || customTag.Value == "^5B^7" || customTag.Value == "^6A^7" + || customTag.Value == "^3S^7" || customTag.Value == "^3SS^7" || customTag.Value == "^3SSS^7" + || customTag.Value == "^6 I ^7" || customTag.Value == "^6II^7" || customTag.Value == "^6III^7" + || customTag.Value == "^5IV^7" || customTag.Value == "^5V^7" || customTag.Value == "^5VI^7" || customTag.Value == "^5VII^7" + || customTag.Value == "^1IIX^7" || customTag.Value == "^1IX^7" || customTag.Value == "^1-X-^7")) + withdrawMoney = 10000 + else if (stats.Value == "10" && (customTag.Value == "^9F^7" || customTag.Value == "^8E^7" || customTag.Value == "^2D^7" + || customTag.Value == "^4C^7" || customTag.Value == "^5B^7" || customTag.Value == "^6A^7" + || customTag.Value == "^3S^7" || customTag.Value == "^3SS^7" || customTag.Value == "^3SSS^7" + || customTag.Value == "^6 I ^7" || customTag.Value == "^6II^7" || customTag.Value == "^6III^7" + || customTag.Value == "^5IV^7" || customTag.Value == "^5V^7" || customTag.Value == "^5VI^7" || customTag.Value == "^5VII^7" + || customTag.Value == "^1IIX^7" || customTag.Value == "^1IX^7" || customTag.Value == "^1-X-^7")) + withdrawMoney = 50000 + else if (stats.Value == "20" && (customTag.Value == "^8E^7" || customTag.Value == "^2D^7" + || customTag.Value == "^4C^7" || customTag.Value == "^5B^7" || customTag.Value == "^6A^7" + || customTag.Value == "^3S^7" || customTag.Value == "^3SS^7" || customTag.Value == "^3SSS^7" + || customTag.Value == "^6 I ^7" || customTag.Value == "^6II^7" || customTag.Value == "^6III^7" + || customTag.Value == "^5IV^7" || customTag.Value == "^5V^7" || customTag.Value == "^5VI^7" || customTag.Value == "^5VII^7" + || customTag.Value == "^1IIX^7" || customTag.Value == "^1IX^7" || customTag.Value == "^1-X-^7")) + withdrawMoney = 100000 + else if (stats.Value == "30" && (customTag.Value == "^2D^7" + || customTag.Value == "^4C^7" || customTag.Value == "^5B^7" || customTag.Value == "^6A^7" + || customTag.Value == "^3S^7" || customTag.Value == "^3SS^7" || customTag.Value == "^3SSS^7" + || customTag.Value == "^6 I ^7" || customTag.Value == "^6II^7" || customTag.Value == "^6III^7" + || customTag.Value == "^5IV^7" || customTag.Value == "^5V^7" || customTag.Value == "^5VI^7" || customTag.Value == "^5VII^7" + || customTag.Value == "^1IIX^7" || customTag.Value == "^1IX^7" || customTag.Value == "^1-X-^7")) + withdrawMoney = 200000 + else if (stats.Value == "40" && (customTag.Value == "^4C^7" || customTag.Value == "^5B^7" || customTag.Value == "^6A^7" + || customTag.Value == "^3S^7" || customTag.Value == "^3SS^7" || customTag.Value == "^3SSS^7" + || customTag.Value == "^6 I ^7" || customTag.Value == "^6II^7" || customTag.Value == "^6III^7" + || customTag.Value == "^5IV^7" || customTag.Value == "^5V^7" || customTag.Value == "^5VI^7" || customTag.Value == "^5VII^7" + || customTag.Value == "^1IIX^7" || customTag.Value == "^1IX^7" || customTag.Value == "^1-X-^7")) + withdrawMoney = 1000000 + else if (stats.Value == "50" && (customTag.Value == "^5B^7" || customTag.Value == "^6A^7" + || customTag.Value == "^3S^7" || customTag.Value == "^3SS^7" || customTag.Value == "^3SSS^7" + || customTag.Value == "^6 I ^7" || customTag.Value == "^6II^7" || customTag.Value == "^6III^7" + || customTag.Value == "^5IV^7" || customTag.Value == "^5V^7" || customTag.Value == "^5VI^7" || customTag.Value == "^5VII^7" + || customTag.Value == "^1IIX^7" || customTag.Value == "^1IX^7" || customTag.Value == "^1-X-^7")) + withdrawMoney = 2000000 + else if (stats.Value == "60" && (customTag.Value == "^6A^7" + || customTag.Value == "^3S^7" || customTag.Value == "^3SS^7" || customTag.Value == "^3SSS^7" + || customTag.Value == "^6 I ^7" || customTag.Value == "^6II^7" || customTag.Value == "^6III^7" + || customTag.Value == "^5IV^7" || customTag.Value == "^5V^7" || customTag.Value == "^5VI^7" || customTag.Value == "^5VII^7" + || customTag.Value == "^1IIX^7" || customTag.Value == "^1IX^7" || customTag.Value == "^1-X-^7")) + withdrawMoney = 4000000 + else if (stats.Value == "70" && (customTag.Value == "^3S^7" || customTag.Value == "^3SS^7" || customTag.Value == "^3SSS^7" + || customTag.Value == "^6 I ^7" || customTag.Value == "^6II^7" || customTag.Value == "^6III^7" + || customTag.Value == "^5IV^7" || customTag.Value == "^5V^7" || customTag.Value == "^5VI^7" || customTag.Value == "^5VII^7" + || customTag.Value == "^1IIX^7" || customTag.Value == "^1IX^7" || customTag.Value == "^1-X-^7")) + withdrawMoney = 8000000 + else if (stats.Value == "80" && (customTag.Value == "^3SS^7" || customTag.Value == "^3SSS^7" + || customTag.Value == "^6 I ^7" || customTag.Value == "^6II^7" || customTag.Value == "^6III^7" + || customTag.Value == "^5IV^7" || customTag.Value == "^5V^7" || customTag.Value == "^5VI^7" || customTag.Value == "^5VII^7" + || customTag.Value == "^1IIX^7" || customTag.Value == "^1IX^7" || customTag.Value == "^1-X-^7")) + withdrawMoney = 16000000 + else if (stats.Value == "90" && (customTag.Value == "^3SSS^7" + || customTag.Value == "^6 I ^7" || customTag.Value == "^6II^7" || customTag.Value == "^6III^7" + || customTag.Value == "^5IV^7" || customTag.Value == "^5V^7" || customTag.Value == "^5VI^7" || customTag.Value == "^5VII^7" + || customTag.Value == "^1IIX^7" || customTag.Value == "^1IX^7" || customTag.Value == "^1-X-^7")) + withdrawMoney = 32000000 + else + { + Player.Tell("You do not have the required rank to make that purchase. use ^7.buy for info") + return; + } + if (stats.Value == "100") + { + Player.Tell('Your ^1HP^7 is maxed out.'); + return; + } + + if (totalMoney < withdrawMoney) + { + Player.Tell('Not enough money in bank to buy HP, use ^3.buy^7 to see buying cost.') + return + } + + Player.Tell(Utils.formatString(Localization['ZBANK_WITHDRAW_SUCCESS'], { + amount: withdrawMoney.toLocaleString() + }, '%')[0]) + + this.setPlayerMoney(Player.ClientId, parseInt(totalMoney) - parseInt(withdrawMoney)) + Player.Data.lastWithdraw = new Date() + + if (stats.Value == "0") + stats.Value = "10" + else if (stats.Value == "10") + stats.Value = "20" + else if (stats.Value == "20") + stats.Value = "30" + else if (stats.Value == "30") + stats.Value = "40" + else if (stats.Value == "40") + stats.Value = "50" + else if (stats.Value == "50") + stats.Value = "60" + else if (stats.Value == "60") + stats.Value = "70" + else if (stats.Value == "70") + stats.Value = "80" + else if (stats.Value == "80") + stats.Value = "90" + else if (stats.Value == "90") + stats.Value = "100" + else + { + Player.Tell("Error#006, Contact admin") + } + + var hp = parseInt(stats.Value); + if (customName && customName.Value != "" && (customName.Value.includes('[^2VIP') || customName.Value.includes('[^3VIP') || customName.Value.includes('^3[VIP') + || customName.Value.includes('^6[VIP') || customName.Value.includes('[^6VIP'))) + { + hp += 50; + } + + await Player.Server.Rcon.executeCommandAsync(`set hp ${Player.Guid};${hp}`) + await this.Server.DB.metaService.deletePersistentMeta('hp', Player.ClientId) + await this.Server.DB.metaService.addPersistentMeta('hp', stats.Value, Player.ClientId) + this.Managers.forEach(manager => + { + if (manager) + { + manager.Server.Rcon.executeCommandAsync(`set bold ^1[Announcement] ^5${Player.Name}^7 Leveled his ^1HP ^7to ^3${hp}^7, use ^2.buy^7 `) + } + + }) + + Player.Tell(`You now have ^3${hp} ^7extra ^1HP !`) + } + //-----------------------------------HP------------------------------------------------------------- + //-----------------------------------SPEED------------------------------------------------------------- + else if(args[1] && args[1].toLocaleLowerCase() == 'speed') + { + var totalMoney = (await this.getZMStats(Player.ClientId)).Money + if (totalMoney == undefined) + { + Player.Tell("Error, zm_stats") + return + } + + var stats = await this.Server.DB.metaService.getPersistentMeta('speed', Player.ClientId) + var customTag = await this.Server.DB.metaService.getPersistentMeta('custom_tag', Player.ClientId) + if (!stats) + { + Player.Tell("Error#005, contact admin") + return + } + var withdrawMoney = 100000000 + console.log("stats value is %s", stats.Value ) + if (stats.Value == "1" && (customTag.Value == "^9F^7" || customTag.Value == "^8E^7" || customTag.Value == "^2D^7" + || customTag.Value == "^4C^7" || customTag.Value == "^5B^7" || customTag.Value == "^6A^7" + || customTag.Value == "^3S^7" || customTag.Value == "^3SS^7" || customTag.Value == "^3SSS^7" + || customTag.Value == "^6 I ^7" || customTag.Value == "^6II^7" || customTag.Value == "^6III^7" + || customTag.Value == "^5IV^7" || customTag.Value == "^5V^7" || customTag.Value == "^5VI^7" || customTag.Value == "^5VII^7" + || customTag.Value == "^1IIX^7" || customTag.Value == "^1IX^7" || customTag.Value == "^1-X-^7")) + withdrawMoney = 10000 + else if (stats.Value == "1.01" && (customTag.Value == "^9F^7" || customTag.Value == "^8E^7" || customTag.Value == "^2D^7" + || customTag.Value == "^4C^7" || customTag.Value == "^5B^7" || customTag.Value == "^6A^7" + || customTag.Value == "^3S^7" || customTag.Value == "^3SS^7" || customTag.Value == "^3SSS^7" + || customTag.Value == "^6 I ^7" || customTag.Value == "^6II^7" || customTag.Value == "^6III^7" + || customTag.Value == "^5IV^7" || customTag.Value == "^5V^7" || customTag.Value == "^5VI^7" || customTag.Value == "^5VII^7" + || customTag.Value == "^1IIX^7" || customTag.Value == "^1IX^7" || customTag.Value == "^1-X-^7")) + withdrawMoney = 50000 + else if (stats.Value == "1.02" && (customTag.Value == "^8E^7" || customTag.Value == "^2D^7" + || customTag.Value == "^4C^7" || customTag.Value == "^5B^7" || customTag.Value == "^6A^7" + || customTag.Value == "^3S^7" || customTag.Value == "^3SS^7" || customTag.Value == "^3SSS^7" + || customTag.Value == "^6 I ^7" || customTag.Value == "^6II^7" || customTag.Value == "^6III^7" + || customTag.Value == "^5IV^7" || customTag.Value == "^5V^7" || customTag.Value == "^5VI^7" || customTag.Value == "^5VII^7" + || customTag.Value == "^1IIX^7" || customTag.Value == "^1IX^7" || customTag.Value == "^1-X-^7")) + withdrawMoney = 100000 + else if (stats.Value == "1.03" && (customTag.Value == "^2D^7" + || customTag.Value == "^4C^7" || customTag.Value == "^5B^7" || customTag.Value == "^6A^7" + || customTag.Value == "^3S^7" || customTag.Value == "^3SS^7" || customTag.Value == "^3SSS^7" + || customTag.Value == "^6 I ^7" || customTag.Value == "^6II^7" || customTag.Value == "^6III^7" + || customTag.Value == "^5IV^7" || customTag.Value == "^5V^7" || customTag.Value == "^5VI^7" || customTag.Value == "^5VII^7" + || customTag.Value == "^1IIX^7" || customTag.Value == "^1IX^7" || customTag.Value == "^1-X-^7")) + withdrawMoney = 200000 + else if (stats.Value == "1.04" && (customTag.Value == "^4C^7" || customTag.Value == "^5B^7" || customTag.Value == "^6A^7" + || customTag.Value == "^3S^7" || customTag.Value == "^3SS^7" || customTag.Value == "^3SSS^7" + || customTag.Value == "^6 I ^7" || customTag.Value == "^6II^7" || customTag.Value == "^6III^7" + || customTag.Value == "^5IV^7" || customTag.Value == "^5V^7" || customTag.Value == "^5VI^7" || customTag.Value == "^5VII^7" + || customTag.Value == "^1IIX^7" || customTag.Value == "^1IX^7" || customTag.Value == "^1-X-^7")) + withdrawMoney = 1000000 + else if (stats.Value == "1.05" && (customTag.Value == "^5B^7" || customTag.Value == "^6A^7" + || customTag.Value == "^3S^7" || customTag.Value == "^3SS^7" || customTag.Value == "^3SSS^7" + || customTag.Value == "^6 I ^7" || customTag.Value == "^6II^7" || customTag.Value == "^6III^7" + || customTag.Value == "^5IV^7" || customTag.Value == "^5V^7" || customTag.Value == "^5VI^7" || customTag.Value == "^5VII^7" + || customTag.Value == "^1IIX^7" || customTag.Value == "^1IX^7" || customTag.Value == "^1-X-^7")) + withdrawMoney = 2000000 + else if (stats.Value == "1.06" && (customTag.Value == "^6A^7" + || customTag.Value == "^3S^7" || customTag.Value == "^3SS^7" || customTag.Value == "^3SSS^7" + || customTag.Value == "^6 I ^7" || customTag.Value == "^6II^7" || customTag.Value == "^6III^7" + || customTag.Value == "^5IV^7" || customTag.Value == "^5V^7" || customTag.Value == "^5VI^7" || customTag.Value == "^5VII^7" + || customTag.Value == "^1IIX^7" || customTag.Value == "^1IX^7" || customTag.Value == "^1-X-^7")) + withdrawMoney = 4000000 + else if (stats.Value == "1.07" && (customTag.Value == "^3S^7" || customTag.Value == "^3SS^7" || customTag.Value == "^3SSS^7" + || customTag.Value == "^6 I ^7" || customTag.Value == "^6II^7" || customTag.Value == "^6III^7" + || customTag.Value == "^5IV^7" || customTag.Value == "^5V^7" || customTag.Value == "^5VI^7" || customTag.Value == "^5VII^7" + || customTag.Value == "^1IIX^7" || customTag.Value == "^1IX^7" || customTag.Value == "^1-X-^7")) + withdrawMoney = 8000000 + else if (stats.Value == "1.08" && (customTag.Value == "^3SS^7" || customTag.Value == "^3SSS^7" + || customTag.Value == "^6 I ^7" || customTag.Value == "^6II^7" || customTag.Value == "^6III^7" + || customTag.Value == "^5IV^7" || customTag.Value == "^5V^7" || customTag.Value == "^5VI^7" || customTag.Value == "^5VII^7" + || customTag.Value == "^1IIX^7" || customTag.Value == "^1IX^7" || customTag.Value == "^1-X-^7")) + withdrawMoney = 16000000 + else if (stats.Value == "1.09" && (customTag.Value == "^3SSS^7" + || customTag.Value == "^6 I ^7" || customTag.Value == "^6II^7" || customTag.Value == "^6III^7" + || customTag.Value == "^5IV^7" || customTag.Value == "^5V^7" || customTag.Value == "^5VI^7" || customTag.Value == "^5VII^7" + || customTag.Value == "^1IIX^7" || customTag.Value == "^1IX^7" || customTag.Value == "^1-X-^7")) + withdrawMoney = 32000000 + else if (stats.Value == "1.10") + { + Player.Tell('Your ^2Speed^7 is maxed out.'); + return; + } + + if (totalMoney < withdrawMoney) + { + Player.Tell("You do not have the required money/rank to make that purchase. use ^7.buy for info") + return; + } + + Player.Tell(Utils.formatString(Localization['ZBANK_WITHDRAW_SUCCESS'], { + amount: withdrawMoney.toLocaleString() + }, '%')[0]) + + this.setPlayerMoney(Player.ClientId, parseInt(totalMoney) - parseInt(withdrawMoney)) + // Player.Data.lastWithdraw = new Date() + + if (stats.Value == "1") + stats.Value = "1.01" + else if (stats.Value == "1.01") + stats.Value = "1.02" + else if (stats.Value == "1.02") + stats.Value = "1.03" + else if (stats.Value == "1.03") + stats.Value = "1.04" + else if (stats.Value == "1.04") + stats.Value = "1.05" + else if (stats.Value == "1.05") + stats.Value = "1.06" + else if (stats.Value == "1.06") + stats.Value = "1.07" + else if (stats.Value == "1.07") + stats.Value = "1.08" + else if (stats.Value == "1.08") + stats.Value = "1.09" + else if (stats.Value == "1.09") + stats.Value = "1.10" + else + { + Player.Tell("Error#006, Contact admin") + } + + var speed = parseFloat(stats.Value); + await Player.Server.Rcon.executeCommandAsync(`set speed ${Player.Guid};${speed}`) + await this.Server.DB.metaService.deletePersistentMeta('speed', Player.ClientId) + await this.Server.DB.metaService.addPersistentMeta('speed', stats.Value, Player.ClientId) + + this.Managers.forEach(manager => + { + if (manager) + { + manager.Server.Rcon.executeCommandAsync(`set bold ^1[Announcement] ^5${Player.Name}^7 Leveled his ^2Speed ^7to ^3${speed}^7, use ^2.buy^7 `) + } + + }) + + Player.Tell(`You now have ^3${speed} ^7extra ^2Speed !`) + } + //-----------------------------------SPEED------------------------------------------------------------- + //-----------------------------------INFO------------------------------------------------------------- + else + { + Player.Data.lastWithdraw = new Date() + var health = await this.Server.DB.metaService.getPersistentMeta('hp', Player.ClientId) + var speed = await this.Server.DB.metaService.getPersistentMeta('speed', Player.ClientId) + + Player.Tell("^3Usage: ^2[.buy hp] [.buy speed]") + var customName = await this.Server.DB.metaService.getPersistentMeta('custom_name', Player.ClientId) + + if (customName && customName.Value != "" && (customName.Value.includes('[^2VIP') || customName.Value.includes('[^3VIP') || customName.Value.includes('^3[VIP') + || customName.Value.includes('^6[VIP') || customName.Value.includes('[^6VIP'))) + { + Player.Tell(`^3Extra health : ^1${parseInt(health.Value) + 50} HP ^7(^1${health.Value} ^7+ ^150 ^3VIP^7)`) + } + else + { + Player.Tell(`^3Extra health : ^1${health.Value}) HP`) + } + //^9F ^8E ^2D ^4C ^5B ^6A ^3S ^3SS ^3SSS + var nextPurchase = 0; + var requiredRank = ""; + if (health.Value == "0") + { + nextPurchase = 10000 + requiredRank = "^9F^7" + } + else if (health.Value == "10") + { + nextPurchase = 50000 + requiredRank = "^9F^7" + } + else if (health.Value == "20") + { + nextPurchase = 100000 + requiredRank = "^8E^7" + } + else if (health.Value == "30") + { + nextPurchase = 200000 + requiredRank = "^2D^7" + } + else if (health.Value == "40") + { + nextPurchase = 1000000 + requiredRank = "^4C^7" + } + else if (health.Value == "50") + { + nextPurchase = 2000000 + requiredRank = "^5B^7" + } + else if (health.Value == "60") + { + nextPurchase = 4000000 + requiredRank = "^6A^7" + } + else if (health.Value == "70") + { + nextPurchase = 8000000 + requiredRank = "^3S^7" + } + else if (health.Value == "80") + { + nextPurchase = 1600000 + requiredRank = "^3SS^7" + } + else if (health.Value == "90") + { + nextPurchase = 3200000 + requiredRank = "^3SSS^7" + } + + if (health.Value == "100") + { + Player.Tell("You are ^3Max ^1HP^7") + } + else + { + Player.Tell(`Next ^1HP purchase^7 will cost : ^2$${nextPurchase}^7`) + Player.Tell(`^5Required rank for next ^1HP purchase^7 : ${requiredRank}^7`) + } + + // await new Promise(resolve => setTimeout(resolve, 5000)) + + + + var customName = await this.Server.DB.metaService.getPersistentMeta('custom_name', Player.ClientId) + + Player.Tell(`^3Extra Speed : ^2${speed.Value} ^7`) + //^9F ^8E ^2D ^4C ^5B ^6A ^3S ^3SS ^3SSS + var nextPurchase = 0; + var requiredRank = ""; + if (speed.Value == "1") + { + nextPurchase = 10000 + requiredRank = "^9F^7" + } + else if (speed.Value == "1.01") + { + nextPurchase = 50000 + requiredRank = "^9F^7" + } + else if (speed.Value == "1.02") + { + nextPurchase = 100000 + requiredRank = "^8E^7" + } + else if (speed.Value == "1.03") + { + nextPurchase = 200000 + requiredRank = "^2D^7" + } + else if (speed.Value == "1.04") + { + nextPurchase = 1000000 + requiredRank = "^4C^7" + } + else if (speed.Value == "1.05") + { + nextPurchase = 2000000 + requiredRank = "^5B^7" + } + else if (speed.Value == "1.06") + { + nextPurchase = 4000000 + requiredRank = "^6A^7" + } + else if (speed.Value == "1.07") + { + nextPurchase = 8000000 + requiredRank = "^3S^7" + } + else if (speed.Value == "1.08") + { + nextPurchase = 1600000 + requiredRank = "^3SS^7" + } + else if (speed.Value == "1.09") + { + nextPurchase = 3200000 + requiredRank = "^3SSS^7" + } + + if (speed.Value == "1.10") + { + Player.Tell("You are ^2Max Speed^7") + } + else + { + Player.Tell(`Next ^2Speed purchase^7 will cost : ^2$${nextPurchase}^7`) + Player.Tell(`^5Required rank for next ^2Speed purchase^7 : ${requiredRank}^7`) + } + //-----------------------------------INFO------------------------------------------------------------- + return; + } + } + } + this.Manager.commands['inithp'] = { + ArgumentLength: 0, + Alias: 'inithp', + logToAudit: false, + Permission: Permissions.Commands.COMMAND_USER_CMDS, + callback: async (Player, args) => { + /* if (!this.Server.isZM()) { + Player.Tell(Localization['COMMAND_UNAVAILABLE_GAMETYPE']) + return + }*/ + var customName = await this.Server.DB.metaService.getPersistentMeta('custom_name', Player.ClientId) + if (customName) + { + var customNameValue = customName.Value + if (customName && customName.Value != "" && customNameValue.includes('^1')) + { + var stats = await this.Server.DB.metaService.getPersistentMeta('hp', Player.ClientId) + if (!stats) + { + await this.Server.DB.metaService.addPersistentMeta('hp', "0", Player.ClientId) + } + Player.Tell("hp created"); + return + } + else + { + Player.Tell('Admins only.') + return + } + } + + + } + } + + + this.Manager.commands['remove'] = { + ArgumentLength: 0, + Alias: 'remove', + logToAudit: false, + inGame: false, + Permission: Permissions.Commands.COMMAND_USER_CMDS, + callback: async (Player, args) => + { + if (await this.is_staff(Player) == false) + return + if (!args[2]) + { + Player.Tell("specify metadata") + return + } + const Client = await this.Server.getClient(args[1]) + + if (!Client) { + Player.Tell(Localization['COMMAND_CLIENT_NOT_FOUND']) + return + } + + await this.Server.DB.metaService.deletePersistentMeta(args[2], Client.ClientId) + Player.Tell(Client.Name + " removed from " + args[2]) + } +} + + this.Manager.commands['add'] = { + ArgumentLength: 0, + Alias: 'add', + logToAudit: false, + inGame: false, + Permission: Permissions.Commands.COMMAND_USER_CMDS, + callback: async (Player, args) => + { + if (Player.ClientId != 12) + { + Player.Tell("Not for staff") + return + } + if (await this.is_staff(Player) == false) + return + if (!args[2]) + { + Player.Tell("specify metadata") + return + } + const Client = await this.Server.getClient(args[1]) + + if (!Client) { + Player.Tell(Localization['COMMAND_CLIENT_NOT_FOUND']) + return + } + + if (!args[3]) + { + Player.Tell("missing value") + return + } + await this.Server.DB.metaService.addPersistentMeta(args[2], args[3], Client.ClientId) + Player.Tell(Client.Name + " added " + args[2] + "with value " + args[3]) + } +} + + this.Manager.commands['delhp'] = { + ArgumentLength: 0, + Alias: 'delhp', + logToAudit: false, + Permission: Permissions.Commands.COMMAND_USER_CMDS, + callback: async (Player, args) => { + /* if (!this.Server.isZM()) { + Player.Tell(Localization['COMMAND_UNAVAILABLE_GAMETYPE']) + return + }*/ + var customName = await this.Server.DB.metaService.getPersistentMeta('custom_name', Player.ClientId) + if (customName) + { + var customNameValue = customName.Value + if (customName && customName.Value != "" && customNameValue.includes('^1')) + { + await this.Server.DB.metaService.deletePersistentMeta('hp', Player.ClientId) + Player.Tell("hp deleted"); + + } + else + { + Player.Tell('Admins only.') + return + } + } + } + } + + //Event', 'ClientId', 'Kills', 'Downs', 'Revives', 'HighestRound', 'Headshots', 'Score' + this.Manager.commands['top'] = { + ArgumentLength: 0, + Alias: 'top', + inGame: false, + logToAudit: false, + Permission: Permissions.Commands.COMMAND_USER_CMDS, + callback: async (Player, args) => { + if (!args[1]) + { + Player.Tell("Usage: ^3.top^7 ^3gamemodes^7|^3ee^7|^3kills^7|^3rounds^7|^3headshots^7|^3score^7") + return + } + if (args[1] && (args[1].toLocaleLowerCase() == "gamemodes" || args[1].toLocaleLowerCase() == "kills" || args[1].toLocaleLowerCase() == "rounds" + || args[1].toLocaleLowerCase() == "headshots" || args[1].toLocaleLowerCase() == "score" || args[1].toLocaleLowerCase() == "ee")) + { + var extra_text = "" + var selected_stat = "" + var selected_pers_stat = "" + + var max_index = 5; + if (args[1].toLocaleLowerCase() == "gamemodes") + { + var Stats = await this.Server.DB.getPlayerStatsLDB("Event") + var Player_Stats = await this.Server.DB.getPlayerPersStats(Player.ClientId, "Event") + // max_index = 10; + } + else if (args[1].toLocaleLowerCase() == "kills") + { + var Stats = await this.Server.DB.getPlayerStatsLDB("Kills") + var Player_Stats = await this.Server.DB.getPlayerPersStats(Player.ClientId, "Kills") + } + + else if (args[1].toLocaleLowerCase() == "deaths") + { + var Stats = await this.Server.DB.getPlayerStatsLDB("Downs") + var Player_Stats = await this.Server.DB.getPlayerPersStats(Player.ClientId, "Downs") + } + + else if (args[1].toLocaleLowerCase() == "revives") + { + var Stats = await this.Server.DB.getPlayerStatsLDB("Revives") + var Player_Stats = await this.Server.DB.getPlayerPersStats(Player.ClientId, "Revives") + } + + else if (args[1].toLocaleLowerCase() == "rounds") + { + var Stats = await this.Server.DB.getPlayerStatsLDB("HighestRound") + var Player_Stats = await this.Server.DB.getPlayerPersStats(Player.ClientId, "HighestRound") + } + + else if (args[1].toLocaleLowerCase() == "headshots") + { + var Stats = await this.Server.DB.getPlayerStatsLDB("Headshots") + var Player_Stats = await this.Server.DB.getPlayerPersStats(Player.ClientId, "Headshots") + } + + else if (args[1].toLocaleLowerCase() == "score") + { + var Stats = await this.Server.DB.getPlayerStatsLDB("Score") + var Player_Stats = await this.Server.DB.getPlayerPersStats(Player.ClientId, "Score") + } + + else if (args[1].toLocaleLowerCase() == "ee") + { + var Stats = await this.Server.DB.getPlayerStatsLDB("Easter") + var Player_Stats = await this.Server.DB.getPlayerPersStats(Player.ClientId, "Easter") + } + + for (var i = 0; i < max_index; i++) + { + if (args[1].toLocaleLowerCase() == "gamemodes") + { + extra_text = "gamemodes completed" + selected_stat = Stats[i].Event + selected_pers_stat = Player_Stats[0].Event + } + if (args[1].toLocaleLowerCase() == "ee") + { + extra_text = "easter egg completed" + selected_stat = Stats[i].Easter + selected_pers_stat = Player_Stats[0].Easter + } + else if (args[1].toLocaleLowerCase() == "kills") + { + extra_text = "zombies killed" + selected_stat = Stats[i].Kills + selected_pers_stat = Player_Stats[0].Kills + } + + else if (args[1].toLocaleLowerCase() == "deaths") + { + extra_text = "downs" + selected_stat = Stats[i].Downs + selected_pers_stat = Player_Stats[0].Downs + } + + else if (args[1].toLocaleLowerCase() == "revives") + { + extra_text = "players revived" + selected_stat = Stats[i].Revives + selected_pers_stat = Player_Stats[0].Revives + } + else if (args[1].toLocaleLowerCase() == "rounds") + { + extra_text = "rounds accomplished" + selected_stat = Stats[i].HighestRound + selected_pers_stat = Player_Stats[0].HighestRound + } + else if (args[1].toLocaleLowerCase() == "headshots") + { + extra_text = "headshots" + selected_stat = Stats[i].Headshots + selected_pers_stat = Player_Stats[0].Headshots + } + else if (args[1].toLocaleLowerCase() == "score") + { + extra_text = "points earned" + selected_stat = Stats[i].Score + selected_pers_stat = Player_Stats[0].Score + } + var name = Stats[i].Name + var customName = await this.Server.DB.metaService.getPersistentMeta('custom_name', Stats[i].ClientId) + if (customName) + name = customName.Value + Player.Tell(`^3Top ${i + 1}^7 - ^5${name}^7 ^2@${Stats[i].ClientId}^7 - ^3${selected_stat}^7 ${extra_text}`) + await new Promise(resolve => setTimeout(resolve, 100)) + if (i == 4 && max_index == 10) + await new Promise(resolve => setTimeout(resolve, 3000)) + } + var player_name = Player.Name + var customName = await this.Server.DB.metaService.getPersistentMeta('custom_name', Player.ClientId) + if (customName) + player_name = customName.Value + Player.Tell(`^2Your score: ^5${player_name}^7 ^2@${Player.ClientId}^7 - ^3${selected_pers_stat}^7 ${extra_text}`) + return + } + else + { + Player.Tell("^1Invalid category^7.") + Player.Tell("Usage: ^3.top^7 ^3gamemodes^7|^3ee^7|^3kills^7|^3rounds^7|^3headshots^7|^3score^7") + } + } + } + this.Manager.commands['event'] = + { + ArgumentLength: 0, + Alias: 'event', + inGame: false, + logToAudit: false, + Permission: Permissions.Commands.COMMAND_USER_CMDS, + callback: async (Player, args) => + { + if (args[1]) + { + const Client = await this.Server.getClient(args[1]) + + if (!Client) { + Player.Tell(Localization['COMMAND_CLIENT_NOT_FOUND']) + return + } + var gm_count = await this.Server.DB.metaService.getPersistentMeta('event_gamemode', Client.ClientId) + if (!gm_count) + { + await this.Server.DB.metaService.addPersistentMeta('event_gamemode', "0", Client.ClientId) + var gm_count = await this.Server.DB.metaService.getPersistentMeta('event_gamemode', Client.ClientId) + } + var gm_count_int = parseInt(gm_count.Value) + + var extra_text = ""; + if (gm_count_int < 10) + extra_text = "^3Gonna need ^2more than that^3 for the ^2LDB^3 !" + else if (gm_count_int > 300) + extra_text = "Blud ^5sacrificed everything^3 for the ^5Tavern^3 !" + else if (gm_count_int > 200) + extra_text = "Absolutely ^2massive^3 !" + else if (gm_count_int > 100) + extra_text = "A ^2proper Taverner^3 !" + else if (gm_count_int > 75) + extra_text = "That's ^2a lot^3 of gamemodes !" + else if (gm_count_int > 50) + extra_text = "^2Getting there^3 !" + else if (gm_count_int > 25) + extra_text = "A ^2moderate^3 amount !" + else if (gm_count_int >= 10) + extra_text = "Could do ^2better^3 !" + + + + + Player.Tell(`${Client.Name} ^3completed ^5${gm_count_int}^3 gamemodes ! ${extra_text}`) + return + } + var gm_count = await this.Server.DB.metaService.getPersistentMeta('event_gamemode', Player.ClientId) + if (!gm_count) + { + await this.Server.DB.metaService.addPersistentMeta('event_gamemode', "0", Player.ClientId) + var gm_count = await this.Server.DB.metaService.getPersistentMeta('event_gamemode', Player.ClientId) + } + var gm_count_int = parseInt(gm_count.Value) + + var extra_text = ""; + if (gm_count_int < 10) + extra_text = "^3Gonna need ^2more than that^3 for the ^2LDB^3 !" + else if (gm_count_int >= 10) + extra_text = "Could do ^2better^3 !" + else if (gm_count_int > 20) + extra_text = "A ^2moderate^3 amount !" + else if (gm_count_int > 30) + extra_text = "^2Getting there^3 !" + else if (gm_count_int > 50) + extra_text = "That's ^2a lot^3 of gamemodes !" + else if (gm_count_int > 100) + extra_text = "A ^2proper Taverner^3 !" + else if (gm_count_int > 150) + extra_text = "Absolutely ^2massive^3 !" + else if (gm_count_int > 200) + extra_text = "Blud ^5sacrificed everything^3 for the ^5Tavern^3 !" + + Player.Tell(`^3You completed ^5${gm_count_int}^3 gamemodes ! ${extra_text}`) + } + } + this.Manager.commands['setround'] = { + ArgumentLength: 1, + Alias: 'sround', + logToAudit: false, + Permission: Permissions.Commands.COMMAND_USER_CMDS, + callback: async (Player, args) => { + if (!args[1]) { + Player.Tell('Need round number') + return + } + var round = args[1]; + var customName = await this.Server.DB.metaService.getPersistentMeta('custom_name', Player.ClientId) + if (customName) + { + var customNameValue = customName.Value + if (customName && customName.Value != "" && customNameValue.includes('^1Owner')) + { + await Player.Server.Rcon.executeCommandAsync(`set customround ${round}`) + Player.Tell(`set round to ${round}`) + return + } + } + else + { + Player.Tell('^1Error: You have no rank, contact admin') + return + } + } +} + +this.Manager.commands['brutus'] = { + ArgumentLength: 0, + Alias: 'brutus', + logToAudit: false, + inGame: false, + Permission: Permissions.COMMAND_USER_CMDS, + callback: async (Player, args) => { + + if (Player.ClientId != 12 && Player.ClientId != 35663 && Player.ClientId != 62325 && Player.ClientId != 113080) + { + Player.Tell("^3You do ^1not^3 possess the power of the bat") + return + } + + /* if (await this.is_staff(Player) == false) + { + Player.Tell("^3You do ^1not^3 possess the power of the bat") + return + } */ + + var spin = parseInt(await this.Server.Rcon.getDvar('spin')) + + if (spin == 0) + { + await this.Server.Rcon.setDvar('spin', '1') + await this.Server.Rcon.setDvar('bold', '^3You ^2spin^3 me right round babe right round') + Player.Tell("Spin time") + } + else if (spin == 1) + { + await this.Server.Rcon.setDvar('spin', '0') + await this.Server.Rcon.setDvar('bold', '^3When you go ^1down^3, when you go ^1down down') + Player.Tell("No more spin") + } + } +} + +this.Manager.commands['god'] = { + ArgumentLength: 0, + Alias: 'g', + logToAudit: false, + Permission: Permissions.COMMAND_USER_CMDS, + callback: async (Player, args) => { + + if (await this.is_staff(Player) == true) + { + await Player.Server.Rcon.executeCommandAsync(`set godmodeon ${Player.Guid}`) + return + } + else + { + Player.Tell('Admins only.') + } + } +} + +this.Manager.commands['godoff'] = { + ArgumentLength: 0, + Alias: 'goff', + logToAudit: false, + Permission: Permissions.Commands.COMMAND_USER_CMDS, + callback: async (Player, args) => { + if (await this.is_staff(Player) == true) + { + await Player.Server.Rcon.executeCommandAsync(`set godmodeoff ${Player.Guid}`) + return + } + else + { + Player.Tell('Admins only.') + } + } +} + +this.Manager.commands['lock'] = { + ArgumentLength: 0, + Alias: 'lock', + logToAudit: false, + Permission: Permissions.COMMAND_USER_CMDS, + callback: async (Player, args) => { + + if (!args) + { + Player.Tell(`Usage: .lock [1|0] -- Lock = ${this.lock}`) + + return + } + if (await this.is_staff(Player)) + { + this.lock = args[1]; + if (args[1] == "0") + Player.Tell("Server ^1Locked") + else + { + Player.Tell("Server ^2Unlocked") + } + } + else + { + Player.Tell('Staff Manager only') + return + } + } +} + +this.Manager.commands['lock'] = { + ArgumentLength: 0, + Alias: 'lock', + logToAudit: false, + Permission: Permissions.COMMAND_USER_CMDS, + callback: async (Player, args) => { + + if (!args) + { + Player.Tell(`Usage: .lock [1|0] -- Lock = ${this.lock}`) + + return + } + if (await this.is_staff(Player)) + { + this.lock = args[1]; + if (args[1] == "1") + Player.Tell("Server ^1Locked") + else + Player.Tell("Server ^2Unlocked") + } + else + { + Player.Tell('Staff Manager only') + return + } + } +} + +this.Manager.commands['song'] = { + ArgumentLength: 0, + Alias: 'song', + inGame: true, + logToAudit: false, + Permission: Permissions.COMMAND_USER_CMDS, + callback: async (Player, args) => { + + if (!(args[1]) || (args[1] != "1" && args[1] != "2" && args[1] != "3" && args[1] != "4")) + { + Player.Tell("Usage : ^3.song [1-4]") + return + } + if (await Player.Server.Rcon.getDvar("song") != "0") + { + Player.Tell("A ^3Song^7 is currently playing") + return + } + var map = await Player.Server.Rcon.getDvar("mapname") + var error = 0 + if (args[1] == "4" && map != "zm_nuked") + error = 1 + if (args[1] == "3" && map != "zm_nuked" && map != "zm_tomb") + error = 1 + if (args[1] == "2" && (map == "zm_transit" || map == "zm_highrise" || map == "zm_buried")) + error = 1 + + if (error == 1) + { + Player.Tell(`Song ^3${args[1]}^7 does ^1not exist^7 for ^3this map`) + return + } + Player.Tell(`Playing ^3Song ${args[1]}`) + await Player.Server.Rcon.setDvar('song', args[1]) + } +} + +this.Manager.commands['wipe'] = { + ArgumentLength: 0, + Alias: 'wp', + logToAudit: false, + Permission: Permissions.COMMAND_USER_CMDS, + callback: async (Player, args) => { + + if (Player.ClientId == 12 || Player.ClientId == 3649) + { + for(const ig_player of await this.Manager.Server.getClients()) + { + if (parseInt(ig_player.ClientId) != 12 && parseInt(ig_player.ClientId) != 3649) + { + ig_player.Kick("^1Server locked^7 for testing") + } + } + this.lock = args[1]; + Player.Tell("Wiped mon pooote :)") + } + } +} + + + this.Manager.commands['revive'] = { + ArgumentLength: 0, + Alias: 'rev', + logToAudit: false, + Permission: Permissions.Commands.COMMAND_USER_CMDS, + callback: async (Player, args) => { + + if (await this.is_raid() == true) + return + + var guild = await this.init_guild_data(Player.ClientId) + + var totalMoney = (await this.getZMStats(Player.ClientId)).Money + if (totalMoney == undefined) + { + Player.Tell("Error, zm_stats") + return + } + var commandCost = 1000000; + var roundRevived = parseInt(await Player.Server.Rcon.getDvar(`${Player.Clientslot}_revivedRound`)) + var currentRound = parseInt(await Player.Server.Rcon.getDvar(`currentRound`)) + var customTag = await this.Server.DB.metaService.getPersistentMeta('custom_tag', Player.ClientId) + + var customName = await this.Server.DB.metaService.getPersistentMeta('custom_name', Player.ClientId) + if (customName) + { + var customNameValue = customName.Value + if (customName && customName.Value != "" && customNameValue.includes('^1Owner')) + { + await Player.Server.Rcon.executeCommandAsync(`set revive ${Player.Guid};1`) + Player.Tell(`^1Owner Access Override : ^3.reviveall^7`) + return; + } + if (customName && customName.Value != "" && (customName.Value.includes('[^2VIP') || customName.Value.includes('^2[VIP') || customName.Value.includes('[^3VIP') || customName.Value.includes('^3[VIP') + || customName.Value.includes('^6[VIP') || customName.Value.includes('[^6VIP') + || customName.Value.includes('^1[VIP') || customName.Value.includes('[^1VIP') )) + { + if (currentRound >= roundRevived + 1 || this.Manager.Server.Hostname.split("|")[1].includes("BUS") + || this.Manager.Server.Hostname.split("|")[1].includes("AGARTHA") || await this.is_brutus() == true) + { + if (guild && guild.level >= 6) + await Player.Server.Rcon.executeCommandAsync(`set revive ${Player.Guid};guild`) + else + await Player.Server.Rcon.executeCommandAsync(`set revive ${Player.Guid};1`) + roundRevived = currentRound + await Player.Server.Rcon.executeCommandAsync(`set ${Player.Clientslot}_revivedRound ${roundRevived}`) + roundRevived += 1 + if (!(this.Manager.Server.Hostname.split("|")[1].includes("BUS")) && !(this.Manager.Server.Hostname.split("|")[1].includes("AGARTHA")) && + !(this.Manager.Server.Hostname.split("|")[1].includes("AGARTHA"))) + Player.Tell(`^3.revive^7 ^2used^7, next use : Round^2 ${roundRevived}^7`) + return + } + else + { + Player.Tell(`^3.revive^7 ^1on cooldown^7, next use : Round^2 ${roundRevived}^7`) + return + } + } + } + + if(!customTag) + { + Player.Tell('^1Error #002: contact admin') + return + } + else if (customTag.Value != "^3S^7" && customTag.Value != "^3SS^7" && customTag.Value != "^3SSS^7" + && customTag.Value != "^6 I ^7" && customTag.Value != "^6II^7" && customTag.Value != "^6III^7" + && customTag.Value != "^5IV^7" && customTag.Value != "^5V^7" && customTag.Value != "^5VI^7" && customTag.Value != "^5VII^7" + && customTag.Value != "^1IIX^7" && customTag.Value != "^1IX^7" && customTag.Value != "^1-X-^7") + { + Player.Tell('Only ^3VIP^7 & ^3S+ Rank ^7can use this command.') + return + } + if (totalMoney < commandCost) + { + Player.Tell('Not enough ^3$^7 to use that command.') + return + } + var roundDelay = 0 + var shouldgiveperk = 0 + if (customTag.Value == "^3S^7") + { + roundDelay = 5 + } + if (customTag.Value == "^3SS^7") + { + roundDelay = 4 + } + if (customTag.Value == "^3SSS^7" || customTag.Value == "^6 I ^7" || customTag.Value == "^6II^7" || customTag.Value == "^6III^7" + || customTag.Value == "^5IV^7" || customTag.Value == "^5V^7" || customTag.Value == "^5VI^7") + { + roundDelay = 3 + shouldgiveperk = 1 + } + if (customTag.Value == "^5VII^7" || customTag.Value == "^1IIX^7" || customTag.Value == "^1IX^7" || customTag.Value == "^1-X-^7") + { + roundDelay = 2 + shouldgiveperk = 1 + } + + if (roundDelay == 0) + { + Player.Tell("Error #001, please contact Admin") + return + } + if (currentRound >= roundRevived + roundDelay) + { + Player.Tell(Utils.formatString(Localization['ZBANK_WITHDRAW_SUCCESS'], { + amount: commandCost.toLocaleString() + }, '%')[0]) + + this.setPlayerMoney(Player.ClientId, parseInt(totalMoney) - parseInt(commandCost)) + + await Player.Server.Rcon.executeCommandAsync(`set revive ${Player.Guid};${shouldgiveperk}`) + roundRevived = currentRound; + await Player.Server.Rcon.executeCommandAsync(`set ${Player.Clientslot}_revivedRound ${roundRevived}`) + roundRevived += roundDelay; + Player.Tell(`^3.revive^7 ^2used^7, next use : Round^2 ${roundRevived}^7`) + return + } + else + { + Player.Tell(`^3.revive^7 ^1on cooldown^7, next use : Round^2 ${roundRevived}^7`) + } + return + } + } + + this.Manager.commands['reviveall'] = + { + ArgumentLength: 0, + Alias: 'revall', + logToAudit: false, + Permission: Permissions.Commands.COMMAND_USER_CMDS, + callback: async (Player, args) => + { + /*if (!this.Server.isZM()) { + Player.Tell(Localization['COMMAND_UNAVAILABLE_GAMETYPE']) + return + }*/ + var pass = await this.Server.DB.metaService.getPersistentMeta('pass', Player.ClientId) + if (!pass) + { + Player.Tell("Purchase the ^5Premium Pass^7 in ^6Discord^7 to use this command.") + return + } + if (!this.Manager.Server.Hostname.split("|")[1].includes("AGARTHA") + && !this.Manager.Server.Hostname.split("|")[1].includes("BUS") + && await this.is_brutus() == false) + { + Player.Tell("Available only in ^3Gamemodes^7.") + return; + } + await Player.Server.Rcon.executeCommandAsync(`set revive ${Player.Guid};all`) + return + } + } + + + this.Manager.commands['deposit'] = { + ArgumentLength: 1, + Alias: 'd', + logToAudit: false, + Permission: Permissions.Commands.COMMAND_USER_CMDS, + callback: async (Player, args) => { + /* if (!this.Server.isZM()) { + Player.Tell(Localization['COMMAND_UNAVAILABLE_GAMETYPE']) + return + }*/ + + if (Player.Data && Player.Data.lastDeposit && (new Date() - Player.Data.lastDeposit) / 1000 < 5) { + Player.Tell(Localization['COMMAND_COOLDOWN']) + return + } + + var totalMoney = (await this.getZMStats(Player.ClientId)).Money + if (totalMoney == undefined) + { + Player.Tell("Error, zm_stats") + return + } + var gameMoney = parseInt(await Player.Server.Rcon.getDvar(`${Player.Clientslot}_money`)) + var depositMoney = args[1] == 'all' ? parseInt(gameMoney) : parseInt(args[1]) + + const canUseBank = await Player.Server.Rcon.getDvar(`${Player.Clientslot}_can_use_bank`) + if (canUseBank == "0") { + Player.Tell("Cannot deposit when ^2Time Bomb ^7is active. ^1Nice try kid :)"); + // Player.Tell(Localization['ZBANK_DISABLED']); + return + } + if (canUseBank == "1") { + Player.Tell("Cannot deposit when in ^2Afterlife ^1Nice try kid :)"); + return + } + if (canUseBank == "2") + { + Player.Tell("Bank disabled for Tournament server"); + return + } + + switch (true) { + case (!Number.isInteger(depositMoney)): + Player.Tell(Localization['ZBANK_PARSE_ERROR']) + return + case (depositMoney <= 0): + case (!gameMoney || !Number.isInteger(gameMoney) || gameMoney < depositMoney): + Player.Tell(Localization['ZBANK_BALANCE_ERROR']) + return + } + + var result = await Player.Server.Rcon.executeCommandAsync(`set bank_deposit ${Player.Guid};${depositMoney}`) + + if (result) { + Player.Tell(Utils.formatString(Localization['ZBANK_DEPOSIT_SUCCESS'], { + amount: depositMoney.toLocaleString() + }, '%')[0]) + + Player.Data.lastDeposit = new Date() + this.setPlayerMoney(Player.ClientId, parseInt(totalMoney) + parseInt(depositMoney)) + return + } + + Player.Tell(Localization['ZBANK_DEPOSIT_FAIL']) + } + } + + this.Manager.commands['killall'] = + { + ArgumentLength: 0, + Alias: 'kill', + logToAudit: false, + Permission: Permissions.Commands.COMMAND_USER_CMDS, + callback: async (Player, args) => + { + if (await this.is_staff(Player)) + { + await Player.Server.Rcon.setDvar('killzmadmin', Player.Guid) + return + } + var mapname = await Player.Server.Rcon.getDvar('map_name') + if (mapname && mapname != "zm_transit" && mapname != "zm_buried") + { + Player.Tell('^3.kill^7 can only be used in ^3Tranzit/Town/Buried servers^7') + return + } + await Player.Server.Rcon.setDvar('killzm', Player.Guid) + } + } + + + + + + + + + + + + + + + this.Manager.commands['pay'] = { + ArgumentLength: 0, + inGame: false, + logToAudit: false, + Permission: Permissions.Commands.COMMAND_USER_CMDS, + callback: async (Player, args) => { + if (Player.Data && Player.Data.lastpay && (new Date() - Player.Data.lastpay) / 1000 < 5) { + Player.Tell(Localization['COMMAND_COOLDOWN']) + return + } + if (Player.Data) + Player.Data.lastpay = new Date() + var inGame = await this.Server.findClient(Player.ClientId) + if (inGame) + { + + } + + if (this.Manager.Server.Hostname.split("|")[1].includes("AGARTHA")) + { + Player.Tell("Cannot use ^3.pay^7 in ^5PiA^7") + return + } + if (!args[1] || !args[2]) + { + Player.Tell("^3To send ^2Points :^7 .pay ") + Player.Tell("^3To send ^5Z-Coins :^7 .pay zcoins") + return + } + var Target = await this.Server.getClient(args[1]) + if (!Target) { + Player.Tell(Localization['COMMAND_CLIENT_NOT_FOUND']) + return + } + if (args[3] == "zcoins") + { + var Pzcoins = await this.Server.DB.metaService.getPersistentMeta('zcoins', Player.ClientId) + var totalMoney = parseInt(Pzcoins.Value) + var moneyToGive = parseInt(args[2]) + if (!Number.isInteger(moneyToGive) || moneyToGive < 0) + { + Player.Tell(Localization['ZBANK_PARSE_ERROR']) + return + } + if (totalMoney < moneyToGive) + { + Player.Tell("^3Not enough ^5Z-Coins^3 to make that transaction") + return + } + var targetZcoins = await this.Server.DB.metaService.getPersistentMeta('zcoins', Target.ClientId) + var targetres = parseInt(targetZcoins.Value) + moneyToGive + var playerres = parseInt(Pzcoins.Value) - moneyToGive + await this.Server.DB.metaService.addPersistentMeta('zcoins', targetres, Target.ClientId) + await this.Server.DB.metaService.addPersistentMeta('zcoins', playerres, Player.ClientId) + var customName = await this.Server.DB.metaService.getPersistentMeta('custom_name', Target.ClientId) + var name = Target.Name + if (customName) + { + name = customName.Value + } + Player.Tell(`^3Successfully sent ^5${moneyToGive} Z-coins ^3to ^7${name} !`) + + Target.inGame = Utils.findClient(Target.ClientId, this.Managers) + Target.inGame && Target.inGame.Tell(`^3You received ^5${moneyToGive} Z-coins ^3from ^7${Player.Name} !`) + return + } + var totalMoney = (await this.getZMStats(Player.ClientId)).Money + if (totalMoney == undefined) + { + Player.Tell("Error, zm_stats") + console.log("err") + return + } + var moneyToGive = parseInt(args[2]) + + switch (true) { + case (!Number.isInteger(moneyToGive) || moneyToGive < 0): + Player.Tell(Localization['ZBANK_PARSE_ERROR']) + return + case (!totalMoney): + case (totalMoney < parseInt(moneyToGive * 1.05) && Player.Guid != 'Node'): + Player.Tell(Localization['ZBANK_BALANCE_ERROR']) + return + } + + await this.addPlayerMoney(Player.ClientId, -1 * parseInt(parseInt(moneyToGive) * 1.05)) + this.addPlayerMoney(Target.ClientId, parseInt(moneyToGive)) + + var customName = await this.Server.DB.metaService.getPersistentMeta('custom_name', Target.ClientId) + var name = Target.Name + if (customName) + { + name = customName.Value + } + Player.Tell(Utils.formatString(Localization['ZBANK_TRANSFER_FORMAT'], { + amount: moneyToGive.toLocaleString(), + name: name, + fee: parseInt(moneyToGive * 0.05), + id: Utils.getRandomInt(10000000, 90000000) + }, '%')[0]) + + Target.inGame = Utils.findClient(Target.ClientId, this.Managers) + + Target.inGame && Target.inGame.Tell(Utils.formatString(Localization['ZBANK_RECEIVE_FORMAT'], { + amount: moneyToGive.toLocaleString(), + name: Player.Name + }, '%')[0]) + } + } + this.Manager.commands['setmoney'] = { + ArgumentLength: 2, + inGame: false, + logToAudit: false, + Permission: Permissions.Commands.COMMAND_USER_CMDS, + callback: async (Player, args) => { + var Target = await this.Server.getClient(args[1]) + + if (!Target) { + Player.Tell(Localization['COMMAND_CLIENT_NOT_FOUND']) + return + } + + if (await this.is_staff(Player) == false) + return + + const moneyToSet = parseInt(args[2]) + + if (!Number.isInteger(moneyToSet)) + { + Player.Tell(Localization['ZBANK_PARSE_ERROR']) + return + } + + await this.setPlayerMoney(Target.ClientId, moneyToSet) + + Player.Tell(Utils.formatString(Localization['ZBANK_SETMONEY_FORMAT'], { + amount: moneyToSet.toLocaleString(), + name: Target.Name + }, '%')[0]) + + Target.inGame = Utils.findClient(Target.ClientId, this.Managers) + Target.inGame && Target.inGame.Tell(Utils.formatString(Localization['ZBANK_NEWBALANCE_FORMAT'], { + amount: moneyToSet.toLocaleString() + }, '%')[0]) + } + } + + this.Manager.commands['setzcoins'] = { + ArgumentLength: 2, + inGame: false, + logToAudit: false, + Permission: Permissions.Commands.COMMAND_USER_CMDS, + callback: async (Player, args) => { + var Target = await this.Server.getClient(args[1]) + + if (!Target) { + Player.Tell(Localization['COMMAND_CLIENT_NOT_FOUND']) + return + } + if (await this.is_staff(Player) == false) + return + const zCoinsToSet = parseInt(args[2]) + + if (!Number.isInteger(zCoinsToSet)) + { + Player.Tell(Localization['ZBANK_PARSE_ERROR']) + return + } + await this.Server.DB.metaService.addPersistentMeta('zcoins', zCoinsToSet, Target.ClientId) + + Player.Tell(Utils.formatString(Localization['ZBANK_SETMONEY_FORMAT'], { + amount: zCoinsToSet.toLocaleString(), + name: Target.Name + }, '%')[0]) + + Target.inGame = Utils.findClient(Target.ClientId, this.Managers) + Target.inGame && Target.inGame.Tell(Utils.formatString(Localization['ZBANK_NEWBALANCE_FORMAT'], { + amount: zCoinsToSet.toLocaleString() + }, '%')[0]) + } + } + + this.Manager.commands['upgrade'] = + { + ArgumentLength: 0, + inGame: false, + Alias: 'up', + logToAudit: false, + Permission: Permissions.Commands.COMMAND_USER_CMDS, + callback: async (Player, args) => + { + /* if (await Player.Server.Rcon.getDvar(`net_port`) == "30009") + return + if (args) + { + if (args[1] && args[1] == "rate") + { + + } + else if (args[1] && args[1] == "speed") + { + + } + }*/ + + var rate = parseFloat(await Player.Server.Rcon.getDvar(`fire_rate`)) + var cost = parseInt(await Player.Server.Rcon.getDvar(`cost`)) + var zcoins = await this.Server.DB.metaService.getPersistentMeta('zcoins', Player.ClientId) + if(!zcoins) + return + + if (parseInt(zcoins.Value) < this.cost) + { + Player.Tell("No ^5Z-Coins^7 left !") + return + } + var guild = await this.init_guild_data(Player.ClientId) + if (guild) + { + if (rate <= 0.2) + { + Player.Tell(`Team Fire rate ^2Over Maxed^7 ! No ^5Z-Coins^3 used`) + return + } + if (rate <= 0.25 && guild.level < 7) + { + Player.Tell("^6Guild^7 level ^1too low^7 to use extra ^5.up^7") + return + } + else if (rate <= 0.3 && guild.level < 5) + { + Player.Tell("^6Guild^7 level ^1too low^7 to use extra ^5.up^7") + return + } + + if ((rate <= 0.25 && guild.level >= 7) || (rate <= 0.3 && guild.level >= 5) || this.Server.Hostname.split("|")[1].includes("PRIVATE")) //request + { + rate -= 0.05 + Player.Tell("Guild ^5.up^7 used !") + } + else + { + rate -= 0.065 + if (rate == 0.295) + rate = 0.3 //hard fix + } + Player.Server.Rcon.executeCommandAsync(`set upgrade ${rate}`) + + Player.Tell(`Used ^5 ${parseInt(cost)} Z-Coins^7 !\nTeam Fire rate ^3Increased^7 !`) + await this.Server.DB.metaService.addPersistentMeta('zcoins', parseInt(zcoins.Value) - cost, Player.ClientId) + cost *= 1.3; + Player.Server.Rcon.executeCommandAsync(`set cost ${cost}`) + } + else + { + rate -= 0.065 + if (rate == 0.295) + rate = 0.3 //hard fix + if (rate < 0.3) + { + Player.Tell(`Team Fire rate ^1Maxed^7 ! No ^5Z-Coins^3 used`) + return + } + + Player.Server.Rcon.executeCommandAsync(`set upgrade ${rate}`) + + Player.Tell(`Used ^5 ${parseInt(cost)} Z-Coins^7 !\nTeam Fire rate ^3Increased^7 !`) + await this.Server.DB.metaService.addPersistentMeta('zcoins', parseInt(zcoins.Value) - cost, Player.ClientId) + cost *= 1.3; + Player.Server.Rcon.executeCommandAsync(`set cost ${cost}`) + } + } + } + + this.Manager.commands['money'] = { + ArgumentLength: 0, + inGame: false, + Alias: 'balance', + logToAudit: false, + Permission: Permissions.Commands.COMMAND_USER_CMDS, + callback: async (Player, args) => { + if (args[1]) { + const Client = await this.Server.getClient(args[1]) + + if (!Client) { + Player.Tell(Localization['COMMAND_CLIENT_NOT_FOUND']) + return + } + + const amount = (await this.getZMStats(Client.ClientId)).Money + + if (amount == undefined) { + Player.Tell(Localization['ZBANK_PLAYER_NO_ACCOUNT']) + return + } + var customName = await this.Server.DB.metaService.getPersistentMeta('custom_name', Client.ClientId) + var name = Client.Name + if (customName) + { + name = customName.Value + } + Player.Tell(Utils.formatString(Localization['ZBANK_MONEY_FORMAT'], { + name: name, + amount: amount.toLocaleString() + }, '%')[0]) + + var zcoins = await this.Server.DB.metaService.getPersistentMeta('zcoins', Client.ClientId) + if (!zcoins) + { + await this.Server.DB.metaService.addPersistentMeta('zcoins', "0", Client.ClientId) + zcoins = await this.Server.DB.metaService.getPersistentMeta('zcoins', Client.ClientId) + } + Player.Tell(`^5${name} ^3Z-Coins : ^5${zcoins.Value}`) + return + } + + const amount = (await this.getZMStats(Player.ClientId)).Money + + if (amount == undefined) { + Player.Tell(Localization['ZBANK_NO_ACCOUNT']) + return + } + + Player.Tell(Utils.formatString(Localization['ZBANK_MONEY_FORMAT_SELF'], { + amount: amount.toLocaleString() + }, '%')[0]) + + var zcoins = await this.Server.DB.metaService.getPersistentMeta('zcoins', Player.ClientId) + if (!zcoins) + { + await this.Server.DB.metaService.addPersistentMeta('zcoins', "0", Player.ClientId) + zcoins = await this.Server.DB.metaService.getPersistentMeta('zcoins', Player.ClientId) + } + Player.Tell(`^3Z-Coins : ^5${zcoins.Value}`) + } + } + } + + async display_flex(manager, customTag, customName, totalMoney, zcoins, hp, percentspeed, save, Player) + { + if (customName) + manager.Server.Rcon.executeCommandAsync(`set ln [${customTag.Value}]${customName.Value}^7 flex his ^2$${totalMoney.toLocaleString("en-GB")}^7 - ^5${zcoins.Value} Z-Coins^7`) + else + manager.Server.Rcon.executeCommandAsync(`set ln [${customTag.Value}] ^8${Player.Name}^7 flex his ^2$${totalMoney.toLocaleString("en-GB")}^7 - ^5${zcoins.Value} Z-Coins^7`) + await new Promise(resolve => setTimeout(resolve, 500)) + manager.Server.Rcon.executeCommandAsync(`set ln ^1${hp}/450 HP^7 - ^3${percentspeed}/15 Speed^7 - ^5${save.Value} save^7. Use ^5.flex^7`) + } + + async is_staff(Player) + { + for (var i = 0; i < this.staff_list_a.length; i++) + if (this.staff_list_a[i] == Player.Guid) + return true + return false + } + + async guild_staff(guild_id, args, Player, lock) + { + var is_found = 0; + var guild_name_id = guild_id.split(';') + if (guild_name_id[0].toLocaleLowerCase() == args[2].toLocaleLowerCase()) + { + var guild_data = await this.Server.DB.metaService.getPersistentMeta('guild_data', guild_name_id[1]) + if (!guild_data) + { + Player.Tell("err") + return + } + var guild_str = guild_data.Value.split(';') + var guild = [] + + guild.name = guild_str[0] + guild.guild_master = guild_str[1] + guild.guild_members = guild_str[2] + guild.size = guild_str[3] + guild.level = guild_str[4] + guild.xp = guild_str[5] + guild.bank = guild_str[6] + guild.hp = guild_str[7] + guild.speed = guild_str[8] + guild.skills = guild_str[9] + guild.revive = guild_str[10] + + if (args[3] && args[3] == "list") + { + Player.Tell("^6Guild ^3GM^7 : " + guild.guild_master) + await new Promise(resolve => setTimeout(resolve, 500)) + Player.Tell("^3Member ID list^7 : " + guild.guild_members) + return + } + else if (args[3] && args[3] == "add") + { + if (!args[4]) + { + Player.Tell("no ID parameter") + return + } + + if (guild.guild_members.split('-')) + { + var current_members = guild.guild_members.split('-') + } + else + { + var current_members = 0 + } + + if (parseInt(guild.size) > parseInt(current_members)) + { + var members_array = guild.guild_members.split('-') + var err = 0; + members_array.forEach(member => + { + if (member == args[4].replace('@', '')) + { + Player.Tell(args[4].replace('@', '') + " is ^3already^7 in your ^6guild !") + err = 1; + } + }) + if (err && err == 1) + return + + var player_guild = await this.Server.DB.metaService.getPersistentMeta('guild_data', parseInt(args[4].replace('@', ''))) + if (player_guild && player_guild.Value.split(";")[0] != guild.name) + { + Player.Tell("Player ^3" + args[4].replace('@', '') + "^7 belongs to " + player_guild.Value.split(";")[0]) + return + } + + if (guild.guild_members == "0" || guild.guild_members == "-" || guild.guild_members == "") + guild.guild_members = args[4].replace('@', '') //add guild member + else + guild.guild_members += "-" + args[4].replace('@', '') //add guild member + + Player.Tell(args[4].replace('@', '') + " added to " + guild.name) + } + else + { + Player.Tell("Your ^6Guild^7 is ^1full^7 !") + return + } + } + else if (args[3] && args[3] == "remove") + { + var members_array = guild.guild_members.split('-') + var err = 0 + var is_found = 0 + members_array.forEach(member => + { + if (member == guild_name_id[1]) + { + Player.Tell("^6Guild Master^7") + err = 1; + } + }) + if (err && err == 1) + return + + var target_player_id = ""; + members_array.forEach(member => + { + if (member == args[4].replace('@', '')) + { + target_player_id = member + is_found = 1 + } + }) + if (is_found == 0) + { + Player.Tell("This player is ^1not^7 in " + guild.name) + return + } + + var player_guild = await this.Server.DB.metaService.getPersistentMeta('guild_data', parseInt(target_player_id)) + if (player_guild && player_guild.Value.split(";")[0] != guild.name) + { + Player.Tell("Player ^3" + target_player_id + "^7 belongs to " + player_guild.Value.split(";")[0]) + return + } + guild.guild_members = guild.guild_members.replace("\-".toString() + target_player_id , "") + Player.Tell(args[4].replace('@', '') + " removed from " + guild.name) + await this.Server.DB.metaService.deletePersistentMeta('guild_data', parseInt(target_player_id)) + } + else + { + Player.Tell("^3Action ^1missing^7. (add, remove, list)") + return; + } + + guild.guild_members.split("-").forEach(member_id => + { + this.set_player_guild_stat(guild, member_id) + }) + } + } + + async set_player_guild_stat(guild, member_id) + { + await this.Server.DB.metaService.addPersistentMeta('guild_data', (guild.name + ";" + guild.guild_master + ";" + guild.guild_members + + ";" + guild.size + ";" + guild.level + ";" + guild.xp + + ";" + guild.bank + ";" + guild.hp + ";" + guild.speed + + ";" + guild.skills + ";" + guild.revive), member_id) + } + + async guildWatcher() + { + //return + await new Promise(resolve => setTimeout(resolve, 5000)) //wait for NSM to tether servers + + if(!this.Manager.Server.Hostname || !(this.Manager.Server.Hostname.includes('BRUTUS'))) //make this code work 1 time instead of 15 + { + return + } + + while (1) + { + var now = new Date(); + var day = now.getDay(); + var hours = now.getHours(); + var minutes = now.getMinutes(); + // console.log(day + " " + hours + " " + minutes) + if (day == 6 && hours == 18 && minutes == 0) + { + for (const manager of this.Managers) + { + if (manager && manager.Server) + manager.Server.tmp = 1; + } + var lowest_competitive_time_raid = 1000000; + var winner_id_raid = 0; + + var lowest_competitive_time_ee = 1000000; + var winner_id_ee = 0; + + var lowest_competitive_time_gamemode = 1000000; + var winner_id_gamemode = 0; + + var highest_fr_round = 0; + var winner_id_fr = 0; + + for(const guild_name_id of this.guild_list) + { + var gm_id = parseInt(guild_name_id.split(";")[1]) + console.log("searching guild of " + gm_id) + var guild_data = await this.Server.DB.metaService.getPersistentMeta('guild_data', gm_id) + if (!guild_data) + { + console.log("guild_data undefined, skipping guild") + continue + } + + var members_array = guild_data.Value.split(";")[2].split('-') + + for (const member_id of members_array) //foreach guildmate of all guilds + { + var guild_quest = await this.Server.DB.metaService.getPersistentMeta('guild_quest', parseInt(member_id)) + if (guild_quest) + { + var quest_array = guild_quest.Value.split(";") + for (const quest of quest_array) + { + if (quest == "raid_boss_quest") + { + var player_competitive_time = await this.Server.DB.metaService.getPersistentMeta(quest, parseInt(member_id)) + if (player_competitive_time && parseInt(player_competitive_time.Value) < lowest_competitive_time_raid && parseInt(player_competitive_time.Value) > 0) + { + lowest_competitive_time_raid = parseInt(player_competitive_time.Value) + winner_id_raid = parseInt(member_id) + } + } + else if (quest.includes("ee_speedrun_quest")) + { + var player_competitive_time = await this.Server.DB.metaService.getPersistentMeta(quest, parseInt(member_id)) + if (player_competitive_time && parseInt(player_competitive_time.Value) < lowest_competitive_time_ee && parseInt(player_competitive_time.Value) > 0) + { + lowest_competitive_time_ee = parseInt(player_competitive_time.Value) + winner_id_ee = parseInt(member_id) + } + } + else if (quest.includes("gamemode_speedrun_quest")) + { + var player_competitive_time = await this.Server.DB.metaService.getPersistentMeta(quest, parseInt(member_id)) + if (player_competitive_time && parseInt(player_competitive_time.Value) < lowest_competitive_time_gamemode && parseInt(player_competitive_time.Value) > 0) + { + lowest_competitive_time_gamemode = parseInt(player_competitive_time.Value) + winner_id_gamemode = parseInt(member_id) + } + } + else if (quest == "first_room_hr_quest") + { + var player_highest_fr_round = await this.Server.DB.metaService.getPersistentMeta(quest, parseInt(member_id)) + if (player_highest_fr_round && parseInt(player_highest_fr_round) > highest_fr_round && parseInt(player_highest_fr_round) > 0) + { + highest_fr_round = parseInt(player_highest_fr_round) + winner_id_fr = parseInt(member_id) + } + } + } + } + } + } + for(const guild_name_id of this.guild_list) + { + await this.give_new_quest(parseInt(guild_name_id.split(";")[1])) + } + + if (lowest_competitive_time_raid != 1000000) + { + console.log("raid xp given to " + winner_id_raid) + await this.add_guild_xp(winner_id_raid, 60) + } + if (lowest_competitive_time_ee != 1000000) + { + console.log("ee sn xp given to " + winner_id_ee) + await this.add_guild_xp(winner_id_ee, 60) + } + if (lowest_competitive_time_gamemode != 1000000) + { + console.log("gamemode sn xp given to " + winner_id_gamemode) + await this.add_guild_xp(winner_id_gamemode, 60) + } + if (highest_fr_round != 0) + { + console.log("fr xp given to " + winner_id_fr) + await this.add_guild_xp(winner_id_fr, 60) + } + for (const manager of this.Managers) + { + if (manager && manager.Server) + manager.Server.tmp = 0; + } + return + } + await new Promise(resolve => setTimeout(resolve, 20000)) + } + } + + async add_guild_xp(member_id, xp_earned) + { + var guild = await this.init_guild_data(member_id) + + if (guild.level >= 10) + return + var extra_xp_percent = 1 + for (const guild_member_id of guild.guild_members.split("-")) + { + var customName = await this.Server.DB.metaService.getPersistentMeta('custom_name', parseInt(guild_member_id)) + + if (customName && customName.Value != "" && (customName.Value.includes('[^2VIP') || customName.Value.includes('^2VIP'))) + extra_xp_percent += 0.2 + } + var xp_needed = 100; + if (guild.level > 8) + xp_needed = 200; + else if (guild.level > 7) + xp_needed = 150; + else if (guild.level > 5) + xp_needed = 120; + + + if (guild.xp + parseInt((xp_earned * extra_xp_percent)) >= xp_needed) + { + guild.level++; + + var xp_left_to_add = (guild.xp + parseInt((xp_earned * extra_xp_percent))) - xp_needed + guild.xp = xp_left_to_add + if (guild.level == 4 || guild.level == 9) + { + guild.size++; + } + } + else + { + guild.xp += parseInt((xp_earned * extra_xp_percent)) + } + + console.log("total xp : " + guild.xp) + await this.edit_guildmate_guild_data(guild) + console.log("added " + parseInt((xp_earned * extra_xp_percent)) + " xp") + } + + async init_guild_data(member_id) + { + var guild_data = await this.Server.DB.metaService.getPersistentMeta('guild_data', member_id) + if (!guild_data) + return false + var guild_str = guild_data.Value.split(';') + var guild = [] + + guild.name = guild_str[0] + guild.guild_master = guild_str[1] + guild.guild_members = guild_str[2] + guild.size = parseInt(guild_str[3]) + guild.level = parseInt(guild_str[4]) + guild.xp = parseInt(guild_str[5]) + guild.bank = parseInt(guild_str[6]) + guild.hp = parseInt(guild_str[7]) + guild.speed = parseInt(guild_str[8]) + guild.skills = guild_str[9] + guild.revive = guild_str[10] + + return guild + } + + async give_new_quest(member_id) + { + while (1) + { + if (this.are_quest_randomized == true) //make every subsequent fn calls wait for the quest randomizer vars to be set + { + this.are_quest_randomized = false + break + } + await new Promise(resolve => setTimeout(resolve, 100)) + } + var guild = await this.init_guild_data(member_id) + + var quest_basic = [] + quest_basic[quest_basic.length] = "kill_quest" + quest_basic[quest_basic.length] = "headshot_quest" + quest_basic[quest_basic.length] = "gamemode_completion_quest" + quest_basic[quest_basic.length] = "ee_completion_quest" + + var quest_competitive = [] + if (this.gamemode_random == -1) // make all guild have the same competitive quest + this.gamemode_random = randomInt(3) + if (this.gamemode_random == 0) + quest_competitive[quest_competitive.length] = "gamemode_speedrun_quest_pia" + else if (this.gamemode_random == 1) + quest_competitive[quest_competitive.length] = "gamemode_speedrun_quest_titb" + else if (this.gamemode_random == 2) + quest_competitive[quest_competitive.length] = "gamemode_speedrun_quest_botb" + + if (this.ee_random == -1) // make all guild have the same competitive quest + this.ee_random = randomInt(5) + if (this.ee_random == 0) + quest_competitive[quest_competitive.length] = "ee_speedrun_quest_transit" + if (this.ee_random == 1) + quest_competitive[quest_competitive.length] = "ee_speedrun_quest_highrise" + if (this.ee_random == 2) + quest_competitive[quest_competitive.length] = "ee_speedrun_quest_prison" + if (this.ee_random == 3) + quest_competitive[quest_competitive.length] = "ee_speedrun_quest_buried" + if (this.ee_random == 4) + quest_competitive[quest_competitive.length] = "ee_speedrun_quest_tomb" + + // quest_competitive[quest_competitive.length] = "first_room_hr_quest" + + var player_old_quest = await this.Server.DB.metaService.getPersistentMeta('guild_quest', member_id) + if (player_old_quest) + { + var player_old_quest_array = player_old_quest.Value.split(';') //remove old quest from pool to prevent duplicate + // console.log(member_id + " old quest list " + player_old_quest.Value) + for (const old_quest of player_old_quest_array) + { + for (const quest of quest_basic) + { + if (old_quest == quest) + { + const index = quest_basic.indexOf(quest) + if (index > -1) + quest_basic.splice(index, 1) + } + } + for (const quest of quest_competitive) + { + if (old_quest == quest || (old_quest.includes("ee_speedrun_quest") && quest.includes("ee_speedrun_quest")) || (old_quest.includes("gamemode_speedrun_quest") && quest.includes("gamemode_speedrun_quest"))) + { + const index = quest_competitive.indexOf(quest) + if (index > -1) + quest_competitive.splice(index, 1) + } + } + } + for (const old_quest of player_old_quest_array) //reset all quest datas + { + await this.edit_guildmate_metadata(guild, old_quest, "0") + } + } + + var quest_list = "raid_boss_quest" + + //COMPETITIVE QUEST + if (this.competitive_r == -1) // make all guild have the same competitive quest + this.competitive_r = randomInt(quest_competitive.length) + quest_list += ";" + quest_competitive[this.competitive_r] + + //BASIC QUEST + // if (this.basic_r == -1) + this.basic_r = randomInt(quest_basic.length) + quest_list += ";" + quest_basic[this.basic_r] + + + if (quest_basic[this.basic_r] == "kill_quest") + { + await this.edit_guildmate_metadata(guild, "kill_quest_start", "0") + } + if (quest_basic[this.basic_r] == "headshot_quest") + { + await this.edit_guildmate_metadata(guild, "headshot_quest_start", "0") + } + if (quest_basic[this.basic_r] == "gamemode_completion_quest") + { + await this.edit_guildmate_metadata(guild, "gamemode_completion_quest_start", "0") + } + if (quest_basic[this.basic_r] == "ee_completion_quest") + { + await this.edit_guildmate_metadata(guild, "ee_completion_quest_start", "0") + } + + const index = quest_basic.indexOf(quest_basic[this.basic_r]) //remove selected 1st basic quest & run it again for 2nd + if (index > -1) + quest_basic.splice(index, 1) + + // if (this.basic_r2 == -1) + this.basic_r2 = randomInt(quest_basic.length) + quest_list += ";" + quest_basic[this.basic_r2] + + if (quest_basic[this.basic_r2] == "kill_quest") + { + await this.edit_guildmate_metadata(guild, "kill_quest_start", "0") + } + if (quest_basic[this.basic_r2] == "headshot_quest") + { + await this.edit_guildmate_metadata(guild, "headshot_quest_start", "0") + } + if (quest_basic[this.basic_r2] == "gamemode_completion_quest") + { + await this.edit_guildmate_metadata(guild, "gamemode_completion_quest_start", "0") + } + if (quest_basic[this.basic_r2] == "ee_completion_quest") + { + await this.edit_guildmate_metadata(guild, "ee_completion_quest_start", "0") + } + + for (const quest of quest_competitive) + { + await this.edit_guildmate_metadata(guild, quest, "0") + } + + this.are_quest_randomized = true + + console.log(member_id + " new quest list : " + quest_list) + await this.edit_guildmate_metadata(guild, 'guild_quest', quest_list) + } + + async edit_guildmate_metadata(guild, data, value) + { + for(const guildmate_id of guild.guild_members.split("-")) + { + if (value != "-1") + { + if (data == "kill_quest_start") + { + var Player_Stats = await this.Server.DB.getPlayerPersStats(parseInt(guildmate_id), "Kills") + value = Player_Stats[0].Kills + } + else if (data == "headshot_quest_start") + { + var Player_Stats = await this.Server.DB.getPlayerPersStats(parseInt(guildmate_id), "Headshots") + value = Player_Stats[0].Headshots + } + else if (data == "gamemode_completion_quest_start") + { + var gamemodeCountTotal = await this.Server.DB.metaService.getPersistentMeta('gamemodeCountTotal', parseInt(guildmate_id)) + if (gamemodeCountTotal) + value = gamemodeCountTotal.Value + else + value = 0 + } + else if (data == "ee_completion_quest_start") + { + var eeCountTotal = await this.Server.DB.metaService.getPersistentMeta('eeCountTotal', parseInt(guildmate_id)) + if (eeCountTotal) + value = eeCountTotal.Value + else + value = 0 + } + } + + await this.Server.DB.metaService.addPersistentMeta(data, value, parseInt(guildmate_id)) + } + } + + async edit_guildmate_guild_data(guild) + { + for (const guildmate_id of guild.guild_members.split("-")) + { + await this.Server.DB.metaService.addPersistentMeta('guild_data', (guild.name + ";" + guild.guild_master + ";" + guild.guild_members + + ";" + guild.size + ";" + guild.level + ";" + guild.xp + + ";" + guild.bank + ";" + guild.hp + ";" + guild.speed + + ";" + guild.skills + ";" + guild.revive), parseInt(guildmate_id)) + } + } + + async print_competitive_timed_quest(Player, quest, quest_count) + { + var lowest_time = 100000 + var lowest_time_id = 0 + var lowest_time_guild_name = "" + var pers_time = 0 + + for (const guild_info of this.guild_list) + { + var guild = await this.init_guild_data(parseInt(guild_info.split(';')[1])) + for(const member_id of guild.guild_members.split('-')) + { + var raid_boss_quest = await this.Server.DB.metaService.getPersistentMeta(quest, parseInt(member_id)) + if (!raid_boss_quest) + { + await this.Server.DB.metaService.addPersistentMeta(quest, "0", parseInt(member_id)) + raid_boss_quest = await this.Server.DB.metaService.getPersistentMeta(quest, parseInt(member_id)) + } + if (parseFloat(raid_boss_quest.Value) < lowest_time && parseFloat(raid_boss_quest.Value) != 0) + { + lowest_time = parseFloat(raid_boss_quest.Value) + lowest_time_id = parseInt(member_id) + lowest_time_guild_name = guild.name + } + if (parseInt(member_id) == Player.ClientId) + { + pers_time = parseFloat(raid_boss_quest.Value) + } + } + } + + var customName = await this.Server.DB.metaService.getPersistentMeta('custom_name', lowest_time_id) + var name = await this.Server.getClient("@" + lowest_time_id.toString()).Name + if (customName) + name = customName.Value + var pers_time_txt = "^1No Data^7" + if (pers_time != 0) + pers_time_txt = pers_time + + var lowest_time_txt = "^1No Data^7" + if(lowest_time != 100000) + lowest_time_txt = lowest_time + + var index = 0 + + if (!Player.competitive_quest_count || Player.competitive_quest_count == 0) + { + Player.competitive_quest_count = 1 + } + else + { + Player.competitive_quest_count++ + index++ + } + + /* while (1) //wait to load everything before printing + { + if (Player.competitive_quest_count && Player.competitive_quest_count >= 2) + { + if (index > 0) + { + console.log("waiting") + await new Promise(resolve => setTimeout(resolve, 1500)) + } + + break; + } + await new Promise(resolve => setTimeout(resolve, 100)) + }*/ + + if (quest_count == 0) + { + Player.Tell("[^1Competitive Quests^7]") + await new Promise(resolve => setTimeout(resolve, 50)) + } + + var quest_txt = "" + var map_txt = "" + var maps = [] + maps[maps.length] = "transit" + maps[maps.length] = "tomb" + maps[maps.length] = "highrise" + maps[maps.length] = "prison" + maps[maps.length] = "buried" + + var gamemodes = [] + gamemodes[gamemodes.length] = "botb" + gamemodes[gamemodes.length] = "titb" + gamemodes[gamemodes.length] = "pia" + + + if (quest == "raid_boss_quest") + quest_txt = "^1Raid Boss^3 Quest^7" + else if (quest.includes("ee_speedrun_quest")) + { + if (quest == "ee_speedrun_quest_transit") + quest_txt = "^1Tranzit EE Speedrun^3 Quest^7" + if (quest == "ee_speedrun_quest_buried") + quest_txt = "^1Buried EE Speedrun^3 Quest^7" + if (quest == "ee_speedrun_quest_tomb") + quest_txt = "^1Origins EE Speedrun^3 Quest^7" + if (quest == "ee_speedrun_quest_prison") + quest_txt = "^1MOTD EE Speedrun^3 Quest^7" + if (quest == "ee_speedrun_quest_highrise") + quest_txt = "^1Die Rise EE Speedrun^3 Quest^7" + } + else if (quest.includes("gamemode_speedrun_quest")) + { + if (quest == "gamemode_speedrun_quest_pia") + quest_txt = "^1PiA Speedrun^3 Quest (^6GigaChad^7)^7" + if (quest == "gamemode_speedrun_quest_botb") + quest_txt = "^1BotB Speedrun^3 Quest (^6GigaChad^7)^7" + if (quest == "gamemode_speedrun_quest_titb") + quest_txt = "^1TitB Speedrun^3 Quest (^6GigaChad^7)^7" + } + + + Player.Tell("---- " + map_txt + quest_txt + " ----") + await new Promise(resolve => setTimeout(resolve, 50)) + if (lowest_time == 100000) + Player.Tell("No ^6Guild^7 have set a record for this ^3quest^7 yet.") + else + Player.Tell("^3Best time^7: ^2" + lowest_time_txt + "^7 minutes by " + name + "^7 from " + lowest_time_guild_name + " guild.") + await new Promise(resolve => setTimeout(resolve, 50)) + if (lowest_time_id == Player.ClientId) + Player.Tell("^3Poggy^7 ! You have the ^2lead^7 !") + else if (pers_time == 0) + Player.Tell("You did not complete this ^3quest^7 yet.") + else + Player.Tell("^3Your time^7: ^2" + pers_time_txt + "^7 minutes.") + + if (Player.competitive_quest_count && Player.competitive_quest_count >= 2) //start loading basic quest + { + Player.competitive_quest_count = 0 + Player.competitive_quest_ended = 1 + } + } + + async print_basic_score_quest(Player, quest, quest_count, quest_array) + { + while (1) + { + if(Player.competitive_quest_ended && Player.competitive_quest_ended == 1) + break; + await new Promise(resolve => setTimeout(resolve, 100)) + } + + var inGame = Utils.findClient(Player.ClientId, this.Managers) + var count = 0; + var pers = 0; + var guild = await this.init_guild_data(Player.ClientId) + var is_quest_completed = false; + for(const member_id of guild.guild_members.split('-')) + { + var quest_metadata = await this.Server.DB.metaService.getPersistentMeta(quest, parseInt(member_id)) + if (!quest_metadata) + { + await this.Server.DB.metaService.addPersistentMeta(quest, "0", parseInt(member_id)) + quest_metadata = await this.Server.DB.metaService.getPersistentMeta(quest, parseInt(member_id)) + } + if (quest_metadata.Value == "-1") + { + console.log(quest + " already completed") + is_quest_completed = true + break + } + + if (parseInt(member_id) == Player.ClientId) + pers = parseInt(quest_metadata.Value) + count += parseInt(quest_metadata.Value) + } + + if (quest_count == 2) + { + if (inGame) + await new Promise(resolve => setTimeout(resolve, 5000)) + Player.Tell("\n[^2Basic Quests^7]") + await new Promise(resolve => setTimeout(resolve, 50)) + } + + var quest_txt = "" + var type_txt = "" + var req_txt = "" + if (quest == "kill_quest") + { + quest_txt = "^2Kill ^3Quest^7" + type_txt = "Kills" + req_txt = 15000 + } + else if (quest == "headshot_quest") + { + quest_txt = "^2Headshot ^3Quest^7" + type_txt = "Headshots" + req_txt = 5000 + } + else if (quest == "gamemode_completion_quest") + { + quest_txt = "^2Gamemode Completion ^3Quest^7" + type_txt = "Gamemodes completed" + req_txt = 30 + } + else if (quest == "ee_completion_quest") + { + quest_txt = "^2EE Completion ^3Quest^7" + type_txt = "EE completed" + req_txt = 30 + } + + Player.Tell("---- " + quest_txt + " ----") + await new Promise(resolve => setTimeout(resolve, 50)) + + if (is_quest_completed == true) + { + Player.Tell("^2Quest completed !^7") + return + } + + if (count >= req_txt) + { + //give quest rewards + await this.add_guild_xp(Player.ClientId, 25) + await this.edit_guildmate_metadata(guild, quest, "-1") + Player.Tell("^2Quest completed ! ^5XP granted ^7") + return + } + + Player.Tell("Your ^6Guild score^7 : ^2" + count + " ^7/ ^1" + req_txt + "^3 " + type_txt) + await new Promise(resolve => setTimeout(resolve, 50)) + Player.Tell("Your ^6score^7 : ^2" + pers + "^3 " + type_txt) + + if (quest_count + 1 == quest_array.length) // if last quest, reset wait/load system + { + Player.competitive_quest_ended = 0 + } + } + + async add_timed_quest_metadata(quest) + { + var highest_kill = 0 + var highest_kill_id = 0 + + var ig_quest_dvar = await this.Server.Rcon.getDvar(`${quest}`) + var ig_quest = ig_quest_dvar.split(';') + + await this.Server.Rcon.setDvar(`${quest}`, "0") + console.log("quest completed ! " + quest ) + + + if (quest == "raid_boss_quest") + { + for (const client of await this.Manager.Server.getClients()) + { + if (client) + { + var guild_data = await this.Server.DB.metaService.getPersistentMeta('guild_data', client.ClientId) + if (!guild_data) + { + continue + } + var quest_data = await this.Server.DB.metaService.getPersistentMeta(quest, client.ClientId) + if (quest_data && (parseFloat(ig_quest[0]) < parseFloat(quest_data.Value) || parseFloat(quest_data.Value) == 0)) + await this.Server.DB.metaService.addPersistentMeta(quest, ig_quest[0], client.ClientId) + } + } + return + } + for (const client of await this.Manager.Server.getClients()) + { + if (client) + { + var guild_data = await this.Server.DB.metaService.getPersistentMeta('guild_data', client.ClientId) + if (!guild_data) + { + continue + } + + for (const p_data of ig_quest) + { + if (client.Guid == parseInt(p_data.split('-')[0])) //works cuz 1st value is the completion time and does not have a '-', hence [0] exist + { + if (highest_kill < parseInt(p_data.split('-')[1])) + { + highest_kill = parseInt(p_data.split('-')[1]) + highest_kill_id = client.ClientId + } + } + } + } + } + if (highest_kill_id == 0) + { + this.Server.Rcon.executeCommandAsync(`set bold ^1Error, please contact staff.`) + await new Promise(resolve => setTimeout(resolve, 6000)) + console.log("run invalid") + return + } + console.log("winner id : " + highest_kill_id + " winner kills : " + highest_kill) + var quest_data = await this.Server.DB.metaService.getPersistentMeta(quest, highest_kill_id) + if (quest_data && (parseFloat(ig_quest[0]) < parseFloat(quest_data.Value) || parseFloat(quest_data.Value) == 0)) + await this.Server.DB.metaService.addPersistentMeta(quest, ig_quest[0], highest_kill_id) + } + + /*async add_round_quest_metadata(quest) + { + var ig_quest = await this.Server.Rcon.getDvar(`${quest}`) + var ig_quest = ig_quest_dvar.split(";") + await this.Server.Rcon.setDvar(`${quest}`, "0") + for (const client of await this.Manager.Server.getClients()) + { + if (client) + { + var quest_data = await this.Server.DB.metaService.getPersistentMeta(quest, client.ClientId) + if (quest_data && (parseFloat(ig_quest[0]) > parseFloat(quest_data.Value) || parseInt(quest_data.Value) == 0)) + await this.Server.DB.metaService.addPersistentMeta(quest, ig_quest[0], client.ClientId) + } + + } + }*/ + + async guildQuestWatcher() + { + var maps = [] + maps[maps.length] = "transit" + maps[maps.length] = "tomb" + maps[maps.length] = "highrise" + maps[maps.length] = "prison" + maps[maps.length] = "buried" + + var gamemodes = [] + gamemodes[gamemodes.length] = "botb" + gamemodes[gamemodes.length] = "titb" + gamemodes[gamemodes.length] = "pia" + await new Promise(resolve => setTimeout(resolve, 5000)) + while (1) + { + if (await this.Server.Rcon.getDvar(`raid_boss_quest`) != "0") + { + await this.add_timed_quest_metadata("raid_boss_quest") + } + for (const map of maps) + { + if (await this.Server.Rcon.getDvar(`ee_speedrun_quest_${map}`) != "0") + { + await this.add_timed_quest_metadata("ee_speedrun_quest_" + map) + } + } + for (const gamemode of gamemodes) + { + if (await this.Server.Rcon.getDvar(`gamemode_speedrun_quest_${gamemode}`) != "0") + { + await this.add_timed_quest_metadata("gamemode_speedrun_quest_" + gamemode) + } + } + + /* if (await this.Server.Rcon.getDvar(`first_room_hr_quest`) != "0") + { + await this.add_round_quest_metadata("first_room_hr_quest") + }*/ + await new Promise(resolve => setTimeout(resolve, 3000)) + } + } + + async modifierWatcher() + { + await new Promise(resolve => setTimeout(resolve, 5000)) + if(!(this.Manager.Server.Hostname) || this.Manager.Server.Hostname.includes('BURIED') || this.Manager.Server.Hostname.includes('NUKETOWN') || this.Manager.Server.Hostname.includes('RISE')) + { + return + } + + for(;;) + { + var modif = 0 + var restart = await this.Server.Rcon.getDvar(`restart1`) + if (restart && restart != "0") + { + await this.Server.Rcon.setDvar(`restart1`, "0") + for (const client of await this.Manager.Server.getClients()) + { + if (client) + { + var guild = await this.init_guild_data(client.ClientId) + if (guild && guild.level >= 8) + { + if(this.Manager.Server.Hostname && (await this.is_brutus() == true || this.Manager.Server.Hostname.includes('PANZER') + || this.Manager.Server.Hostname.includes('BUS'))) + { + await this.Server.Rcon.setDvar(`guild_modifier`, "1") + this.Server.Rcon.executeCommandAsync(`set ln ^2+1 modifier^7 from ^6Guild ${guild.name}^7`) + modif = 1 + } + } + if (guild && guild.level >= 3) + { + if(this.Manager.Server.Hostname && this.is_raid() == true) + { + await this.Server.Rcon.setDvar(`skill_cooldown`, "1") + this.Server.Rcon.executeCommandAsync(`set ln ^2+33% Skill Haste^7 from ^6Guild ${guild.name}^7`) + } + + } + if (guild && guild.level >= 10) + { + await new Promise(resolve => setTimeout(resolve, parseInt(client.Clientslot) * 250)) + await this.Server.Rcon.executeCommandAsync(`set hat ${client.Guid}`) + } + + } + } + if (modif == 0) + await this.Server.Rcon.setDvar(`guild_modifier`, "2") + } + await new Promise(resolve => setTimeout(resolve, 1000)) + } + } + + async is_brutus() + { + for(const port of this.botb_port) + { + if (port == await this.Server.Rcon.getDvar("net_port")) + return true + } + return false + } + + async is_raid() + { + for(const port of this.raid_port) + { + if (port == await this.Server.Rcon.getDvar("net_port")) + return true + } + return false + } +} + + + +module.exports = Plugin \ No newline at end of file diff --git a/node-server-manager/Plugins/ZombiesLocker.js b/node-server-manager/Plugins/ZombiesLocker.js new file mode 100644 index 0000000..fe97180 --- /dev/null +++ b/node-server-manager/Plugins/ZombiesLocker.js @@ -0,0 +1,187 @@ +const path = require('path') +const Utils = new (require(path.join(__dirname, '../Utils/Utils.js')))() +const Localization = require(path.join(__dirname, `../Configuration/Localization-${process.env.LOCALE}.json`)).lookup +const { Command } = require(path.join(__dirname, `../Lib/Classes.js`)) +const wait = require('delay') +const Sequelize = require('sequelize') + +class Plugin { + constructor(Server, Manager, Managers) { + this.Server = Server + this.Manager = Manager + this.Managers = Managers + this.lockerCost = 100000 + this.defaultLockerSize = 1 + this.Server.on('preconnect', this.onPlayerConnect.bind(this)) + this.Server.on('connect', this.onPlayerConnect.bind(this)) + this.Server.on('line', this.onLine.bind(this)) + this.Server.on('dvars_loaded', this.init.bind(this)) + } + async onLine(line) { + line = line.trim().replace(new RegExp(/([0-9]+:[0-9]+)\s+/g), '') + if (Utils.isJson(line)) { + var lockerEvent = JSON.parse(line) + + switch (lockerEvent.event) { + case 'locker_set': + if (!lockerEvent.player) return + + var Player = this.Server.Clients.find(c => c && c.Guid == lockerEvent.player.Guid) + + if (!Player) return + + if (Player.getSelectedLocker == undefined + || Player.updateLocker == undefined) return + + if (!lockerEvent.weapondata) { + Player.getSelectedLocker().weaponData = {} + Player.updateLocker() + return + } + + Player.getSelectedLocker().weaponData = lockerEvent.weapondata + Player.updateLocker() + break + } + } + } + async onPlayerConnect(Player) { + var locker = await this.Server.DB.metaService.getPersistentMeta('locker', Player.ClientId) + + if (!locker || !locker.Value) { + locker = {} + locker.Value = { + weapons: (new Array(this.defaultLockerSize)).fill({ + weaponData: {}, + selected: false + }) + } + + locker.Value.weapons[0].selected = true + locker.Value = JSON.stringify(locker.Value) + + await this.Server.DB.metaService.addPersistentMeta('locker', locker.Value, Player.ClientId) + } + + Player.locker = JSON.parse(locker.Value) + Player.getSelectedLocker = () => { + return Player.locker.weapons.find(w => w && w.selected) + } + + Player.updateLocker = () => { + this.Server.DB.metaService.addPersistentMeta('locker', JSON.stringify(Player.locker), Player.ClientId) + var value = Object.values(Player.getSelectedLocker().weaponData).length + ? Object.values(Player.getSelectedLocker().weaponData).toString() + : 'undefined' + + this.Server.Rcon.setDvar(`${Player.Guid}_update`, value) + this.Server.Rcon.setDvar(`${Player.Guid}_weapondata`, value) + } + + if (!Utils.isJson(locker.Value) || !Player.getSelectedLocker().weaponData) { + this.Server.Rcon.setDvar(`${Player.Guid}_weapondata`, 'undefined') + return + } + + this.Server.Rcon.setDvar(`${Player.Guid}_weapondata`, Object.values(Player.getSelectedLocker().weaponData).toString()) + } + async addPlayerMoney(ClientId, Money) { + return await this.Server.DB.Models.NSMZombiesStats.update( + {Money : Sequelize.literal(`Money + ${Money}`)}, + {where: {ClientId: ClientId}}) + } + async getPlayerMoney(ClientId) { + return (await this.Server.DB.Models.NSMZombiesStats.findAll({ + where: { + ClientId + }, + raw: true + }))[0].Money + } + async init () { + var buyLocker = new Command() + .setName('buylocker') + .addCallback(async (Player) => { + if (!this.Server.DB.Models.NSMZombiesStats) { + return + } + + var cost = this.lockerCost * Math.pow(2, Player.locker.weapons.length) + + if ((await this.getPlayerMoney(Player.ClientId)) < cost) { + Player.Tell(Localization['ZBANK_BALANCE_ERROR']) + return + } + + await this.addPlayerMoney(Player.ClientId, cost * -1) + + Player.locker.weapons.push({ + weaponData: {}, + selected: false + }) + + Player.updateLocker() + Player.Tell(Utils.formatString(Localization['LOCKER_PURCHASE_SUCCESS'], {cost}, '%')[0]) + }) + + if (this.Server.Gametype == 'zclassic') + this.Manager.Commands.add(buyLocker) + + var lockerCmd = new Command() + .setName('locker') + .addParam({ + name: 'slot', + optional: true + }) + .addCallback(async (Player, params) => { + if (params.slot) { + params.slot = parseInt(params.slot) + + if (Player.locker.weapons[params.slot] == undefined) { + Player.Tell(Localization['LOCKER_INVALID_SLOT']) + return + } + + for (var i = 0; i < Player.locker.weapons.length; i++) { + Player.locker.weapons[i].selected = false + } + + Player.Tell(Player.locker.weapons[params.slot].weaponData.name + ? Utils.formatString(Localization['LOCKER_SELECT_SLOT'], { + slot: params.slot, + weaponName: Player.locker.weapons[params.slot].weaponData.name, + clip: Player.locker.weapons[params.slot].weaponData.clip, + stock: Player.locker.weapons[params.slot].weaponData.stock + }, '%')[0] + : Utils.formatString(Localization['LOCKER_SELECT_SLOT_EMPTY'], {slot: params.slot}, '%')[0]) + + Player.locker.weapons[params.slot].selected = true + Player.updateLocker() + return + } + + for (var i = 0; i < Player.locker.weapons.length; i++) { + Player.locker.weapons[i] && Player.locker.weapons[i].weaponData.name + ? Player.Tell(Utils.formatString(Localization['COMMAND_LOCKER_FORMAT'], { + weaponName: Player.locker.weapons[i].weaponData.name, + clip: Player.locker.weapons[i].weaponData.clip, + stock: Player.locker.weapons[i].weaponData.stock, + slot: i, + color: Player.locker.weapons[i].selected ? '^2' : '^7' + }, '%')[0]) + : Player.Tell(Utils.formatString(Localization['LOCKER_SLOT_EMPTY'], { + color: Player.locker.weapons[i].selected ? '^2' : '^7', + slot: i + }, '%')[0]) + await wait(500) + } + + Player.Tell(Utils.formatString(Localization['LOCKER_UNK_SLOT'], { cost: this.lockerCost * Math.pow(2, Player.locker.weapons.length) }, '%')[0]) + }) + + if (this.Server.Gametype == 'zclassic') + this.Manager.Commands.add(lockerCmd) + } +} + +module.exports = Plugin \ No newline at end of file diff --git a/node-server-manager/Plugins/ZombiesStats.js b/node-server-manager/Plugins/ZombiesStats.js new file mode 100644 index 0000000..d3d8d86 --- /dev/null +++ b/node-server-manager/Plugins/ZombiesStats.js @@ -0,0 +1,390 @@ +const Sequelize = require('sequelize') +const path = require('path') +const Permissions = require(path.join(__dirname, `../Configuration/NSMConfiguration.json`)).Permissions +const Localization = require(path.join(__dirname, `../Configuration/Localization-${process.env.LOCALE}.json`)).lookup +const Utils = new (require(path.join(__dirname, '../Utils/Utils.js')))() +const { emitKeypressEvents } = require('readline') +const { Command } = require(path.join(__dirname, `../Lib/Classes.js`)) + + + + +class Plugin { + constructor (Server, Manager, Managers) { + //add the .pguid of players to grant them staff permissions (must be done on ClanTag, ZombiesBank, ZombiesStats, NativeCommands & the gsc script staff.gsc) + this.staff_list_a = [564391] + this.Server = Server + this.Manager = Manager + this.Managers = Managers + this.Server.on('connect', this.onPlayerConnect.bind(this)) + this.zStats() + // this.getKills() + } + async onPlayerConnect(Player) { + if ((await this.getZStats(Player.ClientId))) return + await this.NSMZStats.build({ + ClientId: Player.ClientId + }).save() + } + async createTable() { + this.NSMZStats = this.Server.DB.Models.DB.define('NSMZStats', + { + ClientId: { + type: Sequelize.INTEGER, + autoIncrement: true, + allowNull: false, + primaryKey: true, + references: { + model: 'NSMClients', + key: 'ClientId' + } + }, + Kills: { + type: Sequelize.INTEGER, + defaultValue: 0, + allowNull: false + }, + Score: { + type: Sequelize.INTEGER, + defaultValue: 0, + allowNull: false + }, + Downs: { + type: Sequelize.INTEGER, + defaultValue: 0, + allowNull: false + }, + Revives: { + type: Sequelize.INTEGER, + defaultValue: 0, + allowNull: false + }, + Headshots: { + type: Sequelize.INTEGER, + defaultValue: 0, + allowNull: false + }, + HighestRound: { + type: Sequelize.INTEGER, + defaultValue: 0, + allowNull: false + }, + Event: { + type: Sequelize.INTEGER, + defaultValue: 0, + allowNull: false + }, + Easter: { + type: Sequelize.INTEGER, + defaultValue: 0, + allowNull: false + }, + }, { + timestamps: false + }) + this.NSMZStats.sync() + this.Server.DB.Models.NSMZStats = this.NSMZStats + } + + async getTopStats(page, limit) { + var Stats = (await this.NSMZStats.findAll({ + limit: limit, + offset: page * limit, + attributes: ['ClientId', 'Kills', 'Downs', 'Revives', 'HighestRound', 'Headshots', 'Score', [Sequelize.literal('ROW_NUMBER() over (order by Score desc)'), 'Rank']], + order: [ + ['Score', 'desc'] + ] + })).map(x => x = x.dataValues) + + for (var i = 0; i < Stats.length; i++) { + Stats[i].Name = await this.Server.DB.getName(Stats[i].ClientId) + } + + return Stats + } + async updateStats(Client, Stats, Round = 0) { + Object.entries(Stats).forEach(Stat => { + if (!Client.previousStats) return + if (Stat[1] < Client.previousStats[Stat[0]]) { + Client.previousStats = null + } + }) + + if (!Client.previousStats) { + Client.previousStats = Stats + return + } + + var newStats = { + Kills: Stats.Kills - Client.previousStats.Kills, + Revives: Stats.Revives - Client.previousStats.Revives, + Downs: Stats.Downs - Client.previousStats.Downs, + Score: Stats.Score - Client.previousStats.Score, + Headshots: Stats.Headshots - Client.previousStats.Headshots, + HighestRound: Round + } + + Client.previousStats = {...Stats, Round} + + this.NSMZStats.update({ + Kills: Sequelize.literal(`Kills + ${newStats.Kills}`), + Downs: Sequelize.literal(`Downs + ${newStats.Downs}`), + Revives: Sequelize.literal(`Revives + ${newStats.Revives}`), + Score: Sequelize.literal(`Score + ${newStats.Score}`), + Headshots: Sequelize.literal(`Headshots + ${newStats.Headshots}`) + }, + {where: {ClientId: Client.ClientId}}) + + if (Round) { + this.NSMZStats.update({ + HighestRound: Round, + }, { where: { + ClientId: Client.ClientId, + HighestRound: { + [Sequelize.Op.lt]: Round + } + }}) + } + } + async getKills(client) + { + //var ClientId = client.ClientId + var Stats = (await this.NSMZStats.findAll({where: client.ClientId})).map(x => x = x.dataValues) + console.log(client.Name + " " + Stats.Kills); + } + async getZStats(ClientId) { + var Stats = (await this.NSMZStats.findAll({where: ClientId})).map(x => x = x.dataValues) + return Stats.length > 0 ? Stats[0] : false + } + async print_servers(manager, Player, delay) + { + await new Promise(resolve => setTimeout(resolve, delay * 500)) + if (manager && manager.Server.Hostname) + { + if(!(manager.Server.Hostname.includes('PRIVATE'))) + { + Player.Tell(`^2.king^7 ^2${manager.Server.Hostname.split(" ")[2]} ^3`) + } + } + } + async king_lock_check(manager, Player) + { + var guild_quest = await this.Server.DB.metaService.getPersistentMeta('guild_quest', 12) + if(guild_quest.Value.split(";")[1] == "gamemode_speedrun_quest_pia" && (manager.Server.Hostname.includes('PANZER')) + || guild_quest.Value.split(";")[1] == "gamemode_speedrun_quest_titb" && (manager.Server.Hostname.includes('BUS')) + || guild_quest.Value.split(";")[1] == "gamemode_speedrun_quest_botb" && (manager.Server.Hostname.includes('BRUTUS')) + || guild_quest.Value.split(";")[1] == "ee_speedrun_quest_transit" && (manager.Server.Hostname.includes('TRANZIT2')) + || guild_quest.Value.split(";")[1] == "ee_speedrun_quest_highrise" && (manager.Server.Hostname.includes('DIE RISE')) + || guild_quest.Value.split(";")[1] == "ee_speedrun_quest_prison" && (manager.Server.Hostname.includes('MOTD')) + || guild_quest.Value.split(";")[1] == "ee_speedrun_quest_buried" && (manager.Server.Hostname.includes('BURIED')) + || guild_quest.Value.split(";")[1] == "ee_speedrun_quest_tomb" && (manager.Server.Hostname.includes('ORIGINS')) + || manager.Server.Hostname.includes('RAID')) + { + Player.Tell("Cannot king a ^1Competitive Server^7.") + return + } + if (await manager.Server.Rcon.getDvar(`king_lock`) == "1") + { + Player.Tell("This server is ^1too advanced^7 to ^3.king^7, please wait a few minutes.") + await manager.Server.Rcon.setDvar('ln', "^5King^7 request ^1denied^7. Too far into the game.") + return + } + if (await manager.Server.Rcon.getDvar(`is_first_room`) == "1") + { + Player.Tell("Cannot .king into a first room challenge.") + await manager.Server.Rcon.setDvar('ln', "^5King^7 request ^1denied^7. First room protection") + return; + } + Player.Data.lastKing = new Date() + var king2 = await this.Server.DB.metaService.getPersistentMeta('king2', Player.ClientId) + var king3 = await this.Server.DB.metaService.getPersistentMeta('king3', Player.ClientId) + var king4 = await this.Server.DB.metaService.getPersistentMeta('king4', Player.ClientId) + if (king4) + await manager.Server.Rcon.executeCommandAsync(`set king ${Player.Name};${Player.ClientId};4`) + else if (king3) + await manager.Server.Rcon.executeCommandAsync(`set king ${Player.Name};${Player.ClientId};3`) + else if (king2) + await manager.Server.Rcon.executeCommandAsync(`set king ${Player.Name};${Player.ClientId};2`) + else + await manager.Server.Rcon.executeCommandAsync(`set king ${Player.Name};${Player.ClientId};1`) + console.log("king dvar set") + } + + async is_staff(Player) + { + for (var i = 0; i < this.staff_list_a.length; i++) + if (this.staff_list_a[i] == Player.Guid) + return true + Player.Tell("hehe boi u tryna scam da kiels by using staff cmd?") + return false + } + + async zStats() { + this.Manager.on('webfront-ready', (Webfront) => { + Webfront.addHeaderHtml(``, 3) + }) + + await this.createTable() + this.Manager.commands['king'] = { + ArgumentLength: 0, + inGame: false, + logToAudit: false, + Permission: Permissions.Commands.COMMAND_USER_CMDS, + callback: async (Player, args) => { + if (!args[1]) + { + Player.Tell("^3Usage^7 : ") + await new Promise(resolve => setTimeout(resolve, 300)) + var i = 0; + this.Managers.forEach(manager => + { + this.print_servers(manager, Player, i); + i++ + }) + return + } + var king = await this.Server.DB.metaService.getPersistentMeta('king', Player.ClientId) + var isServerFound = false; + + var king2 = await this.Server.DB.metaService.getPersistentMeta('king2', Player.ClientId) + var king3 = await this.Server.DB.metaService.getPersistentMeta('king3', Player.ClientId) + var king4 = await this.Server.DB.metaService.getPersistentMeta('king4', Player.ClientId) + + if (king4 && Player.Data && Player.Data.lastKing && (new Date() - Player.Data.lastKing) / 1000 < 60) { + Player.Tell("wait up to 1 min to use .king again") + return + } + else if (king3 && Player.Data && Player.Data.lastKing && (new Date() - Player.Data.lastKing) / 1000 < 180) { + Player.Tell("wait up to 3 mins to use .king again") + return + } + else if (king2 && Player.Data && Player.Data.lastKing && (new Date() - Player.Data.lastKing) / 1000 < 300) { + Player.Tell("wait up to 5 mins to use .king again") + return + } + else if (king && Player.Data && Player.Data.lastKing && (new Date() - Player.Data.lastKing) / 1000 < 900) { + Player.Tell("wait up to 15 mins to use .king again") + return + } + if (king || king2 || king3 || king4 || await this.is_staff(Player) == true) + { + this.Managers.forEach(manager => + { + if (manager && manager.Server.Hostname) + { + if((manager.Server.Hostname.includes('ORIGIN'))) //event + { + Player.Tell("^3.king ^1temp disabled^7 on origins due to ^3ongoing event") + return + } + if(!(manager.Server.Hostname.includes('PRIVATE'))) + { + var serverName = "" + if (manager.Server.Hostname.split(" ")[2]) + { + var serverName = manager.Server.Hostname.split(" ")[2].toLocaleLowerCase() + } + if (serverName == args[1].toLocaleLowerCase()) + { + isServerFound = true + if (!king2 && !king3 && !king4 && serverName == this.Manager.Server.Hostname.split(" ")[2].toLocaleLowerCase()) + { + Player.Tell("You are ^3already connected^7 to this ^3server.") + return + } + if (manager.Server.getClients().length != manager.Server.MaxClients) + { + Player.Tell(`^3${args[1]} is not full`) + return + } + this.king_lock_check(manager, Player); + return + + } + } + } + }) + if (isServerFound == false) + { + Player.Tell("^3Server not found. use ^2.king ^3to see the ^5list of servers") + return + } + } + else + { + Player.Tell("^1King^7 command only. Earn it in events") + } + } + } + + + this.Manager.commands['zstats'] = { + ArgumentLength: 0, + inGame: false, + logToAudit: false, + Permission: Permissions.Commands.COMMAND_USER_CMDS, + callback: async (Player, args) => { + var Client = args[1] ? await this.Server.getClient(args[1]) : Player + if (!Client) { + Player.Tell(Localization['COMMAND_CLIENT_NOT_FOUND']) + return + } + + var Stats = await this.getZStats(Client.ClientId) + if (!Stats) { + Player.Tell(Localization['STATS_NOT_EXIST']) + return + } + + Stats.Player = Client.Name + var formattedStats = Utils.formatString(Localization['COMMAND_ZSTATS_FORMAT'], Stats, '%'); + formattedStats.forEach(async line => { + await Player.Tell(line) + }) + } + } + + this.Server.on('connect', async (Client) => { + Client.previousStats = null + Client.on('round_start', async (Round, Stats) => { + await this.updateStats(Client, Stats, Round) + }) + Client.on('update_stats', async (Round, Stats) => { + await this.updateStats(Client, Stats, Round) + }) + }) + + this.Server.on('line', async (data) => { + data = data.trim().replace(new RegExp(/([0-9]+:[0-9]+)\s+/g), '') + if (Utils.isJson(data) && JSON.parse(data).event) { + var event = JSON.parse(data) + switch (event.event) { + case 'round_start': + this.Server.emit('round_start', event.round) + this.roundNumber = event.round + event.players.forEach(Player => { + this.Server.Clients.forEach(async Client => { + if (!Client) return + if (Client.Guid == Player.Guid) { + Client.emit('round_start', event.round, Player.Stats) + } + }) + }) + break + case 'player_downed': + case 'player_revived': + case 'update_stats': + this.Server.Clients.forEach(async Client => { + if (!Client) return + if (Client.Guid == event.player.Guid) { + Client.emit('update_stats', null, event.player.Stats) + } + }) + break + } + } + }) + } +} + +module.exports = Plugin diff --git a/t6/compiled/t6/_zm_ai_brutus.gsc b/t6/compiled/t6/_zm_ai_brutus.gsc new file mode 100644 index 0000000000000000000000000000000000000000..d4d34f6e1236c629a01902c1dd0d280b127feffd GIT binary patch literal 48630 zcmd_Tdz{tPb^pD;=bV{=;Wi?-Ga`=2W#lFx8G#uXKtu#YL_~sy!uNX69f}>9wvuC3*7k^}7 z?lWeZDTuU~4<)s4J^U zC6cw}$(E+%+S@8uhrAX_)Yep0w-{5~kgTX&ZEQV>%GzXewM|K+Dl1dvEx%=L&5g-b z^}d#Nfr?bJrTVw5r7GF%>u5N>rz6>ryS@RMj<9q-srFW1=ZpQIl+` zX{b+BGc93yGx=+qt7UNQGS#Ij+DFtjtTIdQyLZMtcO~ZCcjw%@W+v{u?}0_>dRm%l z>Z`7iBQbvL*s<4&pYSp9MH26nr8(8o+L$PBsB5fEwWJKXQHL z-+X05Q@Jbb27?Z(I!MFKElsWE*JwM@*w9=f)vH*UiJJPBR8vx0Ow_UJYgU`)`U+cP zO>;}KcBLqRYoR)otYuxc3sD0SPBy1}bW=lXeFZbzTHoTMFc2+nc$(_t+hwXtu5Mqd zB3YNLN+npU<;c;Ov8y40g13ZXL<#B`8DnWqAQz@k%!lh{Bf7v8e{6EPm|JMBT(UOV z#6ql2)|ZE4tE;KUB6g0?jI#o%%jmLn0+oNue@{rc_vo(^y1o8}+@gGHYfiSfl!sn>!U@qCDB? zv$@5WsAz4nn&)KQDc*_H$BX4^Z8r6-%vvkPD$$G*rTmJsE5a2K8QDB#sg_l#RDGhX zVYTf~IQ^;BjkTzCTPopHMs&dGNn=CU+fLa!YHnq+h6R>rM0uJMEe(m5RBft}74C;y z(SY@7sBNffZKn`+-C~r}>s)618qsdGCz6#cI<&OiNEv7q#;DS?)+DNuSo}4ODYMo_ zIbn#>SGCsrVX_nWt~s+-)sU=p!eucSCxeE{O2ZOwXfjQyDzu0NRa=98R@S6y*%M^v zuWNLhe{*{$!Pl=n#S*Y>Rn?S>h4Hhc1|)@Q+689RXv?Bqi9IQ=u0ea+lC?Dz-tuaS z##oiH`OBM-iP*P<{cpP>>BLUuP`FMFq@!#LnI=wz+H8nPsCYAyj1JM-O=Q9-Mbp?8 zY8skqTGkl099c#TiX=%%*4NZwAlbx3BQ;H;4EsV&<(fo2Q;4I)!mAMB%Qh`L27VPA zv*xZ~WtkMVG98bZ51V#k(;?FV-56BxVGc$j6Cpc>GS)(rH#DUTrCL)qCCqMJ4nJg@ zXqB|A2B%3@V@pjP1_IS@E>G5`Ol!S%w7j7i_akFQLt(Uw)IeGej3qPK4M#eh8Qt8j zV%x>^e5*1@Yt41|n2C-FR#$AA%D%FOvD0vej2UfrNNF}5BH9Z{W^HYP^@9NxtqHfv zHOW;z8Yel-0-uq>TsNjWuOa!58;o|CzG{@!cM*;Rn@u{Ou`1q_tkb$wz8O)LZ7+3Q z08$`h-031nJe@%b8hX9jkH+m4>2CXovW8?6K8ntR@4DYu(!F;vm}aRNBc}!0i7s4G zj8=V|m8mt&CfVGaN?Tg1mZ7nA!G>nTTCA$6r*~!PgA7L5SyBeJrdiyNWQ+H63`?}B zMJ$(dUaFJL-lKNrvAPCNB4cx?tHKDaOwo#LeY%dDTI?vOg|1246}3XzMH_9B ztrhskYTRU`wW%u1T~$3c0T-lJjI^u|m)Rwx>Qi-V+WTHL^~h~y4JE{zZo(U94tl5~=YUEa7P(#1h zqa#|%%iBu~88T%VcPCC3l{I(-mCRQ)6DCKO3U75%Yf_0SIkacav-HZINA10U?S7}q zTR3Jr+lk8BtaETtanD*CQD#$HQ@^sMLAC}&(!jAbT#qcz#?V*AU9pY~E)L$L9U5bm zAYNXTtXesF8oJs*-rA&TNm%p2xw}>T!78H);?vV!HsWhZ%BfNRYsFkuExw0WyV_K; zzBTmcy^2Yd;h9zSRMwhpM0GS{A;HSZavitz`s(dqbT#Vch2O?uUnkEQ+iPe_Vtj=P zO}Cx)HMzqR3yy8X)kr_-oSO+2E^_wMVrS8X7>2bOeo@ypaFCJN5ymzaj#;8~0Wyy= zbP^tDX=t3G*L?G&AhPF(&z51IWIMHJUFtlgg;X+={KTyp5$0}ulJttR*?k8EH<=@k|zq&iNQO8+S@3#!j$wA0%ojum^UNcS^^^=`o_& z*<*Ss-nFSutr8+lCX(V6VCGzrHj30{thS};{!B*g?*>j>hvCC0WrmvN=6Uo?vm8n#t%_1vfRkEg~MK$_w3av@~!nW%N$Tb;T{3%qYFgb;(wz?L^BNzd2c%V*XZ# z6Q&vbyleG|=GHQNa17b6sRJiYD>cp7Pa#U&7j zP6+2aZ!UZeDeRmwH}G~Ta>an*c3R+aa7`NeLt0*(t831Qt4p*#qpyB%#YePj$*ioe zsl+3}sbL9mCN_50U6o2U(sf+Y)-o)`Xe@i64ocRH6AeNobRJMD2^!Q zHG68UiY{+^RhOZpc4m>Z&4f9y-F62bxm9&OjT}YPJRvg%-Bi=eKGwc}*K`9p;LCjh zSDbRAmvA10xTXeSu{DNDWK}`>85%NwaFj{l7$RxvnX5l+-CJSRzHmcAx&$km8aQQX zkUUL(x3GrJ_gP0C-hkOqXbUrSw!H$2PID|Xc$?1hsiP!8F%;HGcV^V>1#aDlH*dwA z&gie?Y`i#Px=;A>Ob5F#dXDV5Hq%?J^c3?H<=&YRtr#e|W1)cBCZ^^Z{;*mPcR3n5 zeVId*69Z>Rxw7Tn*ewYyCB{b`0_nS&#Dq*gHcjtk)wFy2zE-Eho+Q?~2Lk5?*v3p< zLmMVco+t3&>T$^A6+`Y%w?U#@2eoUgBfRKDhKrYRVb|#jFMX`y&CY5| zM#*bwtGw+=3+YBNA)VS3XCSi=PEg76M_ai*L5XC4!b=nbmTIeNtwCVo-P?duKvTxZ zLo=-x0C;br;-OO7QiwglUTIfkn5Df3<}O6N$LOfI1zhTecbw_^I%c#J!i$ML$EGhF1FJGU*G3cR<7! z^O96v{=>CU#R`t>>Ig`%rh+>cu5D`U6uX-ZE?VmwDjGO5qX=A7*y|3rfw{)C557a` zk-F_d-BF)Y+z;LpWN}+TxSGU#tIH?`TE=6YS=q@o-r7EQUz|`O%Z%7+!;551$S{+( zD9cTHC_>^Gq{Adi50`Sq?6(BH7If!ce9YQ1xlHzYq`CDJ(R`abhgvb|{ZM7HUhfv| z)gp$ZhKJ&cgg-s9iHo#-AjGwXv!WwrUv?hZ5^rX=66V z71y0suUd7_Zc$~~jJdAR$1(J8Kr)so9CJ?divoE%cC?KEXvd?T8gDx6n? z?^YphY%QH_!lYBEscDVd&}wuxnbF~mo8bKKf^0+EyPO2S7DFMxEAkp?M?mm^@UbA9?LpX2P9kxs(BgetdnJz zjVu&Z84YSi*Bg6}o%TrOW>p$+l4f0@C1Kvm+BH7lM=Q6|CdIzgs5-0za~;!3_xm&B zkrm6^oj!58kO;=-&;%y6h8Ix1$>d%vb9Ey)?u`xFr8m6XcFC1-YaOlxcfUSbBkUTm z@AKU1lyRW60V_9Z<$X{uExj3WR>oGU&x<-|zdqTeqMuwth;a}nrb1j`{|cdQv%C^= z^TGp8=OdaZiab?0%Oe9uwOMb+tTtAX2@pmjBpmFMDth%j>Sw+Hq_AV~vT&L8`_p#)+|eVWJgDIs22b;rW;rIU1ABlbu>DxtqU6n%F462V3)DZ>m~( zkZ?v@9*o**SZaFC(NmVb2#Y~w8~3%kPa>=hvrlbIyj|U7UBwGr2ZdjSNo!c8D^hPf zm|!N|Pn)xbqTKDG4DT2Epw%wc9x>b^u&ujqq5R6Qk@o6@OQ}YEFE;v2Sy9mJ>P4D6^PBwHe zGWW*lw^Vm;qV-kit5=4Sp{DHaHj94XBwJ6jD`E+2u326b>_=hsm9;hcU56Y%d35BS zu(_eq-o3Qxl^&9)X<^B6&7+UlB167cs7GMp--K5n&Zp#ZM8CBP<1L5MMe%nuCGW5^>9OU zCg55NRz$1^C|Azj68RHK`|`GX;<;f&r224E;f9&5vtHu3h^T0m(J`$VkG=YCrHbRe z&@AbDq%S0*6i3jAV zX`W8kHFNXn?3~11wPhHyd3S~E!h2xn*7Jm%=18^=IyGzEafCb%aiP~@Gg+2gNmEr* z#vN^?Jge(N_?*P_`jy<1Yh{)tUwi4fF{$m5Z|Ll8iJbyFan3?kq{>>W^Z>+Z#os%M zSIP!o+bYKskx+SgD^^%P;AB5bso&S(4DIUkwis8THh-r@Wxob)VOh!`LZ2awb_OS78FCnx z4*}a{w{e~GitCYTs!z7sPm(%kXs%7kT5hP6h1|YQm(;lo%5P6~+J#Od@<&2tix??h+O72!>*}EAC@E=dVD5Ee-lDN4pZ~_|9d@t6Qs* zWvv~gZGg|=KzP-5pq)1n{@9PJ713Y z&|Q^RGr(XM!wI}!8oCWyIaO3 zJD(2Q)@{zrw&k3_(@_ndYS^zLGSVO%(!p*!kOU|bl8gh6GbRly(e&vzI(p# zY2kYYw*z%7JFAS%xBa?0RK?`1K61P<|2)o^UEuFW8gnmrZn!Z63XC~?qcJ@P8uNC( zG0WrR8(_>N@Xdb4eDOMCKH1Bdhq@S3$*+Sx2fhyWfb)Hf`D>{C8#X!@W{d`e>v6L& z0}Cbc|J%5tjDCGQ-!1HW(dgfXPmi@|bSy}Rj4A3-KwXKF91|NaGAMN6Zl*8sRxX93 zCGs{?q%r)CDlkU6nORS|>;utR#gf66xBsOcYOs=}&FFAb7}qHC!0ci(%)|m4%)f&! zm_i>kEwO+V}m4t!`g77I9%MW(w^H zVy=bkW7^fi>?NA5(8v4Q7*)Y^Z4b_v#u>`{R9hEQR}E$rGw)Vfn)l68n|G{jUv)7S zWShcUWUe#kyC_rcsxu{MNIJ5}O}y6kalCYozy2{xjTz+H?YIV`G%bxdeIO)#`9F?v z{pwJc#{Qmh*{7wenLX3xmeJGf!#N#tjP~n7u>1{|)0S=rq0#bMxDc zFYdIhexKDe*Y@j_#0-4^*vlJk%+gQMX@M8qW$ZyzYg~y-SCXMcBa=@ zA6pcUB}$NKEVxN_=F%J!k0}?AYJ5}zHeOjq)G#FH2)=2TUP@>GhC|C{O>ZX$0Hl@p(H^H_w{)#)B;((lw&St?4RsH{up}Dm z6AGxvx3NU})N8S3?;u6%pN2(Dkrx6bibhAn1mZ&{4L8YgXDG1%_>HUcp-0= z`Z*mrIv#i)#VPH9-uMXhAd!6cQ1Y~CtYRcex|(IeGhpY>PQeo^Fs9ga6W#N3brVsh z#Pm{cHta4wu}ErqIGT2S&g}ok^0puLzZvygbp6bTXXiaQ)T(m9G&?=( zGS@ciUUr9g%o~SrE+aC9qobKxzbY5XTinm^lY zyq@&A#pZf5I$L>HgO+!Bwp^FaqkN}4np+3dzlR;ywf-9&-mNg+UChAnT(l_Hcecbt zOf(Q-g;8dB*TQ&Lxx(O|n283Z=5u%m!@J>8#y{FM8~_uyUeHiDv=Vi)>$N5 z4m+mttWwv%Ec&#CXZu(>~3gM zGfT5_@$&Pl(zmZ)jd$~lDdW6O?a|P?qe3&v;6P2m-?9Fll~DBV;+QElU5SlH9vB`O zSU5c3MrZ$3LeYEF3Pm1pW0ISpcqCs2mLEj4$^KdCS&fDcrsR+oXXCkPixDkjTa4Kj zvEXryHu-LXw6k#w#&Rw#$6t=5DJ5I)?9xpaUWhfb)Xjp+cTC1eR`o#LkYzQPzxbJCC zicNv`9jl^YtU*Q_*o4yQ_{P3oH3y@)J09^m7mw)pXBGD&J}Vu+B(66sd5f);k+H#9iRq0;n3esT z#vY~V()CwG1$r$eGk?QacZ0Ad{7oB)`SxQh)_zD|{vljP{c|K+`tLDjjsB>_@)NdX zkq_&DW$hxZ(b2d+!HCC`t#(Dk;5ft*)3`*jSUVetMjxIpd3*}KBA%fQNs>4*I1}M1 z#)J+EW3qaz8sYjCYAx%@4Z-^{G63tHrf1Zx1RWcFwp8}=;(e+^;u&~Z$u>?ECf0TK zlx5HKP;7}3dbgfVQi&$ z{EyR7o9tyGyWkRC$$5)QO^w?T<`mCV+u+9}diK=S4E1B}-V{m<*!#_x6WUc)Dm>vtAcy4DIQ_$HH)OnE|{O*>AaaRMY64#_pXY37CH?W z!f{XZIT8;jHRRepud_6^{Lgh?w0l?Dkt`~GG2Pd|jv~%D=nmeb_*F~d(q!J^SU|G= z4U3JncMzIOy(clxqn&ROiy)*7_42|k~r9oK!@@9!CEGIA)5 z8vJy7)JXdXcA2tpF_XD?eCdn6nPIK-ww68bA&tVP-EJT`#y_pdq`$! zqMN0mDxpbJ*zuJULzBKouzQlquj@|_&YLo_bYFTd!nc%gsf#s>Tc^+4@u{I5w^mrs zvg-9snsS}kW7^Az)AVMdlQnme{hHy>ds)2PbFmUxFp3YNX9)v zrk`i?;(N;;R9umsvrc0v`88vabFbf#cqPUQi%NxlTQPgDx@&{dk)>bJJ;vW^*z=L} z0y(c~9yoaQUV)0gp zRLc|7i*w$l+l2;cDARubHas$WJFpT;%j|=zUaPRv8J;cnRGt&K`|YE0_8}|V?_HJi zT-@I3>$v6q!q>$7ls<@kOO)W1a_$e8nY*W-)XrW=MebfHyffDEmEuEYl-4*Zor3(a zH=1Z|{3O zB#nrz5L#kZqLH>W(JqM-Wc0CPJN7zTSNN>r-n#SKsQGb&ch(oF$_S)3`IhYXlc-QHr_g{^7 z*L%?J#pW5Q3Tx|?1qZTU~W*FLXydY3D$ zS$)Pz!3gjBj!kl_)8@cKY?njQu};LL`>b}%b^Lefx0R1|7_<)6UG)of&AFXM`OMhN z-NgD)?e7T3vjgeqU43|*8DZ)7tl};{jvLGA__ysxq&{_cyZ`^jnB+v`z25ZwCu=>* zTF<-$)zerRdaFY+`OHLmtmCkNqVK#l_;i&)hq;PJ?W&H-s+Kzhu@tU88WV|pnY+{9 zOBbanH)8`;N2CLS1or@v=)=}q2{^I(*u<2yuhhwB_+8e6_94OP=GrxjtR=xsGhISu&xIiF(h=WNK{&w1~}7M80zuQhU}va#OV z?-X_|x?G$^(uSWqc$fMKcW-Zla;tB-bg5E2RvB|TCi6s)d9L_3Zt3=YL{|OtevXty z7U~E`K55J&gk4sOVqd1X)C!{AHfG-CR#~Z>Y|Hlvf*nrux6Rg-CmnewKd2c{qJH zhCoCny=0bPe0k(1!E{*eg3?_@2c-RjQ~AEc>Z?Cbr{itCK0c!zH;XbzfQU5lq??*O9 z(lg;t>;4_b*W7-t+=$vqOxB6?&6gl773=EVHDg(1xxEJG5G2u=BkcG#ljPLvC#-#% zovqGOTP6$@-xXqzIiQ@kBNw{d##yreHL+^QPkR0fP&EaCO95#y_ zJf&zxEjB{z&hJu--MTXG!{RY-?W|RhEhcK);%g_~D(t&*MBnmQXB zEXed9;^vc_rw!jnv6lHyh^6usJHNWfS!YhLZg=!r$Lq?~tBw8FnZJXQWPahO@aern zrp2nJ+=HvCsUFx}q(p|OGiPP#C#I9`bXWsUiW%>0qTsv@rk_H?^PcL3yS?-Evt7vX zUs@;G$`nzmTqOUjsok8EG*oQwplm*|m)&(m`mkL)G7Xa3FGOm)nbWzBR?=+k_O8(K z>2r?DYbBw*usyYMaJgO0nQ?wR@=cL8r+3!rUif-#4Kl0gi%?sJj_I4kz`~9a%-l!p z`8`8w85gSPAPt7HuuWx10^JumxOlq~oD_7KcvsEkvog?>b~4Zy8JV`^gzRLIk()Iw zcQVp|$Rfj{`uc4TYy~dPM&U^D9g5@Am!P~q+7&hhod|m&?+>bePI@*a@oV#RlyK%c z5jBx!GS-D%5-Le~Kb6upN{k3ux%e38Vni;pihE|{SzP)tcOq`JIoW0`n9O}wdLy<) z?$BF(mKLuiLo0{hcYZ^C&d`ERbN;)}FO%xV+sR_Mc`NCgG4nD&m!DC}U#1O~ z{_q+A$=KVpzZqd`<6`Z1C3I82H%6kP<1s&04jKMiY0e3}#c`kG6a8BE5#d{$J|>F~ zD7|5(N}aE$@#)8Bbs@}zJC}7?KEGU4%bu{gp^@_lpUmi7x>&!aN^i_a>nMHM$J0i3 zSXH(;mNj1-FjENRPi%kOj1+a{tv-EzYUh_|PV#2>|M7@C3fb?T1ZDfo1txh?^Kh`evz&&9^Q0sdfjrMjb)A4rM>K4)jkat3%z~ zM@qE%aHU=G^MCabLH)~Iul9W~bd&JC>`0vK#C6sCJ7MhoUSbNjfnlgbzlV@uMjd(= z`d8su?b^SUbbaaYeTAsMd{@sqXKVrAP;JrE;B;LTc19i-Jr5i6-xuYo=-0W8iBOH)+LaAPYU7?G{#%`$j|ODqAcPdt5wQbZjyGih9S#>!98X>wYn- zc&N@s!F1M5*W6#;f^TK#ARdW?i=2M3glyxey#DDOgO4Oe+IH_R>AO9Co%);p;=SzH z{D(XCJnutte>gcGPx$L6S6FtF|4yP`g2Om|rSfqUpJV@rTqaJnrI6aEC(+dg&$ijI{nxp#9yy3*OHsah7${V}r%=YkA|a=VxFueEhB7E< zEZ@(;Z|<|^{vG;E&pP!=CCn>!uF6fV0ihmYNF;DKw`D>AU6WMilhH3*yZ(w?8)JT z@&&nDk)d9O-}OihcuCQbSg$VOUMa8K?l#8xUmZUAF$Ih%{C3luo{VoS|1Q1X(}Mh^ z@561Iu6{hQExs+)d<A0%3U%MX1lY3ggk`-?;PcT44y62oG4u6!g?LaA=TDV%V>B9MhY-(z6yI(4-Xrg) z;nOB@SZT>6f(z@h=aJd+^5xRR4SVLQjputp7#a{)9`hrA>AM!50(i;5_tw!Cn*n}) zMvJO@xfYe;`?@<*=TWEiz*gz*C9PNK2az7U_>!|3O9y|kLj?EY?J{%v2Y#RO0Rg{j=Q!^jaNP9MqeueGFlJUC%Dd->q6L+0L>VLf}Be?BS^ z3njlF^)c=|YQMD%qeTm6$@e_60r(>!J`U%2(Y3I&ZQ0pB*GsEOpXC+Af1McWeW%}J z#B-#>@*&9}&NXTQI;;ZmA?$A|ZCmVt?%NXiJrKVclKw>bO^|G=el6)Yz#2)F;T@eS zy8U-i_-;*xmg8?A#4E&~4ePOotOs152Fj-_S@J_7?V)~q^63u$VvDXj{pLkv9`?)0 z-Syq|i^$)#U#^~O^h^lSPh-==84kWO|QUnSM5U6Snjztur^eqwHMO2S;Z^c#kro@^(H#lu79OI zZ>M%M>-9a>ru+=pQRwbd&)V~Y4rLwKH?Xvy&xu7ZTxDCGTRhU=_V_zO`-Y^qVj^hC z<>knk&VMcve$$h#_s(|p-u~Ge&T0hnB*3Fgu3K zw)pYmmt9>S_npS08FkBK&Mp3wt6xIiBi1$u>w4A}MXspq0cllipe ziktbeh<#<`)!{|w@{$|Z6Kq58Cnw8qa!aXMf3&MBKK$vD{06%H?`2eOvg*=nQ0=ma zP45cxsoC#*33gEp@pItmrT$k{>HEiztAk&Grt6SjgN7ly-ZN|co3uam8~gTq)|=r6 z#`RyKnZ>=Z_wdyw^6NpLlKxs)4jAbZgSDOFPs@9YFOBS^tez-4#+RwW(FYzV|ojZZA@H`p1bxU;n)BlET->EVD(*8S~U9jQOm)jX!dSG50x*zBI*{ zgD#!}n>p1T9p-Nc{4dcq`P(wxn4h>?%>gs`x5j$g0;lfe-{HI7=ASszm~ULKQ)_m> zH|J?l)8{VkWBb@Vv*EY6UvLkYWz45t{8M)ubETKfa{+!pp5<51Hs%lAzn*a#{&H_y z=YV^R`41Pr0REJXHnDlewDq@vvGCuF+x{Gd=hG+qcP}=Ie^XHZ=CdkquxuXuJ&r#O z-|9THE%zC-DQ^4o2K=io&n5Vg{QHFRH(-G=b&fB9U+efn_&L|xt^FDJg9EM5kHG(@ z&wsx$H}h{D%HJmVKXdV~!Qb!VkHJ6c`09nmWDT*iP^By#2 z-ykc83iyA#&X#@gA+)Q&j%&ga?#K#ko@)57-(>kwd=+qGuFW$Ke&o%T-zZ-TxcFD# z|5+~C_&WjLe6!`JJ#5U6U7lL_?})PU_cDBZu;u$a!dK;O%WtxI_+P=8IgZ~CU*!0KNxp~} zV#jz4e)15Te}9=VKObUc5-aE5NE~Y8H^L`}+WdT!l(D93E&`H<-#udhV+wmJ$8uLm|+lS}iw-ws@_rw2# z<70J<>sFhm1%8=bvSt(fW4C5$!n}IcU7qddHuzJw+IrrA|9PJ4M3XTo*H#z!XC1#B zK7W+0|5A%FOGewW6|Kf>9Bt!k;h)U2{E#-*vg4P-|Jdc}zRH;K*V(em;lJS4-D&tI z$Jnx?R`XTa7(0Mx;BOma^Iuqlm3I7zwal;M&pmETgX150!kCtEHvcQ|JG)rE&u5Hz z*YRD}@o$ZGweg$axAn6!nf6&@zCYgf;VJmPb^I~-e{%eU^{k`YBj#y-N87~&k@*vh zDFbcbY4BCB2fPjV*U`<@;Pc#a2a)#(-xT>gFAG8Befaa>BTz+LjJVuS7}F0724lbx z;v>XQhJSyaF_#DjCK8!Vcv)0<6Rd!L89s;jP4E|yVHe~z74&=z+Xdz$n}aU@F7h06 z{LAqFu6#7|2K=otTYs!b_6n^(>w5S*y9l2ZS$Bun$cIFNSzmzvg5!6<@3egIXYlVj z{`>GfyK4U6FX0niKQCVtM&5@%G7){AWX#dYlr1J)A~wa2>0Z)ext1@7zY(5t!7BKN zD02s89;VD4lzC{1tS_7Q3#5O?@uSK2W5?eK|4YZOgfHx7^Y@^h>5jhzezD`{!XI(` zINCYs_`BghbbJH+(C)ULUi4#<<8Oh#$MJLFzvTGQ^mB*f?}Y!h<5$8ThRwJjam3GFC~wFPw^Ed7~DhZh(z+HqC?Y-Im8}$ ztjw4T;4`G5f3Z^1wkU66+u>6^ZU6h0${M%)&G4@{el+|=%SRT#=k}63(b#hM$;t<@ z&%w`k{2#!#_WGpk>anlEZ*lQ2!GA~NgRIx!_t`vIe+7Te=82qwzvB3F@B{L+&yipn zwgSE%b@qYJoxyFzo!B1m9Ju2y5*X_pAi>_a8vGQ@DmP{g_;c*z-L1y_Y%S~easItw z?7>A)_8DW|0gbHvQ#uzxY!>xTqb=54>|yvnru^M`c06^2o3&3SYZd${*1oKRC*hxT z@n3@fL&yIy{ENy*V&8-Rxs4Bg3V+4%e+NJQIvr=$zro)RA7u`s%-@d~&-Jw5N*uo% zjNL}u1;&08WBcVp^kq3Vk-5E%edk-(eepVMN*4btg!vrtrNsY4>or;B#Qme=8{q%r zIvr2eWAH@fK&v}`o;ukgR5 zY*)s1k+K2%;s2y;K)LUO?^5os!CvxXCu3{L`@is~zE4}ZwYE-)f06iC!Exe008TEk z*qz9Ux=WGO1?q^PG6RU4PTZvHrOrs?O~UWa=F8@LxecbzbBK?atgK%U&;N1Kv=Wvz z`X7YLk<&x?f}f%f-vYlx7h>d%5x*L=5cd}NBg$MyzlIR^Ech$xUq`uk8Re)mUSZ6? z;2(5BR(%-r490vE{9o+*Ujg3{+JJ7;pHEVk>>>A2&(Gj_O}lc|IWRPe}Vb@!LV9kJc5tNLrrdv!bk{Vi!LGz6m~ytPjJd=Hdt9kNzj9 zX=86~S+^p*z^Ci(pV+X)_Xeh`90a$TqSK z{+&g%>(X8!JWKhk$RYT3nvZ=Go49zsoE@wTCLza{NfUebBz!;S>@>K8JRhuM{k!^h zlUCGE+l`IBN6r$$o2(V^|DkzI*5mNoG*6KAW%$47_sxFDIqPfir#0S0-i2@LZ_7@a z!yNTL-$!gj75qP7TNV$PG(gIHmvHR>yO-~U?}0pi1s-fP<`0OM@gF6Azw)uHEAS#` znb*O{_`e4H^8oP!#=^f}hny+bhCHv2+p*3hekr&_+BDKOk~Ww$Df0#5i7m*M}@_9^R6ACxng&Hp|4qMI!L7w~f&|2Oc<;juxHe}iwOt#z6fM6M8i z6&Z+J@1Reo!6VrEuWSBDYyshC!9iPBtQ=m_(4W{^_tEn)n?YnVYd06UtSgXqB9Rk>C*Lf5ERrPtA>~c% z&*A?PKASw3;PdfM#sK+=%0%{w5l_lFQO6x?B7S0}oC$4s7I~h+2Ik(PV~N~?K8?40 zYzq9B;3KrR89skC^P=HMrhh8ewsgP4Yu_%JnhH64F6}~k)e`iVmD#Kw<(_$c^7`NmN8l9 z;8Vk-Ob|PYj_-Iv&W3iMxkPv{V;zIN@3}(Gk9N=Bk30?$zq^M2F9LaG{gn{D)7BH2 zLH@zymo(YyDhQVm{vV&AU1a;i;m-}1K8+`CNTKcDTkw;V4`TlWzd-p&>^!{q8hpVO zd2l830uIu!Oa63G5+%F7khiJnw_-HTd#i7N`Upz)tWscpn@eYvmTBz6j<2 z2VwDB_7I*y{qKP$>VJBi`YEvu=-hEI8~u0*EL?|AGH#cgiep!akBt9k_#o>9X*0%; z953ts3G%dz7ymGb?1F!Kyp{W};CCt?iQW2HIUh@3Ol0nQduJ}jsH7Vt|XxB_}*8fP%t ziO|L=tnU-VJx80bg8!iJ8wuYK1ZFdI1oS!RgF)2ngg!-I&eD$*@h=nJ97N3P&=%sq zN!(lTKPT=G^fG;ZKZu#5@JncO8{;_wdPE}T6miE{XXD||!M_cEC;S!o_3(=#QPbrU z$P4>1k$T!l>qEGV@U!p*@cci&%})4H@GIc=!cT-hicTKqH^sBy`Dim(1icZu40=~I z8dN}=z-q7|+Bet$J$eVSn}rVCO~1jJ`Q%xGEV12BW3S7W(Fg2E7i3<^TB@LpBJ}tp zboC56c?DgZiLPt}Cxk}1FQML#z;?cyeHQvgv|F$px&yop4uNCfLvZ#^)*b%oBKG{H z?Da2#EA;s!X*s;VorlI_to|b8LAWQhI+hg_K+og%y|a$Gz(m@9ES3`#692+f^Z-16 z7i$5W1hdhT&&MLcSkj*%ydxG1ir_cEZviiZ@5Q1)32}?y^N`8kP~Qx~)y(0G^z$Y3 zWIO%bkN&hUpGT>04(ZPm_W@-W!_UONjlzCirH{)9??rBhh&u^X9T1 z!C1oega^Pc0rzF)1Z{+mQSKrbLYb+cmO3|p>a6VG3DQ?HPj7&?z+vzncswf-Y#{A5 z_$~0y!XJU(1HTo1Kl}mO`zm~&d(lyFobXP%?+)jcs;0vUmB(6^#b^!hi{3vw%huK-ddH6DT z{@;pbCwLkBj5;n6U&P!Eqp!2U*=&>u9i0I`5A@Cnf-Zz77r|@b05}QG0y7C2f+1ism=DT88`uc8fn8u9I0R0B^B^`EpA3uvGr(d{4OWAv z!FKQxcmo^)?}PIoR?N8#6oRQ>A*cjv!871Fum|h~hrvm30c4lZ9vA~=fW@F1tOiem z?O+#p9UK5B!CAoP^`yIGU<;b@J zKdO>-RD}*;_vds)zmfSU%B?2fS<)ZqniU))ZVYinls~|lIZyn`uD#4z;xB<*WIhm# z0n@-@umU^*HiH+yE8uN#F-3mbZ0*`5h!DO2jv)I>$nh= z1sA(^4VDu(jq(MQpGm#~(x*{=DRXgh3G>4o^vUfKw2*HR`6iHW3Hc_FZxQ+U=eW&V z5r5CCVg2%`fk#nCB2^X z&7{|p{tW5Ww2{co4)&7%Rnngz{Rz@0GDkB&Q*Kspn6#Hk+eF$X(z1zvBDbeGPW%~g z1@t7n02F~aU>RrvPk}99Cz!{a7ocZf;7#okWp?C7OfK=yGhZL%_BMOr4}fFfEHJd! z4~zg)!9q|0TEGUd6}$*u0|&q+>K?^8;yAQ$~4a^~K3HVC4Sg?=ymnriCYv2{|4dRXv zcbK@h2_FUD?bh9#B z9`>sJ;4IiZhcPifkAv0hRRh`M#bfy3bPgUEsXYZo{H7CnSr0!Kj6Qsx6J0gr$d zuo@hBggFEsE@SSnbx(s$;2_9fPCv`oEAfk71EY{tHCPRv2G4=rU@zEO$#~Gob;y3+ zO7ejPwb(|m1#Aa1@z<8GMV4SSc;qp316%-?!84DuUcu~7qc`9rI1Pq9LEE5PkHGXq zjzvA9!7%6u_UvcDtR8tmA>l<}8CZafhal6oJ1Ix{Ch!WfDq{?r!Sn3zFR*tHWPhIq zW`p~C^a@5$widL3VU%A-`7xB;3|^-EGRnR}+1J54l)nJ3fJh_fq#oUaQIvZMJPQgb z|1{;tQg#b?iSkP+-;=ibfeGNz9s`3hpOeF@lrt=a=Ff+6U^cIv3zF8b2~VvKDy7}kcZS%vQOh?*0$-9lYQ(Yu_Ufq9>B-=0Bm20DoF zS?Ey0=b>Yvm!XrOky7R#nhRYB?G615bP)6#&=JsApheKPpi`lTp|hYT_$}Q$=wSLV z3d{rpdIdo}aZu9&y_N9e(Ax>Ghu#U@1U=d-Vva&9kjtdJ8-u~<>=>{M3`2(Vn1_Yn z4466(8G@&g-6k*q`5k@;*(Auj99=7eXRZoahljyQum}0Q0bWCf`@lA2_&gYfd?r7E z-h)^3BEde|TSj|-nb$8k0KWwOE!ymj4qT+I654v5c{+w{U!l!6z}sL1x>rHlm%#<* z>C@x%XFFqhf$==WSgNrNBYS5DyQLgB1WtgDKo|0t^zLI`fjOn=AIdz%cwQuZG4V~rpC*1P@n<<_6_K_LtiL{L3W$3eJboYYygmp@;NOBi z4?TW;7jqE0zlro_)+n-H0*bI>1KBGEGxs0zE!#Qr4DAyH{pjbde4kbTy{8X8Ds&0` z9gGZ5fCtFK|4`ke`g9EzK)cVv7PIzp??vxG3wRnF13T&GR`TbQ=j(mC1p}dnkl{LX zendTEY9tS~uZ1;q5EOleIRhog_D?BSK>i;<2SX1)he3Y^9RWQ79Sc3zCmM{0PNvQ$ z!2NxLVB_8Fk9{M-GtiGfb>Ey|JM<-R26Sg027w|_37)3RCE}ljUV;8a-&nAn_!qzg zY~vj8Zr{MXNw^;`W5bX~A#?=v&VE6#5PA=E5%j@++;u>otHU-i#&W_-34fLFdxY!z zbqgLLJOo*u1eMr>ie*r2&;e}9GO;J1A9Bb=4z2yTD@~zMC%%xl z_kkg<34EG|E8ShJpG0bAo=* z0_Lv~Yz7y=^Yd9-U^#V6AbmUa&Vb?Fr~};4+`nu7_>{0|#UU z8=zajPLRi*|0X(6$jjmLgv&{P19}j94Fj-$(B}xh58X2$V$MU~ zChwcXU4%bAAQBW1?oQob?-Micz>lGhHrm)&4JV4!XWPRsCxlePTiOBHP^yNZ;F}q z&?fr!Jacmqbh#-Ao+a*j=oaWe=yTA*n_|K9(66G~FM-#=S8n2-QN{}P-qb%>3SAGj zf{S1v_4Y%KgTa1al9WS7-vs%U*k7<2>;{iiF;8G`HF^o=)o{)LFRWnhR$^0b3e4lw z_uX!hU>EcNd2TQ08C;Y$u>0>Lt1ifC6gUMw0!`$39Gn3?scQr{(#o77pQ#0bxlGx+ z3wZsa{6+FCF31YHz|W%}R|v;wcOa-BZ$9z$N<6S`;OQ`2pq(4r4^yVN~5A6+o3OeNGXfQ_RADpAiT;gAX zuY&G}K9S4)F?1MpJ##a67Vyj0u-f9WCOWnNEC+31JvfSNUU&>!z&Yp$$R2z{u#UV>gGK1* zGH`}`=fMERIYea1JeFa*R)9_5b+8Yd217o>yn#jFaj+4*0Secl>tGo;w4Sy=&nMY8 z26JamTRXt*gM;7|XvyFn!CvSA@E$k|hOEWjgPotIKCmAg16^pd089YixS6{u@}2-o zkwrClnKJhd&I%?njw{G&5aBn#TVNUO%^<#pKCFPYfG-la0s0l_M(Ed}&p>xl#}4Rj za0q+^1|!>726qW2ehOdkG3+7O3Whz7Z2^11+u(J|&L+ky9aMT^FNIp06Rb)V;cZwu>Kc<4PYxc4$guTgL8uYlsOEJf#uB4CE9(KvbCgt z$oP&Be*#<@+%>oYUBo=jC*MZoaEN>_lW#BR!o2hYky|1`Y#DnmxbYU&2Xy2u?0L}p z2`__I+!71cLf3q&QJA`vUlCcem1O?E|=t9Ae95W1l zGMEV#feO$9o&t|h<~XzpdIH+aH|+h&NTcr?h6H8^{I(%cQv#h2UIpJIehzdGbTM=v zv=aIuWuJxa1l@-6-T=*m9)$KC%3T=rJh+GN;k)Cfw+)R3PeZrYu@}@cHu640cmwG# zLU#|11Sg=U!G7ZUv9|vXIt2Pp&=Tks$}E9q4~qorpqoMAupqbq9X~85xCqU|h7JTn zz$kERJ$njRLcYa>SMoOUJoHn1gMS#hept3S1vRY4?#$y^sqR70MEj?Pv(G^P z9l9F&5p*pyyD%_YpmU)gLMscSraOCCEm)6kK1O^$_|F#x!Di?y(62&&M82KS@$~%n@672guiraG}t0(tb=`E>#g{m zguemZ2Hkxt_Z7rHg-qVMH4-d<-w*zV^o7uOspk>sMZ(*mxg!Fz3wj+NAnb+S0DTL3 zGxTlf80Z1$C!mL*Q=o^T_dwr)J^(!eT?u^`x&e9&x&?Y1`VH#OZor2e5eWuDhk^aX zZGip*bPM!M1jnH7gE(L0>|h+XKzBjMK;M9Vkv#7~Pl6YT`w;rK(0z}h z&(MR=oKb<9(1g!ADiV}IFSp=7j|zec`1_%i(5297XgPERv>sXuT?4I$J_T)rerXi; z6}lcg3kvXewvWm(JK!&a-P{4}qW*p0`;^&D+z&@Z%&X8-U_X5+AkPWu6ZBu9CD4n| zSx_@NFbkmh&;!t+(08C?M@NHW(D%UwFn%;|+R#g2GI_2*XFy}LdoQ#n^f-4ESDFYS$X8$|pD@i!35PWDyZrWHI@D&#Ah%Z_i8+clW=) z-OuOWaOR$RSDiX_&Z$#%Z_Zu0Va2H7rqb~HI6OtS+S_x*jCRCjN_THd? zr-|e@9ob^4J-s!T?muHIrc-_unnbme-D60KBAq(TE^ikP%03q7ay|u-pP&#Q_n3-(L^|I3X zvv7SD;n$war_$Y2)ytrC0(ISnV-A+H#s*~TV@6qTCS5G%kx)70RR$fomco$zLBe+LqSxd_H)3p?=@ zM7jY7>|VCydi#5fR;nX6t?5ikg9YU(lP(ls7Gq~LsHeRv&&thYS+qeD?YZvm+%_vU zwGzo2B!=bENVrTeT9}|aBNHsi$zm=E>-83eCIN3H(*%_Tk4l{lC)uO) zP<6v9)u9P1gmVj16!zVsik-4%+*AzeT-vcQHI)&^Ys;DkVT%eYJsuoBv&HqSMw^jxE9Xn4_>Rwagv zGNe7&oo1e(QpPFX6ec0|XDM3jTQkQn#LdD&nXT!(IriApid;`$cUDQ+RamE1vgt_o zhy+y?KU-lH{3Q`Rgiiw*|RN6+aU{RKIzzoSDDG)~)Q#qwEn7#b@aaW1zR zdpZl-231ImRdUkS=C1B;6>o+yl>#!LQYaivDazJX3M;wW>}<*!f&02KESa>Hx$ATu zlk4(b*kCR5?acKu%XX?6k1l66F6~`yEQcMbg4&>!KQh(gXUbZG}AzghLz9Q0C+Sh3~^ekR>t%%Oy~%9hjG zV`x6hsBDr;n;w}JyGZk?ZCTc^a?;jRc6(p9@PQSj`p6vWw9YGBPcSv(#OO<740!CPplGX))zE4{fQwY#h zuC1-VkG;CmGoZEY7u!2L2f`opN&-&sWK-?ioxGB?p7eG$1l`zb>`ipb={9?!-PuT` z3!Mh)cl8xTJ!ZE-?9Lsf{h%~lDCYaI0K}AcaxYx%_z6mRML6or2Q=zT7li!Cnyop6 z>5gDG85W-_B1JZ}$ZbrCwxVv4jonx2q)ED?i{`WH*!1_p+gq{bWzGU+2TRF>NfF2I zxqJq0w>yvizKqz7(F!wceu@R-$bv-)Cz3ydOn?~>_*-RbEJmw1P3TsK_DN((w_<&W zB}MEo!ydclBNL87W3%I0a!SPd0}8TrlU}KJpuM}RuTOZloMNoOY<{j?7*r*xu8ocy zJuCAbNEJqQ5vaIcY`a$I?wGbzjBNlW6ID41>XK{gCVQlA)@ggcEJ$r$^h$p#%;1ZwxU z?eGXXMGCTO#a_!A6{qD3HPzO)!{DgwRpQbnEG3o)n38-jQ>0T-ZYa2&QL$6D$^o%t zeM;-yx!#UUza7oCu3~3ru25vVW+VF8_=H}wAeS&pp1lm6#+uZp{BdeX>SPezW%X!@ zf+>rWGI{O7pzP`zaH>x$6iDOnP(k96lG@r!)YR~6-RE$Za zb3f^jZTp~@y&<;;E)?g>l>H&rMo4C{U4k78eZ{P{?k0>=+(Tk>46M%yNc&)j=7hD! zq}H!)T61h_`H5@R9J`SjL%`T=UEtfz7W?}!=6l$oqAS_x1hlojUz^g^+nzIRQc@km zF8}7JeZlFhqJK7_aSBX$MT zEITO`@|NAj!ZK`WihcNwVSh05MJ_vS7HBbqW42d_uM5`3qIXo` zp)D{&=&fua=^fiA`~lq=hN3#q+B33O7lRGAo$@jY5+M?LlvNh7DZ~ROf|*^tEV5Fp zcs>z*DtN7E9y*)4{;Y|vUgltg%B7C?IcVv&tAJD}QQmEgD;T@(dpQ%a9CHh*Act}&UH zfl02Np^{t^niQ#hE}YSeB^|no@d+p%WdU4geRE-i-mXF?D@IsK=RaKxjhDW9)+!?L(^~3zu=jPD$`0dF>1}BYWBNa^E{(|K&^Xy59u;xuutj6HozJx! zta;Kmm$ogD!y8E`SQ9`*fgI^=rn3bxQxFsRG+r2e_Mke`1?tCdBnA%RDCG_bgPk46 zR63#}uAFVGi2g3!nyR)E(qfBYD4LyZXtqLEn{g3r^0vzUs-IOvRdVD2?eZBYpDOf= z|BD@Tk2uo{%*DY-j)E879jf1a`hW0fnA#n@p zC=6`zt=VF(w|}#2e65-o;7`=9yQ+g-vu!ts%rMKY4s|7#m0;J-K5}y^*N23*9*-!s z3cX#@Wi1lSeIHJPTzBBdVtgQM%nr(hr z3%&iV7+l$+U2?5EI{Hz6`iIl#ZbmAJHjLRqN82`A2NTiG2kx{T5f&5Or5Qz_4~**U z&lGyZ_ZytZ1{PQW*>QM^|0AvV)ghr6{rj4W7nX!5J-!bYLrS8D(}PIfgBE)8mCjlr(JCGJhuLJqU$1 zJ?GegAHFxcWA^OXrb`dfx_e7iY{bG%@_)~c{GJlr* zPD{2d+90EsA}6V*B-t|m3{8W4>yTny{XNNb$T`M5i|(9g?^9%w>y9}Ia;S_?&LCma z>cd=?Wn!BpkKJCJom?TFfR_5zt6kD2_dH?Uf;macoon@&OR8QzZ~l4|hS)6GEF!YQ z&1vX&EV94u4vtQW*)&!kTB6JPg)k}YeGBJo3M9Nu?O+=yM|-S#)dJmJ?Q&^^Rq57^ z?gDWg$hmA(xgklnMcuX$KQF7qtY5uy)kd>%?K-G+Oz0aH?hyW6foGTz4NRIZYeD$F zU*AzGiiX!TI>pKL=bw&h$DG) zlMo5pEdVOB-P#e5^0z}BR zER+Rhw+u7k{Syl=N?cD}`JMrd>Clk^GOP2E17$stM6J7t6WKH@fD6968QCxE#tOXiQEX?5VMdFxl+T-YbZ&D_PevPXzDbEprV*;t&(8r;v4agi*T0 zlrljkjj_G9&UT#a&fpSGqIV)!)Z1=yoH1{E@Ca8 zPOd?GXs(s8e=#{Xd5pOG5yXYgB+gn{<+=W$p&?Kqc3! z@X?H`dqwdUvLeOvk{?r<`mz~}&6fFLsx_@$`e`lmH*DBIaV+oTYNkvO5xn*(2z+Zz zb1SwEe}{C$_^>9a_mKs54=LPIq8P`waj1E)ngYnXQCL<9B0XH zJ>A#Wy(8$kL0fmHQz8hR`3pO+1IlhKqDV5F3%QFfc#AWI@ScS!W4zD8K z3To?tWpGyzuqUUEA=!S*O+{hJpa<@>&$0pbC1;}j_z_hL+XEv8k~~4WzJvQ7Tn3Sw z9&$B={U41o4JDoxzThHLHrrjmAlWSDNIKcUWq=H)Qc1Zl)Q#=HJVh-8gu#KLLv5QV z$U+edr6-N7vK|-5q6KV!akBJu%sE1yZAZ!;)5x_^d>wj9NKno)N3eRpP+FU62xudbU+4ji{xuMx4rPMpl3 z;sw+FC#U;dh(NDo&=R;bGudsOSq||bVm}*Ir#xsd(Cm7JN-y$QBYm4*Z%E^%>FzE# zzntAmSc%KIq9k$4Vm_ye^EoOpx&sML8}%9psS8M5AZOolVrYxNNlc|RxTK2o_AYe; zr@I(=8+>7tR>-|N?F^HRoTGElzZE@T)^#mQ9h=T~?@;W7u1p46wah*3Kry+Sv)i1^ zRDF5;hLvV>p+lH#A30Xi@opT9{C%HX8({8PtM*mL2`lFuvClN|=;uRAe6BiFG05m^ zYi>uulnnhf*lgT6tqN`ixqBhVG;ZEWN{Drczdq~;<<8q{8@0GxdK`!bjuYygW zM71o!fPv#s7cFzSCcIfp^#g-aVsCJ$MxqFgmbn|(FT*P%mQM59ladFrA)0&Avh~fY zn^#gsT^2I?_Rb0OsW(viIOcTDph%YfzMze@vMgm)Y-4fua;G>WHkHmSts--DvT1WJ zdzGBr$LnOW^_Cr*gP@jG+0L0(bamDCBsAfKK zM!gyI6bD58#f@@G6HeJ0p|tJq>SSBGA1Q4o7w1_41~nNm2~uJbhy$oC$B^YB4{~Pn z+&O_G29yI2Bq2&c8?gsi3l^H5e%Xs7U$fW(9I&t-N~ITVx4pC5qam^kT`Vio%IKDg zGI%1y>d_m!N)0==_Heg;VQ)^H?WUdGSn0=%-{DsX((;~T*Z91v6qthyetyz3rYU8L;)6=(Lj_l^UIcS%9 zkzQ=Z(nrqM5T~9UY!XvJUocVS*j;Z~3$t~gd?JbJAw_MmkDhltdXT-pV-S=vjNdZ9 zm}7U5Q<)&z8^b5$FL1HjAqrNEM6etbWJadz`~t7AZk91-`9=;s&Wvh$D(v4 zx2;cJbm9Iy{xFt67jCoQqNG)It`sDeLq5Ht!3IX$;6*W$#N#Wc&6yOYU!J?{9Wrg) zj(|79OMXHEx3MY63X?U|#=%!UE!sGT01{7gMkXCj!1w1G&FhEF1 zkR)^yO28%;;33DAMa z*_0eNrwgocS6lgbE!pkcNFnX)Ye{yc>Y@u~$F7y&yje}3R4Y2lE-`l%Pu8~0sM8aP zwKZZ0S}7m{u^DA`Q)|xN=cR<~2j%uLJjGe6*hmadpSD1{1F5Rl;5a(OxnrG~mQ%OW zrA{cwI|*_XL*AvxsWMLn0ayl^$HUG~7N953S@r2rQ~zU$vYhXCyu9XxzuKT_m^I zJofHvBvS7du(iNqq;8Q5PK7~0y#dPYX_R&=OF2jhZyo9lPQ0R zU5%?=7Aq$lYCk#ElbVaQBOL0z1$A@IVNBdxURkZU<219Pw``dCg~+azjd8wRanLKWp4 z3Atkx>n63Eex)wgr!|iRiD zDvYC6jCPQoN9HfMLoC;1bVMOZB8(f5*p1gQka}HNcX+^zTziu8j$_Ek8-dXpY&MMv zxGI=0mFv8VC1+sB&B4wD;Sb(8&{q^nSNXYyLo40p)U_upUwv$<`PgHRNv&IZ5@$kW z7e;b)r)#bycM}_L<7VjNMj_OFf9{+)$D5XgACW8V$@RJph@G#o z^ERkAZ$+*F8|Q7k9IIfI*mDJ<>~!hHC*2E) z2n_v>=3>Le@Zo*OP7>%5bi9kUyu|g!09FslI+LCE-p$fXj`)XpwpAv~756 z=o0ul9b1WG!BJjY4=Tm)+r!0*0$wro!^%61j0ppVn+LQx)O6T>u$)j#&g{lAv9T=+ zOU%H&6C%%MxyoDT&>!!d8>8&jS&3y`v3F|%9_3=6sx4O60No)b7+w-lLt*!#R&roh zM$F}46hmfnCUuZU%vSNT239;B7?>2iwmdN2UMb&|#p~wA|kc%0;^X=Zbe_2$l)=@j+s=IfgZm+F=BGR^H(YrhZ_)XzOB& z%3F&yT7C}6`m6VoHtzvR!l{O8BZw>4aB-}f*dIOq_>#k7 zwedP>Nb}4ZBj{XH?_x%nAckCtcxtg3Yi4PUV_Zwb&kE+eHdbd_J8~%>yGg`0_+C>3 zo!1VUy2h)GRGT8T+RV}x4mU?OoNwZ_UR}bIq8nBV~BzZnK*yiLyA@#4L;-m=E?_u4T@mT)YlEq|}d4BtczeEl&F_JoOtjk;fZB#u9|fY;~JXMEcG^* z)sZA-3UoaPu9r+y%ik&Cn$i*5`GWRyZ7&+8YORt}ra`I=YOQY^rD;JUj%OB+G+K$N zqn2t}+*;E~rFB$M7q9gJS#yaB76m=>J;A30bv2k_CgC%qWUP%ZYy9b6GWy=?2D5Pp zjvN-YIFQpDOpTQc^nHU2&`i}uydmMU7E9%V@v+9Iv2uK`;kDA7(>X~G`nEVyZq_V6 z6U6%yRwcYdOtLDig7{ipYm3c+5o*;(W=`lTKtAQ7L`dOa9r_t%N756~HEMYvC=;0( z$~o%Bpzbty3*yG6Agx9U=546;rq(r98lmjZ_cod_d+D*1QR^)cltzZxPM z!GqdfP-A`Lo7%5b!>a+WDc!^LaMoQ_=$lZNSX~e!B~l|a)A-cltKG_%Zb~)5xRh^( z(e??&cWvp%~zlK0$3o7a@(t#f(JA19J`N>J|*c`Z%Q zW`W*pT(rk_VzM+=_8VqCcGcCUwxTY^lGTwh-h|i3ib}+oyYtbQ32%xndKszkSW`pH z#8~(ePAx&FD%N01v6^e?NHZ%D59hAI_(+x+5~nkpsIrt$dL=4Y*TWehJxPd|kyf|R ziAJ++Z^HLnpJ(XoN$s|5{eO2jt}AHp-wIt?rmpHTugdftSZV%k`e`aF>Z;8fw?8CP zf9+?V`+lYQ;bAVm>S}U6NzOk6F_J0ByX+U=*D_~JYAV(9Ypv&@wm;gm1M4DbKhm^S zpMG1@%%KMcX;lx?&fXzS7>uc}dU)%6MW_{_>(nU7p z`ufZJf8l?zd^j|e4})ZCAR~qtLm?s~tS%J6;A8|?C$O>sDI)fDTqTamI)54#vvaRb~b^~psC?K^m2oF)9Td|r;nOG za{7qr!>3mttn`RuYy4xx-Z@fs5Ux`V<~zpfrQORUb7G`Ts2x_97>1_!yh#kxwWc*S zHB1k}HrnZP*$&mYQ8bzkCA`S|ioV*)xZSM=YHR$Py@431Zybib^ni{`DB^}>P&AO^*1^*Jp=9IOd_OPuosPkm%rUmI~4ZEvSEky8}ED3{t zn)@W7i(uh=Ro7u22G$#Tfb}P+Lu6iU`6bw0(#OGLzb>pd zN|XQm*k_gM{Vy4FO^NSiV1s@VSu+%`RCvrI0*5^h8`WyNzDhhZN9j1@edy@A&%Wd- z=)OSn&)#?bgd{cL)e7gj@$nDTcQ=BNwd?JEKBz|ah1Jp3Ei(M%efOipbB{|U<)SN$CbbmsIw zWxF{Znq1)!9!{s~+L8GP=3Ydi+ZoB8s88iMdg?a2J4c1gO86=*N~MU9QZC*;G{&w> z%^qxw>{_>Znq7&Z(xi5k+QFJ~c_nUx%I&FjEqGs~E4Fo<2V3ZE1Uv^OFak*mqcfAz)vu%t)ngZ!-ian_8rrxG5uHY0VkkMhS%2`ncYQW|N`@IBJg zXwFhvwaQPmvA(j`$xvxh?I7!e4*vSX4~z1H=Av&^4snmT8Ww(hRl_dKzY3j7-QD)d zHq&P&4~1&@S!7~;?Y-NfYF}$BmPzUsGB=th_g0&0ueoOFVLGBRWp0vAo5y7qbc<_e zAyDBzr>yGK+Dh!lZuLjjY=RU+jbYF}U1q=LBtI@@QN(|PAryq_6IIppt#O^|pvRXq z>$ne-Atx#lGUpeYM1_ve&WFylNELiJ(K-_qekGQ{24sNpzHCIz1C56%@47W<$6vM{ z4jQx`oV*n$mh$1x_OkO}?7494W%a)gP5l9!U7{)UtF5BWKkRYSZH8FW%Kk&G;ZmRN z%m?cz?6UdUUb|?dbFy1lP-g86UN^JimaiS1bp1RK>VR^a->(Q{41O&;8*UH-@`da4 z&*Tez;eRHdzt47s8&s3J{u3_AUVEA*lqi+2U{4d*nR6!{;*u{5dwy&{xGcYpxct0H zTGZW6B93nIIE5S|yTbVDpjlJj!3yq3#I4UC%eO5^dVHW)SZZ}rBV4!=1FIqjY&X9a^zC_qgc?PBc+$2<_J}xmKFE) zR4a9`LxewUsUTOqwnSSIT~yX)$t{ZwXHU!|eWlnL?qH@qPW$|%zfRVZrHsx)gzZGR zc_V#LSSK!$J}|5eMA8R_tuz%eXhhEVR{GfRfL%CyA*&Bm6QmlLu|RuhjHOw<>V+Sa z){|qtfcGl!ss6^LPUd)6el!eE%ioZbb?(Zg_tD{AED@6iC4UpUUmKFMHu0YmVlXKD zm~{r!ha0r-?3DwxF9&Ti52bd;oFw+QgjY5k&zxDgNc(awQ1ZnG3FNajLBJtHgvIf0 z)CG*cVRuLmnSZejn{4YRvhSe{*Vhn}`hwW^!5i-?)jL3^3IUxC)f3nT!){;BD%2XP zWT**0v|&PFDyKn1X->+rAhm2jK+?N1!4eSQps<95&E7V^OGy}Jv^sD z$|huAU20QD&KIQR=WIfqMd?Lwz$W`kWA0ksQgbGIY+YB@q72K4eUf1R4i$qqDZ($1 zWtL)c3YjF<_g5`ptqFtb`m_D9ewLd|i=1w0KJg4qFjeLTyvdgxRB2wCaT-aDW|NkZ zBlRG42dUq7sYlqL*?56q`!bHLm7kNIhLsVNhq-xHC7`+a@{d3F%hf_$`%5 zSa(Z4G-wn?&sK)5@i+^KiNmY=2k1@+2^z03ZA}^p({nzo^ci)gsH?GD^KVT90n@D+24Dd6R>6R$-m; zzf5pcR!G>%c{T~MS2+PWD!jo-tS=EuBn(GzdamiSBa#1v z<`I!=eW9;}ay*(>+72|eNXcL=2AUmP9IND+u;`R4+Pi4X95luoZ=zCf-zTOLE?^FS~@?@*BF}odL;>^FK4?LUo}^DXnSAaMfj! z(g}@_;UQy-KQ5YkVBRWbPxpx!HlHiucE4nkWVSz8*j)(J`l9#;Ex)gPLLh!Kd=CqZ zXJC)3zAu@&vV+7UA6T{_?UtB>%`6uk-0TSwu@eFmdjpG9SI87kOyOJi+J*+M2cl@!h>L zvSUm1g~Oz0fvgfdlnqjkOqMS~&W_5C$$ze5jN}y9=a_=6X(Y!G;|babb7Mu05gQHy zl_=DBhRmuXtUvPjLFrf~rS$5->2k^!maja%VN`kjvRr~`EAOw$+fzb%MR`GHEhrS6 z1Lzu&F#$~to!Co$n9K3QZlNasm$wt;hkc0dwn*m7r9;r>vzCDl_v4c z1u{oEuWLVgn~(XSB1sa~j;8E8emG7+QOtg9RYQBknhxiBX_>Fjj_p4dN8dzFU9oo` zzS_usNJba(vAr7-j$FnT%o}>fcApDzs~Q#~4^ep5Yp}Rhc*X@o1i2;W!xHbri?M!$ zztxrXnP3hE>~W_FjVeW>BXcVVhy_(CvV*WMVJxUhYhkISBNkMpwXhN~Nymb!6bq|@ zrlm5uG>vXh+wK9~qXlDfe0JBLp}eH5t$5Y_+U#n@CE{U+xFM#tZ!be#y5H`T(qr7mVBPXW1j~i?@+~O%V>Y z{ye2+XjO7gGVmTGf)-0QL6pUZzu(G+Gv^-55xB2p?$bLECe3)+nN%l%(h43C$Z4C*!hV*e-66m3t+ z#kI#=F!1F?U~b^e|f*_{`38o4n+GlB;7OqkmInIkV6^uKcW96Yprso^{@x*&O0F3?JguT z()YxpUZYM)WYH28{O0?66Q0P>DxEb}kXkotL;d$+i3-@JsUhjS7{Wu%mT98*wi|au z`~w?&%noj%i7_on9Cl1^}5;uXn^y5Wt#B0Y-l_xU` zGOc!;1c)6M#DYw#9qVGp2C*R1YHM6wCp4D&Qh zVvdG8N{)NxZmEr%d@PT?}U|3fO=iP~_zTjTnJnj@Gs-|!mCXhV%xvSOx z35P`Fu4LOnDNgvL+IV85zFN~9)erbViH^iz|8hJxLZh4xkvulS?E=YTFBDXsjP?9x ztkjPNbE!#8lois%`(N@5R+rQ{P&?VSZ1ZLMio0XShV{su_-H+YM=?a7Lwh|G)yV4G z!#a<{Mjjpbg52eZ;rJz{MI@t;K0I^K`wG@>3u>%ye8+3#29g^uZ+#?&i`|H=mKgP) zuKPMKpz0EAcbOnLf7|B4sA5M2mpIe|84qu9)M1t5gdD^h_%A)V13{u*;`j$np+qD3 zNRY$4#AvZ!N1?jPWXS(MIRvAW_-$xD`495D} z07ZY=_Sqq*^bnrpgf2X0)py^*kgOe1ld{H~P8=8}MSkV?69OHp*Aryj1g>6pZWpW) z>TgW*o{aQ@w-;$9NU3jJE%A8g-wJIg-A7?&94}|z!9Zv`EE8c+>uZ&LkQi6iw@Rq- zB=$nmS}6uu!Uc?I%zTL{D|Mj6uumy`lxsX0%DO^*R7+Wg_Sf845DeUdU=)|ZgSbm8y;-pD6 z#7%9@GKt(mmd0oICTilxHJFy_+R4jiCG;}5TZ@TFdKYjly-Q5?D~^}9o+pUpJ{kLF zWL;vUbW1$y*m;VV-WY7s`y(T5v~dShjHteLBr@z_d;$zr?Tyk1>Ulqdc7`7>+H8WX zB7A`)mvT_P)UdWZdx)0DvknHfY}@@l{-&YYohI$pxOQ2q{~xp~Q#)w9+ODs39WQkK z%HZ+hzbg${Xnn4XPWd6Q4;oCi6lX<)!7fgWP+7*?v#vnkd~S9$D^aXNQJ znY;1A5LL%7kzK-gnWZ5{}uffkpR6%{x9wK=%C-Q`2Pxe z`7KxVGTbdb_kwBGgNs1Y za@8t*CW@uN&2Z`;qOC#lLv#j=G0K&tqx!-B&t>aR40Z_VLv=8F+4C2xN|_{7P6p!Fbnu4dG{tf zlGZkce^IIjl8m!FH&JY;1B_q!zT+eR1Wx01 z-neh^2o{{u%AJ8!QCP;#9%hz0v4Xi*8iW)J)O&ayR7NjX@@4gUC`Z>oE(&x)3q{ zJ#JmcF(;y09{LZ|@{6%0;>%PoJiQld96N%`fsH$j*c7sN6za(O=`@%nV#S812G|UG zYJh9pUh#A{J?&YMdlfHoH|6gK**h}+fn%=^-VTJ}pVzu1cbL@s$BLTw;I+(TKqiW_h?{_&-lMs|wA-8y`tFQhnIIWg%l zARHYrz*1__mJw0(QkzO!R^r(>$(c+SrYp_-)nfK zR_my2@CH^=UdK1we*WmPIwrKczI^5Y*OyrXs~OOjE~y8RRbJ1JCj4H<)P7?yreFS< zdJdF&(5~fU8s7GAmNws-rv2f5Zy90A$MjFK_eO)2_hr?`?KdWV)HL0V={tX>FQ1iq z&}_$)(dLdtzq4a%=UWvrPfX#zeDNAK6UdxiGB;()>4pJ&;eDBI4l`l(`G{Iuqw z8MS=umpVROV9WVIxk@vbJ7r%Lv#O+=n~Si`UCLOk&d6{4xnkZ`HT4H&+`q^3O}LCG%#z%{r*QA>-x#vfOXxGBbvZ;ry4L1ic?LHaUCITho6oAGg!quO5V1 z#4$aEifVj|B`Zzrl0rPWngo( z?Dwwyg0}g)8}45kwE3~emTQ~8eEPTOvz_QO`JTiQDaUTlwmIXa!xF zX}(_sPoy&N`|CKe>G8FASCJ$Dz+MVCL}dfZ(0{X=>QR*@g4a z2Vx0%66xc<@RQ|SrDjv`{Z*}l7=5ZNQ%uA}Bu+-kJ67c5|I!)_&v&#dB^z>I@vc#A zq4Esd|H{6}8g{RF@(#?pxIZBr2wWJ{3m z5xbT?U!nP4du6=KSCo7-9OSd#NjqSo{r1^w-F*8@>surFkQwFq?pgetl`ZehcKLXZ zP)9rUeaB%^!k`zgLmI;%#|g=o*RbF0!8sGO(l z8zCWAs86ia6JOP>Gp3})nGoc83xoN{P6+H?@M?6r})0a*!$!$dMLkveg~nDew#Yr zDZ6fhko_ig@C|B)sl3B`MSI-cm&1j=CDP;nli66T_N?VIQCSgs26YS^uL@Fm_xFo? z?MIYxKj@5=EMw{GD$d+(=js|cKMyOGTZciYzVQs!;(lRRz6M)LTSooD3EDg5sB-BN z`9^@=&j_2)_f(9&pZupiJoPtuOn?pj6wV0bfZ(ESg7+sl&DHkx_?P&mrB&R!lUz-l zs7g|b`vmeNhvt;D=ESIGN>0Pot8poLGnWJjSUZZd#Kw|U5XL1&l==D5CC<;E7_KX$ zp;_y(p>Y2$x5;!f&?i@dDpK;5x(dG1rmp_PXn7whF+4GHL+!|^^3@c73)vcdHUq>E^=X)tyh5KdF8T+oh(1bmfvc?PltUB?Ki#)44 zKX(W^Ozhq}F)v|3xmOT*@2kF%{j}bQZfZDHYIxzF9;z}AeF*>5A-3FyT)EOa<$8wT z-m6kyr1GfH)rx9lL|G&Cjeixkag?;N+kS8K?N!$I^y&L2*gon2P8B@%ak&K0>Z5!AIZo|bksayn2fAROu)$PkT5s0xs?9?m>Y$wOJ^@^ zgZcskv7Ua(uiUPWzEv9N_|gcJONTs(P+ldYwg2n*_Op3oi0{t2GZX9Mmh*~gb5T3{ zzi7Ph$$zvgyeTvfj0)w|NKE;+zhqpIv6a0a)XH3h?+3}3`ooZvXllS~!E@+-YF3#? zzB3~uG;WMxync=3vwKbB8g^RRy%JAEdaL?)P&himvhmm+p*yyf*1#0$J}#joCZrl>aK9!oeu|s~Pn1~}D<%#KsaZ25 zZ6PCH+{3tVpJ%|{b=)d%)kSoeu8L?lg40Wpc2l^(B%jmL?_7_q8>Y{3b&13&{8K2z z%a}RF)NdWzEACuYVgO^=$-EqO3); z_ZEe}v?lpxygMyw#1f#uvbb6anz~AMr%tfe*N#H=|ElzFKg>!bf}Ps?^^0$Ra9`i` zTUaU_jg_}p7jz9vLjLO2c+URCuPWbDlRMD*l{B1~ORR;$E>~`WjZ7qhdlZQpy+x52 zBM+>WvG(bR27ih*QYCNIm(?&rYT%p36ng&}=qGhxp76%ufI5c%Wp!|Af&0w^>Ztz9 z>Zrh5splc|d(4T`C-N1ciGeI`FjvM12CC4WH@noO*sX3&%Xi^*b=#ZPXG)o%3T$*A z55$_XIN9|GUuwIJbIQ`h<}Ia7c%QU)JliV&2uoR+7d%)g?7>pfqG7p1XiYbt4_eq; zEa7@U42el2^Bz=C-*~yl{SfB|ERC$$eewXCB#hKALSSkIqo)+kgt6QSI70cN)J|M2 zr?Pge)(?uRPq5KUaAQpH2Eu=|jvu?(3A@Rgo&(1%J&E=P9_3%lkr=W3M3sc+!O$o& zMA?5b#IfMgMsa+o4(qZkGp@+3{X07NLej7i+ zzlG)5_zCN&YmCL80srl2ntth|7pcy#55+WWyv46Z;D6QC>7Pd21RKAY0e)+OE%0^lCtdtA;P=$nJlCCJ%uPXj zi!r}(brw^`e97V0f#2ouhru6n_-o+LI()*J#$4h0unTnGuG0VU4m9Xu; z0Y1YSL>F{noV)(qca|}QskWY)&BlDs;fuk4;_&U@hbL^FIo-y5+oEP;4>q8~PX}La zn=%>jCl0WI$HC8ZWl!#9ujl&q9Qg4r{+=8=YKOnlXUs_s-?hb=rDGtXlzhuFTobiOfb4zuw!A2;Sx z)9u^rcY*(_YwNvB>F41#&oh@{cFnf9Btt;22oYrqegY4NXv zU+dbNPA&Gd%LS6sXa;LAPRhZ*2!xcHgi{Vskf_?Nwl zHUBZ--*EApz<)@5jCxK7@4jBvx2>y}@PydATBZnoNX*7x2)@R}?*i|1@z;Z2;Nour zzsAMi4gSN}*JIMx`@nzU;-3KDx(C9S3 z(T^L?-wgi4mB#%0D&&GMb$I?yiTgD;vle>+yzV&W=~iPtTp{VP*iQ0q(t2aD+rh8U zcvCTpI=<-e8^Qn8<$n~swK9#-gpNf%e;)W9V5oQY@m%i*J_UTAJTc>qJBhS!o@va> zgc(Q0X2SU@ZQK7Y_;JG|Uo5tU@~;4=5|(~l1^#ixnG))|RB=DHANYRNX*Xmx07~eP=`++K1CgW0#K{g#xpIYcF6NpMdv)^MRXycY&!FGDhICi`Xn*OgZ5GPqIFNLoeaqUqivpVgHLk!L*Pd`{7LYY4*v!C*$#gX{0fIxL94Gid_4HQ4nF|=afcrU z{+z=Xf&bRwE5J_~BQnT~y$HR}g5DPbH=?U|qBn08Jqo-DOoLZ1+ic7`eT@6#(Ck*m zJZ8!Wc)4OOWxmmC%wJJgHFI<&VITdyYbSFHO!yf8-Usll^Ne{Ees~jTs8K$NO@prv z#g=#v8{(al$X9c84YDS72=NPv?ak(&Z-=kGOr4}bLw^xz^GUmoa3$kiL-+z<6>-~vcc?eRygZ=!O>7HkS>i81 zR0X%N&jonE6Rm8tRSmeixgijuC$9@y}&IgCy{>$L&sQ*hgt>W9@ zcRBna@W&kfB>1xq{{{GO9R6!?Gr{un@4*iRkJH{JXn$drGG8)gIdLMN&L!?D;vVc` zyv)nHq_t{U&%chei@{~izXSd?^4+9iQ!$%){S>y~lP>(X;A5cWw`|#pzbCxkL_3~V z;&5}Q^0$`@wCx{EZZMB_V++P{TgP+<;{cdi{0(Q;9pQY=AQ=seT&C-g8!4v<-S6>H02VM`3K;Wl>05^ z4yVir^3Ml00Ebh~qxx4V*XZ!Kz>jyh$%y@E^Na*P)8YGpUk{F+^Unmo4)~T$^A|BE z-V~iL{|WGg=NR+XzyYkQf4_mge~tbCKLQfSUdul*|3&hCU+eHHZe)#}NF6oQU&Z_$ z3@iga0(=|zDezms>%?9K&I3LVd<_@_56l8q0;d4pRLjp-f!9OlCfYnp+lf`&Lfmnr zi!A&J_#NPi zK^?ov^HpF)4jT-Zh;CQ`WPwirUj`lmHc>W~O!H|K<4^5HzX3O#hyI}LLumV#z%{i0 z5!xS5J`dhKm^?ESkNL~M)5+z@;m~g+?Ysy~+k)&Xpac5R3tN#9fWHlW0Xz&`sQG>W zQ1b2pjv)VT^4E~B6L=6vlJ64W1>kG6C9-K9dCvx}2a@#t$H3PQOmlI`i+z_meh&N& z7>VvV2&e~+16qKyi|`L{2QXp>{0ThyDcO@)-Y<~H`>>8L_I2>@fKQ^$m+99*^k*mV zEHID$Tn)SlT*4e&3p@?H3yl0L#tzH@wgZ;{4*)*_UildE3>bYbeFxg8KgPOjqdz|d zKE+12(p37Zp;;U7G2rvSeZbSePYza|@>^(k+IIT$an`{Mt;0Wp@G9Ckh;STIHxd39 z!gFqyeViTNRg8B+?Vo0d?0yCOU0^DG@J(gx;E!S}0$-zl4+DoEV%N(a>Npi1J3+&- z*n!}G1#}RGfBoyhKLI`xd?{l(4%h^=0=>Xa;6mUE;CkRT;BMeS;8NGd>)_8`BYQpD z=6i%+A^hb-Y+pyii_?Igu*PV!Vhy;=Id+kM8hAgjk~NnDJ`a2sIPTNP7S?a$Rjf_w zx*Z;W1Ng!n$kIcF&c?rlawo#$qu}rF1AhgNFNDX>&~(rL3h5sseGzHD1#TfdMf&#+ z{nDWxZ68HDYYwx0x)i+N`u7z0t;CDn@JI0TX#XkA=f&nQXNj3oChlJX{%LTZb#u@K z=*G*8dHc(Z^Jdly@uHts5x;I1G`v*y#XA2LzacLB33L^(Znn;U#qTd+Y?M#A@Ob$8 zyMzlayoB&t!c~V$+g|J~!jlv?6;;%~0G$5D4g-IZw!ZAydXFOfJmI%U7v1&{bp1K- zufWDRX%2Hd|E)@{wAEW%?*Rt=po_)YP8*U)Hg7E$>ypr%* z!ZTfX1L4yMPaUImc^Sf=BaJrvFM|Kl=JS3I{tfbtny>Z7-X{D6;R7|y+Z3Nit`q)< zhCP2F;ZZk0r}>S(^lL5QTEcgeE_=B=;g5U)o+obgZfpVKW&9r{egkotTUcMVY{f;y zrHFe~!(PRegu4m<$)(>wcpKsI3$$+)d#^L*9|<3z;g~;$c78*6y@uode8Pv(=0yv- z7Qi3=3c_RPdjoM-+B*Exh}%H;1`V^{C)_4w;@N-V1*A!c!KK&!0g*ZqRt+@1oC7xcF~U*DqcChrSq; z_52OsN7ri`{*~aH9DXBsm&5M_zsTYDga5$d6|aJSZIR4JJocq8VV~ZFYyd6-#Mbsq zMQj0Ud+8B&ZkB`J#5ylBH^*z7=dUO3ZsIN^E=`=r82X5N30!2!-QYjG6}@BADjp#G zu_G-Fze~AKQ|=1FQf?FY%||I7n@5=!758H6!Tp9ej`FDQX7Kq9Zhr*+)vvHdZ^L%_ zDmFgwI8bvtb_jW-&YzLzg2lGZOUd_*#h+VDe8u(PKh$`y;w#`%rw7mfGx*Xa2Q8tk zSR?hUU1IAgfS9M7e+m2shkqCRe#QAd2y**ZOFqX-n7&^Rem(Fa;4f7h z%5McfP;t-S0)Ed@+fMZzww&~3Ciw8iHAP3)E%0Ka3b6DOtZ$$dxEpv7covv*A!)#R zpcgnBxB|Etcm;SH7=96b1Qr0t0WH98;11wH;CbLRAa*h11WpFpft|orz)irtz!N|X z`fnOA4`>EX2lBv$z-_ze8}Qy`>`iZBFB6~W9n=K>uST9huaT#*zD}p#z>Q~M*R^2R zq_Ov)$?4GHvMtarkB!pL*ct!4^WZ^rWHb6@=8f$2zl`69dcPYV?M0I!Ofy=>f;&}(~E%3W}J^(!AH+etdc^hrM z3N0r=%O+s!8fXNJWd4o=nt`{0bD-TO==MA?3A$Ym+z4!EP2CDS2po43;{uvarXJw! zQ&1V(?EJV4XU z^c$$V#hB%Hut)PNy^+vmKi~!6RUi+|&juz`RC!H=Hvwk>8Rljya3OFNu%N;-j}qTf z5%Y!-o&apE8095-ZiLPk09OFF0e1uU0gnNvLh}sJ2V4(409;Tp)~lo38q)c<;mymy zNcu1xxE#0m^vp> z{$k((;2q#h>gfdbFqSvTGrH0<@9;c~=P>g3R>sW)o<{-ClJA;I&#ME!jpt0B-{Lu& z=L07?zQt=K;N2xcPYP>@J`CU0K}_2?;OI3D$nfVxwa~1uIBkV@G0V69PD}BQ}?=jl?>M+mDq@Pa^K7!}3hxy)ep7+tt zPRd;l{Ej_1WZ&#CsjCwN}S^T#|dt&VxG@q8P&w>s_(gB}L~i-9L8 zQ^WHQft$;=dC;!5082G@_Y+u0)Ld}Pk=K?f0t(uaTA#L>A)o%VJ+tQ z6`s%W{2tGjc|ObYU7o)l9{1kkc{*!)Dr@=e;o}(ubrDVyeg+y3W6j>oI(?3H`V#Vc z0do63U{@EsQecju<)hFrb{Tnqv!P!S+TC*t^E`Zl7o)yb>N|+~o~6Fw)b}Fm|5oaJ zo;qKq&U)&*AGnM<-=)q6sq-=F^r`Q8;2i2ah&u13&OP+mr_Kk+{{m_85o5dsgii&o zq@8<#jkL8BmlsktqN%H3bzGq~H zQ|1lIJWH94l0qsG{Q6Y5!W`N!aUCNP|Dp1 zy!a{j;!^BKyd}>NzaM2DfDfA)TPLuEa?cUJbA)eR<9Qi8J9-QBq0Gle#Laue-FXT8 z`+4k1@{FYX)8sj-4;@G!ujE8wDslJF&b8E42mVF!&E$DB`MQCN>Hk+oz{kY>Xhhsw z%JZ>L!o%?V^CPOfV+g-^E^W}xP1MtQ8S)i)0=fE|5tZI?q>n?^H_03VGnm5*f%iuE z-g?rmXO2g+uip;ty z9a-VsPTcLZbrj{#BK~?{NM+^OK7(f zIGgcZP1#D~u1K-2z6xy!k0d-C8FD(|+X#;%{37YQ3ExG1`w@N#{JY>u@H}++2k=9| zW8nWXveKIa{xp4j7clVfG~fu}ccj&m_89$n6L<%h#2DuRdr0G79y2?^Zv<`y9syne zMvkiVmXmfU^)&+A+RMR?0sLEM*?D^uLv|+u?=xHZx|*%!WU2hKKT_;$A0dM-cZKa3Ou@C7cAG z!n)rMd~sCF_23hq&qB3&`ILoDQ51JT@xkT|nCIJThT) z%)AW#CeSxJ?!C(MZQ$iwq2HL8cj`xIlQlmPJOe%*d=dDwJWqutOUG237r;9i#|6M{ z^vzUw<*^KN!MNV;Lq~m_bv|aQd6j&(k>_>bsS}yYP4ELY(4D6cPq`VCyBat&4XuGU zTG74Ka|iW2-^1FZy;p(9a_|+jz8bh9k6dAl)1kw=v@;bRUXGlYdNcWH^L5(1gZAD8 zo}tahXmby3-c6f#(B`4EcO8J6$=nFMMVn92=AE?pB5n53-s`{y6+sJnWV|uSZyUhPj=yT;|^q)QtC*MotdzpN&I!^n3i`9{mB zDSa6Y4U;v#nF?M9zJRuOBMZ){!Nw=fC;Z8pO0OM!0)2iA_%U!M_3uahSJjO6ilm(> z;{nbAt_AJ@o&}2JyBtW8_e=rmy9?Nk9Q%At+?+$%dq^Kf+?Q$RQNp8{pGiO;a{FB7 z;zHo>YpTrKq)nmDsTZ)e8OMD$!Bbym%*@j-7|*+;Pb2-UnhKL-ESCWFN-bmuc0cQg3Kre6*iJUqSeO!aE7SMxU-E`~cyz311;=mpoSy z_aJfS5cdw@s|i0$_*}xVadGcj!jBL>pYRC6*Aae{@CAe?jfxrug@<2^6Wb0+5C#XOH3A2XNn z+)iKDlC~Q>N8AfMkE8rm^MSI%RH$zh43jJU$g@f#be!Ug8Fs?$8#@o7vYV3#PbTC&r#2-z$KLJBkfM&&L!<`p0|;I+BwWOaOH$5?+xN6 zFor3>sX!-i0q_oE`u>ENw-o$(@K+hvo#5w#e;xR@2{Cg&;d9{MkrOMu=fKAyZ|>Sb zeaM@uf%h2e=!wvf{0H!Smb}v^R(P-Q90z^(0~Q0P11m_sm*)u+W9AK>_qDTL$a~b8 ztS6ua=mpLJ&f{}`8+m4cB5(n4FXb=e`4G>`dH#s!6+C~+^GcrY@qC5nv6DQHV<@wp zC+sc{0zNdA9TXHtA>ayl+y>>*KiqJNdxL)CoSD=T$t9V~C>;4Iv!IVI1ZdWyV-*45QXE zYbggk&Sf5Fone-Gh~3NekN0_hzMt>sx%WQb`+dImK9|SDxkd)^uo5NMf(q2(AX?C2 z8zWxx$yejTo17q*jc0HOZTOj*+xo73H6a}5s9XUyU3&20E${Vv z?rFUC!4D8)lY9^3DV)L!IESC)6}*+#a21#FtGtU_lVZYioN28-|C+y1CbIQhEq^nNl>iXQCp-VS(g@rR5EGw*uahWk(xs9`4`;6*Z3SiJk{F6i#c|ydBQWfnwRlmF6Q^RlRxAO{42i6zv27r z(OXdF-ZqW*auGK^xYy-YevT8|^B&+VKE_3Sic9$4{vZr%`Da|mS9m}Fr~ZRHB^n8O zxWPHgiB1Un!~-~_-G-|_G^QBCQnlyx9hYAl4TC(cjm8E2eAbx8S2;(5-TP5DcASPQ(U@R0Z^Ynx`lp3qqxi9DF<}#rnV*5V zId_`pirRJN;39FWxWC$(B|arSWiEfiYjgkKF+mZRp&nbOxgKx@n(_R!FxbF*xtu$A zKlgAGe`q`H{9k;MKj(8iJ=y&w=kaAO=Br%BH~0mm6!8O zUe8(l9Ov=@UcyJYkb8JF4^Q_zi+i1?D(B}n^8MP2{mLTVXLbZppV@uSyEp%iF|Y7G z5qZJ)E}TMn%7idcT_*BSj7_M*VZ59Y6Qpn&M)7(|807M?6wkAH(k^Qn_TVsju-ZPi zqY54NeI8vY8Q~W7dHUDOUzW>rEcLjBm5!wyapv7#)ZtAWMhi~hBu=9rmv9v~anHPp z+vB>0WMm-^g(${)Y(Y8pBKZ|-4mQ1R%|%bjgy2obHra74*zY*-l>@H%ui4Mr51w&& z)}_D8YkE`S!yDpp#CtEv$VDkC(THyJ;}c^wrtTugX%F){{*-s~C?DithBbu~X2gXV zjv)^#QGzX~K+=qf!5q#-yz$zE9!xc6HMorFGa^Bu{&LK>%}x9yALWu6<}N=sBO&PI zeq6^J*76g7V;w})`!2*heaiX|Qyj+|lZWli-o+>^e{)RXz?hr>){moANd}>@+&rN8@Sq$PD_N9hF z1J|Wa2o7)?&^!hR5Vii~p4iv@dcMk8&eVNDG5DUYr&Q z<9!xe98;k?og%k7lwlUprUBlm&aez|jUC345*PRg~&U6k7-cUbO>?Y7GOT;CZU z*0)n%r@kw4!*ZX>Rmt_q-BSOl+;7vq5Z>oW#w`W8ScWRKcYRjt)K{vXkRAq6`RVBs z!a_cTdsu6XPhztAR%4Tu9v_y-Z$TyYqX9MgBevCui`ZeC1?iDsx4whgThhN6wu}34 z2{&*TrM6w~wUgA0q0Tt=;<~Xcu#FeeJuiJwuWy_D30%_mqWlH0z4hm6>4QRBVsp{j^-cws<`;Fdrw!R_9SHX2?Kr6bCBlYu-)a zjhvhr3AS@zgE1CYh|i1XiuZ{Riu1(v;yUqiafkSl_(^fE_?oy_d``SeTw>dU;y>f7 zyn}D>39fNIew-N-9_7Bha^G|APrElr1NHCQvuuh!I^{AZX-iEs# zFw6a|ar#Iuhx?tAi*gIZBeQ%*;)E>clDB2W1pPez*Pd0^IacjE+MVLFsML;i@3h1E zUyYZtB0-{d4(e?qlLxqnzcf1xcJQBaBfr8ud~$XeCOL*ap2`P3&yVsmxQrjmr|`$> z)A&EQfN#hb@@Kq}$9M~e*`U?Nvz3{z{JBOGuZij4a>PP@+Tw(Xy0he3v#U)o<254-MO zmrGP1J{}1U@DWUW+??Tbxgy&s#T>aheuh`r<~APVTJCl}-+eqT=;7PQw7<=0!e0Am zR&!InkJIFS$@zSp%Q!kG3=VP8oJi2eyBuq^T$R^;$nAWF&+|RL!|8LwAjz0K!7GhR z$=sOWme;kohClL#>#uyF_?@|7SjwHek$=S7_+u{TU#M&5A@1Yf@gRRW$LEUY-cg`BpBkG4^UI!b3A*VwT~Cf ziv%;j?{k16aUrk4TKz>oFn8uf!cuPfd%xe3>lI&^7aB0ftS^gCyyJS38wtw9+nTIv zxiR5RafNvD-+5lIuUxxIdsl8GtPt-N|7EVti1%?5H|cBVT7AdFUE+FiySP`}ApRF| zzqmy_ARZLAi?4{UicgCFM|?wkO8mL_j`*B-?)*rY{I+Z3@8cj%JT6`#pDm7k*Sw!^ zEfU9z*Naz(lf*S@Hj49p9|xPo1>#ou9pWPK;|u&f&{&L#pAu(_qerZj;uYe2@geax zahbStL2Otl-iKY(rvypi?{XxX-TKUAgnNF)DXW zZIa{ammin^t@Z}(UhUi3U(64~6WUX_gQw-khZlGRS@v6u7PO(z{?}ujW7vfB{Mhi8 zx^e84Z$MUlTo|u53C-G_C|6s9x%s|l%CF6j1nYS~-?Lu|!!q&n`l|R<$5G9V+BJNX z>-nGajT3jYyT-{iiZ9tt2cPx6zr5J@b#X3Vix zJBIFq}$fIm@R#5a~i!a6>P z8DDeF;Ai4AyA^dlNzrnn3 zy+8-<;&*bnyc^vZ$E2mP!4lqsKE$>;9=Sqs4bCD#&YTZ2xMQht=l-Q(koKT#F}`#RRq5=a8uVb-y@0F5a`uoZ)@iH@RIqR{y_i ar|}Rk;gsdBQJl*A_-StB;^kr3#{UO#Wj0g* literal 0 HcmV?d00001 diff --git a/t6/compiled/t6/zm_alcatraz_brutus.gsc b/t6/compiled/t6/zm_alcatraz_brutus.gsc new file mode 100644 index 0000000000000000000000000000000000000000..7a9607496f615be2fc809546c9f3dc2f2bb97797 GIT binary patch literal 3030 zcmds(TWB0r7{|Za%&sw2T2eu6@s>)BLbfqzl;DH5V2g;93X*~{J$vTt%yj3*IcK|@ zpb(^J5g%F*v2O-cq`m~vq7Opog9LmL5i8y(#T!M62tui%{^zo5O!kC4yDC3T57REPX*dff%Oa}pnU5S6 za;7DlcN(&-+p6v&GA#IP*!=2!z8$ z7&fF}Eg>DIHRCNub%NLnMN@AgOa`8>9k%Jnh9S}wO#2)8jC16fj_9Ug;))GNh&+Q^ z3l%b_7|65~5liL?M`>RDC}^D?&fye` zw2bfjQz=pryM0}88Kjysv_~{W^3ZM>S_Jl>CwBx(lbEojA$k|`IjT$)d87o#W-&Qe zMyUYFGD7F}+98vq+6^8urHFL{MH&NB(UD2drGk1{LW|f#>$W=}jpH4j3F~OPh2MUt^E2%RoV?F!_jnnjP)&e#@J>^Gr5RmvYh zp0!)>QsraFFXnd3{uJ_JDgOldFlD(^{R{HB+&)wp#d4QwMeYvBFOWsIVEXGIp9X)% z{LA34;3e=1cmoC@+~*`X3_byF10{G9cnZ87d>=uJGO@4)AvUj$!*{v)^u{StV_uF+-iaXiPTak;ocTrcB# z2Qk0FcNV+~eg;-xzYLCmBUQ^91;@Z0;0!nh9s=(Hk5(" to set it on the client before connecting) +sv_maxclients 8 // Maximum players that are allowed in your server. (1-8, default is 4) Keeping this at 1-4 is recommended to prevent game breaking bugs. +//zombies_minplayers 2 // Minimum players needed to start the game (1-8, default is 1). Do NOT set this higher than sv_maxclients! +//sv_minPing 0 // Minimum ping needed to the server? (NOT recommended to edit, terribly broken and inaccurate since ages!) +//sv_maxPing 400 // Maximum ping allowed to the server? (NOT recommended to edit, terribly broken and inaccurate since ages!) +//zm_gungame 1 // Enable Pluto's custom Gun Game? +//zm_sharpshooter 1 // Enable Pluto's custom Sharp Shooter? +//gts zmDifficulty 1 // Difficulty? 0 = Easy, 1 = Normal !!If set to easy it must be manually set on the client as well!! +demo_enabled 0 // Record matches as demo files? 1 = Enabled, 0 = Disabled (Very efficient <5MB per match for a full server) +sv_sayname "" // name server-side 'say' commands show up as +sv_voice "1" // Allow Voice Chat (0 = Disable 1 = Everyone hears you. 2 = Teams only) +sv_voicequality "9" // Voice Chat Quality. (0-9) Default is 3 (= Steam/Console quality). Use 9 for the best quality. +sv_allowAimAssist 1 // Allow Aim Assist on gamepads. (0 = Will lock the option on gamepad controls menu.) +sv_fix_zm_weapons true // Fix the SMR's ADS spread, 870 MCS's penetration damage and allow sprinting with Galvaknuckles +sv_patch_zm_weapons true // Apply Post DLC1 changes to tar21_zm, type95_zm, xm8_zm, an94_zm, hamr_zm, rpd_zm, pdw57_zm, kard_zm ? (only recoil changes) +////////////////////////////////////////////////// +//These options can also be configured individually on a map basis in each zm config in gamesettings. +////////////////////////////////////////////////// +//gts startRound 1 // Starting Round. Works on all maps. +//gts magic 1 // Remove all supernatural assistance? Only Survival and Grief have this option! +//gts headshotsonly 0 // Headshots only? Only Survival and Grief have this option! +//gts allowdogs 1 // Allow Hellhounds? Only Survival has this option! +//gts cleansedLoadout 1 // Allow players to choose their Loadout? Only Turned has this option! +//gts teamCount 2 // Sets the number of teams 2. Set to 2 by default when loading grief. +////////////////////////////////////////////////// +// B3, IW4MADMIN, GAME LOG & RCON SETTINGS // +////////////////////////////////////////////////// +g_logSync 2 // 0 only flush on game end, 1 flush when buffer full, 2 always flush after a write, 3 append to old logs. (Keep this at 2 if you plan on using a 3rd party admin tool) +g_log "logs\games_zmbrutus.log" // If you choose to use this make sure the filename is unique for each server! +rcon_password "rconAQW25wqa" // RemoteCONtrol password. !!Do NOT skip if you plan on using a 3rd party admin tool such as B3 or IW4m-Admin!! +rcon_rate_limit "0" // Rate limit RCon; limit is per IP; range is 0 to 10 000; value is in milliseconds. Lower this if you use IW4mA's Game Interface. +rconWhitelistAdd "127.0.0.1" // Command used to add an IP address to the whitelist. When no IP is added all IPs can send rcon commands. +rconWhitelistAdd "198.251.84.64" // If it is set only the whitelisted IPs and loopback (127.0.0.0/8) can send commands. + +seta sv_wwwBaseURL "" // Configure the URL to Fast DL mods from. (i.e. http://domain.tld/iw5) +seta fs_game "" // What mod are we loading? (i.e. "mods/MyMod") +////////////////////////////////////////////////// +//The "exec zm__.cfg" line sets the dvars for the location and gametype for you. This .cfg applies to all following maps in the rotation like MP until another .cfg is defined. +//You may modify these .cfgs in gamesettings. Make sure only one sv_maprotation line is uncommented or you may run into errors on starting or joining the server. +//Currently rotating the map using sv_maprotation doesn't work properly, i.e. clients will be kicked with an error when the map rotates to another map. +//It's recommended to only include one map in your sv_maprotation for this reason. +////////////////////////////////////////////////////////////////////////////// +// Maps and the matching configs // +////////////////////////////////////////////////////////////////////////////// +// Buried - exec zm_classic_processing.cfg map zm_buried // +// Buried Turned - exec zm_cleansed_street.cfg map zm_buried // +// Buried Grief - exec zm_grief_street.cfg map zm_buried // +// Die Rise - exec zm_classic_rooftop.cfg map zm_highrise // +// Mob of The Dead - exec zm_classic_prison.cfg map zm_prison // +// Mob of The Dead Grief - exec zm_grief_cellblock.cfg map zm_prison // +// Nuketown - exec zm_standard_nuked.cfg map zm_nuked // +// Origins - exec zm_classic_tomb.cfg map zm_tomb // +// Tranzit - exec zm_classic_transit.cfg map zm_transit // +// Tranzit Farm Survival - exec zm_standard_farm.cfg map zm_transit // +// Tranzit Town Survival - exec zm_standard_town.cfg map zm_transit // +// Tranzit Bus Depot Survival - exec zm_standard_transit.cfg map zm_transit // +// Tranzit Farm Grief - exec zm_grief_farm.cfg map zm_transit // +// Tranzit Town Grief - exec zm_grief_town.cfg map zm_transit // +// Tranzit Bus Depot Grief - exec zm_grief_transit.cfg map zm_transit // +// Tranzit Diner Turned - exec zm_cleansed_diner.cfg map zm_transit_dr // +////////////////////////////////////////////////////////////////////////////// +// Notes: +// Town/Tranzit servers will not natively spawn in tombstone since servers launch the maps in solo. +// --> https://forum.plutonium.pw/topic/124 +// Grief requires a fix otherwise teams won't balance resulting in clients crashing when a 5th player joins. +// --> https://forum.plutonium.pw/topic/4057 + +//Classic/TranZit Maps rotation +sv_maprotation "exec zm_classic_prison.cfg map zm_prison" + +//Survival Maps rotation +//sv_maprotation "exec zm_standard_town.cfg map zm_transit" + +//Grief Maps rotation +//sv_maprotation "exec zm_grief_town.cfg map zm_transit exec zm_grief_transit.cfg map zm_transit exec zm_grief_farm.cfg map zm_transit exec zm_grief_cellblock.cfg map zm_prison exec zm_grief_street.cfg map zm_buried" + +//Turned Maps rotation +//sv_maprotation "exec zm_cleansed_diner.cfg map zm_transit_dr exec zm_cleansed_street.cfg map zm_buried" + +//Congratulations. You reached the end of this file. Leave map_rotate down below or else the server will not start after launch... +map_rotate diff --git a/t6/dedicated_zmburied.cfg b/t6/dedicated_zmburied.cfg new file mode 100644 index 0000000..7fd1941 --- /dev/null +++ b/t6/dedicated_zmburied.cfg @@ -0,0 +1,94 @@ +////////////////////////////////////////////////// +/// PlutoT6 ZM ServerConfiguration file // +/////////////////////////////////////////////////// +// This config best view with Notepad++ OR // +// other *nix compatible editors of your choice. // +/////////////////////////////////////////////////// +// Remove "//" in front of lines to allow the // +// server to read them. // +// Anything after "//" is a comment. // +////////////////////////////////////////////////// +// GENERAL SETTINGS // +////////////////////////////////////////////////// +//g_password "aqw" // Require a password to join your server. (Use "password " to set it on the client before connecting) +sv_maxclients 8 // Maximum players that are allowed in your server. (1-8, default is 4) Keeping this at 1-4 is recommended to prevent game breaking bugs. +//zombies_minplayers 1 // Minimum players needed to start the game (1-8, default is 1). Do NOT set this higher than sv_maxclients! +//sv_minPing 0 // Minimum ping needed to the server? (NOT recommended to edit, terribly broken and inaccurate since ages!) +//sv_maxPing 400 // Maximum ping allowed to the server? (NOT recommended to edit, terribly broken and inaccurate since ages!) +//zm_gungame 1 // Enable Pluto's custom Gun Game? +//zm_sharpshooter 1 // Enable Pluto's custom Sharp Shooter? +//gts zmDifficulty 1 // Difficulty? 0 = Easy, 1 = Normal !!If set to easy it must be manually set on the client as well!! +demo_enabled 0 // Record matches as demo files? 1 = Enabled, 0 = Disabled (Very efficient <5MB per match for a full server) +sv_sayname "" // name server-side 'say' commands show up as +sv_voice "1" // Allow Voice Chat (0 = Disable 1 = Everyone hears you. 2 = Teams only) +sv_voicequality "9" // Voice Chat Quality. (0-9) Default is 3 (= Steam/Console quality). Use 9 for the best quality. +sv_allowAimAssist 1 // Allow Aim Assist on gamepads. (0 = Will lock the option on gamepad controls menu.) +sv_fix_zm_weapons true // Fix the SMR's ADS spread, 870 MCS's penetration damage and allow sprinting with Galvaknuckles +sv_patch_zm_weapons true // Apply Post DLC1 changes to tar21_zm, type95_zm, xm8_zm, an94_zm, hamr_zm, rpd_zm, pdw57_zm, kard_zm ? (only recoil changes) +////////////////////////////////////////////////// +//These options can also be configured individually on a map basis in each zm config in gamesettings. +////////////////////////////////////////////////// +//gts startRound 29 // Starting Round. Works on all maps. +//gts magic 1 // Remove all supernatural assistance? Only Survival and Grief have this option! +//gts headshotsonly 0 // Headshots only? Only Survival and Grief have this option! +//gts allowdogs 1 // Allow Hellhounds? Only Survival has this option! +//gts cleansedLoadout 1 // Allow players to choose their Loadout? Only Turned has this option! +//gts teamCount 2 // Sets the number of teams 2. Set to 2 by default when loading grief. +////////////////////////////////////////////////// +// B3, IW4MADMIN, GAME LOG & RCON SETTINGS // +////////////////////////////////////////////////// +g_logSync 2 // 0 only flush on game end, 1 flush when buffer full, 2 always flush after a write, 3 append to old logs. (Keep this at 2 if you plan on using a 3rd party admin tool) +g_log "logs\games_zmburied.log" // If you choose to use this make sure the filename is unique for each server! +rcon_password "rconAQW25wqa" // RemoteCONtrol password. !!Do NOT skip if you plan on using a 3rd party admin tool such as B3 or IW4m-Admin!! +rcon_rate_limit "0" // Rate limit RCon; limit is per IP; range is 0 to 10 000; value is in milliseconds. Lower this if you use IW4mA's Game Interface. +rconWhitelistAdd "127.0.0.1" // Command used to add an IP address to the whitelist. When no IP is added all IPs can send rcon commands. +rconWhitelistAdd "198.251.84.64" // If it is set only the whitelisted IPs and loopback (127.0.0.0/8) can send commands. + +seta sv_wwwBaseURL "" // Configure the URL to Fast DL mods from. (i.e. http://domain.tld/iw5) +seta fs_game "" // What mod are we loading? (i.e. "mods/MyMod") + +////////////////////////////////////////////////// +//The "exec zm__.cfg" line sets the dvars for the location and gametype for you. This .cfg applies to all following maps in the rotation like MP until another .cfg is defined. +//You may modify these .cfgs in gamesettings. Make sure only one sv_maprotation line is uncommented or you may run into errors on starting or joining the server. +//Currently rotating the map using sv_maprotation doesn't work properly, i.e. clients will be kicked with an error when the map rotates to another map. +//It's recommended to only include one map in your sv_maprotation for this reason. +////////////////////////////////////////////////////////////////////////////// +// Maps and the matching configs // +////////////////////////////////////////////////////////////////////////////// +// Buried - exec zm_classic_processing.cfg map zm_buried // +// Buried Turned - exec zm_cleansed_street.cfg map zm_buried // +// Buried Grief - exec zm_grief_street.cfg map zm_buried // +// Die Rise - exec zm_classic_rooftop.cfg map zm_highrise // +// Mob of The Dead - exec zm_classic_prison.cfg map zm_prison // +// Mob of The Dead Grief - exec zm_grief_cellblock.cfg map zm_prison // +// Nuketown - exec zm_standard_nuked.cfg map zm_nuked // +// Origins - exec zm_classic_tomb.cfg map zm_tomb // +// Tranzit - exec zm_classic_transit.cfg map zm_transit // +// Tranzit Farm Survival - exec zm_standard_farm.cfg map zm_transit // +// Tranzit Town Survival - exec zm_standard_town.cfg map zm_transit // +// Tranzit Bus Depot Survival - exec zm_standard_transit.cfg map zm_transit // +// Tranzit Farm Grief - exec zm_grief_farm.cfg map zm_transit // +// Tranzit Town Grief - exec zm_grief_town.cfg map zm_transit // +// Tranzit Bus Depot Grief - exec zm_grief_transit.cfg map zm_transit // +// Tranzit Diner Turned - exec zm_cleansed_diner.cfg map zm_transit_dr // +////////////////////////////////////////////////////////////////////////////// +// Notes: +// Town/Tranzit servers will not natively spawn in tombstone since servers launch the maps in solo. +// --> https://forum.plutonium.pw/topic/124 +// Grief requires a fix otherwise teams won't balance resulting in clients crashing when a 5th player joins. +// --> https://forum.plutonium.pw/topic/4057 + +//Classic/TranZit Maps rotation +sv_maprotation "exec zm_classic_processing.cfg map zm_buried" + +//Survival Maps rotation +//sv_maprotation "exec zm_standard_town.cfg map zm_transit exec zm_standard_transit.cfg map zm_transit exec zm_standard_farm.cfg map zm_transit exec zm_standard_nuked.cfg map zm_nuked" + +//Grief Maps rotation +//sv_maprotation "exec zm_grief_town.cfg map zm_transit exec zm_grief_transit.cfg map zm_transit exec zm_grief_farm.cfg map zm_transit exec zm_grief_cellblock.cfg map zm_prison exec zm_grief_street.cfg map zm_buried" + +//Turned Maps rotation +//sv_maprotation "exec zm_cleansed_diner.cfg map zm_transit_dr exec zm_cleansed_street.cfg map zm_buried" + +//Congratulations. You reached the end of this file. Leave map_rotate down below or else the server will not start after launch... +map_rotate diff --git a/t6/dedicated_zmdierise.cfg b/t6/dedicated_zmdierise.cfg new file mode 100644 index 0000000..c44444b --- /dev/null +++ b/t6/dedicated_zmdierise.cfg @@ -0,0 +1,93 @@ +////////////////////////////////////////////////// +/// PlutoT6 ZM ServerConfiguration file // +/////////////////////////////////////////////////// +// This config best view with Notepad++ OR // +// other *nix compatible editors of your choice. // +/////////////////////////////////////////////////// +// Remove "//" in front of lines to allow the // +// server to read them. // +// Anything after "//" is a comment. // +////////////////////////////////////////////////// +// GENERAL SETTINGS // +////////////////////////////////////////////////// +//g_password "aqw" // Require a password to join your server. (Use "password " to set it on the client before connecting) +sv_maxclients 8 // Maximum players that are allowed in your server. (1-8, default is 4) Keeping this at 1-4 is recommended to prevent game breaking bugs. +//zombies_minplayers 1 // Minimum players needed to start the game (1-8, default is 1). Do NOT set this higher than sv_maxclients! +//sv_minPing 0 // Minimum ping needed to the server? (NOT recommended to edit, terribly broken and inaccurate since ages!) +//sv_maxPing 400 // Maximum ping allowed to the server? (NOT recommended to edit, terribly broken and inaccurate since ages!) +//zm_gungame 1 // Enable Pluto's custom Gun Game? +//zm_sharpshooter 1 // Enable Pluto's custom Sharp Shooter? +//gts zmDifficulty 1 // Difficulty? 0 = Easy, 1 = Normal !!If set to easy it must be manually set on the client as well!! +demo_enabled 0 // Record matches as demo files? 1 = Enabled, 0 = Disabled (Very efficient <5MB per match for a full server) +sv_sayname "" // name server-side 'say' commands show up as +sv_voice "1" // Allow Voice Chat (0 = Disable 1 = Everyone hears you. 2 = Teams only) +sv_voicequality "9" // Voice Chat Quality. (0-9) Default is 3 (= Steam/Console quality). Use 9 for the best quality. +sv_allowAimAssist 1 // Allow Aim Assist on gamepads. (0 = Will lock the option on gamepad controls menu.) +sv_fix_zm_weapons true // Fix the SMR's ADS spread, 870 MCS's penetration damage and allow sprinting with Galvaknuckles +sv_patch_zm_weapons true // Apply Post DLC1 changes to tar21_zm, type95_zm, xm8_zm, an94_zm, hamr_zm, rpd_zm, pdw57_zm, kard_zm ? (only recoil changes) +////////////////////////////////////////////////// +//These options can also be configured individually on a map basis in each zm config in gamesettings. +////////////////////////////////////////////////// +//gts startRound 1 // Starting Round. Works on all maps. +//gts magic 1 // Remove all supernatural assistance? Only Survival and Grief have this option! +//gts headshotsonly 0 // Headshots only? Only Survival and Grief have this option! +//gts allowdogs 1 // Allow Hellhounds? Only Survival has this option! +//gts cleansedLoadout 1 // Allow players to choose their Loadout? Only Turned has this option! +//gts teamCount 2 // Sets the number of teams 2. Set to 2 by default when loading grief. +////////////////////////////////////////////////// +// B3, IW4MADMIN, GAME LOG & RCON SETTINGS // +////////////////////////////////////////////////// +g_logSync 2 // 0 only flush on game end, 1 flush when buffer full, 2 always flush after a write, 3 append to old logs. (Keep this at 2 if you plan on using a 3rd party admin tool) +g_log "logs\games_zmdierise.log" // If you choose to use this make sure the filename is unique for each server! +rcon_password "rconAQW25wqa" // RemoteCONtrol password. !!Do NOT skip if you plan on using a 3rd party admin tool such as B3 or IW4m-Admin!! +rcon_rate_limit "0" // Rate limit RCon; limit is per IP; range is 0 to 10 000; value is in milliseconds. Lower this if you use IW4mA's Game Interface. +rconWhitelistAdd "127.0.0.1" // Command used to add an IP address to the whitelist. When no IP is added all IPs can send rcon commands. +rconWhitelistAdd "198.251.84.64" // If it is set only the whitelisted IPs and loopback (127.0.0.0/8) can send commands. + +//seta sv_wwwBaseURL "http://198.251.88.2/" // Configure the URL to Fast DL mods from. (i.e. http://domain.tld/iw5) +s//eta fs_game "mods/mymods" // What mod are we loading? (i.e. "mods/MyMod") +////////////////////////////////////////////////// +//The "exec zm__.cfg" line sets the dvars for the location and gametype for you. This .cfg applies to all following maps in the rotation like MP until another .cfg is defined. +//You may modify these .cfgs in gamesettings. Make sure only one sv_maprotation line is uncommented or you may run into errors on starting or joining the server. +//Currently rotating the map using sv_maprotation doesn't work properly, i.e. clients will be kicked with an error when the map rotates to another map. +//It's recommended to only include one map in your sv_maprotation for this reason. +////////////////////////////////////////////////////////////////////////////// +// Maps and the matching configs // +////////////////////////////////////////////////////////////////////////////// +// Buried - exec zm_classic_processing.cfg map zm_buried // +// Buried Turned - exec zm_cleansed_street.cfg map zm_buried // +// Buried Grief - exec zm_grief_street.cfg map zm_buried // +// Die Rise - exec zm_classic_rooftop.cfg map zm_highrise // +// Mob of The Dead - exec zm_classic_prison.cfg map zm_prison // +// Mob of The Dead Grief - exec zm_grief_cellblock.cfg map zm_prison // +// Nuketown - exec zm_standard_nuked.cfg map zm_nuked // +// Origins - exec zm_classic_tomb.cfg map zm_tomb // +// Tranzit - exec zm_classic_transit.cfg map zm_transit // +// Tranzit Farm Survival - exec zm_standard_farm.cfg map zm_transit // +// Tranzit Town Survival - exec zm_standard_town.cfg map zm_transit // +// Tranzit Bus Depot Survival - exec zm_standard_transit.cfg map zm_transit // +// Tranzit Farm Grief - exec zm_grief_farm.cfg map zm_transit // +// Tranzit Town Grief - exec zm_grief_town.cfg map zm_transit // +// Tranzit Bus Depot Grief - exec zm_grief_transit.cfg map zm_transit // +// Tranzit Diner Turned - exec zm_cleansed_diner.cfg map zm_transit_dr // +////////////////////////////////////////////////////////////////////////////// +// Notes: +// Town/Tranzit servers will not natively spawn in tombstone since servers launch the maps in solo. +// --> https://forum.plutonium.pw/topic/124 +// Grief requires a fix otherwise teams won't balance resulting in clients crashing when a 5th player joins. +// --> https://forum.plutonium.pw/topic/4057 + +//Classic/TranZit Maps rotation +sv_maprotation "exec zm_classic_rooftop.cfg map zm_highrise" + +//Survival Maps rotation +//sv_maprotation "exec zm_standard_town.cfg map zm_transit" + +//Grief Maps rotation +//sv_maprotation "exec zm_grief_town.cfg map zm_transit exec zm_grief_transit.cfg map zm_transit exec zm_grief_farm.cfg map zm_transit exec zm_grief_cellblock.cfg map zm_prison exec zm_grief_street.cfg map zm_buried" + +//Turned Maps rotation +//sv_maprotation "exec zm_cleansed_diner.cfg map zm_transit_dr exec zm_cleansed_street.cfg map zm_buried" + +//Congratulations. You reached the end of this file. Leave map_rotate down below or else the server will not start after launch... +map_rotate diff --git a/t6/dedicated_zmmotd.cfg b/t6/dedicated_zmmotd.cfg new file mode 100644 index 0000000..3cf5ee8 --- /dev/null +++ b/t6/dedicated_zmmotd.cfg @@ -0,0 +1,93 @@ +////////////////////////////////////////////////// +/// PlutoT6 ZM ServerConfiguration file // +/////////////////////////////////////////////////// +// This config best view with Notepad++ OR // +// other *nix compatible editors of your choice. // +/////////////////////////////////////////////////// +// Remove "//" in front of lines to allow the // +// server to read them. // +// Anything after "//" is a comment. // +////////////////////////////////////////////////// +// GENERAL SETTINGS // +////////////////////////////////////////////////// +//g_password "" // Require a password to join your server. (Use "password " to set it on the client before connecting) +sv_maxclients 8 // Maximum players that are allowed in your server. (1-8, default is 4) Keeping this at 1-4 is recommended to prevent game breaking bugs. +//zombies_minplayers 3 // Minimum players needed to start the game (1-8, default is 1). Do NOT set this higher than sv_maxclients! +//sv_minPing 0 // Minimum ping needed to the server? (NOT recommended to edit, terribly broken and inaccurate since ages!) +//sv_maxPing 400 // Maximum ping allowed to the server? (NOT recommended to edit, terribly broken and inaccurate since ages!) +//zm_gungame 1 // Enable Pluto's custom Gun Game? +//zm_sharpshooter 1 // Enable Pluto's custom Sharp Shooter? +//gts zmDifficulty 1 // Difficulty? 0 = Easy, 1 = Normal !!If set to easy it must be manually set on the client as well!! +demo_enabled 0 // Record matches as demo files? 1 = Enabled, 0 = Disabled (Very efficient <5MB per match for a full server) +sv_sayname "" // name server-side 'say' commands show up as +sv_voice "1" // Allow Voice Chat (0 = Disable 1 = Everyone hears you. 2 = Teams only) +sv_voicequality "9" // Voice Chat Quality. (0-9) Default is 3 (= Steam/Console quality). Use 9 for the best quality. +sv_allowAimAssist 1 // Allow Aim Assist on gamepads. (0 = Will lock the option on gamepad controls menu.) +sv_fix_zm_weapons true // Fix the SMR's ADS spread, 870 MCS's penetration damage and allow sprinting with Galvaknuckles +sv_patch_zm_weapons true // Apply Post DLC1 changes to tar21_zm, type95_zm, xm8_zm, an94_zm, hamr_zm, rpd_zm, pdw57_zm, kard_zm ? (only recoil changes) +////////////////////////////////////////////////// +//These options can also be configured individually on a map basis in each zm config in gamesettings. +////////////////////////////////////////////////// +//gts startRound 1 // Starting Round. Works on all maps. +//gts magic 1 // Remove all supernatural assistance? Only Survival and Grief have this option! +//gts headshotsonly 0 // Headshots only? Only Survival and Grief have this option! +//gts allowdogs 1 // Allow Hellhounds? Only Survival has this option! +//gts cleansedLoadout 1 // Allow players to choose their Loadout? Only Turned has this option! +//gts teamCount 2 // Sets the number of teams 2. Set to 2 by default when loading grief. +////////////////////////////////////////////////// +// B3, IW4MADMIN, GAME LOG & RCON SETTINGS // +////////////////////////////////////////////////// +g_logSync 2 // 0 only flush on game end, 1 flush when buffer full, 2 always flush after a write, 3 append to old logs. (Keep this at 2 if you plan on using a 3rd party admin tool) +g_log "logs\games_zmmotd.log" // If you choose to use this make sure the filename is unique for each server! +rcon_password "rconAQW25wqa" // RemoteCONtrol password. !!Do NOT skip if you plan on using a 3rd party admin tool such as B3 or IW4m-Admin!! +rcon_rate_limit "0" // Rate limit RCon; limit is per IP; range is 0 to 10 000; value is in milliseconds. Lower this if you use IW4mA's Game Interface. +rconWhitelistAdd "127.0.0.1" // Command used to add an IP address to the whitelist. When no IP is added all IPs can send rcon commands. +rconWhitelistAdd "198.251.84.64" // If it is set only the whitelisted IPs and loopback (127.0.0.0/8) can send commands. + +seta sv_wwwBaseURL "" // Configure the URL to Fast DL mods from. (i.e. http://domain.tld/iw5) +seta fs_game "" // What mod are we loading? (i.e. "mods/MyMod") +////////////////////////////////////////////////// +//The "exec zm__.cfg" line sets the dvars for the location and gametype for you. This .cfg applies to all following maps in the rotation like MP until another .cfg is defined. +//You may modify these .cfgs in gamesettings. Make sure only one sv_maprotation line is uncommented or you may run into errors on starting or joining the server. +//Currently rotating the map using sv_maprotation doesn't work properly, i.e. clients will be kicked with an error when the map rotates to another map. +//It's recommended to only include one map in your sv_maprotation for this reason. +////////////////////////////////////////////////////////////////////////////// +// Maps and the matching configs // +////////////////////////////////////////////////////////////////////////////// +// Buried - exec zm_classic_processing.cfg map zm_buried // +// Buried Turned - exec zm_cleansed_street.cfg map zm_buried // +// Buried Grief - exec zm_grief_street.cfg map zm_buried // +// Die Rise - exec zm_classic_rooftop.cfg map zm_highrise // +// Mob of The Dead - exec zm_classic_prison.cfg map zm_prison // +// Mob of The Dead Grief - exec zm_grief_cellblock.cfg map zm_prison // +// Nuketown - exec zm_standard_nuked.cfg map zm_nuked // +// Origins - exec zm_classic_tomb.cfg map zm_tomb // +// Tranzit - exec zm_classic_transit.cfg map zm_transit // +// Tranzit Farm Survival - exec zm_standard_farm.cfg map zm_transit // +// Tranzit Town Survival - exec zm_standard_town.cfg map zm_transit // +// Tranzit Bus Depot Survival - exec zm_standard_transit.cfg map zm_transit // +// Tranzit Farm Grief - exec zm_grief_farm.cfg map zm_transit // +// Tranzit Town Grief - exec zm_grief_town.cfg map zm_transit // +// Tranzit Bus Depot Grief - exec zm_grief_transit.cfg map zm_transit // +// Tranzit Diner Turned - exec zm_cleansed_diner.cfg map zm_transit_dr // +////////////////////////////////////////////////////////////////////////////// +// Notes: +// Town/Tranzit servers will not natively spawn in tombstone since servers launch the maps in solo. +// --> https://forum.plutonium.pw/topic/124 +// Grief requires a fix otherwise teams won't balance resulting in clients crashing when a 5th player joins. +// --> https://forum.plutonium.pw/topic/4057 + +//Classic/TranZit Maps rotation +sv_maprotation "exec zm_classic_prison.cfg map zm_prison" + +//Survival Maps rotation +//sv_maprotation "exec zm_standard_town.cfg map zm_transit" + +//Grief Maps rotation +//sv_maprotation "exec zm_grief_town.cfg map zm_transit exec zm_grief_transit.cfg map zm_transit exec zm_grief_farm.cfg map zm_transit exec zm_grief_cellblock.cfg map zm_prison exec zm_grief_street.cfg map zm_buried" + +//Turned Maps rotation +//sv_maprotation "exec zm_cleansed_diner.cfg map zm_transit_dr exec zm_cleansed_street.cfg map zm_buried" + +//Congratulations. You reached the end of this file. Leave map_rotate down below or else the server will not start after launch... +map_rotate diff --git a/t6/dedicated_zmnuketown.cfg b/t6/dedicated_zmnuketown.cfg new file mode 100644 index 0000000..77ae6f6 --- /dev/null +++ b/t6/dedicated_zmnuketown.cfg @@ -0,0 +1,93 @@ +////////////////////////////////////////////////// +/// PlutoT6 ZM ServerConfiguration file // +/////////////////////////////////////////////////// +// This config best view with Notepad++ OR // +// other *nix compatible editors of your choice. // +/////////////////////////////////////////////////// +// Remove "//" in front of lines to allow the // +// server to read them. // +// Anything after "//" is a comment. // +////////////////////////////////////////////////// +// GENERAL SETTINGS // +////////////////////////////////////////////////// +//g_password "" // Require a password to join your server. (Use "password " to set it on the client before connecting) +sv_maxclients 8 // Maximum players that are allowed in your server. (1-8, default is 4) Keeping this at 1-4 is recommended to prevent game breaking bugs. +//zombies_minplayers 1 // Minimum players needed to start the game (1-8, default is 1). Do NOT set this higher than sv_maxclients! +//sv_minPing 0 // Minimum ping needed to the server? (NOT recommended to edit, terribly broken and inaccurate since ages!) +//sv_maxPing 400 // Maximum ping allowed to the server? (NOT recommended to edit, terribly broken and inaccurate since ages!) +//zm_gungame 1 // Enable Pluto's custom Gun Game? +//zm_sharpshooter 1 // Enable Pluto's custom Sharp Shooter? +//gts zmDifficulty 1 // Difficulty? 0 = Easy, 1 = Normal !!If set to easy it must be manually set on the client as well!! +demo_enabled 0 // Record matches as demo files? 1 = Enabled, 0 = Disabled (Very efficient <5MB per match for a full server) +sv_sayname "" // name server-side 'say' commands show up as +sv_voice "1" // Allow Voice Chat (0 = Disable 1 = Everyone hears you. 2 = Teams only) +sv_voicequality "9" // Voice Chat Quality. (0-9) Default is 3 (= Steam/Console quality). Use 9 for the best quality. +sv_allowAimAssist 1 // Allow Aim Assist on gamepads. (0 = Will lock the option on gamepad controls menu.) +sv_fix_zm_weapons true // Fix the SMR's ADS spread, 870 MCS's penetration damage and allow sprinting with Galvaknuckles +sv_patch_zm_weapons true // Apply Post DLC1 changes to tar21_zm, type95_zm, xm8_zm, an94_zm, hamr_zm, rpd_zm, pdw57_zm, kard_zm ? (only recoil changes) +////////////////////////////////////////////////// +//These options can also be configured individually on a map basis in each zm config in gamesettings. +////////////////////////////////////////////////// +//gts startRound 1 // Starting Round. Works on all maps. +//gts magic 1 // Remove all supernatural assistance? Only Survival and Grief have this option! +//gts headshotsonly 0 // Headshots only? Only Survival and Grief have this option! +//gts allowdogs 1 // Allow Hellhounds? Only Survival has this option! +//gts cleansedLoadout 1 // Allow players to choose their Loadout? Only Turned has this option! +//gts teamCount 2 // Sets the number of teams 2. Set to 2 by default when loading grief. +////////////////////////////////////////////////// +// B3, IW4MADMIN, GAME LOG & RCON SETTINGS // +////////////////////////////////////////////////// +g_logSync 2 // 0 only flush on game end, 1 flush when buffer full, 2 always flush after a write, 3 append to old logs. (Keep this at 2 if you plan on using a 3rd party admin tool) +g_log "logs\games_zmnuketown.log" // If you choose to use this make sure the filename is unique for each server! +rcon_password "rconAQW25wqa" // RemoteCONtrol password. !!Do NOT skip if you plan on using a 3rd party admin tool such as B3 or IW4m-Admin!! +rcon_rate_limit "0" // Rate limit RCon; limit is per IP; range is 0 to 10 000; value is in milliseconds. Lower this if you use IW4mA's Game Interface. +rconWhitelistAdd "127.0.0.1" // Command used to add an IP address to the whitelist. When no IP is added all IPs can send rcon commands. +rconWhitelistAdd "198.251.84.64" // If it is set only the whitelisted IPs and loopback (127.0.0.0/8) can send commands. + +seta sv_wwwBaseURL "" // Configure the URL to Fast DL mods from. (i.e. http://domain.tld/iw5) +seta fs_game "" // What mod are we loading? (i.e. "mods/MyMod") +////////////////////////////////////////////////// +//The "exec zm__.cfg" line sets the dvars for the location and gametype for you. This .cfg applies to all following maps in the rotation like MP until another .cfg is defined. +//You may modify these .cfgs in gamesettings. Make sure only one sv_maprotation line is uncommented or you may run into errors on starting or joining the server. +//Currently rotating the map using sv_maprotation doesn't work properly, i.e. clients will be kicked with an error when the map rotates to another map. +//It's recommended to only include one map in your sv_maprotation for this reason. +////////////////////////////////////////////////////////////////////////////// +// Maps and the matching configs // +////////////////////////////////////////////////////////////////////////////// +// Buried - exec zm_classic_processing.cfg map zm_buried // +// Buried Turned - exec zm_cleansed_street.cfg map zm_buried // +// Buried Grief - exec zm_grief_street.cfg map zm_buried // +// Die Rise - exec zm_classic_rooftop.cfg map zm_highrise // +// Mob of The Dead - exec zm_classic_prison.cfg map zm_prison // +// Mob of The Dead Grief - exec zm_grief_cellblock.cfg map zm_prison // +// Nuketown - exec zm_standard_nuked.cfg map zm_nuked // +// Origins - exec zm_classic_tomb.cfg map zm_tomb // +// Tranzit - exec zm_classic_transit.cfg map zm_transit // +// Tranzit Farm Survival - exec zm_standard_farm.cfg map zm_transit // +// Tranzit Town Survival - exec zm_standard_town.cfg map zm_transit // +// Tranzit Bus Depot Survival - exec zm_standard_transit.cfg map zm_transit // +// Tranzit Farm Grief - exec zm_grief_farm.cfg map zm_transit // +// Tranzit Town Grief - exec zm_grief_town.cfg map zm_transit // +// Tranzit Bus Depot Grief - exec zm_grief_transit.cfg map zm_transit // +// Tranzit Diner Turned - exec zm_cleansed_diner.cfg map zm_transit_dr // +////////////////////////////////////////////////////////////////////////////// +// Notes: +// Town/Tranzit servers will not natively spawn in tombstone since servers launch the maps in solo. +// --> https://forum.plutonium.pw/topic/124 +// Grief requires a fix otherwise teams won't balance resulting in clients crashing when a 5th player joins. +// --> https://forum.plutonium.pw/topic/4057 + +//Classic/TranZit Maps rotation +sv_maprotation "exec zm_standard_nuked.cfg map zm_nuked" + +//Survival Maps rotation +//sv_maprotation "exec zm_standard_town.cfg map zm_transit" + +//Grief Maps rotation +//sv_maprotation "exec zm_grief_town.cfg map zm_transit exec zm_grief_transit.cfg map zm_transit exec zm_grief_farm.cfg map zm_transit exec zm_grief_cellblock.cfg map zm_prison exec zm_grief_street.cfg map zm_buried" + +//Turned Maps rotation +//sv_maprotation "exec zm_cleansed_diner.cfg map zm_transit_dr exec zm_cleansed_street.cfg map zm_buried" + +//Congratulations. You reached the end of this file. Leave map_rotate down below or else the server will not start after launch... +map_rotate diff --git a/t6/dedicated_zmorigin.cfg b/t6/dedicated_zmorigin.cfg new file mode 100644 index 0000000..a4f17a9 --- /dev/null +++ b/t6/dedicated_zmorigin.cfg @@ -0,0 +1,93 @@ +////////////////////////////////////////////////// +/// PlutoT6 ZM ServerConfiguration file // +/////////////////////////////////////////////////// +// This config best view with Notepad++ OR // +// other *nix compatible editors of your choice. // +/////////////////////////////////////////////////// +// Remove "//" in front of lines to allow the // +// server to read them. // +// Anything after "//" is a comment. // +////////////////////////////////////////////////// +// GENERAL SETTINGS // +////////////////////////////////////////////////// +g_password "" // Require a password to join your server. (Use "password " to set it on the client before connecting) +sv_maxclients 4 // Maximum players that are allowed in your server. (1-8, default is 4) Keeping this at 1-4 is recommended to prevent game breaking bugs. +//zombies_minplayers 4 // Minimum players needed to start the game (1-8, default is 1). Do NOT set this higher than sv_maxclients! +//sv_minPing 0 // Minimum ping needed to the server? (NOT recommended to edit, terribly broken and inaccurate since ages!) +//sv_maxPing 400 // Maximum ping allowed to the server? (NOT recommended to edit, terribly broken and inaccurate since ages!) +//zm_gungame 1 // Enable Pluto's custom Gun Game? +//zm_sharpshooter 1 // Enable Pluto's custom Sharp Shooter? +//gts zmDifficulty 1 // Difficulty? 0 = Easy, 1 = Normal !!If set to easy it must be manually set on the client as well!! +demo_enabled 0 // Record matches as demo files? 1 = Enabled, 0 = Disabled (Very efficient <5MB per match for a full server) +sv_sayname "" // name server-side 'say' commands show up as +sv_voice "1" // Allow Voice Chat (0 = Disable 1 = Everyone hears you. 2 = Teams only) +sv_voicequality "9" // Voice Chat Quality. (0-9) Default is 3 (= Steam/Console quality). Use 9 for the best quality. +sv_allowAimAssist 1 // Allow Aim Assist on gamepads. (0 = Will lock the option on gamepad controls menu.) +sv_fix_zm_weapons true // Fix the SMR's ADS spread, 870 MCS's penetration damage and allow sprinting with Galvaknuckles +sv_patch_zm_weapons true // Apply Post DLC1 changes to tar21_zm, type95_zm, xm8_zm, an94_zm, hamr_zm, rpd_zm, pdw57_zm, kard_zm ? (only recoil changes) +////////////////////////////////////////////////// +//These options can also be configured individually on a map basis in each zm config in gamesettings. +////////////////////////////////////////////////// +//gts startRound 1 // Starting Round. Works on all maps. +//gts magic 1 // Remove all supernatural assistance? Only Survival and Grief have this option! +//gts headshotsonly 0 // Headshots only? Only Survival and Grief have this option! +//gts allowdogs 1 // Allow Hellhounds? Only Survival has this option! +//gts cleansedLoadout 1 // Allow players to choose their Loadout? Only Turned has this option! +//gts teamCount 2 // Sets the number of teams 2. Set to 2 by default when loading grief. +////////////////////////////////////////////////// +// B3, IW4MADMIN, GAME LOG & RCON SETTINGS // +////////////////////////////////////////////////// +g_logSync 2 // 0 only flush on game end, 1 flush when buffer full, 2 always flush after a write, 3 append to old logs. (Keep this at 2 if you plan on using a 3rd party admin tool) +g_log "logs\games_zmorigin.log" // If you choose to use this make sure the filename is unique for each server! +rcon_password "rconAQW25wqa" // RemoteCONtrol password. !!Do NOT skip if you plan on using a 3rd party admin tool such as B3 or IW4m-Admin!! +rcon_rate_limit "0" // Rate limit RCon; limit is per IP; range is 0 to 10 000; value is in milliseconds. Lower this if you use IW4mA's Game Interface. +rconWhitelistAdd "127.0.0.1" // Command used to add an IP address to the whitelist. When no IP is added all IPs can send rcon commands. +rconWhitelistAdd "198.251.84.64" // If it is set only the whitelisted IPs and loopback (127.0.0.0/8) can send commands. + +seta sv_wwwBaseURL "" // Configure the URL to Fast DL mods from. (i.e. http://domain.tld/iw5) +seta fs_game "" // What mod are we loading? (i.e. "mods/MyMod") +////////////////////////////////////////////////// +//The "exec zm__.cfg" line sets the dvars for the location and gametype for you. This .cfg applies to all following maps in the rotation like MP until another .cfg is defined. +//You may modify these .cfgs in gamesettings. Make sure only one sv_maprotation line is uncommented or you may run into errors on starting or joining the server. +//Currently rotating the map using sv_maprotation doesn't work properly, i.e. clients will be kicked with an error when the map rotates to another map. +//It's recommended to only include one map in your sv_maprotation for this reason. +////////////////////////////////////////////////////////////////////////////// +// Maps and the matching configs // +////////////////////////////////////////////////////////////////////////////// +// Buried - exec zm_classic_processing.cfg map zm_buried // +// Buried Turned - exec zm_cleansed_street.cfg map zm_buried // +// Buried Grief - exec zm_grief_street.cfg map zm_buried // +// Die Rise - exec zm_classic_rooftop.cfg map zm_highrise // +// Mob of The Dead - exec zm_classic_prison.cfg map zm_prison // +// Mob of The Dead Grief - exec zm_grief_cellblock.cfg map zm_prison // +// Nuketown - exec zm_standard_nuked.cfg map zm_nuked // +// Origins - exec zm_classic_tomb.cfg map zm_tomb // +// Tranzit - exec zm_classic_transit.cfg map zm_transit // +// Tranzit Farm Survival - exec zm_standard_farm.cfg map zm_transit // +// Tranzit Town Survival - exec zm_standard_town.cfg map zm_transit // +// Tranzit Bus Depot Survival - exec zm_standard_transit.cfg map zm_transit // +// Tranzit Farm Grief - exec zm_grief_farm.cfg map zm_transit // +// Tranzit Town Grief - exec zm_grief_town.cfg map zm_transit // +// Tranzit Bus Depot Grief - exec zm_grief_transit.cfg map zm_transit // +// Tranzit Diner Turned - exec zm_cleansed_diner.cfg map zm_transit_dr // +////////////////////////////////////////////////////////////////////////////// +// Notes: +// Town/Tranzit servers will not natively spawn in tombstone since servers launch the maps in solo. +// --> https://forum.plutonium.pw/topic/124 +// Grief requires a fix otherwise teams won't balance resulting in clients crashing when a 5th player joins. +// --> https://forum.plutonium.pw/topic/4057 + +//Classic/TranZit Maps rotation +sv_maprotation "exec zm_classic_tomb.cfg map zm_tomb" + +//Survival Maps rotation +//sv_maprotation "exec zm_standard_town.cfg map zm_transit" + +//Grief Maps rotation +//sv_maprotation "exec zm_grief_town.cfg map zm_transit exec zm_grief_transit.cfg map zm_transit exec zm_grief_farm.cfg map zm_transit exec zm_grief_cellblock.cfg map zm_prison exec zm_grief_street.cfg map zm_buried" + +//Turned Maps rotation +//sv_maprotation "exec zm_cleansed_diner.cfg map zm_transit_dr exec zm_cleansed_street.cfg map zm_buried" + +//Congratulations. You reached the end of this file. Leave map_rotate down below or else the server will not start after launch... +map_rotate diff --git a/t6/dedicated_zmorigin2.cfg b/t6/dedicated_zmorigin2.cfg new file mode 100644 index 0000000..2ef7485 --- /dev/null +++ b/t6/dedicated_zmorigin2.cfg @@ -0,0 +1,93 @@ +////////////////////////////////////////////////// +/// PlutoT6 ZM ServerConfiguration file // +/////////////////////////////////////////////////// +// This config best view with Notepad++ OR // +// other *nix compatible editors of your choice. // +/////////////////////////////////////////////////// +// Remove "//" in front of lines to allow the // +// server to read them. // +// Anything after "//" is a comment. // +////////////////////////////////////////////////// +// GENERAL SETTINGS // +////////////////////////////////////////////////// +//g_password "aaa" // Require a password to join your server. (Use "password " to set it on the client before connecting) +sv_maxclients 4 // Maximum players that are allowed in your server. (1-8, default is 4) Keeping this at 1-4 is recommended to prevent game breaking bugs. +//zombies_minplayers 1 // Minimum players needed to start the game (1-8, default is 1). Do NOT set this higher than sv_maxclients! +//sv_minPing 0 // Minimum ping needed to the server? (NOT recommended to edit, terribly broken and inaccurate since ages!) +//sv_maxPing 400 // Maximum ping allowed to the server? (NOT recommended to edit, terribly broken and inaccurate since ages!) +//zm_gungame 1 // Enable Pluto's custom Gun Game? +//zm_sharpshooter 1 // Enable Pluto's custom Sharp Shooter? +//gts zmDifficulty 1 // Difficulty? 0 = Easy, 1 = Normal !!If set to easy it must be manually set on the client as well!! +demo_enabled 0 // Record matches as demo files? 1 = Enabled, 0 = Disabled (Very efficient <5MB per match for a full server) +sv_sayname "" // name server-side 'say' commands show up as +sv_voice "1" // Allow Voice Chat (0 = Disable 1 = Everyone hears you. 2 = Teams only) +sv_voicequality "9" // Voice Chat Quality. (0-9) Default is 3 (= Steam/Console quality). Use 9 for the best quality. +sv_allowAimAssist 1 // Allow Aim Assist on gamepads. (0 = Will lock the option on gamepad controls menu.) +sv_fix_zm_weapons true // Fix the SMR's ADS spread, 870 MCS's penetration damage and allow sprinting with Galvaknuckles +sv_patch_zm_weapons true // Apply Post DLC1 changes to tar21_zm, type95_zm, xm8_zm, an94_zm, hamr_zm, rpd_zm, pdw57_zm, kard_zm ? (only recoil changes) +////////////////////////////////////////////////// +//These options can also be configured individually on a map basis in each zm config in gamesettings. +////////////////////////////////////////////////// +//gts startRound 1 // Starting Round. Works on all maps. +//gts magic 1 // Remove all supernatural assistance? Only Survival and Grief have this option! +//gts headshotsonly 0 // Headshots only? Only Survival and Grief have this option! +//gts allowdogs 1 // Allow Hellhounds? Only Survival has this option! +//gts cleansedLoadout 1 // Allow players to choose their Loadout? Only Turned has this option! +//gts teamCount 2 // Sets the number of teams 2. Set to 2 by default when loading grief. +////////////////////////////////////////////////// +// B3, IW4MADMIN, GAME LOG & RCON SETTINGS // +////////////////////////////////////////////////// +g_logSync 2 // 0 only flush on game end, 1 flush when buffer full, 2 always flush after a write, 3 append to old logs. (Keep this at 2 if you plan on using a 3rd party admin tool) +g_log "logs\games_zmorigin2.log" // If you choose to use this make sure the filename is unique for each server! +rcon_password "rconAQW25wqa" // RemoteCONtrol password. !!Do NOT skip if you plan on using a 3rd party admin tool such as B3 or IW4m-Admin!! +rcon_rate_limit "0" // Rate limit RCon; limit is per IP; range is 0 to 10 000; value is in milliseconds. Lower this if you use IW4mA's Game Interface. +rconWhitelistAdd "127.0.0.1" // Command used to add an IP address to the whitelist. When no IP is added all IPs can send rcon commands. +rconWhitelistAdd "198.251.84.64" // If it is set only the whitelisted IPs and loopback (127.0.0.0/8) can send commands. + +seta sv_wwwBaseURL "" // Configure the URL to Fast DL mods from. (i.e. http://domain.tld/iw5) +seta fs_game "" // What mod are we loading? (i.e. "mods/MyMod") +////////////////////////////////////////////////// +//The "exec zm__.cfg" line sets the dvars for the location and gametype for you. This .cfg applies to all following maps in the rotation like MP until another .cfg is defined. +//You may modify these .cfgs in gamesettings. Make sure only one sv_maprotation line is uncommented or you may run into errors on starting or joining the server. +//Currently rotating the map using sv_maprotation doesn't work properly, i.e. clients will be kicked with an error when the map rotates to another map. +//It's recommended to only include one map in your sv_maprotation for this reason. +////////////////////////////////////////////////////////////////////////////// +// Maps and the matching configs // +////////////////////////////////////////////////////////////////////////////// +// Buried - exec zm_classic_processing.cfg map zm_buried // +// Buried Turned - exec zm_cleansed_street.cfg map zm_buried // +// Buried Grief - exec zm_grief_street.cfg map zm_buried // +// Die Rise - exec zm_classic_rooftop.cfg map zm_highrise // +// Mob of The Dead - exec zm_classic_prison.cfg map zm_prison // +// Mob of The Dead Grief - exec zm_grief_cellblock.cfg map zm_prison // +// Nuketown - exec zm_standard_nuked.cfg map zm_nuked // +// Origins - exec zm_classic_tomb.cfg map zm_tomb // +// Tranzit - exec zm_classic_transit.cfg map zm_transit // +// Tranzit Farm Survival - exec zm_standard_farm.cfg map zm_transit // +// Tranzit Town Survival - exec zm_standard_town.cfg map zm_transit // +// Tranzit Bus Depot Survival - exec zm_standard_transit.cfg map zm_transit // +// Tranzit Farm Grief - exec zm_grief_farm.cfg map zm_transit // +// Tranzit Town Grief - exec zm_grief_town.cfg map zm_transit // +// Tranzit Bus Depot Grief - exec zm_grief_transit.cfg map zm_transit // +// Tranzit Diner Turned - exec zm_cleansed_diner.cfg map zm_transit_dr // +////////////////////////////////////////////////////////////////////////////// +// Notes: +// Town/Tranzit servers will not natively spawn in tombstone since servers launch the maps in solo. +// --> https://forum.plutonium.pw/topic/124 +// Grief requires a fix otherwise teams won't balance resulting in clients crashing when a 5th player joins. +// --> https://forum.plutonium.pw/topic/4057 + +//Classic/TranZit Maps rotation +sv_maprotation "exec zm_classic_tomb.cfg map zm_tomb" + +//Survival Maps rotation +//sv_maprotation "exec zm_standard_town.cfg map zm_transit" + +//Grief Maps rotation +//sv_maprotation "exec zm_grief_town.cfg map zm_transit exec zm_grief_transit.cfg map zm_transit exec zm_grief_farm.cfg map zm_transit exec zm_grief_cellblock.cfg map zm_prison exec zm_grief_street.cfg map zm_buried" + +//Turned Maps rotation +//sv_maprotation "exec zm_cleansed_diner.cfg map zm_transit_dr exec zm_cleansed_street.cfg map zm_buried" + +//Congratulations. You reached the end of this file. Leave map_rotate down below or else the server will not start after launch... +map_rotate diff --git a/t6/dedicated_zmpanzer.cfg b/t6/dedicated_zmpanzer.cfg new file mode 100644 index 0000000..8e30583 --- /dev/null +++ b/t6/dedicated_zmpanzer.cfg @@ -0,0 +1,93 @@ +////////////////////////////////////////////////// +/// PlutoT6 ZM ServerConfiguration file // +/////////////////////////////////////////////////// +// This config best view with Notepad++ OR // +// other *nix compatible editors of your choice. // +/////////////////////////////////////////////////// +// Remove "//" in front of lines to allow the // +// server to read them. // +// Anything after "//" is a comment. // +////////////////////////////////////////////////// +// GENERAL SETTINGS // +////////////////////////////////////////////////// +//g_password "panzos" // Require a password to join your server. (Use "password " to set it on the client before connecting) +sv_maxclients 8 // Maximum players that are allowed in your server. (1-8, default is 4) Keeping this at 1-4 is recommended to prevent game breaking bugs. +//zombies_minplayers 2 // Minimum players needed to start the game (1-8, default is 1). Do NOT set this higher than sv_maxclients! +//sv_minPing 0 // Minimum ping needed to the server? (NOT recommended to edit, terribly broken and inaccurate since ages!) +//sv_maxPing 400 // Maximum ping allowed to the server? (NOT recommended to edit, terribly broken and inaccurate since ages!) +//zm_gungame 1 // Enable Pluto's custom Gun Game? +//zm_sharpshooter 1 // Enable Pluto's custom Sharp Shooter? +//gts zmDifficulty 1 // Difficulty? 0 = Easy, 1 = Normal !!If set to easy it must be manually set on the client as well!! +demo_enabled 0 // Record matches as demo files? 1 = Enabled, 0 = Disabled (Very efficient <5MB per match for a full server) +sv_sayname "" // name server-side 'say' commands show up as +sv_voice "1" // Allow Voice Chat (0 = Disable 1 = Everyone hears you. 2 = Teams only) +sv_voicequality "9" // Voice Chat Quality. (0-9) Default is 3 (= Steam/Console quality). Use 9 for the best quality. +sv_allowAimAssist 1 // Allow Aim Assist on gamepads. (0 = Will lock the option on gamepad controls menu.) +sv_fix_zm_weapons true // Fix the SMR's ADS spread, 870 MCS's penetration damage and allow sprinting with Galvaknuckles +sv_patch_zm_weapons true // Apply Post DLC1 changes to tar21_zm, type95_zm, xm8_zm, an94_zm, hamr_zm, rpd_zm, pdw57_zm, kard_zm ? (only recoil changes) +////////////////////////////////////////////////// +//These options can also be configured individually on a map basis in each zm config in gamesettings. +////////////////////////////////////////////////// +//gts startRound 1 // Starting Round. Works on all maps. +//gts magic 1 // Remove all supernatural assistance? Only Survival and Grief have this option! +//gts headshotsonly 0 // Headshots only? Only Survival and Grief have this option! +//gts allowdogs 1 // Allow Hellhounds? Only Survival has this option! +//gts cleansedLoadout 1 // Allow players to choose their Loadout? Only Turned has this option! +//gts teamCount 2 // Sets the number of teams 2. Set to 2 by default when loading grief. +////////////////////////////////////////////////// +// B3, IW4MADMIN, GAME LOG & RCON SETTINGS // +////////////////////////////////////////////////// +g_logSync 2 // 0 only flush on game end, 1 flush when buffer full, 2 always flush after a write, 3 append to old logs. (Keep this at 2 if you plan on using a 3rd party admin tool) +g_log "logs\games_zmpanzer.log" // If you choose to use this make sure the filename is unique for each server! +rcon_password "rconAQW25wqa" // RemoteCONtrol password. !!Do NOT skip if you plan on using a 3rd party admin tool such as B3 or IW4m-Admin!! +rcon_rate_limit "0" // Rate limit RCon; limit is per IP; range is 0 to 10 000; value is in milliseconds. Lower this if you use IW4mA's Game Interface. +rconWhitelistAdd "127.0.0.1" // Command used to add an IP address to the whitelist. When no IP is added all IPs can send rcon commands. +rconWhitelistAdd "198.251.84.64" // If it is set only the whitelisted IPs and loopback (127.0.0.0/8) can send commands. + +seta sv_wwwBaseURL "" // Configure the URL to Fast DL mods from. (i.e. http://domain.tld/iw5) +seta fs_game "" // What mod are we loading? (i.e. "mods/MyMod") +////////////////////////////////////////////////// +//The "exec zm__.cfg" line sets the dvars for the location and gametype for you. This .cfg applies to all following maps in the rotation like MP until another .cfg is defined. +//You may modify these .cfgs in gamesettings. Make sure only one sv_maprotation line is uncommented or you may run into errors on starting or joining the server. +//Currently rotating the map using sv_maprotation doesn't work properly, i.e. clients will be kicked with an error when the map rotates to another map. +//It's recommended to only include one map in your sv_maprotation for this reason. +////////////////////////////////////////////////////////////////////////////// +// Maps and the matching configs // +////////////////////////////////////////////////////////////////////////////// +// Buried - exec zm_classic_processing.cfg map zm_buried // +// Buried Turned - exec zm_cleansed_street.cfg map zm_buried // +// Buried Grief - exec zm_grief_street.cfg map zm_buried // +// Die Rise - exec zm_classic_rooftop.cfg map zm_highrise // +// Mob of The Dead - exec zm_classic_prison.cfg map zm_prison // +// Mob of The Dead Grief - exec zm_grief_cellblock.cfg map zm_prison // +// Nuketown - exec zm_standard_nuked.cfg map zm_nuked // +// Origins - exec zm_classic_tomb.cfg map zm_tomb // +// Tranzit - exec zm_classic_transit.cfg map zm_transit // +// Tranzit Farm Survival - exec zm_standard_farm.cfg map zm_transit // +// Tranzit Town Survival - exec zm_standard_town.cfg map zm_transit // +// Tranzit Bus Depot Survival - exec zm_standard_transit.cfg map zm_transit // +// Tranzit Farm Grief - exec zm_grief_farm.cfg map zm_transit // +// Tranzit Town Grief - exec zm_grief_town.cfg map zm_transit // +// Tranzit Bus Depot Grief - exec zm_grief_transit.cfg map zm_transit // +// Tranzit Diner Turned - exec zm_cleansed_diner.cfg map zm_transit_dr // +////////////////////////////////////////////////////////////////////////////// +// Notes: +// Town/Tranzit servers will not natively spawn in tombstone since servers launch the maps in solo. +// --> https://forum.plutonium.pw/topic/124 +// Grief requires a fix otherwise teams won't balance resulting in clients crashing when a 5th player joins. +// --> https://forum.plutonium.pw/topic/4057 + +//Classic/TranZit Maps rotation +sv_maprotation "exec zm_classic_tomb.cfg map zm_tomb" + +//Survival Maps rotation +//sv_maprotation "exec zm_standard_town.cfg map zm_transit" + +//Grief Maps rotation +//sv_maprotation "exec zm_grief_town.cfg map zm_transit exec zm_grief_transit.cfg map zm_transit exec zm_grief_farm.cfg map zm_transit exec zm_grief_cellblock.cfg map zm_prison exec zm_grief_street.cfg map zm_buried" + +//Turned Maps rotation +//sv_maprotation "exec zm_cleansed_diner.cfg map zm_transit_dr exec zm_cleansed_street.cfg map zm_buried" + +//Congratulations. You reached the end of this file. Leave map_rotate down below or else the server will not start after launch... +map_rotate diff --git a/t6/dedicated_zmprivate.cfg b/t6/dedicated_zmprivate.cfg new file mode 100644 index 0000000..90d0107 --- /dev/null +++ b/t6/dedicated_zmprivate.cfg @@ -0,0 +1,93 @@ +////////////////////////////////////////////////// +/// PlutoT6 ZM ServerConfiguration file // +/////////////////////////////////////////////////// +// This config best view with Notepad++ OR // +// other *nix compatible editors of your choice. // +/////////////////////////////////////////////////// +// Remove "//" in front of lines to allow the // +// server to read them. // +// Anything after "//" is a comment. // +////////////////////////////////////////////////// +// GENERAL SETTINGS // +////////////////////////////////////////////////// +//g_password "tournamentultimiss" // Require a password to join your server. (Use "password " to set it on the client before connecting) +sv_maxclients 8 // Maximum players that are allowed in your server. (1-8, default is 4) Keeping this at 1-4 is recommended to prevent game breaking bugs. +//zombies_minplayers 3 // Minimum players needed to start the game (1-8, default is 1). Do NOT set this higher than sv_maxclients! +//sv_minPing 0 // Minimum ping needed to the server? (NOT recommended to edit, terribly broken and inaccurate since ages!) +//sv_maxPing 400 // Maximum ping allowed to the server? (NOT recommended to edit, terribly broken and inaccurate since ages!) +//zm_gungame 1 // Enable Pluto's custom Gun Game? +//zm_sharpshooter 1 // Enable Pluto's custom Sharp Shooter? +//gts zmDifficulty 1 // Difficulty? 0 = Easy, 1 = Normal !!If set to easy it must be manually set on the client as well!! +demo_enabled 0 // Record matches as demo files? 1 = Enabled, 0 = Disabled (Very efficient <5MB per match for a full server) +sv_sayname "" // name server-side 'say' commands show up as +sv_voice "1" // Allow Voice Chat (0 = Disable 1 = Everyone hears you. 2 = Teams only) +sv_voicequality "9" // Voice Chat Quality. (0-9) Default is 3 (= Steam/Console quality). Use 9 for the best quality. +sv_allowAimAssist 1 // Allow Aim Assist on gamepads. (0 = Will lock the option on gamepad controls menu.) +sv_fix_zm_weapons true // Fix the SMR's ADS spread, 870 MCS's penetration damage and allow sprinting with Galvaknuckles +sv_patch_zm_weapons true // Apply Post DLC1 changes to tar21_zm, type95_zm, xm8_zm, an94_zm, hamr_zm, rpd_zm, pdw57_zm, kard_zm ? (only recoil changes) +////////////////////////////////////////////////// +//These options can also be configured individually on a map basis in each zm config in gamesettings. +////////////////////////////////////////////////// +//gts startRound 1 // Starting Round. Works on all maps. +//gts magic 1 // Remove all supernatural assistance? Only Survival and Grief have this option! +//gts headshotsonly 0 // Headshots only? Only Survival and Grief have this option! +//gts allowdogs 1 // Allow Hellhounds? Only Survival has this option! +//gts cleansedLoadout 1 // Allow players to choose their Loadout? Only Turned has this option! +//gts teamCount 2 // Sets the number of teams 2. Set to 2 by default when loading grief. +////////////////////////////////////////////////// +// B3, IW4MADMIN, GAME LOG & RCON SETTINGS // +////////////////////////////////////////////////// +g_logSync 2 // 0 only flush on game end, 1 flush when buffer full, 2 always flush after a write, 3 append to old logs. (Keep this at 2 if you plan on using a 3rd party admin tool) +g_log "logs\games_zmprivate.log" // If you choose to use this make sure the filename is unique for each server! +rcon_password "rconAQW25wqa" // RemoteCONtrol password. !!Do NOT skip if you plan on using a 3rd party admin tool such as B3 or IW4m-Admin!! +rcon_rate_limit "0" // Rate limit RCon; limit is per IP; range is 0 to 10 000; value is in milliseconds. Lower this if you use IW4mA's Game Interface. +rconWhitelistAdd "127.0.0.1" // Command used to add an IP address to the whitelist. When no IP is added all IPs can send rcon commands. +rconWhitelistAdd "198.251.84.64" // If it is set only the whitelisted IPs and loopback (127.0.0.0/8) can send commands. + +seta sv_wwwBaseURL "" // Configure the URL to Fast DL mods from. (i.e. http://domain.tld/iw5) +seta fs_game "" // What mod are we loading? (i.e. "mods/MyMod") +////////////////////////////////////////////////// +//The "exec zm__.cfg" line sets the dvars for the location and gametype for you. This .cfg applies to all following maps in the rotation like MP until another .cfg is defined. +//You may modify these .cfgs in gamesettings. Make sure only one sv_maprotation line is uncommented or you may run into errors on starting or joining the server. +//Currently rotating the map using sv_maprotation doesn't work properly, i.e. clients will be kicked with an error when the map rotates to another map. +//It's recommended to only include one map in your sv_maprotation for this reason. +////////////////////////////////////////////////////////////////////////////// +// Maps and the matching configs // +////////////////////////////////////////////////////////////////////////////// +// Buried - exec zm_classic_processing.cfg map zm_buried // +// Buried Turned - exec zm_cleansed_street.cfg map zm_buried // +// Buried Grief - exec zm_grief_street.cfg map zm_buried // +// Die Rise - exec zm_classic_rooftop.cfg map zm_highrise // +// Mob of The Dead - exec zm_classic_prison.cfg map zm_prison // +// Mob of The Dead Grief - exec zm_grief_cellblock.cfg map zm_prison // +// Nuketown - exec zm_standard_nuked.cfg map zm_nuked // +// Origins - exec zm_classic_tomb.cfg map zm_tomb // +// Tranzit - exec zm_classic_transit.cfg map zm_transit // +// Tranzit Farm Survival - exec zm_standard_farm.cfg map zm_transit // +// Tranzit Town Survival - exec zm_standard_town.cfg map zm_transit // +// Tranzit Bus Depot Survival - exec zm_standard_transit.cfg map zm_transit // +// Tranzit Farm Grief - exec zm_grief_farm.cfg map zm_transit // +// Tranzit Town Grief - exec zm_grief_town.cfg map zm_transit // +// Tranzit Bus Depot Grief - exec zm_grief_transit.cfg map zm_transit // +// Tranzit Diner Turned - exec zm_cleansed_diner.cfg map zm_transit_dr // +////////////////////////////////////////////////////////////////////////////// +// Notes: +// Town/Tranzit servers will not natively spawn in tombstone since servers launch the maps in solo. +// --> https://forum.plutonium.pw/topic/124 +// Grief requires a fix otherwise teams won't balance resulting in clients crashing when a 5th player joins. +// --> https://forum.plutonium.pw/topic/4057 + +//Classic/TranZit Maps rotation +sv_maprotation "exec zm_classic_prison.cfg map zm_prison" + +//Survival Maps rotation +//sv_maprotation "exec zm_standard_town.cfg map zm_transit" + +//Grief Maps rotation +//sv_maprotation "exec zm_grief_town.cfg map zm_transit exec zm_grief_transit.cfg map zm_transit exec zm_grief_farm.cfg map zm_transit exec zm_grief_cellblock.cfg map zm_prison exec zm_grief_street.cfg map zm_buried" + +//Turned Maps rotation +//sv_maprotation "exec zm_cleansed_diner.cfg map zm_transit_dr exec zm_cleansed_street.cfg map zm_buried" + +//Congratulations. You reached the end of this file. Leave map_rotate down below or else the server will not start after launch... +map_rotate diff --git a/t6/dedicated_zmtitb.cfg b/t6/dedicated_zmtitb.cfg new file mode 100644 index 0000000..325f17d --- /dev/null +++ b/t6/dedicated_zmtitb.cfg @@ -0,0 +1,93 @@ +////////////////////////////////////////////////// +/// PlutoT6 ZM ServerConfiguration file // +/////////////////////////////////////////////////// +// This config best view with Notepad++ OR // +// other *nix compatible editors of your choice. // +/////////////////////////////////////////////////// +// Remove "//" in front of lines to allow the // +// server to read them. // +// Anything after "//" is a comment. // +////////////////////////////////////////////////// +// GENERAL SETTINGS // +////////////////////////////////////////////////// +//g_password "" // Require a password to join your server. (Use "password " to set it on the client before connecting) +sv_maxclients 8 // Maximum players that are allowed in your server. (1-8, default is 4) Keeping this at 1-4 is recommended to prevent game breaking bugs. +//zombies_minplayers 1 // Minimum players needed to start the game (1-8, default is 1). Do NOT set this higher than sv_maxclients! +//sv_minPing 0 // Minimum ping needed to the server? (NOT recommended to edit, terribly broken and inaccurate since ages!) +//sv_maxPing 400 // Maximum ping allowed to the server? (NOT recommended to edit, terribly broken and inaccurate since ages!) +//zm_gungame 1 // Enable Pluto's custom Gun Game? +//zm_sharpshooter 1 // Enable Pluto's custom Sharp Shooter? +//gts zmDifficulty 1 // Difficulty? 0 = Easy, 1 = Normal !!If set to easy it must be manually set on the client as well!! +demo_enabled 0 // Record matches as demo files? 1 = Enabled, 0 = Disabled (Very efficient <5MB per match for a full server) +sv_sayname "" // name server-side 'say' commands show up as +sv_voice "1" // Allow Voice Chat (0 = Disable 1 = Everyone hears you. 2 = Teams only) +sv_voicequality "9" // Voice Chat Quality. (0-9) Default is 3 (= Steam/Console quality). Use 9 for the best quality. +sv_allowAimAssist 1 // Allow Aim Assist on gamepads. (0 = Will lock the option on gamepad controls menu.) +sv_fix_zm_weapons true // Fix the SMR's ADS spread, 870 MCS's penetration damage and allow sprinting with Galvaknuckles +sv_patch_zm_weapons true // Apply Post DLC1 changes to tar21_zm, type95_zm, xm8_zm, an94_zm, hamr_zm, rpd_zm, pdw57_zm, kard_zm ? (only recoil changes) +////////////////////////////////////////////////// +//These options can also be configured individually on a map basis in each zm config in gamesettings. +////////////////////////////////////////////////// +//gts startRound 1 // Starting Round. Works on all maps. +//gts magic 1 // Remove all supernatural assistance? Only Survival and Grief have this option! +//gts headshotsonly 0 // Headshots only? Only Survival and Grief have this option! +//gts allowdogs 1 // Allow Hellhounds? Only Survival has this option! +//gts cleansedLoadout 1 // Allow players to choose their Loadout? Only Turned has this option! +//gts teamCount 2 // Sets the number of teams 2. Set to 2 by default when loading grief. +////////////////////////////////////////////////// +// B3, IW4MADMIN, GAME LOG & RCON SETTINGS // +////////////////////////////////////////////////// +g_logSync 2 // 0 only flush on game end, 1 flush when buffer full, 2 always flush after a write, 3 append to old logs. (Keep this at 2 if you plan on using a 3rd party admin tool) +g_log "logs\games_zmtitb.log" // If you choose to use this make sure the filename is unique for each server! +rcon_password "rconAQW25wqa" // RemoteCONtrol password. !!Do NOT skip if you plan on using a 3rd party admin tool such as B3 or IW4m-Admin!! +rcon_rate_limit "0" // Rate limit RCon; limit is per IP; range is 0 to 10 000; value is in milliseconds. Lower this if you use IW4mA's Game Interface. +rconWhitelistAdd "127.0.0.1" // Command used to add an IP address to the whitelist. When no IP is added all IPs can send rcon commands. +rconWhitelistAdd "198.251.84.64" // If it is set only the whitelisted IPs and loopback (127.0.0.0/8) can send commands. + +seta sv_wwwBaseURL "" // Configure the URL to Fast DL mods from. (i.e. http://domain.tld/iw5) +seta fs_game "" // What mod are we loading? (i.e. "mods/MyMod") +////////////////////////////////////////////////// +//The "exec zm__.cfg" line sets the dvars for the location and gametype for you. This .cfg applies to all following maps in the rotation like MP until another .cfg is defined. +//You may modify these .cfgs in gamesettings. Make sure only one sv_maprotation line is uncommented or you may run into errors on starting or joining the server. +//Currently rotating the map using sv_maprotation doesn't work properly, i.e. clients will be kicked with an error when the map rotates to another map. +//It's recommended to only include one map in your sv_maprotation for this reason. +////////////////////////////////////////////////////////////////////////////// +// Maps and the matching configs // +////////////////////////////////////////////////////////////////////////////// +// Buried - exec zm_classic_processing.cfg map zm_buried // +// Buried Turned - exec zm_cleansed_street.cfg map zm_buried // +// Buried Grief - exec zm_grief_street.cfg map zm_buried // +// Die Rise - exec zm_classic_rooftop.cfg map zm_highrise // +// Mob of The Dead - exec zm_classic_prison.cfg map zm_prison // +// Mob of The Dead Grief - exec zm_grief_cellblock.cfg map zm_prison // +// Nuketown - exec zm_standard_nuked.cfg map zm_nuked // +// Origins - exec zm_classic_tomb.cfg map zm_tomb // +// Tranzit - exec zm_classic_transit.cfg map zm_transit // +// Tranzit Farm Survival - exec zm_standard_farm.cfg map zm_transit // +// Tranzit Town Survival - exec zm_standard_town.cfg map zm_transit // +// Tranzit Bus Depot Survival - exec zm_standard_transit.cfg map zm_transit // +// Tranzit Farm Grief - exec zm_grief_farm.cfg map zm_transit // +// Tranzit Town Grief - exec zm_grief_town.cfg map zm_transit // +// Tranzit Bus Depot Grief - exec zm_grief_transit.cfg map zm_transit // +// Tranzit Diner Turned - exec zm_cleansed_diner.cfg map zm_transit_dr // +////////////////////////////////////////////////////////////////////////////// +// Notes: +// Town/Tranzit servers will not natively spawn in tombstone since servers launch the maps in solo. +// --> https://forum.plutonium.pw/topic/124 +// Grief requires a fix otherwise teams won't balance resulting in clients crashing when a 5th player joins. +// --> https://forum.plutonium.pw/topic/4057 + +//Classic/TranZit Maps rotation +sv_maprotation "exec zm_classic_transit.cfg map zm_transit" + +//Survival Maps rotation +//sv_maprotation "exec zm_standard_town.cfg map zm_transit" + +//Grief Maps rotation +//sv_maprotation "exec zm_grief_town.cfg map zm_transit exec zm_grief_transit.cfg map zm_transit exec zm_grief_farm.cfg map zm_transit exec zm_grief_cellblock.cfg map zm_prison exec zm_grief_street.cfg map zm_buried" + +//Turned Maps rotation +//sv_maprotation "exec zm_cleansed_diner.cfg map zm_transit_dr exec zm_cleansed_street.cfg map zm_buried" + +//Congratulations. You reached the end of this file. Leave map_rotate down below or else the server will not start after launch... +map_rotate diff --git a/t6/dedicated_zmtown.cfg b/t6/dedicated_zmtown.cfg new file mode 100644 index 0000000..3865684 --- /dev/null +++ b/t6/dedicated_zmtown.cfg @@ -0,0 +1,93 @@ +////////////////////////////////////////////////// +/// PlutoT6 ZM ServerConfiguration file // +/////////////////////////////////////////////////// +// This config best view with Notepad++ OR // +// other *nix compatible editors of your choice. // +/////////////////////////////////////////////////// +// Remove "//" in front of lines to allow the // +// server to read them. // +// Anything after "//" is a comment. // +////////////////////////////////////////////////// +// GENERAL SETTINGS // +////////////////////////////////////////////////// +g_password "" // Require a password to join your server. (Use "password " to set it on the client before connecting) +sv_maxclients 8 // Maximum players that are allowed in your server. (1-8, default is 4) Keeping this at 1-4 is recommended to prevent game breaking bugs. +//zombies_minplayers 1 // Minimum players needed to start the game (1-8, default is 1). Do NOT set this higher than sv_maxclients! +//sv_minPing 0 // Minimum ping needed to the server? (NOT recommended to edit, terribly broken and inaccurate since ages!) +//sv_maxPing 400 // Maximum ping allowed to the server? (NOT recommended to edit, terribly broken and inaccurate since ages!) +//zm_gungame 1 // Enable Pluto's custom Gun Game? +//zm_sharpshooter 1 // Enable Pluto's custom Sharp Shooter? +//gts zmDifficulty 1 // Difficulty? 0 = Easy, 1 = Normal !!If set to easy it must be manually set on the client as well!! +demo_enabled 0 // Record matches as demo files? 1 = Enabled, 0 = Disabled (Very efficient <5MB per match for a full server) +sv_sayname "" // name server-side 'say' commands show up as +sv_voice "1" // Allow Voice Chat (0 = Disable 1 = Everyone hears you. 2 = Teams only) +sv_voicequality "9" // Voice Chat Quality. (0-9) Default is 3 (= Steam/Console quality). Use 9 for the best quality. +sv_allowAimAssist 1 // Allow Aim Assist on gamepads. (0 = Will lock the option on gamepad controls menu.) +sv_fix_zm_weapons true // Fix the SMR's ADS spread, 870 MCS's penetration damage and allow sprinting with Galvaknuckles +sv_patch_zm_weapons true // Apply Post DLC1 changes to tar21_zm, type95_zm, xm8_zm, an94_zm, hamr_zm, rpd_zm, pdw57_zm, kard_zm ? (only recoil changes) +////////////////////////////////////////////////// +//These options can also be configured individually on a map basis in each zm config in gamesettings. +////////////////////////////////////////////////// +//gts startRound 29 // Starting Round. Works on all maps. +//gts magic 1 // Remove all supernatural assistance? Only Survival and Grief have this option! +//gts headshotsonly 0 // Headshots only? Only Survival and Grief have this option! +//gts allowdogs 1 // Allow Hellhounds? Only Survival has this option! +//gts cleansedLoadout 1 // Allow players to choose their Loadout? Only Turned has this option! +//gts teamCount 2 // Sets the number of teams 2. Set to 2 by default when loading grief. +////////////////////////////////////////////////// +// B3, IW4MADMIN, GAME LOG & RCON SETTINGS // +////////////////////////////////////////////////// +g_logSync 2 // 0 only flush on game end, 1 flush when buffer full, 2 always flush after a write, 3 append to old logs. (Keep this at 2 if you plan on using a 3rd party admin tool) +g_log "logs\games_zmtown.log" // If you choose to use this make sure the filename is unique for each server! +rcon_password "rconAQW25wqa" // RemoteCONtrol password. !!Do NOT skip if you plan on using a 3rd party admin tool such as B3 or IW4m-Admin!! +rcon_rate_limit "0" // Rate limit RCon; limit is per IP; range is 0 to 10 000; value is in milliseconds. Lower this if you use IW4mA's Game Interface. +rconWhitelistAdd "127.0.0.1" // Command used to add an IP address to the whitelist. When no IP is added all IPs can send rcon commands. +rconWhitelistAdd "198.251.84.64" // If it is set only the whitelisted IPs and loopback (127.0.0.0/8) can send commands. + +seta sv_wwwBaseURL "" // Configure the URL to Fast DL mods from. (i.e. http://domain.tld/iw5) +seta fs_game "" // What mod are we loading? (i.e. "mods/MyMod") +////////////////////////////////////////////////// +//The "exec zm__.cfg" line sets the dvars for the location and gametype for you. This .cfg applies to all following maps in the rotation like MP until another .cfg is defined. +//You may modify these .cfgs in gamesettings. Make sure only one sv_maprotation line is uncommented or you may run into errors on starting or joining the server. +//Currently rotating the map using sv_maprotation doesn't work properly, i.e. clients will be kicked with an error when the map rotates to another map. +//It's recommended to only include one map in your sv_maprotation for this reason. +////////////////////////////////////////////////////////////////////////////// +// Maps and the matching configs // +////////////////////////////////////////////////////////////////////////////// +// Buried - exec zm_classic_processing.cfg map zm_buried // +// Buried Turned - exec zm_cleansed_street.cfg map zm_buried // +// Buried Grief - exec zm_grief_street.cfg map zm_buried // +// Die Rise - exec zm_classic_rooftop.cfg map zm_highrise // +// Mob of The Dead - exec zm_classic_prison.cfg map zm_prison // +// Mob of The Dead Grief - exec zm_grief_cellblock.cfg map zm_prison // +// Nuketown - exec zm_standard_nuked.cfg map zm_nuked // +// Origins - exec zm_classic_tomb.cfg map zm_tomb // +// Tranzit - exec zm_classic_transit.cfg map zm_transit // +// Tranzit Farm Survival - exec zm_standard_farm.cfg map zm_transit // +// Tranzit Town Survival - exec zm_standard_town.cfg map zm_transit // +// Tranzit Bus Depot Survival - exec zm_standard_transit.cfg map zm_transit // +// Tranzit Farm Grief - exec zm_grief_farm.cfg map zm_transit // +// Tranzit Town Grief - exec zm_grief_town.cfg map zm_transit // +// Tranzit Bus Depot Grief - exec zm_grief_transit.cfg map zm_transit // +// Tranzit Diner Turned - exec zm_cleansed_diner.cfg map zm_transit_dr // +////////////////////////////////////////////////////////////////////////////// +// Notes: +// Town/Tranzit servers will not natively spawn in tombstone since servers launch the maps in solo. +// --> https://forum.plutonium.pw/topic/124 +// Grief requires a fix otherwise teams wont balance resulting in clients crashing when a 5th player joins. +// --> https://forum.plutonium.pw/topic/4057 + +//Classic/TranZit Maps rotation +//sv_maprotation "exec zm_classic_tomb.cfg map zm_tomb" + +//Survival Maps rotation +sv_maprotation "exec zm_standard_town.cfg map zm_transit" + +//Grief Maps rotation +//sv_maprotation "exec zm_grief_town.cfg map zm_transit exec zm_grief_transit.cfg map zm_transit exec zm_grief_farm.cfg map zm_transit exec zm_grief_cellblock.cfg map zm_prison exec zm_grief_street.cfg map zm_buried" + +//Turned Maps rotation +//sv_maprotation "exec zm_cleansed_diner.cfg map zm_transit_dr exec zm_cleansed_street.cfg map zm_buried" + +//Congratulations. You reached the end of this file. Leave map_rotate down below or else the server will not start after launch... +map_rotate diff --git a/t6/dedicated_zmtown2.cfg b/t6/dedicated_zmtown2.cfg new file mode 100644 index 0000000..2781e90 --- /dev/null +++ b/t6/dedicated_zmtown2.cfg @@ -0,0 +1,93 @@ +////////////////////////////////////////////////// +/// PlutoT6 ZM ServerConfiguration file // +/////////////////////////////////////////////////// +// This config best view with Notepad++ OR // +// other *nix compatible editors of your choice. // +/////////////////////////////////////////////////// +// Remove "//" in front of lines to allow the // +// server to read them. // +// Anything after "//" is a comment. // +////////////////////////////////////////////////// +// GENERAL SETTINGS // +////////////////////////////////////////////////// +//g_password "" // Require a password to join your server. (Use "password " to set it on the client before connecting) +sv_maxclients 8 // Maximum players that are allowed in your server. (1-8, default is 4) Keeping this at 1-4 is recommended to prevent game breaking bugs. +//zombies_minplayers 1 // Minimum players needed to start the game (1-8, default is 1). Do NOT set this higher than sv_maxclients! +//sv_minPing 0 // Minimum ping needed to the server? (NOT recommended to edit, terribly broken and inaccurate since ages!) +//sv_maxPing 400 // Maximum ping allowed to the server? (NOT recommended to edit, terribly broken and inaccurate since ages!) +//zm_gungame 1 // Enable Pluto's custom Gun Game? +//zm_sharpshooter 1 // Enable Pluto's custom Sharp Shooter? +//gts zmDifficulty 1 // Difficulty? 0 = Easy, 1 = Normal !!If set to easy it must be manually set on the client as well!! +demo_enabled 0 // Record matches as demo files? 1 = Enabled, 0 = Disabled (Very efficient <5MB per match for a full server) +sv_sayname "" // name server-side 'say' commands show up as +sv_voice "1" // Allow Voice Chat (0 = Disable 1 = Everyone hears you. 2 = Teams only) +sv_voicequality "9" // Voice Chat Quality. (0-9) Default is 3 (= Steam/Console quality). Use 9 for the best quality. +sv_allowAimAssist 1 // Allow Aim Assist on gamepads. (0 = Will lock the option on gamepad controls menu.) +sv_fix_zm_weapons true // Fix the SMR's ADS spread, 870 MCS's penetration damage and allow sprinting with Galvaknuckles +sv_patch_zm_weapons true // Apply Post DLC1 changes to tar21_zm, type95_zm, xm8_zm, an94_zm, hamr_zm, rpd_zm, pdw57_zm, kard_zm ? (only recoil changes) +////////////////////////////////////////////////// +//These options can also be configured individually on a map basis in each zm config in gamesettings. +////////////////////////////////////////////////// +//gts startRound 23 // Starting Round. Works on all maps. +//gts magic 1 // Remove all supernatural assistance? Only Survival and Grief have this option! +//gts headshotsonly 0 // Headshots only? Only Survival and Grief have this option! +//gts allowdogs 1 // Allow Hellhounds? Only Survival has this option! +//gts cleansedLoadout 1 // Allow players to choose their Loadout? Only Turned has this option! +//gts teamCount 2 // Sets the number of teams 2. Set to 2 by default when loading grief. +////////////////////////////////////////////////// +// B3, IW4MADMIN, GAME LOG & RCON SETTINGS // +////////////////////////////////////////////////// +g_logSync 2 // 0 only flush on game end, 1 flush when buffer full, 2 always flush after a write, 3 append to old logs. (Keep this at 2 if you plan on using a 3rd party admin tool) +g_log "logs\games_zmtown2.log" // If you choose to use this make sure the filename is unique for each server! +rcon_password "rconAQW25wqa" // RemoteCONtrol password. !!Do NOT skip if you plan on using a 3rd party admin tool such as B3 or IW4m-Admin!! +rcon_rate_limit "0" // Rate limit RCon; limit is per IP; range is 0 to 10 000; value is in milliseconds. Lower this if you use IW4mA's Game Interface. +rconWhitelistAdd "127.0.0.1" // Command used to add an IP address to the whitelist. When no IP is added all IPs can send rcon commands. +rconWhitelistAdd "198.251.84.64" // If it is set only the whitelisted IPs and loopback (127.0.0.0/8) can send commands. + +seta sv_wwwBaseURL "" // Configure the URL to Fast DL mods from. (i.e. http://domain.tld/iw5) +seta fs_game "" // What mod are we loading? (i.e. "mods/MyMod") +////////////////////////////////////////////////// +//The "exec zm__.cfg" line sets the dvars for the location and gametype for you. This .cfg applies to all following maps in the rotation like MP until another .cfg is defined. +//You may modify these .cfgs in gamesettings. Make sure only one sv_maprotation line is uncommented or you may run into errors on starting or joining the server. +//Currently rotating the map using sv_maprotation doesn't work properly, i.e. clients will be kicked with an error when the map rotates to another map. +//It's recommended to only include one map in your sv_maprotation for this reason. +////////////////////////////////////////////////////////////////////////////// +// Maps and the matching configs // +////////////////////////////////////////////////////////////////////////////// +// Buried - exec zm_classic_processing.cfg map zm_buried // +// Buried Turned - exec zm_cleansed_street.cfg map zm_buried // +// Buried Grief - exec zm_grief_street.cfg map zm_buried // +// Die Rise - exec zm_classic_rooftop.cfg map zm_highrise // +// Mob of The Dead - exec zm_classic_prison.cfg map zm_prison // +// Mob of The Dead Grief - exec zm_grief_cellblock.cfg map zm_prison // +// Nuketown - exec zm_standard_nuked.cfg map zm_nuked // +// Origins - exec zm_classic_tomb.cfg map zm_tomb // +// Tranzit - exec zm_classic_transit.cfg map zm_transit // +// Tranzit Farm Survival - exec zm_standard_farm.cfg map zm_transit // +// Tranzit Town Survival - exec zm_standard_town.cfg map zm_transit // +// Tranzit Bus Depot Survival - exec zm_standard_transit.cfg map zm_transit // +// Tranzit Farm Grief - exec zm_grief_farm.cfg map zm_transit // +// Tranzit Town Grief - exec zm_grief_town.cfg map zm_transit // +// Tranzit Bus Depot Grief - exec zm_grief_transit.cfg map zm_transit // +// Tranzit Diner Turned - exec zm_cleansed_diner.cfg map zm_transit_dr // +////////////////////////////////////////////////////////////////////////////// +// Notes: +// Town/Tranzit servers will not natively spawn in tombstone since servers launch the maps in solo. +// --> https://forum.plutonium.pw/topic/124 +// Grief requires a fix otherwise teams won't balance resulting in clients crashing when a 5th player joins. +// --> https://forum.plutonium.pw/topic/4057 + +//Classic/TranZit Maps rotation +//sv_maprotation "exec zm_classic_processing.cfg map zm_buried" + +//Survival Maps rotation +sv_maprotation "exec zm_standard_town.cfg map zm_transit" + +//Grief Maps rotation +//sv_maprotation "exec zm_grief_town.cfg map zm_transit exec zm_grief_transit.cfg map zm_transit exec zm_grief_farm.cfg map zm_transit exec zm_grief_cellblock.cfg map zm_prison exec zm_grief_street.cfg map zm_buried" + +//Turned Maps rotation +//sv_maprotation "exec zm_cleansed_diner.cfg map zm_transit_dr exec zm_cleansed_street.cfg map zm_buried" + +//Congratulations. You reached the end of this file. Leave map_rotate down below or else the server will not start after launch... +map_rotate diff --git a/t6/dedicated_zmtown3.cfg b/t6/dedicated_zmtown3.cfg new file mode 100644 index 0000000..8bf5a4c --- /dev/null +++ b/t6/dedicated_zmtown3.cfg @@ -0,0 +1,93 @@ +////////////////////////////////////////////////// +/// PlutoT6 ZM ServerConfiguration file // +/////////////////////////////////////////////////// +// This config best view with Notepad++ OR // +// other *nix compatible editors of your choice. // +/////////////////////////////////////////////////// +// Remove "//" in front of lines to allow the // +// server to read them. // +// Anything after "//" is a comment. // +////////////////////////////////////////////////// +// GENERAL SETTINGS // +////////////////////////////////////////////////// +//g_password "" // Require a password to join your server. (Use "password " to set it on the client before connecting) +sv_maxclients 8 // Maximum players that are allowed in your server. (1-8, default is 4) Keeping this at 1-4 is recommended to prevent game breaking bugs. +//zombies_minplayers 1 // Minimum players needed to start the game (1-8, default is 1). Do NOT set this higher than sv_maxclients! +//sv_minPing 0 // Minimum ping needed to the server? (NOT recommended to edit, terribly broken and inaccurate since ages!) +//sv_maxPing 400 // Maximum ping allowed to the server? (NOT recommended to edit, terribly broken and inaccurate since ages!) +//zm_gungame 1 // Enable Pluto's custom Gun Game? +//zm_sharpshooter 1 // Enable Pluto's custom Sharp Shooter? +//gts zmDifficulty 1 // Difficulty? 0 = Easy, 1 = Normal !!If set to easy it must be manually set on the client as well!! +demo_enabled 0 // Record matches as demo files? 1 = Enabled, 0 = Disabled (Very efficient <5MB per match for a full server) +sv_sayname "" // name server-side 'say' commands show up as +sv_voice "1" // Allow Voice Chat (0 = Disable 1 = Everyone hears you. 2 = Teams only) +sv_voicequality "9" // Voice Chat Quality. (0-9) Default is 3 (= Steam/Console quality). Use 9 for the best quality. +sv_allowAimAssist 1 // Allow Aim Assist on gamepads. (0 = Will lock the option on gamepad controls menu.) +sv_fix_zm_weapons true // Fix the SMR's ADS spread, 870 MCS's penetration damage and allow sprinting with Galvaknuckles +sv_patch_zm_weapons true // Apply Post DLC1 changes to tar21_zm, type95_zm, xm8_zm, an94_zm, hamr_zm, rpd_zm, pdw57_zm, kard_zm ? (only recoil changes) +////////////////////////////////////////////////// +//These options can also be configured individually on a map basis in each zm config in gamesettings. +////////////////////////////////////////////////// +//gts startRound 23 // Starting Round. Works on all maps. +//gts magic 1 // Remove all supernatural assistance? Only Survival and Grief have this option! +//gts headshotsonly 0 // Headshots only? Only Survival and Grief have this option! +//gts allowdogs 1 // Allow Hellhounds? Only Survival has this option! +//gts cleansedLoadout 1 // Allow players to choose their Loadout? Only Turned has this option! +//gts teamCount 2 // Sets the number of teams 2. Set to 2 by default when loading grief. +////////////////////////////////////////////////// +// B3, IW4MADMIN, GAME LOG & RCON SETTINGS // +////////////////////////////////////////////////// +g_logSync 2 // 0 only flush on game end, 1 flush when buffer full, 2 always flush after a write, 3 append to old logs. (Keep this at 2 if you plan on using a 3rd party admin tool) +g_log "logs\games_zmtown3.log" // If you choose to use this make sure the filename is unique for each server! +rcon_password "rconAQW25wqa" // RemoteCONtrol password. !!Do NOT skip if you plan on using a 3rd party admin tool such as B3 or IW4m-Admin!! +rcon_rate_limit "0" // Rate limit RCon; limit is per IP; range is 0 to 10 000; value is in milliseconds. Lower this if you use IW4mA's Game Interface. +rconWhitelistAdd "127.0.0.1" // Command used to add an IP address to the whitelist. When no IP is added all IPs can send rcon commands. +rconWhitelistAdd "198.251.84.64" // If it is set only the whitelisted IPs and loopback (127.0.0.0/8) can send commands. + +seta sv_wwwBaseURL "" // Configure the URL to Fast DL mods from. (i.e. http://domain.tld/iw5) +seta fs_game "" // What mod are we loading? (i.e. "mods/MyMod") +////////////////////////////////////////////////// +//The "exec zm__.cfg" line sets the dvars for the location and gametype for you. This .cfg applies to all following maps in the rotation like MP until another .cfg is defined. +//You may modify these .cfgs in gamesettings. Make sure only one sv_maprotation line is uncommented or you may run into errors on starting or joining the server. +//Currently rotating the map using sv_maprotation doesn't work properly, i.e. clients will be kicked with an error when the map rotates to another map. +//It's recommended to only include one map in your sv_maprotation for this reason. +////////////////////////////////////////////////////////////////////////////// +// Maps and the matching configs // +////////////////////////////////////////////////////////////////////////////// +// Buried - exec zm_classic_processing.cfg map zm_buried // +// Buried Turned - exec zm_cleansed_street.cfg map zm_buried // +// Buried Grief - exec zm_grief_street.cfg map zm_buried // +// Die Rise - exec zm_classic_rooftop.cfg map zm_highrise // +// Mob of The Dead - exec zm_classic_prison.cfg map zm_prison // +// Mob of The Dead Grief - exec zm_grief_cellblock.cfg map zm_prison // +// Nuketown - exec zm_standard_nuked.cfg map zm_nuked // +// Origins - exec zm_classic_tomb.cfg map zm_tomb // +// Tranzit - exec zm_classic_transit.cfg map zm_transit // +// Tranzit Farm Survival - exec zm_standard_farm.cfg map zm_transit // +// Tranzit Town Survival - exec zm_standard_town.cfg map zm_transit // +// Tranzit Bus Depot Survival - exec zm_standard_transit.cfg map zm_transit // +// Tranzit Farm Grief - exec zm_grief_farm.cfg map zm_transit // +// Tranzit Town Grief - exec zm_grief_town.cfg map zm_transit // +// Tranzit Bus Depot Grief - exec zm_grief_transit.cfg map zm_transit // +// Tranzit Diner Turned - exec zm_cleansed_diner.cfg map zm_transit_dr // +////////////////////////////////////////////////////////////////////////////// +// Notes: +// Town/Tranzit servers will not natively spawn in tombstone since servers launch the maps in solo. +// --> https://forum.plutonium.pw/topic/124 +// Grief requires a fix otherwise teams won't balance resulting in clients crashing when a 5th player joins. +// --> https://forum.plutonium.pw/topic/4057 + +//Classic/TranZit Maps rotation +//sv_maprotation "exec zm_classic_processing.cfg map zm_buried" + +//Survival Maps rotation +sv_maprotation "exec zm_standard_town.cfg map zm_transit" + +//Grief Maps rotation +//sv_maprotation "exec zm_grief_town.cfg map zm_transit exec zm_grief_transit.cfg map zm_transit exec zm_grief_farm.cfg map zm_transit exec zm_grief_cellblock.cfg map zm_prison exec zm_grief_street.cfg map zm_buried" + +//Turned Maps rotation +//sv_maprotation "exec zm_cleansed_diner.cfg map zm_transit_dr exec zm_cleansed_street.cfg map zm_buried" + +//Congratulations. You reached the end of this file. Leave map_rotate down below or else the server will not start after launch... +map_rotate diff --git a/t6/dedicated_zmtranzit.cfg b/t6/dedicated_zmtranzit.cfg new file mode 100644 index 0000000..250cded --- /dev/null +++ b/t6/dedicated_zmtranzit.cfg @@ -0,0 +1,93 @@ +////////////////////////////////////////////////// +/// PlutoT6 ZM ServerConfiguration file // +/////////////////////////////////////////////////// +// This config best view with Notepad++ OR // +// other *nix compatible editors of your choice. // +/////////////////////////////////////////////////// +// Remove "//" in front of lines to allow the // +// server to read them. // +// Anything after "//" is a comment. // +////////////////////////////////////////////////// +// GENERAL SETTINGS // +////////////////////////////////////////////////// +//g_password "" // Require a password to join your server. (Use "password " to set it on the client before connecting) +sv_maxclients 8 // Maximum players that are allowed in your server. (1-8, default is 4) Keeping this at 1-4 is recommended to prevent game breaking bugs. +//zombies_minplayers 2 // Minimum players needed to start the game (1-8, default is 1). Do NOT set this higher than sv_maxclients! +//sv_minPing 0 // Minimum ping needed to the server? (NOT recommended to edit, terribly broken and inaccurate since ages!) +//sv_maxPing 400 // Maximum ping allowed to the server? (NOT recommended to edit, terribly broken and inaccurate since ages!) +//zm_gungame 1 // Enable Pluto's custom Gun Game? +//zm_sharpshooter 1 // Enable Pluto's custom Sharp Shooter? +//gts zmDifficulty 1 // Difficulty? 0 = Easy, 1 = Normal !!If set to easy it must be manually set on the client as well!! +demo_enabled 0 // Record matches as demo files? 1 = Enabled, 0 = Disabled (Very efficient <5MB per match for a full server) +sv_sayname "" // name server-side 'say' commands show up as +sv_voice "1" // Allow Voice Chat (0 = Disable 1 = Everyone hears you. 2 = Teams only) +sv_voicequality "9" // Voice Chat Quality. (0-9) Default is 3 (= Steam/Console quality). Use 9 for the best quality. +sv_allowAimAssist 1 // Allow Aim Assist on gamepads. (0 = Will lock the option on gamepad controls menu.) +sv_fix_zm_weapons true // Fix the SMR's ADS spread, 870 MCS's penetration damage and allow sprinting with Galvaknuckles +sv_patch_zm_weapons true // Apply Post DLC1 changes to tar21_zm, type95_zm, xm8_zm, an94_zm, hamr_zm, rpd_zm, pdw57_zm, kard_zm ? (only recoil changes) +////////////////////////////////////////////////// +//These options can also be configured individually on a map basis in each zm config in gamesettings. +////////////////////////////////////////////////// +//gts startRound 23 // Starting Round. Works on all maps. +//gts magic 1 // Remove all supernatural assistance? Only Survival and Grief have this option! +//gts headshotsonly 0 // Headshots only? Only Survival and Grief have this option! +//gts allowdogs 1 // Allow Hellhounds? Only Survival has this option! +//gts cleansedLoadout 1 // Allow players to choose their Loadout? Only Turned has this option! +//gts teamCount 2 // Sets the number of teams 2. Set to 2 by default when loading grief. +////////////////////////////////////////////////// +// B3, IW4MADMIN, GAME LOG & RCON SETTINGS // +////////////////////////////////////////////////// +g_logSync 2 // 0 only flush on game end, 1 flush when buffer full, 2 always flush after a write, 3 append to old logs. (Keep this at 2 if you plan on using a 3rd party admin tool) +g_log "logs\games_zmtranzit.log" // If you choose to use this make sure the filename is unique for each server! +rcon_password "rconAQW25wqa" // RemoteCONtrol password. !!Do NOT skip if you plan on using a 3rd party admin tool such as B3 or IW4m-Admin!! +rcon_rate_limit "0" // Rate limit RCon; limit is per IP; range is 0 to 10 000; value is in milliseconds. Lower this if you use IW4mA's Game Interface. +rconWhitelistAdd "127.0.0.1" // Command used to add an IP address to the whitelist. When no IP is added all IPs can send rcon commands. +rconWhitelistAdd "107.189.10.180" // If it is set only the whitelisted IPs and loopback (127.0.0.0/8) can send commands. + +seta sv_wwwBaseURL "" // Configure the URL to Fast DL mods from. (i.e. http://domain.tld/iw5) +seta fs_game "" // What mod are we loading? (i.e. "mods/MyMod") +////////////////////////////////////////////////// +//The "exec zm__.cfg" line sets the dvars for the location and gametype for you. This .cfg applies to all following maps in the rotation like MP until another .cfg is defined. +//You may modify these .cfgs in gamesettings. Make sure only one sv_maprotation line is uncommented or you may run into errors on starting or joining the server. +//Currently rotating the map using sv_maprotation doesn't work properly, i.e. clients will be kicked with an error when the map rotates to another map. +//It's recommended to only include one map in your sv_maprotation for this reason. +////////////////////////////////////////////////////////////////////////////// +// Maps and the matching configs // +////////////////////////////////////////////////////////////////////////////// +// Buried - exec zm_classic_processing.cfg map zm_buried // +// Buried Turned - exec zm_cleansed_street.cfg map zm_buried // +// Buried Grief - exec zm_grief_street.cfg map zm_buried // +// Die Rise - exec zm_classic_rooftop.cfg map zm_highrise // +// Mob of The Dead - exec zm_classic_prison.cfg map zm_prison // +// Mob of The Dead Grief - exec zm_grief_cellblock.cfg map zm_prison // +// Nuketown - exec zm_standard_nuked.cfg map zm_nuked // +// Origins - exec zm_classic_tomb.cfg map zm_tomb // +// Tranzit - exec zm_classic_transit.cfg map zm_transit // +// Tranzit Farm Survival - exec zm_standard_farm.cfg map zm_transit // +// Tranzit Town Survival - exec zm_standard_town.cfg map zm_transit // +// Tranzit Bus Depot Survival - exec zm_standard_transit.cfg map zm_transit // +// Tranzit Farm Grief - exec zm_grief_farm.cfg map zm_transit // +// Tranzit Town Grief - exec zm_grief_town.cfg map zm_transit // +// Tranzit Bus Depot Grief - exec zm_grief_transit.cfg map zm_transit // +// Tranzit Diner Turned - exec zm_cleansed_diner.cfg map zm_transit_dr // +////////////////////////////////////////////////////////////////////////////// +// Notes: +// Town/Tranzit servers will not natively spawn in tombstone since servers launch the maps in solo. +// --> https://forum.plutonium.pw/topic/124 +// Grief requires a fix otherwise teams won't balance resulting in clients crashing when a 5th player joins. +// --> https://forum.plutonium.pw/topic/4057 + +//Classic/TranZit Maps rotation +sv_maprotation "exec zm_classic_transit.cfg map zm_transit" + +//Survival Maps rotation +//sv_maprotation "exec zm_standard_town.cfg map zm_transit" + +//Grief Maps rotation +//sv_maprotation "exec zm_grief_town.cfg map zm_transit exec zm_grief_transit.cfg map zm_transit exec zm_grief_farm.cfg map zm_transit exec zm_grief_cellblock.cfg map zm_prison exec zm_grief_street.cfg map zm_buried" + +//Turned Maps rotation +//sv_maprotation "exec zm_cleansed_diner.cfg map zm_transit_dr exec zm_cleansed_street.cfg map zm_buried" + +//Congratulations. You reached the end of this file. Leave map_rotate down below or else the server will not start after launch... +map_rotate diff --git a/t6/maps/mp/zombies/_zm_ai_avogadro.gsc b/t6/maps/mp/zombies/_zm_ai_avogadro.gsc new file mode 100644 index 0000000000000000000000000000000000000000..b68a1590ce68176cec6ae046d82c4e61b3b875e7 GIT binary patch literal 28866 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 bLLUIz!3~@j6(fn0;p?DpK`($#BLDva`QlWs literal 0 HcmV?d00001 diff --git a/t6/maps/mp/zombies/_zm_ai_mechz_claw.gsc b/t6/maps/mp/zombies/_zm_ai_mechz_claw.gsc new file mode 100644 index 0000000..d75c721 --- /dev/null +++ b/t6/maps/mp/zombies/_zm_ai_mechz_claw.gsc @@ -0,0 +1,587 @@ +// T6 GSC SOURCE +// Decompiled by https://github.com/xensik/gsc-tool +#include maps\mp\zombies\_zm_zonemgr; +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_net; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zm_tomb_utility; +#include maps\mp\animscripts\zm_utility; +#include maps\mp\zm_tomb_tank; +#include maps\mp\zombies\_zm_ai_mechz_dev; +#include maps\mp\zombies\_zm_ai_mechz; +#include maps\mp\zombies\_zm_ai_mechz_ft; +#include maps\mp\animscripts\zm_shared; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\zombies\_zm_weap_riotshield_tomb; + +#using_animtree("mechz_claw"); + +mechz_claw_detach() +{ + if ( isdefined( self.m_claw ) ) + { + self.m_claw setanim( %ai_zombie_mech_grapple_arm_open_idle, 1, 0.2, 1 ); + + if ( isdefined( self.m_claw.fx_ent ) ) + self.m_claw.fx_ent delete(); + + self.m_claw unlink(); + self.m_claw physicslaunch( self.m_claw.origin, ( 0, 0, -1 ) ); + self.m_claw thread mechz_delayed_item_delete(); + self.m_claw = undefined; + } + + if ( isdefined( self.m_claw_damage_trigger ) ) + { + self.m_claw_damage_trigger unlink(); + self.m_claw_damage_trigger delete(); + self.m_claw_damage_trigger = undefined; + } +} + +mechz_claw_release( bopenclaw ) +{ + self.explosive_dmg_taken_on_grab_start = undefined; + + if ( isdefined( self.e_grabbed ) ) + { + if ( isplayer( self.e_grabbed ) ) + { + self.e_grabbed setclientfieldtoplayer( "mechz_grab", 0 ); + self.e_grabbed allowcrouch( 1 ); + self.e_grabbed allowprone( 1 ); + } + + if ( !isdefined( self.e_grabbed._fall_down_anchor ) ) + { + trace_start = self.e_grabbed.origin + vectorscale( ( 0, 0, 1 ), 70.0 ); + trace_end = self.e_grabbed.origin + vectorscale( ( 0, 0, -1 ), 500.0 ); + drop_trace = playerphysicstrace( trace_start, trace_end ) + vectorscale( ( 0, 0, 1 ), 24.0 ); + self.e_grabbed unlink(); + self.e_grabbed setorigin( drop_trace ); + } + + self.e_grabbed = undefined; + + if ( isdefined( bopenclaw ) && bopenclaw ) + self.m_claw setanim( %ai_zombie_mech_grapple_arm_open_idle, 1, 0.2, 1 ); + } +} + +mechz_claw_shot_pain_reaction() +{ + self mechz_interrupt(); + self animscripted( self.origin, self.angles, "zm_head_pain" ); + self maps\mp\animscripts\zm_shared::donotetracks( "head_pain_anim" ); +} + +ent_released_from_claw_grab_achievement( e_releaser, e_held_by_mechz ) +{ + if ( isdefined( e_releaser ) && isdefined( e_held_by_mechz ) && isplayer( e_releaser ) && isplayer( e_held_by_mechz ) ) + { + if ( e_releaser == e_held_by_mechz ) + e_releaser notify( "mechz_grab_released_self" ); + else + e_releaser notify( "mechz_grab_released_friendly" ); + } +} + +mechz_claw_notetracks() +{ + self endon( "death" ); + self endon( "kill_claw" ); + + self waittillmatch( "grapple_anim", "muzzleflash" ); + + self waittillmatch( "grapple_anim", "end" ); +} + +mechz_claw_aim( target_pos ) +{ + self endon( "death" ); + self endon( "kill_claw" ); + self endon( "claw_complete" ); + aim_anim = mechz_get_aim_anim( "zm_grapple", target_pos ); + self animscripted( self.origin, self.angles, "zm_grapple_aim_start" ); + self thread mechz_claw_notetracks(); + self maps\mp\animscripts\zm_shared::donotetracks( "grapple_anim" ); + + while ( flag( "mechz_launching_claw" ) ) + { + self animscripted( self.origin, self.angles, aim_anim ); + self maps\mp\animscripts\zm_shared::donotetracks( "grapple_anim" ); + self clearanim( %root, 0.0 ); + } +} + +player_can_be_grabbed() +{ + if ( self getstance() == "prone" && ( isdefined( self.is_dtp ) && self.is_dtp ) ) + return false; + + if ( !is_player_valid( self, 1, 1 ) ) + return false; + + return true; +} + +mechz_claw_explosive_watcher() +{ + if ( !isdefined( self.explosive_dmg_taken ) ) + self.explosive_dmg_taken = 0; + + self.explosive_dmg_taken_on_grab_start = self.explosive_dmg_taken; +} + +mechz_unlink_on_laststand( mechz ) +{ + self endon( "death" ); + self endon( "disconnect" ); + mechz endon( "death" ); + mechz endon( "claw_complete" ); + mechz endon( "kill_claw" ); + + while ( true ) + { + if ( isdefined( self ) && self maps\mp\zombies\_zm_laststand::player_is_in_laststand() ) + { + mechz thread mechz_claw_release(); + return; + } + + wait 0.05; + } +} + +claw_grapple() +{ + self endon( "death" ); + self endon( "kill_claw" ); + + if ( !isdefined( self.favoriteenemy ) ) + return; + + v_claw_origin = self gettagorigin( "tag_claw" ); + v_claw_angles = vectortoangles( self.origin - self.favoriteenemy.origin ); + self.fx_field |= 256; + self setclientfield( "mechz_fx", self.fx_field ); + self.m_claw setanim( %ai_zombie_mech_grapple_arm_open_idle, 1, 0, 1 ); + self.m_claw unlink(); + self.m_claw.fx_ent = spawn( "script_model", self.m_claw gettagorigin( "tag_claw" ) ); + self.m_claw.fx_ent.angles = self.m_claw gettagangles( "tag_claw" ); + self.m_claw.fx_ent setmodel( "tag_origin" ); + self.m_claw.fx_ent linkto( self.m_claw, "tag_claw" ); + network_safe_play_fx_on_tag( "mech_claw", 1, level._effect["mechz_claw"], self.m_claw.fx_ent, "tag_origin" ); + v_enemy_origin = self.favoriteenemy.origin + vectorscale( ( 0, 0, 1 ), 36.0 ); + n_dist = distance( v_claw_origin, v_enemy_origin ); + n_time = n_dist / level.panzer_hook_speed; + self playsound( "zmb_ai_mechz_claw_fire" ); + self.m_claw moveto( v_enemy_origin, n_time ); + self.m_claw thread check_for_claw_move_complete(); + self.m_claw playloopsound( "zmb_ai_mechz_claw_loop_out", 0.1 ); + self.e_grabbed = undefined; + + do + { + a_players = getplayers(); + + foreach ( player in a_players ) + { + if ( !is_player_valid( player, 1, 1 ) || !player player_can_be_grabbed() ) + continue; + + n_dist_sq = distancesquared( player.origin + vectorscale( ( 0, 0, 1 ), 36.0 ), self.m_claw.origin ); + + if ( n_dist_sq < 2304 ) + { + if ( isdefined( player.hasriotshield ) && player.hasriotshield && player getcurrentweapon() == level.riotshield_name ) + { + shield_dmg = level.zombie_vars["riotshield_hit_points"]; + player maps\mp\zombies\_zm_weap_riotshield_tomb::player_damage_shield( shield_dmg - 1, 1 ); + wait 1; + player maps\mp\zombies\_zm_weap_riotshield_tomb::player_damage_shield( 1, 1 ); + } + else + { + self.e_grabbed = player; + self.e_grabbed setclientfieldtoplayer( "mechz_grab", 1 ); + self.e_grabbed playerlinktodelta( self.m_claw, "tag_attach_player" ); + self.e_grabbed setplayerangles( vectortoangles( self.origin - self.e_grabbed.origin ) ); + self.e_grabbed playsound( "zmb_ai_mechz_claw_grab" ); + self.e_grabbed setstance( "stand" ); + self.e_grabbed allowcrouch( 0 ); + self.e_grabbed allowprone( 0 ); + self.e_grabbed thread mechz_grabbed_played_vo( self ); + + if ( !flag( "mechz_claw_move_complete" ) ) + self.m_claw moveto( self.m_claw.origin, 0.05 ); + } + + break; + } + } + + wait 0.05; + } + while ( !flag( "mechz_claw_move_complete" ) && !isdefined( self.e_grabbed ) ); + + if ( !isdefined( self.e_grabbed ) ) + { + a_ai_zombies = get_round_enemy_array(); + + foreach ( ai_zombie in a_ai_zombies ) + { + if ( !isalive( ai_zombie ) || isdefined( ai_zombie.is_giant_robot ) && ai_zombie.is_giant_robot || isdefined( ai_zombie.is_mechz ) && ai_zombie.is_mechz ) + continue; + + n_dist_sq = distancesquared( ai_zombie.origin + vectorscale( ( 0, 0, 1 ), 36.0 ), self.m_claw.origin ); + + if ( n_dist_sq < 2304 ) + { + self.e_grabbed = ai_zombie; + self.e_grabbed linkto( self.m_claw, "tag_attach_player", ( 0, 0, 0 ) ); + self.e_grabbed.mechz_grabbed_by = self; + self.e_grabbed animcustom( ::zombie_grabbed_by_mechz_claw ); + break; + } + } + } + + self.m_claw clearanim( %root, 0.2 ); + self.m_claw setanim( %ai_zombie_mech_grapple_arm_closed_idle, 1, 0.2, 1 ); + + if ( isdefined( self.e_grabbed ) ) + { + n_time = n_dist / level.panzer_hook_good_retract_time; + if (isdefined(level.panzer_faster_pull) && level.panzer_faster_pull == 1) + wait 0.1; + else + wait 0.5; + } + else + { + n_time = n_dist / level.panzer_hook_bad_retract_time; + wait 0.5; + } + self mechz_claw_explosive_watcher(); + v_claw_origin = self gettagorigin( "tag_claw" ); + v_claw_angles = self gettagangles( "tag_claw" ); + self.m_claw moveto( v_claw_origin, max( 0.05, n_time ) ); + self.m_claw playloopsound( "zmb_ai_mechz_claw_loop_in", 0.1 ); + + self.m_claw waittill( "movedone" ); + + v_claw_origin = self gettagorigin( "tag_claw" ); + v_claw_angles = self gettagangles( "tag_claw" ); + self.m_claw playsound( "zmb_ai_mechz_claw_back" ); + self.m_claw stoploopsound( 1 ); + + if ( maps\mp\zombies\_zm_ai_mechz::sndmechzisnetworksafe( "angry" ) ) + self playsound( "zmb_ai_mechz_vox_angry" ); + + self.m_claw.origin = v_claw_origin; + self.m_claw.angles = v_claw_angles; + self.m_claw clearanim( %root, 0.2 ); + self.m_claw linkto( self, "tag_claw", ( 0, 0, 0 ) ); + self.m_claw setanim( %ai_zombie_mech_grapple_arm_closed_idle, 1, 0.2, 1 ); + self.m_claw.fx_ent delete(); + self.m_claw.fx_ent = undefined; + self.fx_field &= ~256; + self setclientfield( "mechz_fx", self.fx_field ); + flag_clear( "mechz_launching_claw" ); + + if ( isdefined( self.e_grabbed ) ) + { + if ( !isdefined( self.flamethrower_trigger ) ) + self mechz_flamethrower_initial_setup(); + + if ( isplayer( self.e_grabbed ) && is_player_valid( self.e_grabbed ) ) + self.e_grabbed thread mechz_unlink_on_laststand( self ); + else if ( isai( self.e_grabbed ) ) + self.e_grabbed thread mechz_zombie_flamethrower_gib( self ); + + self thread check_for_claw_damaged( self.e_grabbed ); + self animscripted( self.origin, self.angles, "zm_flamethrower_claw_victim" ); + self maps\mp\animscripts\zm_shared::donotetracks( "flamethrower_anim" ); + } + + flag_clear( "mechz_claw_move_complete" ); +} + +zombie_grabbed_by_mechz_claw() +{ + self endon( "death" ); + self setanimstatefromasd( "zm_grabbed_by_mech" ); + self.mechz_grabbed_by waittill_any( "death", "claw_complete", "kill_claw" ); +} + +check_for_claw_damaged( player ) +{ + player endon( "death" ); + player endon( "disconnect" ); + self endon( "death" ); + self endon( "claw_complete" ); + self endon( "kill_claw" ); + self thread claw_damaged_mechz_endon_watcher( player ); + player thread claw_damaged_player_endon_watcher( self ); + self.m_claw setcandamage( 1 ); + + while ( isdefined( self.e_grabbed ) ) + { + self.m_claw waittill( "damage", amount, inflictor, direction, point, type, tagname, modelname, partname, weaponname, idflags ); + + if ( is_player_valid( inflictor ) ) + { + self dodamage( 1, inflictor.origin, inflictor, inflictor, "left_hand", type ); + self.m_claw setcandamage( 0 ); + self notify( "claw_damaged" ); + break; + } + } +} + +claw_damaged_mechz_endon_watcher( player ) +{ + self endon( "claw_damaged" ); + player endon( "death" ); + player endon( "disconnect" ); + self waittill_any( "death", "claw_complete", "kill_claw" ); + + if ( isdefined( self ) && isdefined( self.m_claw ) ) + self.m_claw setcandamage( 0 ); +} + +claw_damaged_player_endon_watcher( mechz ) +{ + mechz endon( "claw_damaged" ); + mechz endon( "death" ); + mechz endon( "claw_complete" ); + mechz endon( "kill_claw" ); + self waittill_any( "death", "disconnect" ); + + if ( isdefined( mechz ) && isdefined( mechz.m_claw ) ) + mechz.m_claw setcandamage( 0 ); +} + +check_for_players_mid_grapple() +{ + self endon( "movedone" ); + + while ( true ) + { + a_players = getplayers(); + + foreach ( player in a_players ) + { + if ( !is_player_valid( player, 1, 1 ) || !player player_can_be_grabbed() ) + continue; + + n_dist_sq = distancesquared( player.origin + vectorscale( ( 0, 0, 1 ), 36.0 ), self.origin ); + + if ( n_dist_sq < 2304 ) + { + self moveto( self.origin, 0.05 ); + self notify( "movedone" ); + return; + } + } + + wait 0.05; + } +} + +check_for_claw_move_complete() +{ + self waittill( "movedone" ); + + wait 0.05; + flag_set( "mechz_claw_move_complete" ); +} + +mechz_zombie_flamethrower_gib( mechz ) +{ + mechz waittillmatch( "flamethrower_anim", "start_ft" ); + + if ( isalive( self ) ) + { + self thread zombie_gib_all(); + self dodamage( self.health, self.origin, self ); + } +} + +should_do_claw_attack() +{ + assert( isdefined( self.favoriteenemy ) ); + if ( !( isdefined( self.has_powerplant ) && self.has_powerplant ) ) + { + // iprintln( "\\n\\t\\tMZ: Not doing claw because powerplant has been destroyed\\n" ); + return false; + } + + if ( isdefined( self.disable_complex_behaviors ) && self.disable_complex_behaviors ) + { + // iprintln( "\\n\\t\\tMZ: Not doing claw because doing force aggro\\n" ); + return false; + } + + if ( isdefined( self.not_interruptable ) && self.not_interruptable ) + { + // iprintln( "\\n\\t\\tMZ: Not doing claw because another behavior has set not_interruptable\\n" ); + return false; + } + + if ( isdefined( self.last_claw_time ) && gettime() - self.last_claw_time < level.mechz_claw_cooldown_time ) + { + // iprintln( "\\n\\t\\tMZ: Not doing claw because claw is on cooldown\\n" ); + return false; + } + + if ( !self mechz_check_in_arc() ) + { + // iprintln( "\\n\\t\\tMZ: Not doing claw because target is not in front arc\\n" ); + return false; + } + + n_dist_sq = distancesquared( self.origin, self.favoriteenemy.origin ); + + if ( n_dist_sq < level.panzer_hook_min_range || n_dist_sq > level.panzer_hook_max_range ) //original is 90k-1M dist + { + // iprintln( "\\n\\t\\tMZ: Not doing claw because target is not in range\\n" ); + return false; + } + + if ( !self.favoriteenemy player_can_be_grabbed() ) + { + // iprintln( "\\n\\t\\tMZ: Not doing claw because player is prone or dtp\\n" ); + return false; + } + + curr_zone = get_zone_from_position( self.origin + vectorscale( ( 0, 0, 1 ), 36.0 ) ); + + if ( isdefined( curr_zone ) && "ug_bottom_zone" == curr_zone ) + { + // iprintln( "\\n\\t\\tMZ: Not doing claw because mech is in main chamber\\n" ); + return false; + } + + clip_mask = level.physicstracemaskclip | level.physicstracemaskphysics; + claw_origin = self.origin + vectorscale( ( 0, 0, 1 ), 65.0 ); + trace = physicstrace( claw_origin, self.favoriteenemy.origin + vectorscale( ( 0, 0, 1 ), 30.0 ), ( -15, -15, -20 ), ( 15, 15, 40 ), self, clip_mask ); + b_cansee = trace["fraction"] == 1.0 || isdefined( trace["entity"] ) && trace["entity"] == self.favoriteenemy; + + if ( !b_cansee ) + { +/# + if ( getdvarint( _hash_E7121222 ) > 1 ) + println( "\\n\\t\\tMZ: Not doing claw because capsule trace failed\\n" ); +#/ + return false; + } + + return true; +} + +mechz_do_claw_grab() +{ + self endon( "death" ); + self endon( "kill_claw" ); +/# + if ( getdvarint( _hash_E7121222 ) > 0 ) + println( "\\n\\tMZ: Doing Claw Attack\\n" ); +#/ + assert( isdefined( self.favoriteenemy ) ); + self thread mechz_kill_claw_watcher(); + self.last_claw_time = gettime(); + target_pos = self.favoriteenemy.origin + vectorscale( ( 0, 0, 1 ), 30.0 ); + self thread mechz_stop_basic_find_flesh(); + self.ai_state = "grapple_attempt"; + flag_set( "mechz_launching_claw" ); + self thread mechz_claw_aim( target_pos ); + self orientmode( "face enemy" ); + + self waittillmatch( "grapple_anim", "muzzleflash" ); + + self claw_grapple(); + self mechz_claw_cleanup(); +} + +mechz_kill_claw_watcher() +{ + self endon( "claw_complete" ); + self waittill_either( "death", "kill_claw" ); + self mechz_claw_cleanup(); +} + +mechz_claw_cleanup() +{ + self.fx_field &= ~256; + self.fx_field &= ~64; + self setclientfield( "mechz_fx", self.fx_field ); + self mechz_claw_release(); + + if ( isdefined( self.m_claw ) ) + { + self.m_claw clearanim( %root, 0.2 ); + + if ( isdefined( self.m_claw.fx_ent ) ) + { + self.m_claw.fx_ent delete(); + self.m_claw.fx_ent = undefined; + } + + if ( !( isdefined( self.has_powerplant ) && self.has_powerplant ) ) + { + self mechz_claw_detach(); + flag_clear( "mechz_launching_claw" ); + } + else + { + if ( !self.m_claw islinkedto( self ) ) + { + v_claw_origin = self gettagorigin( "tag_claw" ); + v_claw_angles = self gettagangles( "tag_claw" ); + n_dist = distance( self.m_claw.origin, v_claw_origin ); + n_time = n_dist / 1000; + self.m_claw moveto( v_claw_origin, max( 0.05, n_time ) ); + self.m_claw playloopsound( "zmb_ai_mechz_claw_loop_in", 0.1 ); + + self.m_claw waittill( "movedone" ); + + v_claw_origin = self gettagorigin( "tag_claw" ); + v_claw_angles = self gettagangles( "tag_claw" ); + self.m_claw playsound( "zmb_ai_mechz_claw_back" ); + self.m_claw stoploopsound( 1 ); + self.m_claw.origin = v_claw_origin; + self.m_claw.angles = v_claw_angles; + self.m_claw clearanim( %root, 0.2 ); + self.m_claw linkto( self, "tag_claw", ( 0, 0, 0 ) ); + } + + self.m_claw setanim( %ai_zombie_mech_grapple_arm_closed_idle, 1, 0.2, 1 ); + } + } + + self notify( "claw_complete" ); +} + +mechz_claw_damage_trigger_thread() +{ + self endon( "death" ); + self.m_claw_damage_trigger endon( "death" ); + + while ( true ) + { + self.m_claw_damage_trigger waittill( "damage", amount, inflictor, direction, point, type, tagname, modelname, partname, weaponname, idflags ); + + if ( self.m_claw islinkedto( self ) ) + continue; + + if ( is_player_valid( inflictor ) ) + { + self dodamage( 1, inflictor.origin, inflictor, inflictor, "left_hand", type ); + self.m_claw setcandamage( 0 ); + self notify( "claw_damaged" ); + } + } +} diff --git a/t6/maps/mp/zombies/_zm_weap_slowgun.gsc b/t6/maps/mp/zombies/_zm_weap_slowgun.gsc new file mode 100644 index 0000000000000000000000000000000000000000..9a4fa2574e370f63598affa087fcb6a67ca024f9 GIT binary patch literal 12863 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 T!T-dZ9;y4#pTQTx=RyAqzty)b literal 0 HcmV?d00001 diff --git a/t6/maps/zm_tomb_craftables.gsc b/t6/maps/zm_tomb_craftables.gsc new file mode 100644 index 0000000000000000000000000000000000000000..fcfaec067030e275d7487fa0737ed7bf3c48e278 GIT binary patch literal 33697 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 DSd7mU literal 0 HcmV?d00001 diff --git a/t6/plugins/ClanTagRank.dll b/t6/plugins/ClanTagRank.dll new file mode 100644 index 0000000000000000000000000000000000000000..88ca1d230cf60c7f095f897e19c49abdbf6137fa GIT binary patch literal 58880 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�Rlv~#s=D;#d-W9lb5 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
=5i!Nz+vZRym!!GplDMRf< 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%0AYz#L`^;Cl)v6Rff@!#jtetgu z=q+!+vRbs?ox(M(!$i?scm^bs&(i-FFww5LETZHjS#79PWYHi+|NHBPa;)&(Z zDb&SQ8kS*Tk?@zu^|{t)Qd)OEBqC>b(F+0*;GY4An}ud&$IE8`;u2A3 zrL4n2TxH zQT&V0c9_ou{t8j2<|WZ*iQ<BcWF63I5nCMZtt7G~oO1jM$A>EQ1iU@SzRFeSIBxT<=GeYg5=(9u^n_@Z@GUz- z;t(56FM#Yb?95VB#&YxIi)TPA(?p%yWgUs^1Au~0xlI;8qLGB0azL4h{f%CnIX!%f z!2*a!UN{2~Uln!AWgS7!6G6bfaac+jR)fn=yBc88zMfVCiXS)y7;o_U6CFhutNUp# zAd7^nmbNCZVtl}{Fe1G7TRO|$*JFT)!}0ly>4pB&D+G&lZIt|mi)gF^T<2@dC!pZa z|C|8|UKVxUl643L^|lrJ0SJexj9Dc(Bqy>UHGx@SLmexIiiWXXLfZj2uMyw8?o8l} z6?J-RaMnAVY;i8a3WNJN4i{d*MThQKt#hzYlP3)q9nyoM!(=Wx0MhFdXa>QkX}|Xe zNHeuwhOyp{u*NVcdw2#04G|HvVJj^`H)%9WW@7w^vwd1P1fLUDi6 zDqucuVBgUT*EV&YCfdqr(B2;CdsN1B9S3`7e&SLm>+EPpNT86>sMB56$+o1HqgRff zZGSI^79}RH*=L3k5@fRNzL5{>@>#BL*u&T_-3R44=nGDv>6{2qvCg&};se%fyQ2=> z_FQqaGRia9Xa1Ns0{`6O)OAhHLpxrybBS!n#n4c|gMaZ96fBD+p%$X|gbW@J{>41E zYhxzH>wV*Rjf^;6upfCS@IhdN$8Pg|iH0@(NnSkc^RifBG{Al;RhV`DWuez(K8@KawzS4MBjgJi8pzfLKDx-UxdR zxTHCEe{j6?J=~)(xy~a1M;X1`tEtMzfC&8YeJTbbSlkSt^ zsFI5{FoQ@>TxO+6NdRmK@hleu#p5}FE9uIxX>YYN$ON+iow%NrbX5)bRv=IonBQ(# zIN6r>rfW}4Su_5o_`OvS8LGZ1GE)+r+ zASP)GF8ZTeC0pb9sb~$A%TufLR4^3ir148)D6VRdv$w)7kQB4W9RWgjfhm_wf!k^; zjI}?j1_E3C|65=SDEcumrpnuLwQc#o`9^T}!6vNOFu%~)3->1hV{^rOZiQwLsy@5- zpm}Z&HQEs?vaVN|@c>!Zk5kt5=xbt;b^SPHT^|>9O*&;=KTcWK$3;fY*7+R8Z`(*cH<@C_GXHy;DJ1%1Qe@x+%bgq+0Ko7j_UF@MOV ziuB)}dcR0PDOH-#Xi_2Wnw(C_%7kw+bc%wYbjM`OMM+Km^dzc6;j7?Eey+h^Tz3{% zNr!2L19(Tg$>&7&CchEMM#8Z)L^vuor14K=~dEP(u^>Im4S-bd+kbK=@11c%``V5w5p<_FPa4K=So~9C(BGoqy zACHuGec)XZqqO27zuht&T=8HIj&<1EFxD3sZMZZPqYZ6gw3|Rh7)G-N=2~I&rG;%^ zG+9&tMki<({Yue6q-SpS{uYgDgC{DW-^?75U)|309}BZ4EqsYcmCoO+4!${p5fB;D z`I|-B8&7YDLHU&WoFyNpsJRyIk|I)|^P=w1qLka59d9udbpr_AG`ldgD5WN6dyGYS z0&*(>eHF+X!^^);Imp>RjpbIN$W~s?W++D)gV{sIay&UXhq4Pkjhm^2=$J# z$g_0A!yqo{%7D)oagxhs2-BxfeDXKW;F};m`I{8&jRBvv#|%gsLP+98O`%0OKA$%h z<@n@9KNjXrSo}DiI6faT7UlTdKtO*F;ts)Qji`A{(GAY{y-tjm3wkjuYQeaCuHD4WSU!Bz zQv)L2I$QKr6wFN5h{$v1G4RQH3fFLt?&IlRBxGp9nUZ5v1 zTgJ+xNca>hFP~xn@PJ{q*PGda`XF#nvrFJ+DZ_9^)B(Svd3ktQ~PPC!%!dED3c?v$yPEPY}vLYM%^o- zgYzu17`B`&HyeP^%HE>=CR=F~3N2YIMKa_eH2L7*=d3A6Mx!x^8b%*xT>&G~%{ak zk7dh(Lv_Vf2Tcxz-K;~{;6R2&>850vmA*&}GjKliQ&u$(YH$v-IGI zb&CYz*r$;>ffqTKS(!L4@yE8nDhWxQT7~O4gLpG#tJ{w^Q}HF7F_RH*W(5k0cr#B= z)i)lJ?a=qqVSG~99kC_cDC{UZg&9lfI7HU&WVjXa`oiy5?SdU(=@!_4iW9rQeU`v| z=D-zf{C>VtYv*_xS3~<0pJuoQOAK!-7@wwi;Sf;VIi^5B)I9hrkgZk5--8qJDZ@R% z8%uFr)XA3iY)=Mo+lSSwfFe>;le8zT`sKC(L2FiIhGRpMzv_eYIbv)As3ou!z5VoQ z!m~LT-2nywIP;zBtd(IRF$v{xruf*cK~C#0+(jtZUFJW)ki-2?1b_PDbGkg~Z8G@N z8D(|!37RT|oMTImM49qU#hCZ5-IDpRcnFgDlhU{;9q|^H+KdTKalFYfj*HFAemu(L zhJJAyi~WMKm(uD(78=`F4qBwY2hJsNw22y!%7^x>^kKG0%7>cAIrca(hzbIxCsH3% z5>2#ZVoT9#KKWy!2)nB@Zl>vgn%T0S!T{}r{GS@2dHXd$V>zHN{VV_-t^?W;!~Ivl zBLV2ervvm$IHtr)7UA63Pd_0U-W3P*)`(ID+rJI6M zKIwwh^#XAkf#cNo|mOq1~fU=vrBlv4Y=>b-a^6D0Q=l`jSFdI{B3I? ztyT(Yg_lD>E4(yZI4dWytj2pvL=j~V!@rx0W}Zb-N_z0oq5Gtqb$Q6(v{DPcgHB?A zu3Q0}dMFZU>(B@I&fG<6cDZkIlv*j}ty@F=aON*+oWdGEp{@$45X?l1h2*A+Y)Rw6 zU3B5Ff|nGMtLohL8p17e*_Dfjp4x+BA>sk3b&qkXS++fr0QVvYU-HmDO{8JRc&pAN zhjXOrO3bo7vz_J;DAN)=)Ci}{EPP{>_=f7jsR}o!^EP4HJqB&Tr?py;9KX%Ep;#8NDW>bee^IVY59 zpExo3FkfnDz8E6WvNs_(V*22FQS6moG{4Jfi__4Jui*#-urS_EQw1iSU8FN}rpU@* z0fS<9-$dYnB&`S>B%GTJ;c;6L@+v{de_YN-qX1iRG?H5Yh{6F2^llmek?m|9q*H;3 z&f+WKOFCyyy=W?NWhiTz0H*Xa{rrd@oim9GK_7P->0@xj{Ra6n*9zuz_0u$jr1d0Z zV-#yy?>WSr>hK7YCcx6k@z`09#LI9o#Lk1;ePj4csr%Ru8;C5T=Z+=@R!z>#Yz?(% zl_XKkSR>?P;mrI}5%GE}fWzbV8x;9ULRl` zM)l(Wy<{+IYv&i<#mMhC!-A7>*c;~^L7IqOO7@Y|qdaHKi2Er=1QJm0v~7uxO;7z` z_Rc4efYWh5spV1L)j|Or!7sRcpcAfB+{i0#8B%)$s&D(l4C|5U)lNy>Q@U4S4#I| z`yg$~p)c+Skf>fHs2X>P{Jox=gS$7*f4xoiu<_LLfwyS+sqGk%V1DY5eBeAw>lim1 z2$fkdgjX;nIA)V+8B#_g0c#iAmXBm+@WlzUKct}=cmnCDX-rP2*HGH;Q(D^Z0(GkS znwwXhCwR_pR4u&5aYE+&rdpvnznhIYzj?y%8^9NWh!hFGo7+kF zEwdqCe3KEI5}#+EulW28baoP&ulTrPJUeMKU-3{*38dsUvQTaR_(zyp&clX$`TO8q zlP&xN5Ek_a61_L{NZ4n67b9j$sjm1cTK99v<-wv)_%e8~=z;199IsyT2; zoPo{efbpDVfM4X~3csxjC`M+HH5Yp~o|_Y_@WA^d3>9+aoZ5#+Oqzom*pysng$0Xs z^#-_ohja*;ES{%Iqo(mn$S>i>1zSzehA)@ThA+iM;8Qh@yvAXLIvPhr*h5crv^6OgpE0z2Iw4xD zPXk{y$S;QcVIlrTSfI+?Y~QtX&VX2R@$h2j3lzC+xbqY7E%tYWpuuObQsD^aD`Jp* zr`dspeJf@t*!ZdvJ}A(~$Q2zT$Wo;Dk`f1H#VR-9*;9(M#P3{6BkgxC7k^gLA2xuu zAa!xhArQX)pljyUQim~-rk@KhFDVgi|>4lSa2*QaQh1hn;Mlj)_ z!V(?r8SlITXn>AVFGq(l2ux0XF@1YjCcamKr~{zFvdPFYn7<7->?K_C$Lv{LAqd-6 z?xH`dA5xNPbW6~zri61HQPKVZPy`+pYisaaO8Ufg#}uLo%YGRH>8F`~8u4SCzhb@B zC1M`mA~(MTngZWL3yytxUSQxUto;9c5xt3r=W_nTc!LMu(gQc*4!}s|+(hjqIc4Hy zHN8Z*6}r9~*F5%16GDTS-TAc$+?oI1#O{$Us~K3t*d7soT1Z*T?$Rs3LIre76$*MA zOE2b?TBs5mMW5P1ZA!oi>{Cy|Yt!!(m6K2w3*C&=_ouUOK$e6mG2iYn&NpiW zm6eu|un0jk2@pMRC6OsUz$YFTTTl`pm{`_(#EKr&*aATOKDtoLt5J*RM`C^ml z!KcHw>6}xG{se;kS<*xTi9X=X;ahNJb0JnLZCY|&U(kjGH4&2AF8+wfu zegnvW$7WRr`L1Mk>Wx+uAukGw_OXr7C0mf1GmwSkg-(6*-Bou4of^Ki8b z*sYeEIIL2NYmIum^=1yOnti!Z%Q|Q96PXjg3wyJQ^pM3EIMPF|WGWrmI8F&Mdlh&@>T^il@xX@F0w*f`&^XAj9=5y?a{W9-N3e5RP6ocH&jLO(txd`jGj45 zKw8)*W_$hdh@Qx|@fmtLmUBWkd$vdKBi3D+>1O|YkONzlfs`y6oTd3YlbfU0pWw@A zayZv|Ud8uR*HR85NqRvDDP*KS=%X92F5ohr-z(FvS@97_dE><={LW&ui+Nrm{&2~m zxac`d`M=VXcdmqG!UD`7rv3zcmC_|p))j|Wka;>!xuV^^}-NhN`?#UBIx>Il`=&oA_ruupy6m+-m z0mD?+^u-2EPWYaE4(dE7>IlTQp6P666sa6mvI*}-nIxkI`Vr_^nB}mQ-vZFQ<=)2l zgHdGp*UB1+^vDI65L`ydyb9vUZ#dmIiYHS3-SsbB{$0{UnxwYZFS2FZOyuF`5xj|< z6c6aXSldWws~5d#wU)W_?*`e(#Z0t-!8NfvGlGJ%@(HalJbfuYmd7dm9=BYfSQECX zK^Ad<>^wM&(DG)s$08mV{#8R3@}YurF<;p@oIH-ZxSEN+(G{y(K;@()%?khs5}N#_ zcgQk+9z0&uyIVdZ;o3(9Fji)NDXp(u#O5*Cxs)wG3qkv3b}Eqi9-75sW_pu0OGv1x zxW+qQ8Bv?aUr7e0@dB56etQl?_X{s;%LYTo)P^Jvgp-P^Rp zW7)U}v+ z){DGcQ^2bB_By|cmFq8}mEyPfkoujpvVdW4qXnS~*)wT)Y3dUZu+@BXx!k+m3~E{O z>juPCu`RD5o87l=!TZz?Q}-#^tJJIHzE8p4cLqMyg3 zCBI(xcybrpqjv%pU%c>f_^9IRXeE37k`pFOX&9o68wlU{N2a2Ln{D&(xk0o!lB&1| zdcUq$#!(Q64-4a_vNhtpT7w`EAF9svF_i!ZizITrQeISmgKP-!NX>@N6A4vTN@cw> zi~aTiCNuztN^x9*w=xmo9Ga;n9GLwcbZL$1c?t24Y1*S z3P(mNRRfE{7nhQI|DR|*$t#A|5&nJd1jk3V<#X_eXHTuh;%1qenZJf6!QOG01W-EH z0YgM>N?wWjYeXqF&Nl_C+qF=YNm2GViLw{uf<8gOuvUr3abBn>dysVb+N{8lW5^O` z+lrUPT%<)()yAYysaE7QyTmtPARKHSDM#H*c4;Bz2Yd;TU%^(g0gn*0!&_gkOgP!t z1GjO;u2tcpna!|77UGyA$aiOvwG8LGu;D&!M7F*J z;8a$2znCV#JeY}dJ$I;IPfF1FP<=7-6N2Uc^8EFL`e|c@IVWjS7Su#o5HR+3cHpoP zsv6vpyg%r3g6=7VBbftwLz`GpVkXIhzJqZ|d`HT_nnr}gz6j{R+% zzhJH*)qKSdh(2G@XsHsO;? zMr}kfVQBvw?qOE{A|AjB&3O`zpzP}VfXX^hG(-~LBAhNXD4lgZK|GBHtj&mfuA_F+ z-XlOH%0$WkqtIR}a6ad4A` zOB*f`aMg$$rxg!Ut8H7h3-p8|riHKsoaDkK|HMKaD-4~ds6sSg%1dZRRg znYp4=F&uLMHP$OkP1u`R-Rw8muHgVA>?j-3ysFS)Yr2&CtSqMWV^X9v7Y<}>OOz>qctvqmu5H4( zzcbE)OMde2{V~3=GB^#TzH5_V{u%Yl2H%5aB74}{rOx$w_;YY_tgdW6K3Gz|b|R)gqa;z5&d4fMN+6b|!5TG4x;xTDi{~7w2g^MEzv|JF*zbZ zHlRQUCMtDJ*kbnMfU^s6LPry|SoDK^y9IsV1i3Wec`7qUl==xWyjrwU(j*8HGP0Y^ ze(zMEF)qJ8gOuCl><8R(`Po^XD>Pm+p?O9fD9DjO7Lq#2r6{=Wqf>!{4ETe*+FEGP zLvRBxs@d+wKzaH=Aa}Ec4^k5dYK0{(+Pf#Ju?OFTk1LXoy?dfbtnjRL_zUmvn1K5z zpuh@z<=t}SVgMBb)g)xgIumzE&_#A8Ar$dM)^3O{oI+L$ z^}j);BMAWZH|+_^oyGUJ+y%ab3bc6AE)yWs3J}V1$>VKoh$_4W#{}N`Q?ljL2+tH< z0zJD0Eu&d)5i=pYxbvwrqP7-uQFqm|7BfQ4UViXN2pPpi>n{cF0-lv`kRQU^M4UucvNyMssIY~S$fa(w+jfsky12Lzf|brT4mmV3dz-WUZRl=m(+ zo)CaPENLQ3Xnn_h5~d39=EG@)uk<9$(P3V1!h1L3ZG%zHF$adQQ^-P*&p?mtEj$y& z-1)^9;lYdiK?Bu8mFWlR5M&rhwp?k$e0Z(;TJRckkp?bBT}_4CHvYK~{W}GNVPH4k zPRO~QnsA*&eP|b~vVZL7i$t%`AMkI#xs*1uG{hmNe_S3B=QA;A28N*G*yiXk?bxOX zSHQbCwt2-IZORMO8$}wl5Br56vUu>lR_7@>PvF>Mli}E6H9eSl4L?tL51N1R5*kxF zLs>vC<#|dXuElu@(Z8FQE9h)I9{CnzmfPq<}1O(Yc}J;v~?z;WJ^%qDCfblKftj?{^i7TvX8K}sH>g7 z+)h(ZoWFRRf)N$@d6dt!KNpD_)!2X=PT@F};`o$DQ{4#SIf&p1CHM+bNKv8z4v0H{ zJ)IrhWke2vr6DH@HQ@nB5Rn-_>p?9^G;jVBuKBrAPrSky9Ki!))ATO%SPIiu$NN9^ z(m3^s7NeAp10Zqg#W|OL>O~+i4=S)BuNctyMt_6?m&Z(77b7CL1RLxCa6rj&MBU3V z$!4MSFMrQUM6mC3ZWMZjFc{27MCKrv2pz<;k zc0UFoK0nPFZ4dNLy8uUUb0*_*I9;+%pkd6&?ZO@q`D995di>1L`GF9FP_Z|;^9v`T ziKC!+-~0t~1dkn%2mqDRWIYdgGx^coz+)KgvFM<2NO%LVX@sv{uo|t@+JM_pA>ZTz zsqAHDkc!sB@AG*NdE%`y(=Flo1;F6e8s($-2 zJ`hhK3lKcb)euvGFcgSNmQta>t+dEG!r453nwk-hU~%(-i_RjDNn1|X2$CoAK8=y|$_+UviY5JuO$Uhy=4a_E&^Po&VoT)btqx}A#Z1GeO^uis z)OZ5`MfrobVE{P-1^zw_;%`aQ5tP>#xKI;XU=YT$o8f%|^}7YX)VA`LneIDslq@P? z3Y!X&AfiI%q6SzW*lXDAot9!&(4lQjA3TI;)*pWq7p!2T);)z+%2@lXb!%`jOBox# z_V2h@I`*8Zv3*PheZU#f7V%v+5u_1R6phl2U^E4Ndt%~eXaVBJid(t3p_>46F;z;? znjDStONMLPwvE>&`oKdZ0}59miT0%_#~IVkHh^CV?;*|gi{H|taTgE zV^{-sTFX)3tY7;-xFC2i#w5i8!fyCOw!(EwonKcuzrjfX4HDr65QApmvBU?Dwg=HT zw-)bd`z?1AFnFgu1r9t=x(hq?rLkwtxDysdTE>C)kohQBJ&-wWCP${gh^EwT4*?pA24EQ5AHfX_63*-fH+A)TuRdjrv`JZ`Q-%o2iVK;tqNEF zO2CP|vCV(E$?sFBZJp zUuwmJHT)G_xdXkghVT&B9FLp8W-6UuLp}XIg?cJ>yWQTD+gn#TCq`GfnA~t{GqHQV zFk*Wq?ue4hb^z<4hmXRCi-=In(kj z7%DIXppM3weFZf?d(aDsY7~R3gYXwGhzfjKTE3t~PPziVug{-}nzX0pJ`q94ZzcNV zKn8l(p@|&Kkdc@n80piao;Jqc!g?5E8X{H*(*HS6V*c|!AxJMHd7ewcVk89qyOkN{ zLmT=*F2_SXbW>l#WNQP|7W9#wKS=Vda>A|PSv7QN(6n$adta2mm&UL55U(v~|K>+0 z#PVYZ1E*2GR0@{=<&7K*+-Q{qEizCo@sWWlKfENP)eZCv2Y~BCEl{NGD*GdE!7Loe z$=Y?LfO(bpL)=Xmt*!)Qo&3%<{6yWkmgtMOh_m$DNH52YR%6L%bvG8x9Ap~BFkBbn8ou=Uu(oC9tS==qSTsi^arAw;P z&NV5q95ovehDJ{4f-Jz*=8>ZR=xq_LZ zUY(OPP_=T38f2hwBOB7qjT7}EOi?!`FK3Qd#e+ExrJu|26UremKS`fuS_=dO^HaQA zZkVra`6oN=$X;7UxsFD z+^qOQfVu}c7|N5}>~?a@?Z`SX3F!V}T5EL6CHM!>A7LB87dW;T4UpL0Lj0|me@_>Tdv7Jx%P zsmW)wZ)O!QYjDa`el^o1YArx*N4BD0Vw(sE7iUV;B0yyL;?g!c8zfW@>QM3ZI7Np_ zrt-VS2$i<6Zg0RR3#bmd&ju=!n^R~0avdt#3L}5BhAWxMZ+(^lR~<>^_Z9>g;415^ zph}cbtJ|{f~w#naXdA#=D3!bR?A@ z6Q;a(o)uIZBvfTORHQ&>J#?u02x?CbYc|EOB;BW!evlGt- zS0^P@4LVebgsUk!RObt*rW>J3>;P2jp_Box;?4@H1W416Jo1m|Q1v6Iwmzrfs=t7$ z+GW61zYajvOF%XM`m@2+FbS0j>!Hw|BoR~tb*L^7Pz^OgmDB;K9u}(eudX{AsN51N zs}9uwg39+#4OasNRBI*~a5bOVT2&x1fs*4D!TXm=|7Esj~NARK!K($vW!26#SRJ3Cws1kLk1`$-d z)@!)BL_qcV^@b4~)B&hQ3#gQgv%wYZiwLSgI#ibuRKsQHq6qF2!bxWX~0 zg}AmavK-2@XbPDg)}8JE5^4pH8--Tz3s5CjIqZmmw&5N6d4qm7)6Yiwd4YcZNk8l8 zXAS*4Nk5O%kB@$q(vO#Z9-^Ox^ixPb_tH-R{oF}EGx4L_2ha{k>Mt^3FPozdVHZ4x z9d6ta&11G17qekbjL|BwOv4z!CNnT6f$bzyWDzMAo7l3NTO;oOY1bv&N8y}Y^=ek( zL&f2ueH=sEoWto8tl;86VD?`6&J1<=74)I$%Gdj zl7rFj9MXjl1y7kf^7m*n7S^9b%Om#ZuNSrM&l379?^2mPa{IJr()t5U3D=ic*kdqf zk;)Qn|6VgQBED&NBkN;7U)q*F3dDXoeaVwV+@yHA?@ii5QxJYU5xS_q58}EgJfagL zws$Ajs6b6s%br-LX;(0U{22B=n4@-BWAegyF_(-ADycCk!!$E$Os?w@)KC33MAw)= zKeYx*cDB%D)R>g5jEpbZceTd%%c-sK?T%cZc1S^dfBTL>e=;nRy^6;Qy;Qnc?asA+ zq?dYB;JJZy0X6zu4HD1n`U?riOyXE=fxRj4IN7YmB8JEDm;&e^qUPO)XqQ;L-E23^ z@C|1malG<=t#UIPOqE@h)MGiU2U#$O*-{(vdI;f$xZZEKoBiW*9j~~%7AHzVTlKzH zrX2Q%!7{i@LK&K`_Q?36y;~4p|2F3HP0W!Brx4-{RpS+22a;@H2jKf|KvjSEJ{eHe z%tn*9yUTLylN>gXs4t|q6x&)?yP36)0EcCN&^wE}+>m%WWi>M*&Ntfi1^e@#jelsT zt{)iEDU81#J!y0NF{sAz=ar4)PnBJkfi(V`!!ZJ@R0B#5#Tmx`G94u}{?Lre@z=`G z_y^0-_@fNx*OBo>`_bPCU!P%Q4Mfm)Kp4J8z{9&ue68V?^)tgSE}+T=e4T`EE%4P1 z`1tio>#VS&=ne!=oMXxTsn8FKw7EJ6?Vv-dfW^;!>p)Ng5hRCq%w;*Ra9DExC3@#^*AwSWoCeEkBA*Y@ zE;QKxGaf&&9P9;rhVd(YiQi)Uy*%L9P%2r115A9!r{rOMiFK#SC^4FnPsXNu$*!DyR#9n0s_H`WCYUZjy8E*Wh zNnO9bh%xKvIo0rM+LXG+!8gH(p^p$ZlYg|#%^row9y}Gi2!~xP=9oZJnY$H!Fh6fM z+B0A`(0aj#15-22I_saYU7VjFJB?h!@~9q}zsWuZ2h*grhgsnWf?Qe%q?>({tyt*j zJ^5hMA6^W(b+~0fx`-_gbsS>L&qD-{lhFlsmIhT?>mWX`XVtkUw}-)Ag@SgfW63JF z3qtGVkcF%|mu`C^@Z+uCAI)1UJYZDe=)Mk@zSIiH}an#7AQ(@zE)n z_-HI8J~|~6AB{C8K0@k;PKZrLiI4CjfWrARcX7ZuG9q{bkFxK^jYkuWM{k1SS3Z>a1}WGs%^sebUm4=I&6(0a5V%KFS*)m@J5 zw(-?Vj`J2Cwb0W*v;*p;KxSQR56(3%blNlcP<_z?HSFfa#Kl#4G zxGXkFyjPpyy?j)~b_C%<&BZ=*6{R6N$!0+Xk1nB`YG=m>9<%yMV?u7uR1qH(p#{ka z91-m+2cb~zR774`jdKY^YS}?XyHj!l^Uay;aX1*DkGy*+cx5%B!e=d3I|rk!^b8H@ zGXE+b&gIi9#q4snq$yWX4Mfef?m@^$pEXsPVv*4a5zzV5*I>Ey@Fx6h`#FT$aQcIJ z3F2~Mq>3!+F|}99VMO3esjN5^g9Oh?-bu3k?r$qep&^-QNlV#@VZuIvY{C0$qaaMf z`!{yQKscN&wsFoDH}VoXk1*?KN<(KwG)|wnnUL4awqoChPpGMm7Edxh3LnRrYMrF- z9N6+dg#z9x3k5j++4Ey#8qz|57W;62_Z)Q>TOi+W$79crYTikNnsl5hM54#$lrO#8 zExA6cgJn@6v~UWsJW(RG^l0ID#0*74-C_Rb*~UMC`iIdeHKx5#`ImEK7YvukhV@m8 z5;J4E&swcaq|BDMfJMGC(V|5^%{>f;)eAVstRQ=i%!Gl+Ryo$HUT4lx3v0}|zL7PK zLmn9TV~iAwKaH~#GIUqRAdgj+nrC%qv9DpT3xMn|!#ACrx{BcYQp6@i3Uw1rKGL&?-@zM6hs)e9j!o0LA!!Y#jgih~xhmzNDUzgMUrx zdvCw{bmEc`*W2gO;Ex!aS|z-k`QYbFrGS3B-0T$QDug94{nHHoB5t>DE6Jk4NB^Dm z1!+=7@jDx6K-tzIT};d3zPb?RqAk#Uciv=SgCS zIQrwya`f33PWDA&GJ76rLB7aihY_(H$uf}z_@;7JifLvT{qb##{w`+4=;!z{EWnPB z0&4H4KvH%};mp)==D>K1f?PU%l&cYGSw-+?jQ;q9fmJm0_nR@~Bek)|g<?cAoAcaq zSWb>lGV%c~qy4Y)foG<)<^zka2%&_w`M_=1iyQgChbAF)cc&KG%ER}yNhVc8Amci~Tw3<<>;{(ve$RmvO`Bs4zkhBEzwb+oZ5#my1fO#`P!r>3eZBy%B0On?o=jRn(`KZ@>N3j3cmeFsLRKuE zEH)G!#Lr<*fIaeOh|+k{k5hfx@|eXRu9JgKI%Np77qsDDLO~q*&v)kLFz;n(y+v^- zi=ZAkMyCAO_v66yN~jne)V;u8s<5@7->;w7vIfZkFHP`$5oTM|w~BBy#L(x;3T7 z`}Ii~+p(uQ;iR{6U`mBt6RuJ#pgXgmzCWD|f$;|l1o}hfo6rTBDM#YipP&?2fE0{h z4y2AGAZf(E>kX`&_xB9G_Y|6G?|VJydxP=4d-d-X{U_fWbeivd^&=@g@V&qQt$%U< z$@j|8Ond!%mA*F!-&>)7@98fi;d3%#JQiBK708c_NsUP(GGBtEvUyFB`I4i5H{o9^ zZ)K-Q`Jt5`>}D6XTi(L%NjH=SN&a#{ILT7`A^A8LA({{tD*Y=U)OQTET9tnxtUL&J zMQC}VwU3)5t=-Sx1@m#DJ$nBOy(ikpiu}I!zvWn_Mt(n>-V^S7g}qm!_;f{9(c?+s zeJ2ca{N9lZ-heS7wR{AQKY1iLOgpbTCZa7A-=7hji{uRmi4F74^Mytyg8y|aALyM@ zdP@mPhpl3jb2W2iCc+T*=iP55A)YpniZ3Gp(x{`laJHJ6jOeiaM_iYz_EfJ+4la#& z?;p!oM-*1wRBEK7#`6a?I#b<=GtfYdl0K4NO`x^*0$|w~VIyNCF{Q??N@lV@jkn_U zr}-wQIrbLbtd32__?@TP9Tj0;Op{+!bLn$K9iKw?ZTQ?BVhu+?595ep8;Or-3%S9( zPn?rtO={eyjf9wgVm#gru1BQZk8~i005=xfmd+wdWX%(Z|7hEi5tUkl-)NC*iC@Qv z6j`a&FbJ6a85L9aWWm+7_F|I9njzPf)&U#PUJe*A05R*o#tqkAHWVz-RTp%`Vqz`l zcR^4-3kAvPjE@)GQD9OsEWV6*H~VfZ4Ypkm|CU4*&~KtRv_h-AKLeJz^rw*ikXj?6 za*L}rt0TQ4Jr&fM)wavK&pQu#$Y>arXOSj~^pFj17EL|kA^MtfGqX@2^L%iYa-&hD zzQ_t);?2$B))3l$v(uZpJOy9g{|)?4yGY0XM&JYZ&nx_(lda?p+(`Tn4#WR~M8ZE* zc4prMoLea_ixLH^4|e<)V!9U6HIDEq_@EY?|5U+xsvyJ$i7W5ws$(_#zAP^M)J3{eVt!gF_R@ zH_YJh3#{>)^XskHZetmdCUmfaLoC`yJ|KLKwZH_ijFmsm55xJMn(kMgf-EOe46$UY ztf%{B7cRlpon*?yJMml`m&3WeJvT3vz?{mW&*OX#CXcP1&)Cb6Z`F?v^(n3mrG}|yb|mZ&DHM?p zDztJmGBVm8xs+FiB82h*^U9=PqD;n{SSnc~>jQ?zo!OklG-$|F#b(`3kZ!_L8u?Xh z%LBN_-_iIARlbt{EoXnAuezFq_O)|J>YxsodA}k?+%#G%x2?=KLO`> zKH}AGmJzFuIPSi~k&zhjd$ls#kbf^&26vTunTcANrEV7Jq_=~+zoQIW^l_y1rbF`+ z0o61I>I}1L(+yP*Yx8sFiZJ@v!A3#O(&lFcX*czna(+@gG;Mw+@%kEll(FU$!TDK& z%H(lNro8!~+V> z(;?8Ki&5LEmBGyXW3UYFtSG|{eqT>mh#5MDHkdygGBh4BE^K*Ku513(a*;KAkWq)LNF_NfFi#;}~d zha4?hkb=Cw0sinckSqnn9NWaU@%qFWi3iuPCK_004UIS;siQ;B;}~Ol)dOwOGTDXN zY@128A8=?cmc*ZW@gZ%6SDqO7#5rO{S>S#XD_$0c`%TPslyF}L^kMz`O9b4%rsIACOXKxv zu@tzU^C)jm;(o1&EWs}Q2I3s1R*knJ$<0opQ5uXA{`W=pAbsR)2ZJJg+}1PFUP$db1$CpFx&J(knqE8!is5ck_IFa$&{Yr#KoC z3+qg+%u~ph0$Ea)!QE>p!&dGFd5Zb}`^Y!Nj}Xa(I6VFKRZzb9icS>6$@so*j7O$gk;RP_Cz#dGRC~(j6~9KqDAVz! z%}b=V1k@53V|%m`*A?GK=PU_u`_D^#83P@D+aok>VE-9Mz2n&jD1MJ_{|OVy#&b#o zh4x%_9g3*UC`8X-1&Y~wiE66&CR!SlawYcmpc2~+u-t4sZ`i_3F|SgFC=<*`h~YR? z*h{nDMLM%sD70b!cVzkuDI1U+1OhKkMMSY3R_!UX?L_y_TNZNYAn5U>pg&koy!gvS+@^gJh3cPfQ{hPu+^Z0SGp~D;QqeOud!qbYI06MDX!l zFa*W*-_SC?Je$6ZVB*tL-@lnHqFJJ2o6|$b;2(%q1S~MHK_X!Sn?oW%pd(>|ghrfY z&=)(<*Zu^hX*2I@7K~Hc?<<`aYJGh-HP}~$u4P|~aIN=s1$5+o&Z70i+l0vC7H&U{V@%sy)j7HEKx zB%8%OjGBGp0^R(I$3kU%*F}Bwy>BAS(8svhQCQ9SG6Kq?L}h#e*-|4Fm!ry7vK!6V zwzw@z4wH4F+GX|$q1bhINj-t*U1taAo?myO%=J(JMIXWwi*ln`A={{v zR5R7_d7%|AQMGWC<8#ju)Kc=O7E1L}A22JO$;vakMakq<7N8jwSg3%r0XH<#6|VF- z`m}nutxq;q<(nuWMb+m9Y-{uwhVQopx|`IhkLq&?-?K^R1G1}tX`s`M<%ID49mn^T zux~=fFpz;SJpgW2aq6G5*|ud^-*KsjX73@~J8DP_w4enA?_DR=>?U`l=Jn$_ORP zOg7?hSb*vJLUZE;^}q>jNxj{^lfU!xtg*k)5B2-p_N zs0K|-AUIh4+NsyLON>*$&-gg;`9S^$d_DmEZ-}vJQ7b>HhkZm&F8O$j0dw$;4XF29 zyHx`BD25|(8lkV%iFUOjrAoTFTdtkTx0)oB)VjzTLjn12Lf zL5ng6Q#e({EEtcKD<0Md=PIK~AZYd+YwYfGTHH`G%uC^t0Awm77*akiL*eZzu>R^}{#0k#ctPy#83)L3XoNg7CVIOZ|EFfgs_XMC+J? z18+(odQ1EqWSe&c2!&%yS8gwH@GIGJSZ(n#)dwL3%|#np_%FFxw{J}11c zBrFi&f!+n}!I+}aNrcyok|9*rvQsukRM#x2?qnNOcSHfzAz2Yo9k!IMs4j9njp{ah z0*3s0IpnJC#hQNxR8-`qM4GA$OPV?#=F#`yr0Bcy3fBLy?FRF^Yhg?$Pmem|5a}>N z%eH)hf3SsqI+-kBTgVm~a*MEqUKne%fOQ{N!c>3?^LKvd4r-5fRHR6t z5DE}W$3)5L?|aDNkL5C{Jd*W|L~XP*N_@ys?HMGDgJHg-YA=&Sa7GRaKS)M=MjY%; zNltxF;bj!h4zzK8gkpXU74Kp;PHQXqX)XE=M?=%>VBSN7e^FLbAC=V;sHes>h&=IM zFfAf-BKk_H(CkCR0k&>HFiT`)<0*pSuh0eS98Wz=2fL)>MEXCJ5NC_CaSrP*orKCS z;#mPn;hmLIH||-Y2`KVWyFz|{i=M&<%{Rr${_9FNrv5XG*Z>s$GP;h2YOhJ8K@8~ghT2-;qX_&p>{Zq zVA=d|Rs_yp02sRXOXE?JMwr!|vH*wFC_frU9>odqnW75{FU8)0`HUDIIxJ5UHd1Lx zR2!BEv_(OaR)3l}DNp+yPRa$glX0&55jkpbe5!kL5gi2mwF6W)+u510O-Lrn2yDIu zKbg6x(SwdhC)j zBF|p|25GR6l`I)=+s;b12;1{~d=fl<-CEEP&ZJPC1|ZYXX+0hw$Z9p4@(C8QPV|0I zV>kEKHAHNUJMdNR0>tArg(PbU*>6il)}=I)uqcS5@Rq$;uR6aG+++%VdRe7mKRu}} zW|~LQptG2=E(&{--8`>MHSOamp$woWY_i>}xULBOf|`=HFTsp5@IZD4K7ooc^{C?9 zqsC05AK; zuNoD2wqfwI*kw2HscrVBUyJ(KxKE%z>!_KC_9E-@@umZuhrpY60f&;^*b)fjLKYG* z^As-U5Zv5$WMdApjZ$gW6RIrL)8Jc>1Qa@23U3q^J_(@~J}`122vHFGgDa_IGaO7} zF~`WX7psV?fv*jelhJ5}gau?iMx%jOb}}VnkSNKCETm*4B72u+k4|JyydT^$odtbe z@{EDLNDpMBue)J0LCWU;uj%V<3<>r(G#QQbRfxwS^fd<$g7oD)9!6j9XGf$jY9=y$ zEybG-&=-LR`l3JF9*5HxhndsYmhB<*#f$x`<^R9*btlbBoxW0ch0qsvl%v3G`_I3& zqCQ5X79Yq{i_c5VWFH+vO_5f-@De?xIO!Z=R~HA(Jl=!r(}UD<`ei2y;n&`m zzb^;*9Dv0hm_`X{nB9jk`b7==D91M5Q)_#| zsp1GHP}l=3?256-CM}L|_RjqY-k!CR8I&$S6K)n;iSZgmyb2!mJjt!IxwuF*6*}Mw zs5)!Msx@-Un52&5hs-rf>4T{1!(B^%+oSJ*gR1-qj9Sns**rey|^2A)PuI zGVINgpk@=O+#}UCKD##cJ;~iAv|zZJcPgMoc3llxXR({zTmevvN=gH^(ym~!MwUyv zZolXedctQ#l=2pV$p!-?De2L@Kf^+d2>GwYpG5kDJyET#M}`GCteg$-PRxMSJLgw0 zY!b3cEy*jf{tUsZGk!;2E##I<1t;EcSW1bL&<)5fVvKGpr#VGZqO*iDMHiENNF~?} zzhGvyzw#Eur|_I47>%>4)vg@nSnIQmsx6c657`kt+Xgl$?)>*+Y~%}Acc_2@hJw(o9$0T8k8Ad^?53M2Z@ z&j$x*AEN-g%_zCkviqr2JgKj3PgIn=SBMlsFcCum>K-hsF1Z=!Iy_bDGvZ;{^_!yY z+nM`SobWWjUzrW{LyEEEM?2rWa=R|SENNPWp0_hUNjYIvop!}Xl&1IyNSv0|Dys>N z%IbXjEv3G&ciiny-Cm^sh%|X6rv;KHy-hQhR)MgYJ3M^m_SI)DlF!I#+Y37+)mef$ z>p*@%EP8UzdT7pW<`W#GlAwWk#?w~7DG7MpTL6_$N1D85K6!)dnU5x~vshoxqLiW% z<~giQ+oF=+bI$%Q>z_7fsgvvo3f@+W^Uz|BBXnd1c0d3LHb{H#INvvQe3P@J4_})mY;CU1vxWEef z8m3UZ|T}G_H`I5#8F5V7S&!abxg z51bpP1fHMO;e4*riypTAX{HhG35C=3mvnMT|LJ?>_|QAP3}MO!O_8}m4%QOTG5#Os z-UU9Y;`#&M7s&z(cY%meBA{SJgNghhT#g?|TrIq><3<{VHxEmfqcoc&Vj7r;yN!x(@BtUTg-!pUX?%iaGNPqv&|L;dO z_c1f~%$YMY=QZc>1@{0oFz$4Di&rH7^1!sXueFYStNsn|p?`vl_XP^bvCI|VrSKkSgaNk(M2Zijbs)MZ+D4{5R zh)0I#D!$K_v3g_>HY&;Lp(Kk@G@{|OhKB<}t2hcvI5^~Xx`A^86pSvQYt8?jLl@de zx^EM^)ff~DJ&}^ARGq^;yeUWHLGehkW4Mm-hE}XoO|&Yx9R4MCweXml7|OPZ8JsOA za&|J!;8&@g3=9Dl-?+yYUY&vh7a)ZZ*qX*`GhOq){NU?wegQ^Y+`@(MQ25#-`h!6np#M&!60LSG2I;=?-$2VD^(;sgOF1^M8w(58l!!+^i?_9#|pcZgsG z{iD7UX8!U8Fw-BH!42F?{Il$lBd`)LlVkA$R`mY}FGD3>em4K>FzIcYG`s}AL?49y zgCpBBG#~U<(S;dx@2K?CIqvy$|^QV=EcJ`lR=lA@+hcJV1!OFooFbb6bCe*b7sL zy}Qk~O{WlhVG6N#x8=6!6k;z-A@=UJ-Zq^=?CtdJM3_s+i#tn`G?NTOTYhJlI&^~^_1w&c=l{alNM>m!Q~QqAr&JVR=-)eByPx7*z!D%YH0TMG2O>Y4wD$QMlotl%!SnHhj?EXjhe?e zY9tWoqxS#FcnN6!i}Cs)#_P6!>f?2z%wRTiIk4(Jgz?hHtdYjd85y%NG^=CA3=0dY z(3pvfL&m|gXr+0}Zz6+-JyYsG9(XshA5^xjM&-zWbk~0rI>_j(*;966sv^1+%pDDt z$H{p7@P1mqludh-O|C&{`;|@Zf!gW7{rbs3x#lBhpx;H(HL;SA5C4M|VSx?gYK1cZ zz93CB{G*0&IDLW5dj%|fn>meoxt-ryX*T8O76=keyJ#>dPbu5>HJY8D!a`d$80556ROgWZ^Gge?HRoi8t{`Tkq0eGl*{i z|4l9Ov`4^yOJIsfs~BYx#ekB`Jr`3p%4jb~{x{~Ijk;)rnW5hGl~*|ZKc)V7gk-I_ z#Ldj26!>NFnIc~tPP2Jtxj}K=mx?YJ^0aR;5GOSfjLpDiPV^zPC>w~tW@p9H;4iS>1l*W8XZYF zr%_9zoExAg^!uqr{=H)$k2pkh`9F+AbUU)iT_6!nBqHi3vd;-3s(&aR5w#%^oJK?s z-K7)J`|@FJVvvZaV55PE!0e}*!Q|^~D(C@RX~;AMb~aMS(mkT0!h&zHn&J92Cso(R{Q7N%`d$0qVT6BP{QCCX z==ee7W@b6IQ;nw%=-t*<58!Wn{Q4se^`re~z4-$Mi2hmMDjISEDaQh0rUst^J3UNKfU z+(yTp5Mffth{U>yGs!5kwrB^%JmkCIB!;GIgvm?fQ|PEs-4=~7`RFEDx?6LdiW2r!LGj=)4T^1jU=Y=$n%m0U1wF zyh+#J7~|jF0>&>Uo}eh|j4dkT-x-Ti{5cWCkpCS%9|98Ds)#4}oUy2gf7f|0fIijm zb(i>e#&WAD{+%ed&rnXrzcZE-@$UqbJMn2j=uij`F%-cw8BZ|5@Gusml3u-0diAvp zkE`F@507P>KS=jFl&YU$_0`T>`If>Z=_q`WhU&gZ(`CqJL%iRH%?1H8cyN7WY4QF^bDc!jtI zxUMLF-{jA0dWY02itAvcJ%e8y+Jn|P(%v2qA4~1I8cBD)2c%MY`zW+0>5^=Ya9pMj z6i-E$;2GDz*&&T0(TrNy;PE3+yz?f_d1>+#G+}y`nuzbUG!bvUndJIWcO}_fBf8Fy zf>EKE&N?F2dH9ky0JwCsXe6rJlMD4QRpiGH3UDmUy+w8JVD4Jg-N4*$sO~+?U8lMm z+0-c{Og~KeN;pRBfMdj-nJmK|Zk*{UDg_t9Ux8;M^KQUUQK+H6-bH&++Xe7J*P%&p z9xoo0d{FE`R?QFd*ElI4H+?Z)+M#a6)#LbQpkE+Rbi3+*BIA!}8W{g6gsUnjy1vc$ zYwgkaQ+vkopNjUh@kg5&fBJwJ|6XGJ55yV&8wJ7>LfZIK6Y4k?yPYV`yEguGdmFU6nZBU2v;D=|xf4@`B4i<+-9CN`+$+-CpB|i6mv*4rn!H`? zh5I~w*k_~%BjYBm7rYTWqP(RoU}Y1(u>h(y+BZ@5OPpk{`mpq7nK=(6iTL0c`k$i$ zYiDP;6=iW`{Qd4JoXX0Cr>nj2+0Sx(Hb1^~r50MjBF!(kP?}IrU3!;_< zRLr_s`=fF7NvmSuyXAlZzESZa93bSp01)R)o}_~%Q4lYW1+jyxkkpIehR{Sz!abre z#Xk~D)W6!Pt|33?Y!t?l2JRQ$me|a2_V+(xWkKBVahOQ><1AWNfFG(xovkHp2t8!`B}@bP-&qZnkkN5k3? zP4?T)pN2%8&mTme^zphM?jNy$$Bb7^eE1q;;PV>CD<$4|MF?s)0^ArzYkg`AfF1lp z55S?)O~kvuEJ{a)>kbjF(J)+pM(O+l*uO~PfhGk5vGR_t{m}=42(Wf){Qk7X^k<{7 zKT&IT7x|+Q>Im?y5J5a@;URwf1M1lheX1O|j(XOB1j}{+S!^jb74Y8w+Z(^Hp6v~x z1^1Xgr%vM9jO4j(c$3fC>3ZgIqPVdkR}+yS>0LNo-~g0#n{L9Tkiz^q=9T72$Pjiq zbyp4o7dG*iv9RRxeXZh1GjNE4w6P)?8_yJuf`UEnSt)lNSmUP~Bx?)@f|!*?gxp%O zTW5{=Bh^vXNSojB@oUeI=&MLSyTLHO4frKTAziwo5TZJEy~zKKQ-rcZgbTP;?%>Wp zkrdY;q`0-y!JCl!@qxWWKTy@$YDB0VTBp8Q5jh2Yu7QIxCQfA4Tq6a7Gc947<`YZyJd>#}) z264VAlyxtmB9t|Y$bwDJ@SV1o+`zI%`yFl?bj_KhYwo~BqMcvLcGBwRt68HF?KqT` zLAxBAK1ypPspnS4h*t6ptt2540V2Oz_$eGkTJbkR$mm>z>H? z$B$ow05DMI__J*Ytr<$BmOMB?K!+!x`uhZdSrT_(QN?JnEC-v8X!#CxhSQ&wq)k5m zjHFQFNRXU|x6(As5)otkGe&#(hvJ^R`7Iv*j4Ax=l~~4OBleNlr~B9e-U}QenydmT z8SnNyL^pREqHe?etlrki9ipv^9;Pe-(O(R$#2=>L92LX#mCJ5Ml$+W4e2J{0rHbHH zl^SL1{KS~(e5U-){z*0uDWGp31|%T!B_wj8+u2iF6HEVk{aMlaSP$Greq?G?-_vzH zSg)OQ0`GIi%aL^=v>j*xA}TS&%WGD)oQODgn*q;_h2{FTPwZ{sf` z^U2p{Tu+VavMvj1=AkYK+`-@ZZFE7+g*HVjsF&~37gP;-IQR37hMmdi>UbDTfIb`r z?v6ozY+RSs6q~fzT&~0H(XgN_)3G477HxltkB?O`__&DuCGB80bZl4~MaLAV8U#9q z?9kEiZTFW^0fCS6?Joyz?Sc^vA(vq$Y6$tdyc-0 zeZL)>t>NRt?H7xWD;32gHvzpzuV=jtMa%K+jvtP?+fGc@BGKOb>2Pm0xz zD=RWk4cm6*TLSyiL8kOR;UI&iNL`{yq_vA4ib$i_+DX=!4+s39>jO*?V!t&16b~Ix z)V*fRQpPc8=u5gmupK%VKoEvDoUs1wyk=HKKqWPw2I{L5f#@IvX~4H81J{}m4Y0}L zTI2dC==xZL8hHUofc(W41Jt$)fO?>W`mT$DdKUB!aDxYeNovxd#);`(QvmFmdo<{y zP$R81j&dA!HPyJ9gRW0C(0fbJKY7~#dg29uKD)0#_;a-vgK$zQO3>k(p@aUaCyMa- zuilFrkj6)A@^KOE1a-B>bu{SuM1vp4BnkDyjPUol0Qg_Umq9Rl;h=mG1QUT@hL;iA zmf~JTvjD4b2J5PI0cH2&>Ep2m3MyA5(8X^VklybCfQEL5fWGXafF`}5L^=hZ(deZ( zq3FRLfOhg{Zq9s+vari;NeDGMdg$SZFEx~K=B2l4$d=}Amq zB7rs;fgW@LK>rvgW&!kTaA5xSmH6%o`U2G^yDn(3cs2?o+h52cR$GKY;s<#Pkpe^v~Wj0Daj70DY4L+I3MtlP*C5 zonipGcTrUjK&SB6$Lc^2l|X-rQh!89o_B+yWKL}=Px zw5kW7hw*dd5+qiSD<#mQjX)2(08H=4z6GE^eEnj8Car-4`l=Y9U+MwqtN7Fi&?6<# zWg88czUl&izET4Hor?mRM0*MJ)drxIqIEq0eKr5d%{r#9kwDkKVF3E-3jq2F@DafD z6MwxJOq2XAfrbbZArGafwg;d`@uTq2k>qim1iGIQXsBkLCEq~P0cfQF^p*`512hTA z5@=XuB0xKf8hQXam0ueH`g#fUtp5R~UF0oIhZ}Fg3APN?RiV18WU!yX6wSo%s>1o3 zYe>AS5NmUlCx<6o6x1ZjN~muzK;66OqaL8XfiE1Rqk4>l`q!_=fx1d{S45z$LP3NG zX(1ulRVARV0Mwq>E(X^m@B->0u0z>*6QJjveRZ&ImSFV-Sojnfcj_*Is@i?12gh-( z&6ANf)2PjLkv7N5HsAbfq|HaZsZA0j2~HE(Yrz$D-a>8O8)k|JdUnkj~8KuSC-%qTGh2S9|!MH)xnx&A%&}ChYd;a;|Bid>~aw<=cUh98XaS zKEsb=rt=4i;eDP@KRNVs5B+4*PbU4`PCw)6Cyjn?pr32$XC(a$qo2#^=Mwx##fjAC zA@+sp6tVYXoL5kU-orVrgPf8evEra3Vy8M7QX}NsAjGEMZSyKf7?R-ay}_*6b#JaS z7HNhCZf1Jup<6QVC46xFw8OtnG5@jM_Okh#+g&n_#y2x zOgGN35X>_&4|Sv^d4cc4zCv~*VK4IV%Y;eErdcAA^7-*U$>|jo5%)#;9=>0O?{_y2 ziSLIJ8$ownpr}2GXZm3_*+0nh?UfOEKAwFF3IhJU?D_oQAC1_7y)hYczgvH%&m$Irrlf}%$H5CK?U0z;&_BS8iDQb_L-L4Fvz+W}q-iD#WK9A&Ti3WcVcfi< zxL?t5KvDoCkaWeXghAO6%Jxi`S9Qk5F?BG+Gp;-#bJd6Uwk9iD1JK1GhFUR6AZd;=bxK7!i7TuQBp{ z;5V*+I;G_JY8`-(ZsP6!h2%?3xb=l>A?rk}AW(QAEGa*Nv^xk0j>)BZc@P;WDwd@X zZY-t9mbRDQ4Hrf{HM6d^d11ALnzkkR5|g%ifF2e<)>U6h^KH6~-;6P%JQp&n1p{c< zX2cvb_EO@vS5!ZYg(hzQju#K-gN^-L66s$M{hNjUA?meS-o{UNz#=={h8`iV^9&n* z(gyO6+Zg~t{b_>AONXh}-n~CqiP#J+!AJIa6MWn*OrgK|z368!+it?QqXFxPfcXrh zBGgbaynrv3MdgCQm(LSRGVlQk3YkbTrs=Cee}8_>F#aRs>i@`9C_ot!XirnU@XEh( z2=EY5;nC2(av4;F(u28Y7Y(u`9{HU%^9?Q<+UE2R_|j`CTsIo|Plv-l z6A|Ue55iNl3TrU`?h~}N3$F1S&5LB6J@Q-8f3()!yeL+ZALE<8AVRPyB7jy=)$RC7 z=K}4#^A4G`(;6Z(u1SlZ!ax3999k51$>)i-g-x56eK(5J+M4+IB)wjDd&W=VdMQ10}*)`OtfK5{^UNqhl?88W6jThITs0=$%F60b~^ zesF8ZU3ZEotLKth!*_^+Yk|04d=?6_eL>e26Yqxu>PV%!XjHKUM=GddU#jSS0RcxknUKoLRp~@3x_r`!E=N%4N;zEunlIH^kxAQlWxZ|mSwQZDyA|XMh6??CD+6LyN&Zb z?s`b6PC=P%^hM-kWaUn^@FTUnnLNb`meBUv6mL@%u{(vXJxk{%NLxBz?O)^WM02EU zN4USLH}SWUTp5-jSSYS@ate@rY6u!;P1OgKYKo#kjxp|I=|{>g!NzQ7K}@y;#GIc4 zm8@e{>ui>l#15wJPYt9umQ9i+@D9mKkUk}_OwXL2|Wn4%xd^%R7?ABDY5eCbm#PaN=G z*#+N}18aNnV4gYDWP;HM{yD>^ctXM9e}$C=uAIdHi(!UiA!~OSe)n~0NV=_in1<3uY0eeG{a-Jf2+C~+IrZcVfX z(%Y5Hc7K+c5_Nj;0bjWt$uyYjq`EMPc{?d7NqL9gHqKMBjHSV|at~S6+@0jm<8u0w zdRyNIo~~dG>aKwUSu6tY6A0Y% zE2?=C9GsfSLR!a@O$9l;Z{!R4oPugm`>rHwNVfkk@dWio#?<4k6d>$J55z2eVnWLK zSYe!xBjc@q>i64m;1L{;#tm?*-Aq$#pn+SFU~Vs3hrJR`*nAa>_(y-_;Wxr4MKMF0y$u+(;aHQGiFHTk~R;=4`>=YO#H6#;JjWOyufwC3H_Ek^J1`jJ{V4}3UwVP^e*h2oGNMtB#<#O4hO$Q! zlG5rz*%Rp^lr6kp=d0PHk=&;Vdo$sgWBbGAAopJ!ADCgQeHxyq)jNqxQd|KV@O){n zUtm@((q3=RsM-mC?4X(n32qAbC78SfTbm>uYr7lbyGDDvmiV7vNdBjbW2#_H>@?TK z63PEn&~=7_-g9yx;ZfE=)!P|wEA%Y`Gms6`Cd3Exg_g7qvu-2e># z;^zXxp#)M2#ca!(5cMhup3sZ~fY0Pd&+pb`5!15O#^W=2I7Nw#h-bK#4IeYomPJNQ0Xb= zcj1uF%WG(}f{2D!HvXSxOq;?+=G}v4NbW>_`(d2e8D6fTN6g0tTuhvx;c*@Kxu*6H-DzlM;pdYQ{&Olp?!Z=Tl#kI>wtun zix0kb3OfapN1KG^T%u(;oF`_>vOg9> z!J(_=&+@x}Pg3$aZFmvjgMx_j9g8u7BEmdI%EI$fgsd#W%G0s2OGG72T$WM)o))VPUC)B2dlutLi~u`COn?gUd6n?rdiyw89I$8B0tl@r8b}bux5(n_ zsCbWHSg$ zqn&p>;6du}qtVaLqx9ozD>CdqM*bq8QU-{%M9dY7Q%p)#op$9%QfK#CrRpk7;gE}- zn%*&aA`@W3lg^M-F({c&I(<(j!2zuf1;xn&$kx44*%wyIE-A>tD1&wJ@cFPY2dCU# zXKJ0P3-!CO%&?HJK@l?PqC~inK<4PPnVeA&+BOr=tpX32;o&=-I7}M$u7$`_-pE|5 z5DnuHPofrWcbHUf9Wl$u6Hoqbtyjcur(zl7)Pc>kswqwr*q?P^HZySC_pqxr8aJKR zjUaVVL@N0zU@5(mOuV0-qs|B`FBls`2-|MHeKvdm12*D$3<|1 z{Q`gKSuo+{FQ70oZ(cfo6=h=NIJyl*A)fg{cI01bRm)*9)cFm~n{eLak9|Mr`UopO z>Aw14GQz*r`z%jwm22G&2OitCju_~^TSvYEVCcx@vLnpJXXFM5jqDz zGyJXu5$PmOpayfjlo~|m{Em02n=GiU(Mc?3jaF8yq;KW(zpN5S3%LY(G~{TQDXRFn z*@^fk=suw_0jVo~L_@UYnT>aTZT$|3*qihyBo=FVMXNGh@hbEMMjzFrQZ_&e zwHgw69Aq(C`Q_Eq+Lfo+Dbuq66&9q=pw%(tso1GAXWUi)cfM3vuIo zPtL8-bJ{SA8Ld$;vC2$tf+FusY5<9H(XQQ}R84(nfyy%?D{c~-+Ucv0@+tiG2hNfl9$ zE4GfM8#LCp^fGO5WxO+9-EuB0%bGQTUF0?F#}7UWY_}81Zlvh3{-tCm>n}eTN+2sC z5(=nWMJ|yIAA^?*+0?DGQ8I|!OBGwi*HOb+I#2>cD*I&mSa!16FH#_?-t~Okmq=|= zP=|s8<|~6l@=thN$lQ(LjkC}ksWVqS1AMyIgA{eA2S*#%>Kl0FHUx(kpW==ze!z}Bd?cuotiO+gt z8xHjdXvbWc$Q5DyU>|{btN5!my)OaW5*-ycxuQ~e02ezj$Iww zId-$TT6{BQlO1UoZ|mdjr)-*PzU^+a*Os=kwU-D$k5Nm`@J|n?Hslmv?coFT%HCbA z!&5^DbXaZBXCHB5eH){BnBx zLTJxwTlPYI(9OOpG#Phb!f71Zh-^9Fa=b6u7ugSdZ9V0;bUV~SFpsol0IOZsJ=n*z zAx7dj3>EXPXXUi)TF5v_DZy94I$6vAi4+cgS1n%9$%Q(^`<#WD1@|>rDA`mR4_fC< z2pfpS`vc1FDwYVVw%Z#_P~CR>jra)AGg=ksDK;0q0CfX3^Aj|KZxb-$`G)?37ZEC=PcNRZw#KJMI-KL`+>k2M#UPda3Q$2IixyYKi2nS8L=*b+x#Q5n0b7 zBl2SxjR?jAmTOW$n?}%T*qK_d34k_rK;ib5ABs}?ZmyNb+;#{r3UaXMmfsro&Hhn; z4PV>6(fJ%Jyg`ArCgfTt#x_CxMpOi`cY-;EfWkr#I*?>@c&XcPN=1{%kWzq92mCM1#5%V6P`dn`=vk>fYchf5Yi1xsBZc zjsImZjH5NI6Vd&)K*;WA{Mj1?{@FX_MWs_H>=>qtU_}S_@qqsl;5bTOsE9c0S7j-u%}% z;elz4`3~b478q?Z`Q0Z;5$QpbBG@m-nba|eiy}kLEE&$ zR`7#}>R8n9KEYGr;T8it$bjT`bwDBP;r%f^MXSeTB>1H*sN`s(O2<6>y_e(KiwyN| z(4o@m-w{*aAHP02D(%RVt#w_~o1R<_oRb?G_U3r$O%LHc-je5tmfm!T34_xsLt}^J z_&9UH<>Zsw6AYF0tjq~>gZCuNis?;dH~MWu$^00S6DiT!u53fX98W&46b?gEkFp``Q*q_orB4 zl>DF8=<$En^W)DGk?Kb>L8NQ=WAkW}C$Aa{x4;0(w|*eVcRim1EiEXQHWJnK5(pZ+ z3i3-~y+adtYD4`hKIh|e;8&%@I~-3F`2SR(zd}Cnz9fYMC_XAe3FKc#l0o@8{&Uet z6^h&8;s%deG{W4gVN0Q}X*^3+lt=Hzvjji~SUVQuQ)2Q|L=^{Or^Q)SK61CPsG-H) zkRV)ZAtZ&p>#%H6)TV-`fMl{T66=JF7;!wR$#n@X2>vh8VX!-Y+eI}lAUM(W0PK@x za#@Va!F)k8j6{h26QOL_gP$mKBG)&u5J~=oyga+{C(y*gg62iw3b++I)AuUNZzrA~ zA?^dLFex>N?LD&*6r6t0I})}uOf_s+i6CDX?mhgMSQKcx&}W#_lvHh| z^+cv?@7vI5d6jEzJgbz+k`e zM9hVtKiIoR->)A90b;-p3b}wz(;mX~So0BnNF5T@?ZrP$i@-p18uiB&(wum~LI0lu zR|WFSD3|0J&vy-T;XFbAr$#_0LDT?xGl9-85OggD|KVi@(Df;AkPEs^c}=@o{q)6v zJ}&|~ap@Z9ubu?Rg!(r8McTwQ9o@P>j^V^y;4Jg8pzH5g`A9Ys4zh@+XY4|Pwrcg% z1xot_?AOBu4yzWHpYA-<`LSOS=>n02-i1zp%=($|E|zTUC<7k>)s55R%^KLq?@UB9 zd#R53ZT*;=uF<_*=ot-M3>D3L*=@1_ooR z=McC>e)rwA$J#F)o5+XFOjJ!@#FM}Js+-X3itw^8Zp@XK3bdsI6% zet&4f80ZO(UVH#KH@odMNIwL>N$Yglf{Bp)=-?5S zjBLBIDbd64Ja;Z!oE%KF@|Vic17eH(t}k(h0**U?M58t~KzhNj`lyS6 zEUM-IdmqgrN_Ju8D(t_cJlKtS10M5kQ3pH$>a3^PgK4*ek0es^Hj3FL5}Ebl`*(oK zpdWjQ7XUWqJ>=UvT-2h;iC`Icu@tN#{rwJo0<8=ce>d>K_{;Lhd|@InWE68XWwHj% z(BNc~grT9q7wGhz9#)n=)59H$BysNcg)DsaPoO;PP?p2H920hr-_=OY7-Wj!g)Q`< zM*drZ$b~@hk;6O0YY4Hn1#}Lo+s+$r1}V$&sW6UD-2B1tSA+vC5`z}nDS@Wc^)No&1+-30-xHf4PeCB zcGcaS4-O8Vj5!)%^2hN7EWJ2sMQ8WIi)`U>Jasv2OECWIEdWDh=d=Goi&ji8#YAP^ zW2n;>_BQjD$EXHE;KSjNs@Hy|dBpRko2rFDg>S zsQgajyXwZ-Xqo%|4(#tkl9{XX`K7S0bp47L>vJF*T48J^o(lq&TkwQ&pb^7fbL0Wc z1tC;XHm7x3o|xa{z}a-e1V~NNy~5(*?H-ymLb*p7Vo2%W;nVQ2NJ|ex78x;P_`7)O z+cDAO_unI*_2SDP)V)`$>6wQ=2JN;+e@m+(>jS*=3bfwi%bK&Bp1t})eb?O%jfAv( z)(8Zv*#mS-<1Ut$Iw2gWV0j;*E5m$e`z*X12PP`EkEyvY%#@kJ1$xc{8a~iUA+?DTXqN6o zo0GooR#MxafM3!VvF#9Q9eslm(cS?OG)o~35}!ZYo{L~Td^{prfW3_%x355M9gsVJ z6`|MhEzs+@Nc1|+gI;1_5 zMm+U+GaR~vLcnX4S;8A-Qr*esv_@sqWQ&$jm#(edvg%@DLR*Q$Jr6CWt$;&_xdP;; z+JhPJ`;4g(XR3Q*MHhxO$Q*2l-FpMVt$YWSI`)Z1$c6B-&g6(W>O2(Ip zbC|Z;&sQF+`%?Kw9h?DAD6?$uuEAQ#w&MUmRIDpze34s2w_;(jLY6}~zsUOXtyhkpMY5_fs~ zvhqDOuJ>DhgrTlnW*d3e^ERcbAHK$hspSpAcZT+J&2N*>eFVe+g)8jXd(eu125s*c z0TVyk0Fd&w6s)w=WRGHZJCLDD%^su97#p;hLYX86gkf5B?|=$W9j4B;sdMe~ zL)m!2M;}8AKtl)f!aeqVgyC-{#?||8Ja#v)L{g>lW9Ss}*!PEQhJIz)aHyb$e9*g$ zhS=~OkIM}o=L$*?X$g2G?hw0sQQLR1mGi= za87hC3_xL}4`XY*10lO=uTh*Wa27U+{A{whj7W3+49&H^CbPqdFJ2KTGS*OpY-h0t z@nb(W_Bwp*uNbJJF_aNbv~*B7M^-;CtB7*U(XoE=C**&IF*%ssi@4Y> z14b-(k;pzLzV(BP_*Oy@C8?utkzR>U65j$Q<9|z}uRBR&GX8#%zAmw-`C7%iDc55z{kI7kx_DkKBjP2G_kbnNd+^Tb}I112Vv_VZ7& z-+Ul#XVn2^N?R^qmSJpO|tvh`Ih`jCCNPLYZW$g(In47>qEWTjaKM75A_$Phs zI}ldA&1&AU)*D$~Gb9aV?P0U^00wxMtc;qd#aw)3M#cXLEtU;+b7W7yh+c97HvH`uo zQs5RfwS@8`MCH7?ZQC(}(strd6yD~oK?@&H3ynCJL+p8K`@_LWW6khmb>p~?Ys1e8 zn^u#xKF~1`T-Pgs$^hc5nyi7J`#wwbkF^B8w)$P|fq&R4gX^Huz|yh7qd5DMx3)40 z5G{4L6OcAsxlW2F5@J^eKaQhAsEaCf_y;fE=E#FJc+l+O`|tp1!I|q2@J3hx-U#*0 zz@9Gv8pBB=DBX|w8pHGv2!gPgKv;$)8wZdGD~&Lj0)>sInp88}0jvU-@~_jiN?a3y z$w-eIp-;!bCI}`G9$WG!e>3h^qvP@?*sM5K0g*p(3osP%FG`RsOM_%tvdn1>%BC#K z!#n9-TwC?)hXeEs%R3z&b~VGU_m{`9?v@`jDb@F*$;u@fW3m7@{>flWnhcD|N0<~Q ze(?KP;QMR4(MReGJDX-_lT#*vi2-ji1dAH#LTmh3K=39lf;V}OcoU5+(Rr5ha3(T6 z(V|%Pr14`{Be5s@o+0+6k)~#&&Yt|K$jF|+=Q%yF(0RMYpfp=?XJG;InmPfmsj#;l zOtjFnGYf{0OU8;^(pR%!Oqyb=)!Lqc6;9-pa zSV|y$C`N-7a&RjX1FeH5Bn9MEKd2QZ+$&fYWLwl0d4vmr)FZMiP9twCjgd29S@Q)IvEk`FfaJOxx`uJMo}RFSo{MhLnqT@zJ*2Buz3^%VSus!5umPQV@0 z7l1P!U=+;6t5{aW>FA|SS%^lmB*A(I8`o-qL&ip`9^Od8Gbw!cs6w{ZvS+fqv5>s2 zIE_9~q|Rifa3d21)JY=?{M8=RLIE>~Zu1{$v!BSe5>Tw6px8_@JHJXeTvhPP-@~W~ zS6Fb;No;_uD?B_k$42HJi&q2KO|Vqa^Lk~|ftg{PbBuS&;Hmk7BhfbpiO-(n(Hs{_ z71E|W_by;DGCCpzjZw)c+pCU_kFZX5*C3Ge4Dpq$;7DGSO^QT9JpBQsgE$1A4e7u&KPOM}$<2&o~W0tKxmwlIl?rt)iQ11HYXL}SXfI!}IRvXdV2 zzk?q`1HotL&eZZ_{II>k-vB4racEul=IQ6R-LzRj8MsnqONX9zntbnm0z|so)oDq} zHn&r>pMzznO>e&%?Te6fj$noOgzsw#rDyd|H%HtHVh``l5}w4R4{7!6s+Hnuxsucs zMfg0t^RM*nhFfF163DV4qizD!Z%*9Iu}||RiaVTIj-?mf7CL^YLB%edIG`_aq&E6K z>(n%)17lsW%L-WlI#T{1LR%42O}Ms)vL%+Yljs4?rbeBw>4@Br{Q2TMDjQSmK$tUB zC8Jmn`h|bZDRzX*Z2af)+1%~?_g6##B6u#vBBl9pThP=c`LdCsu8rKv^Yk_%EKWXq z!Up7AUEte?v?>ximqxI&)IP)8o9^b$2|s9?J7>E%@A%w2V3f>dsq7h|C*5tWYv!6f zF(jYDtq*+(ilU~_GY_H${TF(MnjytLTl8%};OkPN-PiPW9~m=Q7UKpsJuzW6RUGr@Ol(KVEVtbx>S4Jan_D46+{Nu+b!gZY7jw)`k5J@@h# zMHMaTim39_NEHh|T_>s_{RGwGe?*ychh7w1|)BBcKn5Bb?sSOrPfUyGH4tYo(x zB(`Ophd*%*5t5UN77vFzG`XEvb65i(-ycvwX?;jP(q*JHjqctS2cEL!6i+lwxQ|>t zY)a;R;=q$y*eDM=9rB%3$_60it2)=oD_}Sa+J>20bA*Z=kxSmiX!&+4@^(?;+W-}3 zoNC1xrzRzn4jYpL`#(R#>~2@*!soFOa_%AcH|6u2$qeUe4B8S*>aAqg6DM$lvAbtu z*en>sUMdts)ZIi330B6-N#LJ;b`C?ch2M1y=;%6?g*3Vp z^o7rrCa;`izAe-2OsUF-dRwLyF6DJ_DX;T2U}aHWs3RpU;$%}}`9_?3+Nn&7dH@K&5shDlTF{o58a_dZv~xy^_iga*F+U7q6>iu7ghcosRDZ~ zf|j7eGIo%a*Q1U`=Woz_=VmZmQ92)lG@v5*&{~boXEqX@zu@8O$XGfj1%Cq3xu-8R z09KtSALhj2PijXi9aLf^a3{j88eA;9`Azr$2*}C(fJRREChfbzy`N6~g}pDpK8EJ( z{CW5?;%osw^C|j%A+Ap3tbOu+(eTQ+u1;YPvDA_CW0z`_2YS=u1BMbDP-Eh(G-4?J zSvI3(bBZk1xQLcVNn1Ymbtwr(D3O_q5ro4oSR6J9Va$;6PQOQe_=_T>3T@WIK+o*7 zI5MGZZGf`9{N%yr^hRaHRbchlT$?{L+&8EecH(8O|1R^vfB0v>=V=`DGrNGBEEru= z)a+#1%X+8pR;p+ZVgY57$6k4Yl4Y~r51)`yh^Kej2|Vxf@K-_#q3gc-^}~mS6jGKv z;sh&ju!$%9DJRrIdwO}NH&L~!lWnc@SgwsNu&0;Uy`$McHLoMRv2-X~Y-5ETs)GGX z9n5ChRExS0PweWGHq~RJYS*WqDRtlt>XnX%8u28XWmEeyyuXx{*q}ZEE1zelJn9Qj z8_r_oC)3@XN_9FgqbZG{u*GLCmtPqQFvM5nCtBYtGLeseuhB*p9ry)9=W9zw(})5D zWL6HyeM$7DtVOZi|C(;^Vi^S_bx`c-7zWOx;4tY5uz#Jh8 zQDX~{I0|tE(nyef&BhVyP%;Y&Znh)$o%w{PW<5Zx@Dzm*+`06Kk!#m!=t$!A^-xS_Rl3OmjiGQ|Mx*Ifb z{tAJ1FP{4vEULJWy~WCorL;G(QD9`A_z+mD9*JTe{@bBqjjy=VgaUoMqlz8DL<@f= zkD@$+b~SbuaXksup$s7nspeKI-d5acQL0bToSMM0Z3y3VY3eQ*`_qq<-0fdzPCveI zAhbgT))VlcUN(aqLu{=#EV>c)l2quFKsSpZLCysbU{vzC{}brw1{S0q&nFi9N6i@R zY#S*o#b5?Lw=t77d8Gh)W#1Yrs~(M-HGb*@%eAwG4tbVN8UWOv(pz=o82pAeQW?LW zo}h~kKKTRMP8x7+;lBqan4m2t#HEeVd08(%@qRs+D?kR7}CifoZEZ< zz~^)qEGK{N2m!sCe+4&a?12RQH@nH*hkdXuSL}mKOdUzylMU1@$r|x#mQMsz;}>Ml z2js!J9hYwl=8KJUJO8s2d2sjfYlgyT2)K)!50Xux_q=mq#098E{&hlq z-y&qZf(Tr{P}&s4bIq)<h-WZe>ha*ro0saWYvTwUF;*3CN28n4&M>*+-|pg-_l>pKmX1uS}WlTvw_TOqwJ$IPR9N9AefHFWo7kNAymRmDThP(UeAu#YyT`YKvFQz-$*sCN?g>J+u?oOE1ENP?p>XmfF;% z2!=-dawy9&6|)|HX5kOwVYXV*zVhv}s2ht=*PoA_oElYsibVknDM2Pet%=`f^%P8SL8KgxYPcOZL*2n2dYg2b zb~cH4+^OkEi0oL{R|4MheGs4T9a4BX{V!5SSt5gD09GkSNdl8kaMA<4FYolsWJ(yz zf&w^WplnXOFeqn9DEm-t?W5FT=CS!#(6@mT2)fCh@Bw_IoJ#3qQ@kWh!xs<9r9Y7R z$!<{HEupd$mFhS_+l0G)GQ?jo^4G(XKzJKX-(pdW-S}2FjFtSVd%ro%$#~l17ifBS z?G4KZAuIk$g5%-eu2{okwYJljydxDFfWyW?9x+ zv`Q}T+Y4Xpm*M*S^ntd4m=;0IW~qc1$S9co@O zh*Nh@6}Gx0lfMl9_Xv}{?5d|>K3kY_>PRr*dK3oVb?SqehzN^X{O{0CX0-OETYd!B zL@$mpIHd<7hLNqe?+kdsw`n8tBF^wT!hQ9hq=x}tl;?~%u(p!}>&a99WF3f0%!0aa zC1Q(12ZON22jG{H40Ve&1mzQ|``#yR501Z%L3L&jZ(hfs#?zS2(w6tvdAi>!ZZ_bCy)PYCXJhYy<0>Hb<=~QeIW`&D zkD~K&vfUrUkjS#Ok^Bo35D!rb#;pEIL9dGMLvdZ! z8#y4ZpRe4|YcXzL`D(|Mr>>eGN*Hqk6fwap%NSqK%9Pahd=DD{wnm2o&4ye;q(Khk zkTj)^4eT#Nh#XFIx8QtIyd0o$nRO5x8mO~@T@<|7zGl^j}QOYpsykw z^?CSl2vT|Wv=7tjz~5qM({|RpTtFhve5PUxbQDM8s$CWAn>`_7oX z_tKaA1=IZt%%wwvHs@@FskqrYKRD%94}Na8($&m)zF@D`et7#Idi%~+U(ixZHs{o! zucP0>zMyvL(G9GMxKqHgpSs&J1rYcrclbK)RaR7^Z_1{M&LXQ5Z16|;Ge3lG%>J$j zUetnP(~zC%L8*N3S>(ZE@&OKkYbEB(2X&DLCGx>*kq1}F2PAvSMrX?hemwA<9k%F3 z>UL=_-`QmgNA`$iA@sK12Mj51ZnqvLyPnBZmh35N1dSIb&g6ea7&zD*YssOn^`@)g znPs}(G!k8Xvw?hz`{Z0tngZp`I!{p(Rp~dAKP9Rp)so@c+HSxkR${Ch#D!*0$EFrV zrzBG*^|^v5GUQOEgJzfC1I|vPPVWs6XuuewfqXWACT17U8DZsHJw*yH_!YK)&`#++ zL^nzJ@xCXj%Lrm@K?xXULCPw2$q2kUln6 zKG!}*R-^f=Zkum)PQ$<1`1dIOEyced;olnk`z!vL%$7u}Eiul2z2ZE(uty2T#ZKy9 zE?9q+vGe~I`YYykV)rD|S-HcXqNJZ)_MP;mWmm!dE2nsj-*$(GhrUZvxdY2d+6`m; zSr#j0NhsW2{o&G7l)Q#q5L}Mb?H>Qwbfk8G3)En;48m-*!;uk8xWP)X2nx4PC`>B9 zt@^`d1$@X~X12nBJvkgq`2J>4rOCh4nz|d?@?8ze>N>y8m5OIISx5uk zXW<~)U@HP+*r^(2E+8i8pbcAiUF~}q!c(6HzOec;$JAt5R@T>jW?`o+^_IHp8c+dc zQG<%t4y$g>p_091Nqqi?^)Fc)v=+dBp%GMXw)h=R3l?fAm+ff{tX|sW0^Es)(;B43YjX|UJJRYOZYRqo7!NvT z&2ip2i|DrvIIgA)CY86ZA}^39QWBM_bGQ$=nxDmk;*n5Y!u^mho``{_>|>w|{}Q`e zcuY;yJ;kIK5z=9irsq{^Cqr9$;vEBdbu9|O-?AazOFGmckAd_fu%*N0NYMp8rE}FJlqYArZq1K$5qi zO${rD(HSFFj^jRp74#2MAQzr(;t|@jXKrtpJmtbLBWR&MWA(z#S1hP|`*-iOyp=1+rA#ZC}%dfaRFZp zKr$TPg~5FHw898u2>kJt~NUmU?xT@7m9p31Ok*Dumbl+E;K8@xG8 zEo<P#GqTJD$-Waq_zLYF~I>NuSO0@ZSH#E3Jcl;Xb$} z!2C~iv?hvWjneFNA`BdK)`Se#u~Ww(K~1-fVFPPygYW_eehNPdn;0l7gN5++45G=S zB<1V)vVqRJVA>qQzr*en<{FNaG3ijSF5iu>l-bh{D$fLPr7dGPKip!)_o}~I_AGpc zk%vj!wqdp=cYI}Sz!GS-Slb8fM@}Yq^P8<-0lh59lW;nR}E6f-?X;R@Q!Erq(|+lb3qO0D9^=X|~p(+=TLW zWyK;;Vu?NdOJxN~2RPvb>-n`fH__fY2{+W|PJtpcX&%E)kfNcS0|YW*xHX71sL7lOmhD1-COIDmtb&?i020u8sF!)FJ3;V5hZWYi&g&VlxLWV$y= zS@9g+vAp3Wz0>oYimw89IQTfKfVm+Pr=;#05=?iEE-5avrSC@ioio<6?C7Av(dmUr zCAXHrZPuCIfn>$?Y;UT|IRq+R*C;HUgWRL>h9d8bgjNhK1WK+&XaLv9bXVu1VR!|B ziG7KU1t0qQo<3prJ|HRa;~R}7E9O2xI)WGzo0P|99*yiTm2D)pM&+@X^U&lz05b+z z(p6!6uMyl>NZ9vL4QJu?lYM;VU(k6wqNYjbY!$KS-433zP87nCvq}8HWCZ3y)Yn9C zg1|Z))kDPZ!3IvOCqGX5<`60cO}$v~=PC}=6*%~`t!OsXvK4D3|K#_2W8dQk^=qYS z3%yHQgH>BJeni-y#Rm|j0j-mH8U9ab9xnW%1K1*hiHQ)LtI4*_V6F0tlF-w2u~>fNK6nEYW~ejv2&2>>Nlf156|YUCpL1fdgW&LFj%r&2IWO zpASX05m&BeLKa+JT+Jvl07XbeHyj^{)Eh|kZa_W43L4hGl7*8tT|R-6lqPQN@e_m_ z`ovbaf<`_8Yqp8+hCfQzPuRPCf;>3+8WcT$FOWh;eByrj3G|EfDnJ4+LcNwupo&o4 z_jiQa(sB8I{}iB!KTs~h^j;R;NNDqmLGTptd$CFr7b*)qvlN>K$=uY!!@rGf;WD&f ztPR?^94%Z0)lIa8DbxaavQY~^kS$!I!|?vo0)`CE{E|XW5VFqu)O0EnY;gkw(aSB^VemV5jfL ztqfg@=10izwL8#!s~e_0z0|>&QX^%lLsaS-!e|w~1+2k|qWC1nCDPp0vLGjD*Fd=d zWr8XoiiW%X144q5U+Rxn%gL(N(h3&CBFRW0?~KL5fc2SQDnAAXi*pE!Ek}joLA{VXT9 z8+h0vLzs(Lb2H`2nkl(zd55q(nbM8iB6NxPCO%JxWGyI9^)_c^VbxTzOJQ%yu)rT8 zz-^@ETe-Rkr+!&Im90sx{1oe9#go16^6hM&Bwkn2>yk@ZpPET#Z0u2I62UvvWX5^e zMI0pl0{EZ%Nu+<3ZRFh_-LGR^xC`yjoxV&?TI$Qg=~p;-sUomHg~K9m&4Aw%_MJ&k zR_w&q5gz%|(xq0Xuz8;q_tmR#pLW3SN~$=Wpt$OpsWp{m#Pgs=To2P;CF0cyWwfca zzxDtkCJriLN!`s?{DxL-;tU9VE#+ueua!eB?uJ4f8wAN|P+fB#DUMy&)G{5#wFqcv zff(rSZt_IuA<-+UQgPZ^dNaXzv;z)uqRW2qiix%;=jVD5@on#AZ+pL}ajLAZ>GqaxpsLC=Qf;m)w}dg0E{ z9e#H^=|(Pt|}5jd}x5^c3%OdQiUB4XGTR=#&5@J(Ioqy z3uPhv!_oQIpCOo&fIScY9i})%-tJ%<3Got+T(mimKkyVff~Zp!{8KNMcj548FTg$C z4&wc&KX|wCb%LH6BS84?=oTn@?iXE=_{f!nL`CFjU}8#Y=-mFij!uQYN!P+d6CD+l zu<=P9ok_d}dU3y>W;4HmFeOWjz@tECZyG6OQ?zF?#=*a#x8}S5 z2^ZL>trI*-Mhd?Rb30*lVpGq6J`*Qs8Q2` z6^*vhL_q^KJSIVHU?P%e6|t@LMr;)^gZKb~lPJS+l-5US)n2gL+E#D5Eo!h-6Tl<_ zA}SYSMU5@$#-th)At*B6f9-wF%$Ym@uf5;z`|#)FJoedp?X}lld+oK?L(I@R+4J${ zOnH{aGxo>@Z)R*8@}?Y31~5rmv=%hgh;7=Q3aZk^v*}WBsxO0$sc*<988h}%39)!G zW^~PzkUZIu#$pWZGcNF5fy%~g2917$fTxnJc+tC3Cm!_Q!uEz1?eq0V*QTA%4t9Eg z6WdQXv2D1q1EZO!6cI~C@uPO{*bM)FA<6&AKhdi`keFF7tIfy3q*_tl`JdjnXqWgb zptri_7449)5e=dL=@+9jItpHKg1lI^KC4kBb$#N>g}Bkd|83aoo(b7xt>hU8)@b^I zEk*jyU;7ZdDWvpY9dbF4))p5 zC>43^5P1@^tlR#F_c}aOhskeg$9pR4&;g%LhnYot4VAZ!E@-*L^kZwi$RS8bvyk>rY^+l`Vs;|`>i&njNX)_WCMMA~Q&|k~vl78^w z!^M}ygMoWA|rx81_Iob{AgnnxqWM zxxPMLJV&M^wvoiJ`_GS=O@#9ZZe`N6R&_#hA+_Wzga+wF?&?It*ptN~KL+;9C&;vV^Umm9xhd&lopD^6qJtgJDw!OJoiuTb!` zqD7DL%zw`kWU%(ZiTHE=+7INxr;%|xC=_^pi?F}5+W7TP949w+GM(l`7DHj-$u-3xb2x6Pj%OgIORfjv zt)Q?L7fSYmI2D3<;E|b2G)rp}ThN9m=P<1yjCj?D3-!chi;DZE_Mz2VRQ0cP(%mC@ zl<{f8*Fk4&Y&~R-#Zi2N_`2ttw)omD7u`>;|Bo9@E;?xsXMsCT63<0kV7=UHmx@Ek z$71Y21NWN-q$_I9Kj`6ludNl31Vm^BR$&{X#&psH35XG!leT2wgj&gOylwSJVyEMk zo(CZ$x~Kgm4;G~PQq%77rd@U58m*eiQ~hQMX?Ur!wxKEz%?NN_=Hae)1RHp@$#Vd(5e`sG#`X_x}@ePgCUS{H-M(UZku1ZK#eR{H#^G3$W z9jU?yWg@#5D)Fca;I^^~i#53Um-q$TeD30}@P!r1Ztf>kDn(gN`w8L7b#p%Ot?se)^Xfc;>GJf`Om;}?YoKnb;OJ}FZF zrBeU;T;X)$;3q9CSYgfe)r@-ygn9gRf21LMUw`$ArA%xIYEJU8*5yCvCK(i8#Iwc0 zzc&Tng#BrT7E+)62@o`cd1Mo{txS7FDizGg#5>oT?wa(+lO-zBIKoL3<-hYAkVE@` zf;~HL05oRci6{6x%jJ7mO3$si=+SorLd`g72{WxblWKCdKo~6zyvYDm0c^^i4v+Du*C&z21VYty^6p9t`Et(#!PW9%eLW-DF zxF&@hPwCbDvRs>|w18vL_Wg07TibU5@pwY&^e;Il_{QIvyz`eap@(zj%n&m_o^sER z(_HH-a)BK}7I_x2>9q4?Bsb;WlM!Ga5OVm{`>PnfPW7Kx3A=rE-;eI`tiH7T9*;k` zffPljh<;SZPr!u=LtmZputf*N!K^B!-j%ULy^JaGYfQbRrrxDjQEz9W-dCP+>b1ET z)n^lLhb;_2bsE?iNftpylA1hfh_0jh1gx&F`}BJ5fvW0C+N(OXw$7t=JSD3W619u( zXas)_F*(XekOsbFV_Kg(;WAI9j;g#xf=Ln0IGk5eb;;FC>uYvuWc>U`{K*=s4Kym@ z-vO@3H3SDI@Y>8P>`fr`MLLEiFutG4S>`(`t9CPq~X`ZTDVHhu~ljM2_RaD(>9$Y04CIO!FU>Xl-$gVzQKc zRBP8x-6B(|ljY;3OL3LitS)0n%y%-6A$jVYHNbkAFS(a5MSixSQZHe1SS8VWfazyk zANw)h|_5Kg+cGCNMywA2h_Aa?uO-pT$zs-U(%Y{7au!JlTOslCHl;DYPTE)E2HSi(Y8fn}`3D2~*q zDLCVDPMZ@gTT_Sg^8J*Ej2ny8$53c7$X|C4&)CoYMxMe*qFH0ONbpSOs=*CCASUZS<;aT;@>*DA_;dGAO1LB_Vm&-+=QG=6kq z#wUAsX1pSI7>u2mfn7o;p$qO1xtd6M=IfW8B3O@{n6aT~m;a83z}un&IuPug*GSn{ z>gC2xHFyMsFSqSS#=HYbayo(3L7l{ZpENCgqqkBmlMf1X-L%2r=WUi2tc^)9Fn#|7 zwX)-+>7_ZWrbKs-cBRwWSfPHzYb2x0&*WL&=4es$R&Olx<>-Yz@|9xf)EV=>q+c~+ zu~Hc;Y-EI9md|e$|9Q-d2oy_*LVHCc)LnHs5tZ=^!(XAfbfkQ0P1(!m)cj~=A%GTr8s4U}E#b)=42TJ&77?gV>Jr;gQiYFP zYE2nQ|A$$F$y=3NV@ouCsE!2UZza|?setd<*6Ms$dVukz&Kr%Zbe@0jM~3PgI@_<` zJEY}2?HZ?vN~@F5*2XSL%k$d>HH8^kHH4T&`3NzjtR3q~tZ~kf6IM zeCJM?Xn5~5vRGn>r|#i^ic@wZIW-cyC$Y)fNG&#gE8V!I64wMG-B%+#9goyZ^(%k` z4Uze~)51p-y&dicTG~fJ%w3pO?N=M64`rx?0~r{8&Dh_qmdX%9)PD7tsYHA*$vJ^h zVwai#a5gprOc7`DZf#uWK+0G}}RJ9u?Q(Z=vd+a+K-vMa$5_48x+WMgtV zw5Lb?%_uPCyOK_8%5EB$NTVfPa1e~SW+-fZ$kN7?t05f#_^QlU2MH}@5fWQ8jaF7w z(3+FL0Hr8IYJyvMQCTsKI@L_~2jqa}gVPcps9kqMfY2ZMv)Qr4`e`qo$%RuGPMJ^r zW}oc*ed<~WJEVS0Wg#_FSLq{vA{Uw+NPSF%BF-^tm(f3&*n!H}ypegZbf28h<>bS6 zrW}k-Xe^%wDo?c1#D6ndGEzV4j>U}Vl#wPv9N`g|22q$7EUc8c>jB}cCHb-vP7yAa zf#qE$cj20u#GrzA!NLp!)ANs4Lz#kbLc__T1Y#m%-rnk?msW7}D;=Sd$U0$PAMui; zq|q6>l_Y~ji@Gjx_~Y<1yFTHv0XQT6dAhzYs82FdOqTkZ#|S(8g8IaNcsKbom8dN= ze5vv%a68hD(SMftc7DbvXoLg5fqGwJ5fTRc?V`=$Tv>!bAFGgN%EzWM<@Su|)RE1G zGsE}c{x<6eZ&M0cpsZ#Bt;4L*44bi)U)sYU(%LsGy%KMEbHeM zgNo)-S)9;AkC8uW&kot1645{xv6`Dp%qd6fzao8I^>z0{5egfA-<5C$8_U zG@R^?lq8Vn4ANU>*E@k9{gBn4B0ptwHW#~@v5+-BmYP{u=ZS2QkX{VSNUQ~o?`9-I zb*7}=y=jC_yZa&*&Z1Dz`YBucWCwU4(4<)ng1$r7R!w z+th;OI$$U&!^_wdJioqKaL$)rMimGD{R47RdNHJ ziW(xnXf_VaBdJmJ>8k%ngpvw&TA!=;{x!e@+b0&6wKh~vE)`Dy)b^orXj>%~*sPj& zb0eCFvBr+i zJ#EPAWIM`3lKDJ7chqqU3aNxv)hRS$m2EF-344jCMnZ;#N8aWwYPqo=6SDnB7+_Kb z%p+P+Xy(oJR$6QUg4%YR&f{CgriI5brR9h?4sJ8W-Fu;kh>?%SSW_M0=j9}~cjhJ7 zDfYIs_p|nbD8W%(o5VG6%WU>B%++rXfVnPfm*1cBD|F!eGvohL_xQW^J1P3g=XdM9 z$@Y5wSbHm@;TC1Ro6uT5st1U$Ukt5QDs$ksT|JCKI5DWVQ#ux0L;i6s9D%u%FgL(6} zNc@`Z*2~9nlKGn8YYIH%YX5ioVXlnoXS>xnH}Jg2bM%vceQ7W;-S-Yz*Y1^Hx?lxc zGMa5d9>jCnU8pRfq0KJm?* z!FEUe;)NdiM>oB*Tj(YJ^sZU?>S)@tL$`OvX8M{3Y-QYR@@9M6JaHt$j;tnou{2gm zwrSJYrcES`Y|1>81>MGzb^d9h3wZ7CP^|=^T-l8u*L!C7$X8j$T#$jesVpIuB9wMd z#eK~Hp=3Ej=sgwp`Ml??0Ai=&UP`zgb<6rBa$pM31K3TV5!T{fr&1K*H({v=VSYo` z3n8!vIX$&9Qy=TgzmoVaujnBWvI`=uTps>--j|9+5i%RM9Un_gr#kg5n|QRllEBf!+zhvHpBG`j#fYoFeP9>|dj$0>t}A36nI;Pf zkp{Zdy-d~QLK5UoGmyJjm1PIPLh*NY4LEYBn|WllJZCQ=?+gF1mk`(ojwZe#Z%4<> zydrvu*DcuD4A}7Bpj+Q`xl7+foHj=xPDR*C!1bCr#}%@hJklmb2K-3Yl=}?ocYA9Pn=1HCmw^iuN z^frZUhz$T?5419Uzi4pHE&};SAQL52fG-cKgmUZ!j*v-~@G3F*c)^ViSAOIa`v&Cy z$_7+SoQZF@J1Z6;N-Rxm%&7UNpob7Yo}utgiR~BV$O5BIywR{fLKd)^aLH#gfp3>bKm`gTG2X;B0CW)<}O- z`nP5p{TmHJ`Ludt8)ZNEr& zP59V~i2&JUJ+oLwtH(IWQ}u0EKUQz0%KG)mp6t0($}p3Ekm$kAsH)I=0FVovrp%0l(@FKckj}f6!Nlzpdx`E%f!1KH$H+Jc0jj^nm}1 z$cx@RYrUF|H2nWn>Vkiiz@N>JJyQ(+DV>CW3R88D$}~{<|5s4S3>By*C!i9> zrT+ST2UqVmu zBe=RR-G!^eNpJrl)d1B$ai93=P|0i(s4h-GB}X&ro=Y8Eu`&x(2htp<>~N7TJarEj z`2(PtesE~?vc9s9W!>0E6vYt(#0Tq}tC5F~m!E9;86rP}__5b{=TFu0tr-Ee4c3bx zL+AD@J*$hCRLOx}`RYj5G9xLo^E)S}%;n^K{vtV_d&>_f$#^G| zHcEC;Ea55t3_m*keHT9(+1q|D`r}TWkk>k~{y(n1`fBlV=1}Ohy&vXr>gP=yKJL(O z_wIB*YaPc2{r$C3Sr<7Hnw^%n(JodmZ=`JMfsp^sODN0PqxCkYj}u!LeW7c(lT&Y= zKFHRQ{TuXaws0rMCXaxo?hqAMxq4)uMj^_zTC55@vDqUc@3%!u_O~C+mO3k>Za43( zP6^~HXRL&H2s_7!F>g&QrztjZl)W`2#({)@AQ@j!jDynIGa!~Hx2f!zL4?0(3nx(9 z+J{wETvV=}-H6D{Mr+zA)ZobRl^2D|)noF|Z>0K*WLpoQq-~LHy+-GWvaR3f##@Zg zBrXl-G;Kol_t?b!k**VO`lY>{)xGXc*{f)j?@BzSfpL48_&;(R3&14*+zvCbxB z*S9Kh=BX7ZJl1(IP4zySx>=`Hs24sntK(kGz24L3+|X~&?<*^$XBed2Yw%zi5cbC3iV@Mn@>ZR zz%Tl$IyZm#Kg)mp<$f6LVdcM`G-(oNAlJ&2mdNcLv&Pz@v~A&~euB+rO8#pCe#^iz zuI7)#R^V==xpPj;12k=yHg0(jyem*UgkYX=u+(*||(ZBqBTc9jUQ<&y;=s zN9b!(GG(8Egs3mFLyKkM&y_{L)kUVL60=+3zy zF!v~uvL7?Pp!pgd=c(v|z?_dNFTz`1l1v@ zeb#9S!e|4r9yM*3UJ(eZKch{Mc%e_dQ6?*ACk6QutEOBjXbTL@6GzD%c16WRx;UX% zN+`*})q0ETRUfHI`%0RA&QU!{VHguJNeWg;PVZSsH>)T9MP#WM8AmrG;cv&^Z3~^T zNr6h#O+RN{3Nb(sMxN;RflL1E-5zcqR#N__GfWh)E#g7xe|lnC!4`hguX$DO^>v2h zN@?c?62lpEZEe#+>WqEDFLofn9WS8z02PH@Px)xkLYp!!a`=UEk%d+YtFa#s@GQxC z_au&?I?ETAby}M^B}LsEJtj8Ar#>KRL@HYlN^y;NB0|{zmMyfs6>O6XwWpJ?pLwn#qDA{6{OY~I}|yumpy zAY`0Oay6O*bXywC#0%9nF0e%cd*#sbT?qkk7H9#lB)f-n$G#Uv6TfrSdGyAf7@{j+4o?ZNdOj(URvl;_wNd0w(ps*7uMb1{> zAg4Z~AGnyvcuaptnikE6aKzMLJRC&wkd$W%AIV%>jcW)QE?-hEIlG!9Ad0Mhv(|SVwj7`Z_-?)l_ zn=(|S-jl8VeF?p}TIjv)LoG;?qd3(YTqN9izjH~r#A;`&bmXkDAvM{2lWH#`_C91z zF3CJte%sMHzpan&6JnUbL&;DXpGcE8es+c01(%(5TKsJF4hQmB++x)8uiv^r(Ov!u z?Jc94gSGcA$5yk((%$un_U3<`_C_6|y>jW_7}|>~r+-;rr@eZrIavRGAng^?-aU!- z9)9d=;B)dJ+8ghT--(I#PVcq7DRQogF>j_CbP*(r$Dk&$(@2ZJxiib2i^OESON0am zMH+k|I`iN_@r%Zo)Bb7Y@YpF_wPS*>VK{G_a}YA_d>gW>Gs~N zzjaA|)QA1rD-uQ$%Sob2EX0YtpBO!3ssEf7$)^V9=Aa0(*Wbb83z|%5+M=mQ=7gq{ z5U<;<4I#CFL@idZO)THqnaJ2SFPi5w2ICTomBdr1+t^hb3n<&hO}&g!qi98g%FfhB zk}%-|&Bc0ihKsjYvvyy(AM@Zw)(*1)5V zw%ERS&lz8^?wVHF!4z$n^RY$9mEeAaR5X4g*2TPy7M{kt#n^&$_Q5v0qouykMQSP1 z?5yHS_0B(}tK#zzS?i6HO?5__Ge`uf=+uL>S_Y|XHyyIdx>9;&O7M=HU1&8)f{E#R zlq@=u+0|cL!-tUtbZvo8x)AiGc44^8`$P7D&$PKn+fq0DTaX+D{u2}M(`K>@GFrf| zN2@D!BzS5OuG$%`%k^k=D`WWY|Ch$AW{)famFhd#asK~tyc)1G7Wl6xQJ8`M|75)2 znY%CnXUz|x$RK}XWo&_0=WrZ=)*_y-T0gfF!K{mqu2dJaGgSwWpmBiC&!|txWOXv> z8RrJb9;43gFG9f3?#AtAJ|D6@A0mPIRN6cD!$Y^%)bH!GH<^ujvb|#uqrHlQwZ|YO zb^BtE*q3tO*dzW7YiF3fwnu#U!S3=O^GVlN!~WTQK9zb*U}`FL)ilkn$;cb;eVEwq zFY0K3!}MXY7xqP;GHEYbDTG=r$N$Wf!i*;WGZpz!om7@}H(FMMb5>ooFo6v{;{mYR z^CnJsjYK>d;*}6&L*fCC@iWPiP+-5H+WCvfY*P!95g(?Ois#& z_O~YNFB(A5rvU_gn(*bhrD@@zOC}sRw=_MRxnx58+|rD&x1gcD-*F9umq5z7uR)?0 z+(8AgDf?|F(V|^;m>L?jL(}*tY?f2on)&y5h{qUg#UnPP{xL&?Cfl<^1aG+$C zA+?;-Y;Bc-c4Rp~MCU(BH~TdQ^-+zHH-IQMzx7!i8g1hI)`Ax~&KYbLl(pArHDA%@ zIUl3kZC(A)1_^|wv+odJ^|$NJ>7Y&kWsLPlruJ*1}SnRxHN-mVz*Hs(#UdL zBlKixy7NCX#!AxwX6OKy8GjS1H55vvKo8(o@d)|w_W+)6(}K9+ZxPJfgwPahkXSJN zV!gz#AYfR7dP&>ZNYF0qMsyY>Oek~J)5Kvkkjd9r7)(amJe(Lf-=j;A&cnuDQ?R_o zVEJMV>=Y$2Zq^8dq$32_O$OL4S_#4n8`vdw6u1rLK)FVp43yUN#e_|=N=8!Th@z5F z)gvIxHAK@By4)n9cpw_eUM&?xN=D{LaHV!^oYoM?kPhAdE*&D;7QL}2z?x*D(jFE% zcNn{&*Wb_+Kx4b?adpPoqUzQ$cn7If+{A*5sZi2Ue~;d+-Yz{=7rsYJ`4VzX4h~Nb z>L|=yk5u1~YZJm(O)uti>MY~0NhCD+oM5fLZn_BOddT(YTk}R{5bZ@qTY^)Q59N2R z(Vpe4dR!aaKw7O(wu9}9+}aZ01`Xs-bPzp0FXq-!MH(23%G`aib{Re{z{cg5L6~vq|}?! zPJ{`y<(;oGh>cJJARlEwW-?o4HN_DWXRByFhzly~De@Hx*@81Jr1x z6*X2D%JKH(+*rtG-I62wzn80r#maMvUauZhbVK%>enmGF&bh_f(B6&-c4LwLF8nfP z7O9#{qbW;O*3HTl{hb{_>XvPy4GMrR*;_Z43_X!6f1uwMD3n>+gb_ltf43Mm(nBYP z9D8>O4aRQ3L-eWpE`-hIvWNhP9O7^34VoUIBoolYZf0?=0RWG~NnY0BB;T%Jy7i?> z)dIf3?>IMpi~A5J42to4nZ71EyD;%+~EP1A&Y;vS~%#1T%4%wV-#P+E`u`yYON031 zniNsCzWA)mF@dYJ#$CxD{k3)iJx)8|5OD!7+zD%?(?1Z+~adw z@8g3hP57au>PU1tR@N$Q%5F!e!We!f_x^x)5Z(XYAm~$arfe%)PD+`zsS=;HL84eC zWj=?VYq*WJM8M*~tTC|0^yvKiRNys8gUAD3ZW6&DjRLFGR$w7* z4lWf9mL6NOE}^>W5!i|%qQWZ8Um*<^Q~iM6bW|&{d3$IDR+eNcTSywv1bKY zDV?s?gw*Cg(^b87FIyZ9-X+?b#a6jD-cKNiR(hlU=(*9Gy(7*V%KZwTJea5)5i!=t?5Qo^@ga<5TZKc@QLc?G>52Q zQnHB{gBBPPp%(z-2^nnuhDAH2Z(8t?t`*}>b2wd_g=q(iPMYZ&{i0I{I{v#(XVMq! zG4iu|6H2nO)_3b#!~br+^yu1*a;Ixz$8LA6W#`xJ+C2kw*S@tykDBh7M&fjg&D_p;CWdY$^d*{kl_nC#RR&E!+~ z;YJW?Wj)cYYmfh%x>iQESTkNsW4e~Z`ljl4eBG`sG#l8XU0n+yk0-`!&r#B;N4s@u z`M;@C^GFt8I>j>Sbn2h~{JNd`gV}?Q-;f-y<rmxO^q%|GyAL|^oRzH1Co%wqDYW1DJ z^K=)|{ZX8O&qIDe9FNT%75O+V{LyOd;IrP8veSdTUv!YEe^TSWz<_6dkXlr7>x4I5imEDPZI(2 z^-_D+A}Jq@vXr1yD5#(JPuy#x9L?#Q)kkrjD)w)V>U1OLi8Jb%+ZO@Tqt?cd+D^7A zast-v31?VDsKZxS0~vfG7JNd=kY8&X`LO3d?@T|-V_g!cJ`Iu8YIbadhFbHqJ4&&Z#?gSzSS6_FPTzf?qCssU$1U@W z_pAnz5$wK@99B;snM{T1iOzPkWCx#Q-)D;a2J>W2J9lTE9Ds&2<+=12SpB|*QD`I%|qeDzI)O_B+GQ=P(v6Wbh~ zq{Et<*yVqsA%IZ>aB9`5(|h`B)!a-dZeRS2_^_OB_yaoMCH8MIH+^RIw5AsSihqDG ztE(y4krth=@D!1`3JN{y6n@azRGKO|*KzkwdgPuFhCehU+pC|HOC4t+^d_f8%B-Ni zFe#K)p$x2u)-~`a`jp(nhvm})aWa}kM2KOdxM{9y<%IxM(D0lr1JSxoQoc^f?^7N8 zF4je?zez!x@}qU@<@MjT^1GCrBKkH|{@#I`(E7_e)rP|b3HTPNkgTa&jxHv*xhAvCZV$ahMp zOnqDuy}v~_L&AaEOKF})I12AH#Uh*i(Z8+X{UQR)#23!>%TieLoLom5MzoK$Ue|T# z=$u{M-<}Zjp36b~gw9w+nyvplJvL!P(OUl*^%y}zC(5e;`B8k5&^s^d?| zC{(J)O|VCZ9!rlacp8CWdzWwa=q1ur!H6Cz`?- z2V|0jLzdi`#as`#UeDVvGoSRP*Gqn>g&OABfxw)+603R90b5ZGBW)UyXEV~9&LXbL zVESchq<8MAXy*qxW1^g_XL5cn>L`TVl5;b4$%3B^8_KMx z@`73>5(tRZbwGv0gNQ!W!fkWiCVr*kDugAFE*Ps*Jfnyj$0G*PJP7HR@nIvW(9{wl z0?ZDP@ALoKGn(ee|8<%C&*s@;r3mG2s&l*fm4@X4%O?ixfup zK6I)1R zmtjBQv7FB&o*z6qBJz;$YdLy38y}J0-@VGdA+q^!N8)xxe#hy_f!0^SHPE zZpDE>_gB7C*#?-%IJxWI-!<<3K1nzmyT4NP!TT$uU6jP`U_PwdjzX?{2YBR zttR5>xbh9~vciNjnmupt+sEx0(MbT)4|a$_M>03Sm3&s4|KTuo@GZ#*}orNSvjFn|3z7w_E+bY+~cXQDUiVbIvoIURcvodv1i<@;q4Nj zLbHlgIMIj}>#IWafGh<9k`w`a)K~n`AE=WlZ9+C}R_*`f`au!sHmi5I#%fa{Fnzj4 z53n6IE=gg~S4w=SUh(-0>iJ6ee4yJ0vkx)=8mT|-_CX&5ppkkhWgVo3NOYc5eL${lq%PswM(VHs+5@TeHFHwpLDlD`-V45M?tii7{yx}j z$mafV*lz4|)1q-6&&qG4AM=N+FrH%P;c!xY!!Vlrbo0{ii%3TRV_c3q=i`WM4axfi z8|l2YjR!IsyE3rP9S4Uw(O;V<)8Rs2aoz?PZsWcTk*H5hMj+R>?E@v=eGs7_*hP+6 z=u}<)JQ51~7lOxmiIj>vlX?*lX~HTf>LR-Id>@9)S6Z$1`L)=4OAxn6lP}UtNcZqZ z7){OaacVkT`*%zH;uib;Iv$5VvdCn4qqpcl^>NmW&b)Ub>xg!rS)_g=g{a{GZm^Un zz%FVcvG1v95S0D`Fwg|we?q6MjJ%e}yIp+f!q4Q!!~Q_uMEi5M+dyP^`P_Y^EEnTKH0qa+?C3ml_a+Yke7 z!K`^)BlL-KjRZJ4XqY=%v5xm^Oas*I$a!L6kZ@(tlhpA4x7_?czn6%I;tt5_iU8i< zu{01`hEOvB7p5yW(J45hWx}I>s>oLzw}#15T-$(iu0J?T*5jmELCm@dlc#1E37cpWuj9uUEk07G^EX8h z(I{|9PNshc&$o33V|{{37m%}RHF7IJZH-KtG=p3B0tDiL1gpS z{!ya^qZ1`o1ommJ4$-(=jA$IBOzaCO&)v2-GnTX1Dp0efd}6pIMqOgK)y4WxJJ-e)}eOs%nnkLq#63d%-*MVOI+V! zn>02UVFs{;YsUgbqSw7jVvo&ID(gOjv-oHrTq;-t4Dr((s`2^JEQ{cf z*YXGpGGDuoOb6?dwr~V-_0^BbV zO4i{w(AO??-#$U}!Rf0@T_>e%`l^h}z&Z3K)WtqaeNUHoNMqELSauNVGWIpn{!sZ& zvW;59gnSudsX2CM0*CmrLC3E`qq?0PT>{CYu6CC9+K%BjFD2=>H)d+{OLdP_I;=xi z8qn9-!OHvt=A)19nWeEf`1PvO?HiBaj7aB%8(>W6*_6YUn-XtQX=_xOWs4z30BGosj zdMTp$T%S`Y$>c0uU$1MLx?aEQmC0e>GZZF=>yE6g_DTwcY5EIiiso1qbKoqCDf=(& zW-bJ1@WE4AUkQuLk|>L;y}}AgKF4b$$#oC4$Wos);aaa}>blA-v zMm=r^1eMK6NM-E;xH7url@v$OavdI7e`x;z58@NOFIT&;j-l`3Sdc8id-T`$*Sq-Z zzc(I8`yNyShZhgT`20(_)MPx6?mqt$pVV7pcRY|6kD!I_@j(7hBY=$F>?7*K4vG4( z13^o?64j8EDIWZNM*z9yn+H-NfNUVeyvuq2|2P83=!HpNN1*~U{s)(bcGXD!(Qm3w z9EPo7X8KwEVUZ#dksdytZ*#_O>?Y;lB1wxWypR_{HG;xyK#A8(NdyH91V-{`eDYf(Y^?w3*GP7)^5|1f$PGse@>d;)DCU2r z?g6d|$2<=7pr~E%i+mCH*WL@RVzHG{Y$T^-vAV~(w1*Vsvs8+#G%bWuPrp*vVQ~P9 z6Q>^$yUhnpb&paoEn2snKOsw8eKORe7%_0+RmZ_W;|3&K*pELY&45!a@$0=5JHQVzOtyzC*~$y&5M@EjRwrU>6VV)~em8 zEkf#-caU~?`?-?NQm2QlWz@h1Rl9{C|bn*n2#3}yr|uOIGjIP{DIx)*BIZjqF%%y zc!wmrJ#iPTN*`YLw^%FZdR>jMky!Z*jd+S?2dYm`eenxkOtZ+-xf@4``YKm<(xL7X^yX|&_&63pv+MMTK#f3LY<8VgQlZNASC?y2*CNp+ zT#88KRcH6C(7GX8o!Ikn^oAVe>-o5Oe73Zw{`FB0$gCTPf7;9A@i{Eal6Zj*th5DVii}kVqK}mP@d<8mW|CFBNpkol>ebkS1 zL4yui9h?OST)2Z2n(=+pHNKb2`1bo#-{VVuBh4|zH)FGy)2N$1(>(gOpaUNLOE@;I z82%mUf={zca`^OZBS>=Q5VRlGs-6}9;MC5_-1|+>$1?Zsay>R|nZC&Y7??uNM6AxV zIeqnIHg8TJ32#0V-P{}ZYrd>`^xweJw91%f*gz$ESoM44VDm(MB*Wdy(4F;L7gye@ zxpKy$9$Yz8<8b9=U`BK0tfdLAEYAoIiXJ>M_*|Irh<%n=Kg;cDmOM&|CFW2FI})aAL%GgPUIBBkX`I|qx0AJpYCshy0u6M z1mZ!Y6}0f1e$9(=udg$lYZKJXc<$kqQ6Ey5|B;ww+7EPYQNK3qt*Wn+7q)ZXbx%r? zyap>j(v(@Dau4i}$B4jX7zB!lR+Ysg?GK`zZh0f(k$A*L=5Gyz{1eL>%8hT+r0ex~ zlZa7WBh}!G`LoO~_<4FF+H#wIB~gQu&$f^I!yo=I&|mu}kz`D?WxrjlUfxLA z?vZmBP*$QXyCUc6O74`n7BTPn#JJS~m%GKxE#)m~bC>HKk=WG~OYua&Wjki>VBYr< zGna_Cu9&&SvCO8}_-rRy?hfq6x`)bb>mL3J)by~g!0}%P$YnB+bkP+gcjQ``D|V3F z9d?jhKM$QCxl>J$+?>Dhh^WjO=O##Q61%a?VvFFo$-Hx^Uhk8%qP_e-ZAH5Yj$2H; z8z(07LBirr%HfRtWBEDdawjbA4kn+n)(GIq$jldFJ|HWAI&pRC%r>(eHG-{Q{~@ZB zUiIsom!N%#EEMJNZ)K${Lp&HM7W~H3M=N4#u|ZGhhD-a<4aW)>tIMQdLMfc0o>1TA zov4Y-md*cMNhZuxq*^UgED4fmv2$^W(G2g8_U8zJ_?@uP7(wHhXdxChN~l&IT`^O* zjLt8j^}##d6Zp34#Z#oR;ILM%yX%9WlTwG!2meZ!xl7knp%qArxt8q{&6x|W>EIGZ4P*GxZ}%qFgGk5s4$80B+it$ec(4!B)Ik?e z>9J)uitcEQkX>P;D7s&#oH|;H9b7|~=xIvl>Ju96daco3bYM*(3_LPdYHh%TU9!=) z(we7!)TY0uuO9XC>lgyJSl<7Zc-);f!%u3t#r8-X2!(%OgLL)M6!W8FB~~>XB{)|| zt!4f-O**U9v-1~x(ViQLAFVBqjNOrmL4JxIz`m2B zJTj!7rv&dY(Q6QZ2!t_|$iz70%P zaH}<+gUZ$>Z@z3s(XZ1@HrpOivF94wcI}L&pt#}y%68+1Fa2)!vnrO0=6#wdq;=E? zolgWy+JoeNI1huROEpxSHmqS->&P3``*QgGhn?k6bq^>ZQyjxb1Yv3{Yu!;7RS*gB6cy;TmXXxr(Y$&Tc8+yg+ zQlnGAEMOWq#|HMX6ng9-DS%3uWdNO`$L?$soE(%NB=y+qq;Ma6`FHxA;mRVr3rn^S z>-y4TJ9rU(aiGeRft}RyEk_2fS^-^oLK;Ozh&dzJRqz7BWam}Ckyp_lbB1I#WQ5@o zU0r-S>S8&fg+k&h(-4xbieeG%@my;3=IgZO^Eyj^C}qxU=vl@AN5+Sf&28^UXRp$1 zhW=d1MLbP4$kTC`+fT<`!i9Q5o}Kj*``KAl@@$#wYrS!o?`4g((i+?PXEcT4uOm9l zl&FKJ$_7(_b+-QMGS|mW(?^_%-IyBB8&+^@*eXqZW|dmWHElfO^FLFZUM}n4t5z8s z$f40RwC5_zRolw6M179-%k1AO)%$Pv*557iv|E4I$g^(!ecbi+A^Ll)y46)U0gvwA z59Cc5XEnN$PtY-zz{lm!GifAE8lTRYEc{2EIlg$8Dh%Rc^l2qvN&H^9nskKIC0$U9aC9pZEsI;i1H1`2@M$SrWB;QLgqL z2~1@^$W`qZ;9aMNQonjV`Ti~ue^TG8`sC{`=j+!ZxfqgF5ArfH&+8!}t@K<ea$9 z=F_A6sHx9t=~1NVK`bRzp6Sk;vyyMbma8g|cypZdCOizNs|rsg7Q^~ox?5V^Qj5oJY(?E+ zH$L^7_mXdt_|$JUI&WO~tai0%@TrR~Pc5qPdA_@-#-}bCPA#hOd4jvB#^-JU`p!r< zeD3);iG(VRPhD=NtDMH?W_LM_Pu=vTH0|K?kFFvKd_LfM*e5=PNY$U7=>?zq&Hc$Y zNqp)zw>ocJ_#EkK(cn`T4W$;<_}urAtMeM4y68!%MKwM*yNhakt`wk0-`)+Mzjc?> z_|)b6u5ucm3*6;2K6TSa(6ock%Uneg_$+Zf>=U1}nHOrNG0RGw@A^$J`6h`^{U*Wr)+sDgEr`Z~&S(7@wk+y|n zhh3qYRM(o1o%Ypb`hK8uFZECER{t2g{)YeQyZ%VmQPuq-T|>hgQ-M}rWJv$LPW^g4 z!F)kmXQ&0@T%Kaq$a~I{-*fMub9zzdnGA5mMp~ec0nRq3NCQ%L&_+&XGb)=km9C*T zhX`6qlVb$-16U+N#uy+r1-BD!PYkNs*si9jcR5@Ub3`;JM-LUvNt^mL@M^vAQ(HwA z?Qm2vL?#B|uJgt2n#+Wdl;UP>yX;ME(2ur3|Fs6fb;96A z<-Y?S@>Bqk&Kcd71gAgXe2Pzghbl|Lbh}^{bPhZyOa?#G-Sn3873eJqgPudry&@dI znL|uts9vVgL1xi|sDNxNZV}*t_!9o=S#&+s9ds7CkJx*l`rmBJQjd4Yn#TUpG*JK4Q}KF zNtM(fM`!E0ot)W-(Rs7LNhL0V$5N+_m2JT9#>y_~qk|RtC&mtfne*-dGlRekH_^$y z*d@N^iSmvtSOzZ>Q}H6~>EDBw6AWIyl}>2SX=q|?yj0vnA9T=t6%X$yuQa8WW3>X* z%vssZV{{Ty$NxhMOfHUSE1gUrj9*@YhpUdse-Bql`p*3#LEnoy#)9vpiX3839-U&; zO3eO;TMlsU{O2!d>SaW!aGv_DbM3DaM5zblezLc`Dti{YS#^<|E&6tP zbyxD35^SuG;wj2rZjLDD#XMew)K7nqJY`Q(R zU{u|nxUYRcI{I^t`RVA=kXpu-=_tz@9rf*&djW4qYDeD@=ur^7pNW z*E8mFcdfo7GQYkn;|?>;I(bWGjkjjhgRV&<1M*DD=sTYna>@(vm?L<6JtPE?v-4xY z%PdJ-2A&4`>oVm2`-%J7hXhZvFp)QSn#~m^TM&d83*q>$2}1C640y^;62vpoc^gk2 z)A?heAD)_cx5o*d6yR~bJ~N4@Ej*#JoRHeaQ;nzCSo8Vu>fY-eRO!IAJ9i4K|3yZz zSZovD3Bo#O3492w`iXkw9dI(gBVdO11VEO9_fS>+Oi-|Os-6=PvSi=eg7Q}NirOFF zxkI{KNws)n*KkB3^JWXrAh7W~)dY8+xj#eSLvXeBdx{%Gm2zcT#fk$&4aZc%5L8ww zLESCAPbH{9A=OIIa6?f3BtaGM(6O46ImooH%(vPbJN zqk9?PVs9wEO%#&&hxzDm?=IQL*TQ(UY_4wPc$eP52X5xd^oBO*&F?W`F?>L>!!Na& zz&e4??uyKHKupJeJJFR4>56cNkg6i`xZM@aMktD+RN|4F-jGNgLVx6^lrnQ;Q%L=c z(;wlN6;%@0z}iJj58}bfjyqG0X`$Q09DCPc+MH=ZcJvM(CDn2AvYUAhNzU%bl$QsZ zdwCg%-r<#(@Amf68@)pSQ0sfXjAGvOr0a3)jxJVj1PuX*gcoY5>!tnJG4~0(URh1{ z%PX44V-w}^IJ)cPdJ#&l7rkx<)k#v{u*(reYa3*9H|!FTN?)~}5u88<%Ij*-0r7@x z>luxf51M+Q1=}U-8I6_=y}b-r&uFwf+1pET0!*I4q?(K&-;poZhrvK}w7OotwjIWR zSvxJI+Z*;Mxv&Wuo78j*HjI9oCDM9Boyo`X0&AETY}=joa4Ba5KEk8k>KzoFzdu~6 z21+Bg30%VXEmM8^LXSSj#^>UDISf<#q6{|k9}R7P!|HFZ=LLJHG2pLT&iJTj&PVJx3zd1KlZ6*^7^d%^kC4UoXx3P-CV7PwUPm-5m0X!%6ZK;yj!kLRM_Xq{4>}_ zd{>Ii-{0Mv1#`7DPe@xxOAwS!Aocs}{wxeLD^W2Yxgfn9NZWntqxJE4-J9WD=ghMz z?aDNvU;(*O8y05ntfC&rGe;m-yc25%!2T1TTjQLLj?*1|P@ZL(j>d4=()CGiL-8B3 z`R;YTyGhC%{NPc#8`4#o>gl!(*CNi#(lExcVaPjVU1C+z&s9~GrzXvl;%o&-JJuZ* zNPm-J_5raNZAzCNNLCzP6}Pym5PT-8h^(IkAeSAomY8=jCx?S;=4BokKGM=Ij@m9$ zhgwdZZAM?_qsqR#tGX-L)Po`qs(!zfrI1rJefHJ7R#(v1R9oO36h2-(VhUwtY8uxX zCZ7wv` z5!wv~FEvOpjjRHTFs=QMG&DJKOw(6I!!Sj#RJo6--a279m3N*_{PEC8JKX%<;ZI z8FL+ieBB`%^pF~QlZZe%_SO*j{*n=qf3`&@?r$H0TY6Tx+C5jlw^}jgc@x5p4UM2} zh)(xec-zUp=s@c=AhrA?!#dvTEZSUMZl%R8@)}D?$wNX$n$6+%_H%hP{OYB>zGP^i z)oc)*x6QI0=A)C&^pZ%kXjk}O)@a-$r_c(iWm!;F_uYheB^o~WbAzv-KF>{GgbsE(bfJ9cxJgbAX_U_gBdJ&-2YSy%>rpVz#g zhXS_x(V3=K^{qYPVKD!W`7*&TQ{wrEqN|+kg|gOMkJ98sVk<5;YkPR zJ9vKTg?7@+{}i4g^R~^EG*h<79`&m^j49S!qP-*~q!WjrRQnM%JBbH~W~cKG=;YL; zJ(E*6m*z@s&87L~Pod~LF~>s3AXDMrma2MgYN~4WR!~W*>M8e%qpK4Ah+=YSN7qxC zXor`oy5Ty(W+y2PYz1(fX!blX27JK|$sVIvXyPQS28qL?W1_c!%MM9c-DD@M4!23d z>OqpWAd#?|D-u?B*a@p|GYPB5^vHM4RK&*Cs1u7P*~Z#ty}#d0PrjZa6YgtZn8B3@ zryU_R_e%&kKNif5G|84{mYudaFPXOaXe-4Q-GApM8J@M}gn*l^XH$>V&EPcGWVsIJ zV+dLjsF$&A4(gGP1`C^lxgIbSEVRmUBywFI%SSS7UH5>+S7HHLNlTO$_82r|7R-@4 zn}R+k#ZK))OhzQoGYx>Jqh z3RM^ry5?jx6U4)J;)juY;(huC$X8yk5nQ1fP|z~roHJfgfsFfz;GivFBwDt$?#1wc zGaGjPTn1*L*BTA`x@xITtyzNDku8~YFgiS9mQPF%o&Q4R>ipgPsrEE%w$2bQGHarC zBnwT8hqtPq@{Ye&tIF6Rr2^~@kF?IF>LZ9V-M-??H`~+yk|vAzJea8Drt>*A@*(;D z$u{}Qx1`qqfPcC{uO|?(x-ZXOqz(SF4!G8@P!j)cU3f}FI`Q;*)XH4EVkIoxEMxwA zzGPcaGj6%&??bB|<*zy&9V;ko>L*XrR>(6e>v4Xg!6%|+k0V&s{(-MhrAFu1Tf3iS zpcY!q&XT1UCQ=!JVUMIKwx$N6WvfiG;(7-3#w>hDo)?mY@Y}0!f^fn@`b$4245Tr~ zKG`6-bnna6=DpLGdU4cTSxk3U zm8;j5$mFi4J674s=;T0j-cTk`Nd0vTJ(_|AYmP(rLSR-%XNJN7=hDcB-Z_IUA3PMl zUlBQZaO203&-YgsF7cf^D136{^DnDUSu#28+$m|{VEW!%=kaR) zlH!bWOERhl=$wjT^WGGEo`@9HUjFJSd*~!FFM~-Y>ND5siOR(2$qrIyy(=<%kNBLo zo62UH%4+66?+G7m1)qpCWJ9Ax!N;pJt@)4cBpV{e&F$%8yzEx4X+f>xIz6%0Rmp5n zzhasR+ZZQzBo*2T|EZdNEK2ZWC}+x?rpx$tzQj9~jUrs7kJ2;J%*W~O`Pi5L27Z;n zRd@^ivp)7`h}lS!-l+E55PSjQuIkSTuJYea zNKwyHEA!51*%MAMbD|z8q0#~l9XdoHAcmzJNC_RrD$@NYdakCvru3^}UZ3TC^2&k8 zfdMz2h_eEuld-3Q)#+HXG?bVSnr~B*VtdlH|t7Sc?eYHBP;8m+BZ!HXGLQDIR1+S8%GIAh|M4frN zVnYegc7b%l8wMqw5Tx}KXT>rdnCc;=MhFudN_c)zvRfo%zQ9*qWF*d1ueR z*G;OK;LUD7B2;c|P-{gaT((sNc6)6)7?n!s0^nL-Ws`gdsO=f#JVEuoIeD?nGU*Mm ziT5RA6E`Mf6Hg+*d)TfHhBbd>F@#YBVcaFbfQcTy65o{hVj*&pf9cZ$XW9$)Z71I zdfBIb=fULsSkzI>5WAMFKDJzJ2w1LKn3B$NwFc}+gk7OSwHv3OS#h>C4siG!j}Nzp}}CN?zMlXRfC)1Ja6RGGAOHUs4f&+`(;5rRiB7 z-GcgfrP!4p2j}@uzNymX|E$*p-_CUD$mQpB_c>%dy2sPBFj2$Ztb@3ou?yze(LeXT zkqG74B|SUt#St6S!lghg@jBHc17pHWKCyw*^|Rz;PLpGZyv>ouFNiZ#=BxZ=0m0hC zKPmb=TxA_U34Vs1M`%{@th9>wYg{(W`d<^7b|S3lcU0j9#p4x7tg>FZ<|=*cK1CL)rlEjGe*>?H(BTT~wX-2PDEW z9}$M6DYN94M+d2Uf5-DdSCqpkk5mu*o*T1$SVNnt=}h4$n10dREh&v3<8GWb2_>AO zAUoLjRDDN;fP)Xw_Pd=STEQd}m{Qev)ISZI2XasRxN=rMbqTUCgC){US2JQi|Jcjq zZH(;fC)n;ct!co{=+rbD=L4b{OG>?qCrTU-u;Jsqd8036&{(8oz$%qb3)$Y8T4e(r==yYs6N3mZ}v;BznU_xDP{wDo(@i(`5ii9#k8}Lvx z_>dJOnvw7wlR3LNxSY>C>NMaW(=*-kEiTR8S%^Fy3odWcS(gc6a}^(uB_vu`#f2-_ z1_9i3I&PFQo&MU#pesioSCJi?;?n|Zbo$b~wUMrL|Ls#m%D7S(JrCgiRFG|s#7JW(+z6)t;qpl(I&a6RQFlieoToT z7if}+isVkO;K9cU8>&?(!TKIcxLLEc6D4`P54L8X$@ z4Xu=|k-cPaxh(;>^8fUZQ+F^3)VB6YLxufO9_u0U*Hy86SbFUH+#QoD*-n2QQjdIZ z0DH{kCewA*$tQcblSJPANy)43dLO8Q53%!1>?^B|GDXyE-c^Mz^aiT(rs$8<6+96! zscNuYq)dujc>zVfu!|JwBDJBa^X($1@_^kiQOqAzCvY8EKUpr%aXLnQ^H~o;$AQnd&-@4f>Lw?+~UzgOdHh)OUJ`!&t z5jdB~NRvmRg!IECV$(ZBC6*@QNkM~4y090;Sa3&3ExbU)UoPsnpq^OS4)%J8_uqA1 zOukUMJGA~Y#(Ev$mU>oXc&_1RGm`N3fYj*5=pM%_Y1EqJ)pmcavZ2Tdnf^b8+1wCz z@tn6{1&D^4hno6plJ)n73~OJd>MYRXBgUfQ-)+q-v~H4v1{gQu=@G2MHE6Ziw&_EJ z53SPt%4lh!dYjL<)|6R2-kLh*U?(PHwSq2p1_uj9!3yOxmljIjnoHSN%er;EfukqB zl;>EVpkQ1I3QYf=O!g0N$Q~%Pc2!`nudoBqD#>TjgXmt+Y)7@EVG2swC%flw} z*R0Djbz4Ps1nd7UgdESWoTgfDW=u;8L5ggR3FfUalC3c^&|u`GEB41L)VpUGbadCI z+4!g^>WL5F*OIMO5{O+9s6>7xSegw;m!naM7vST35m3;6A~SPhz8H)ao3_E|_pPa# zR(C;vLEkz3tB)2M-4*_f2+*dGG1D<*{1&n&rY}Z!pwp+W~ZrRpuX=@dCttP-`0#XP_6@}W=((a{6ccW4Wnq_|9=iEClf%wwj zKfj+J$-Q&$x##6M=RD_mf51FY1#mhm-I4)7%gC&s1zau=IX^kqNTlWO800Ep8GAU3 zGMu#JsE{d#$eEM*=^#^k!mjm>;!;&vKy=lh#jpdaa(1-TwE=3#@;~hwoT!M26AuyQ z3WIbug1Ii^@TV-^1Z(%zak(m4vCdBm{y4 zG^%}IYwQ0ehI=fM89kVxvYz!&r-BEpzTTJl@}yWveD3|F{@}q$eX24L{q3d3ZN3>j z^jSn)+FTp^1Ocko2I|!KV$|Rl;*#y2aQ5^4U-SnC{o6C1x47Bqx`#aQ)x&1+xL%Tk zD`am#3Wb`jose%Ux+dqsav|+_bancQu=itA`uxMXU5J8Uq=^IVt7B)~TzCj6??=49 z)Y&o^pUY?+>WoLOYmwkDCu_4^b9Ipj8Kx;&{x9xHh5jBL&tgy6 z{k}CmEC|#bH<5xrGdO_^n#ro1kQKvfP8Mb6!Nz#h+kX|e7S)inMW zzA|HBsh~d$5Iocoxk%Ocj8auoAb(~X`4rlo!D-T5x;-CcsxYtJS9B-}c9Q~yh_Y*n zjQ|_h`79=51Fg^IH6848g9QjWRilqxqh{VX(gH!EQ0jwG@()gQ4lq+jwYOt_QCJJi^MgWT$;$wZ094e|Z^2bU>^_8x6? z;3z}7U}`jV?QUVEXqk!ihd@%un2@|cuM%WTw33SDnYK z7%{4+o>G;T{mOb$zq0fzi&rO7wM+eWF|S>WUs6BCCfdbRh24VJZh>F&o)#va($zGp zd*{U5f>b~yGcdv9u$?L=7cn8iUNqxMS&gouekY~hMXFAx^y{&6hPG`~Jy4P}?M5h?*pCH?o7st* zK;ot_aZ_yHM3>Jy=WN(mmJCU)o%2DX`dNcBDywITEE0P^tV-E0UNHX(OQ`fSRABX9 zv(Nm@A0MKLIkek*zxAea9Q6K|G@D$1cKz>fkNKuGsY0iP%T`mYe?zl zfd`ZP<#=ZqB7Jki3Ukp8y~0Z$drsymORvnwjOv>nvHn%;8-)CeRhK@dH%^vb{_LB% zkEq)1_M7c`)9}mLG;_b3{6_B?`y2Mc+(!~Jz*x54v`^NYziG8eqCF`^^G8p9jk7?m z^_*^U{gre5HAi3)wsP~K;M?qgGnS=Wzt(Qu(O1+pTh}HegK6t%j8$l=$q&=sAyqkG zuD0<`z{WdC@J&6gDu*@r0>d`W8BTz2>JZ=AuLf+KGmykN#}_AtkfDe0#h?bDGlUh* z))yD*eKZCYk2i!5*?-GiJqG)$jOh>5al>EQA5dzG+AzmPVOT8Az+Ce^uyTv_HXRNJj*VbEhi5s6}VwS!xc1aiAmE9pgtDN6coBe;i4pAp>O73_y% zgSCdU$ri1D7M;LeyXozU-ip1kYuu1!|H}UwnSP->m zqV${hIF&pV3+nONrC&=t##%wcz<#{jehjD_C|SQjqq9?3owV7vkB1fOWuSWs(nx-X z|Ibzxvz6=d-6h?Rk6i)7@v#axdp*>ruZMZ#@p~c`z(m_udt7S%JdvVUD0^MkA1iJ3`a3fy ztk28S)x~*kf5%%g;_BjJF{M3-g{aC#;)1KWv*1G3Cx*383F0x3(#7ghbr9(RK%A(M zTBxb24}Y~RO3T_{O^W0O=%@f4pA2|Jz%s%AbjF~T<>Vu9)A=uuuXuju9>hVtPu2QP zd+O>UrOt}!I7TA9EDSH|JbKuf2j(^~@LiKCe9?itXkTV(#*2o` zawd=I&|{30%4BDRKcOcF%5{#&w`SOItNsLF&5ibX4DNs;ODb~tVAjsZ{#qcG;%^*5 z|A!dX|FX;Vu#PaSui|~|0Om-@x)(K6+OU$hs-jTjY3!%sarYDBj}G}n>3*2yxFV#b zPH4febn4^1@Y+KK(Sb|t<n5Go}YhDpP%vb7q$9g!4s@n@qco}E;X!AWG%M6Vl4SfE2+@` z-ySd@2&kGoXHNNCb{gVRquvsk%2~hvp&v+v%>k`nC5L^}5C%&RUI8*2M@>35<+bGU z`t~m5_;^>-|!x~)?YW2mKhT}^&Mj~lI4*^6rmM6y61d!z4)a6YR`Yi!-Flau(s z9)FKS6M67Tew+8Xlje|X{c=`sdV$TqG1@(2aGrWe7eDkz%)5@B|8~0R$+feBx40e7 z^{>pz8D+ct5B-vALRKYuetmxVJ9-58n3N@*dM*L=1r}RZP{dX)+I~IJb}Jyg-;ig{ zyNod~g$=7Kfp4SL&Td!10YJ62-rogZX;t)MpOo~l83XIKMh)j-O}=;sbDJBjoB5tE z`M%5FTZ`&`I`-|+9{iDp%j%EgR4S_8aRk0rxEo`vgD>#s*?9V*mi?r2XePTbM&;NR z&?>7h*!coIE2Z#)6(Kfwu!@%R$@sNbjKgPG&ef8c64GuNZ-faLnVtfXv?;mD8}c%6^N zO<%DDPaC|_KGySb^~$rpdj4rPn6bm%6->mmCO+RaQl*3Qr@c4MF9*R0`D6XL*pUhx zusU&XQ&~`ina;^B)Pxojowu4q`1Srs^@JeRU(tX*8Tvu0>j+TbAl3em)$-}{)*te? zKt_^&-aJ&whIXVf$i&lJq`;(R=MXD=g@+=>&n3tPg3^_)kbi2Y#9)c(AQlV_d+*Mp zJh05qWpfx7eCRK#2n)|&j`$=d;Ke7s^6$!sVRC>OR?wK_n z4mVBd%~(usHn_$0!lpimC+@BwC+FFseRiFM+CE^7unot6)iK<=j$JlJxX6){wl(wt z#Cil?^(lC96plw<5|P0ht0@*(I6hseZn~MASWSMGepg@@DYP#$?aM6tGTXkO6k)Z@ zh5pwLMv}NGrIWalMFf7tp$3)!6Ctm$q1dP?jn&MPuf*{IVsqFbHiaq!s6chk?=`Ur zX<4Wm3Wc_GK(_TL_2;Ij&!mhpx}nt7wX{4U5`8g1w@H~AA5_c?ef;M%TeIir&Rjsu zfVbX%(LzUttU`LG7wu6N?QSc%Xt8?#XL#HM{23$o%^(?tXI^D)AWaxd344B4rRHZ` zeLPGZu>nWik-r&lSvfO>F0>|3h=Y}dsTE}%`wuLWY66m&iPu+f@dqZ%gKzOqB@Dm< zZZOv0IyuBmS6yCj`Nb|HYj8ox`dO|9joqH=Ppt-Ope9Y4nCsk5lc@%`ddoZZvVda{ z5R0vwe{tT@O-n7H;j^=thSOLi_~$W882H%1!`0c-wevEtM`b;rwTVY2CH&(luWAcb zK4uk)ObC~wq`Ri<)ipEB+u~?-S_%dJ*AuMYm}uVa?#eP2mD&`m{!T>DeP@o56k*!2 z8Lvj)EnJiRd?6zooUXM{x2~CB&Y3ni)lo@Bg>QadC~@TXYs z^`jhIX5J*T(rwh1DvSrbMf>O-99v}62+&2t%Q!snOSL|uSk)%P*|oEc;=$?sRxPFE z*{Jmu;SzfQS7Rx|FnAx}LwDGR=4*u3t<@u-U@S=%&2z`SYEhvKYO1s=Ja$)xs5(3Z z69AwN=aO8H6$Q(zHEKYeRgUwnP6?#v7mS3A z3%x-G`Z`r=w4VxlO7;$-A+WUv-nk1)*JPsLldasEj~1e)6qrNM2C?YRGn$5@mMi?( zsO1jl^2gu#E{%~)`f&{YcMZ0v-O+)}c?9|q`ug;4clc5SBi_!#{?3=AT&!r9UGQ2_ zRCc_;GhDIs`=81Cp2Yhp93G_d!)5?)%=QzR?Y>+wA&|7ykI!w&^Ka>(I8LM^Z5vc< zQZO%^CyixA+fTW|_fU6O#CD$(HEdqC(S!oj9iFaV=BuT?k2R4QR)*i2&pJU#!f(-> zhOg$MD+Lk@S>6cNP@L2ci@LIq!0;>(TXCt8OdcMJb)G>8bri!k+&ywxM#r5gSeiZu zdSN6oGwJ0a_~^sVU!h<)J%8jAZ_U?Y%Jw{nX9R7 z?1Jh`{Rg}->n=HL%WV?ki%CM=Hoy?42xI4ylJ1hjY3OmkhH{OzG5LgAI9s_n6*f$* zW79KgZ-oK%>&D9&x$8yp5KWtn6GYIG4UKmI8x-O3CoG#pKwkY3;9w1jJZ9rADY0y6 z{4@E99@AgwhvC%uw0Y<_(~?GSoo7EB!G5^Uk=7aQ`(rw;ST{sctaBDiu}|)TT~q1wZ! z;D0BjPi-FU;aJw@^>^&yfex1@S$-^1lN}w8R=~zNIucm(5r4p~Eve%X2!SkNI^pu$ z_e-*u!6;-~%31J2$488(a2EWOO*@Hv`agJZfwSOThqiJYA1&MQvA@CkH*~u6kntp& zr5Doj$t)nq$Z>UVwywgDf#)aRf@J6JBcuJ zLOEN1+5w0A%5aLqDA8FL601K!pA}{%`HkpMU>tre+Fpo(51xIPj1?H|l5A&n4o0S# zz3RYVw%O#%+@;=vJHa{o>Y@V(E!5fN{wt~>#-7KM>BcX5U0t3VA&YCuBEykE)o$T^ z?Mo~XO>4z!^MEppind)Y(6-Cxk1gHMz!?Jg0#AZazU+CAz2#>^E-WlqnnDce_=Ph) z{iopf26YG%!ut!9A52k?X`FIp_LTLl$`j3qhW^7ge63Q{#6AjzMB#VC_N5mrxJ z-N;E;6a7Or^Jd%_U4Mq893A`lmRre<*2As!@F)Z>=HvJlVc#tg48vzU{PV`wc;Y42 zsRo$Ay~IZskzM!{lcr(z$#@4%^$gwR$D;`GPZ^3dw3a zpV-{2EsA;@(i#cbEqqm4*i-nd^w?=*!#8OGo+Hh#R8D%75f?sN(f4`rSvp}=O;7qP zA<29L4U=9$%m?yS&i8vZkYl@f`8Mm_KhX7I z!tn-C{;eBG7DI+v-#}Ar)6GTartz*~_Q#5O z=`IHPgIDoJ+f9Q1&c+F+ge*4}e_nXP=u2@Ch>d3UiU#7?#?JN9kIn~V<{%53PAx5p zEt~d|rg2h7@LxQh2TrDs=N3Jl((}gyok5bk2J!{ts>h`RK{VmZG7VOB=Ps=p-qqzDf$IqrMw&v)S2dbF*a$XzJafv zOJwtobw0vV`HvLgX6Ix4;CPm2V(-bVe8ixCF@sZ?qnZdek(}PnFi+8C**CcOTojQY z0QxbO#v;2m*HHxU3W*~|%bU2a3|XVISwmvbY5ZIYh@g#qGzW6XZVL3DWiAXjqM8;_ zy~>{8x4vZE{Uy-Z4)jpk@bdwW$pN2ftifwLd}Z_i(j=7BwI1?Why*aek2deZNVY8x z^u&KI1H+!x3VP{=NzPcpU3gc2LVZn!nQ#Q&m2?CiD*~RyIeZWOXDTk3Q+@ijT}Q2Q z`Yt`0I(VH~)%z2RSL7WSG)gER48c@OK=TJ>z5WMJF-+5Qy=uu*!yuvP0az(7CyhtF zIhe0@9kPo0$_}l~eqO#D%+B1UPa?C%E#Y&%vK^Dcqeh!>Y`6l!9+*BC+&Zj>YRb#p zgd&eh5uv{`U$%3e>B+&(Du8dGWyurLnC&Gx<8qEQ{8@ZKnZTq> zyjiP2-ZE=M1=2QOy@l2Mr;0R4j4QN-KI2EcjfDRnsSGz1UGZ1!imA3_uT&f}u5dO& zz-7I$9a3esbsofkm-tu8F^>%W#Y1ON2%+#nbO?!`a7 zp>eTwm2OM~?b4X9R`t@B@E;9G7<>)v*j2#Lew5mBw8wafWK^~*d@26>{%5?=vv-Bj zHeDCaj&^61?TQSgOStU)w>-7~qC<1uYx7B1Il>9FV|=im^oxWFV3VW;4qy>Gh=^mb z7|(v}5-fEyJFa!eY=Y`N5`EX}uWCA~(TocMY>Il*^i>RIn!XwWoJ}u!d7J;4tmw#H zkqJAmW4@Lfp6iJ|fbWAv6?|+)j;dB@=Ljhrk5~h4L5ayUmg!`ef{flPgn|(3vD(Bd zk-qhk_L2Q;)b9r;E_Vb+TXyh9Vzx9AQTYyI%|V;7)3zfYylZ~1uVPsuUt-y2cYS*7{Z zf3pvZ`0wQNhgf>}k0s6dFX!!C{dTN5zmykq{>90!ky>3~&X38gZO-rS{C7Y*)};SC zm)R!$Q`1cP{hbfV6iCp2Ec=HCA6V(NHeDmrBe*v*B-kCqiwU?Fs{`m?AHkpSp_yn_ zU{>?c*^=J*w}Fp$gobzFwz_Z1QOyP zu;x;pkE4%EZa^E}1L^P{*M9;h_%#23AAQsr5@Sh|#ea=n$T(B}0opkLFM%=s0ioGR z7lD+20LRyRxCkKNifJza+z1>NMv$Wm_kvjFI>6FfRp;uhx>>d@9th%Wknli&Eqt$9 z?JCpjQ%%FM$^}yMcLIPb&)7qc$%X%74+$qC|HU49LSMP7SyiCr9-8%V%%!k- zU5ZUsqX-r}Sz`@UKQW4quf~>{)@Yfjw)(NI72;a7e*#eZ!<}?O>+Z~oZ5V2d5+D4i zoYxO55Hyq-S;yHT`o}&u$CuZd@e!GFAIp6iDhvwWei=1Y&2g-JEJyKjf^YF2m<}Vv z0+A@|xtBxaiKa#C498f5kF#Jo+uqYsC*4LV{9%-XI~g_T%EUdp*}C&!QqO{N@FtW@ zV`kKz&u{;~n$P`uK3B=4#U9$0n7fA_N!}&rxMs!p^XW;>rxrdXtwLo!?HRo1#04|h zmzqJWo%IY}B5=Q821%I741RXnc{6BS`aUyw7lxkB3^wHde>Q`s8Fg|7AOB_g46YmN z1ZvOU(e(NAj>FDizX0_toKGqbB^mQgdi3lEK;mmZ4$ z@^p4uo7Mo1rQsdJY1{De#kaG@Za#LR-QV^P?r(z8)W@ZWHDFD3*PE?64Bnt-MLbkgW_37H!Of;6WSy^U2X80HS^|XN8qFGPzyuogZ$`8M9+o}cGHGBu|_;#<>K-B zp}mS)^{G2nBqtp3n4?SofRT%@&A0ZCVBohfPq^-n3qsPNx03ATScG(?Mo8~qg{-mB z1$b}iZtKslCU8pp6V@u~PPT0CpAU#H-fTVX2i>6~N*HE;>sAr9cw#lPW%;R^ncxfz zvmZ)4)~gbz*^mD=@wmV)oo7E@l6b5aGrC>-aYf>>P52OMPS^cc_G7Vf&^W`Y^$7}2 z3OUEhkrR*=#(3czf#bERrttj%d6fp_PxSc;T2Gq8pvcgBs}M;3@Mr>(>Fev-?DxaZ zY+;9LM5>YUSl_%!&`==xz@ZB*LO_n?0n$gtd@Tn}FNcW@`}liZIE!T4DC2jywOJhR zqeEB#OG~dKL2*vC3^g6qF+z>ZZqt{Kf2`^|bT)c6!~gJEX)QB4@SBfUxNag0>*fCF zA9xf!o4NiH|1(t{8uDvbdfM`LydkePBE-W;$BVlz_LtZu1k~%MrvipU4p3<-h_+!^ zBq>DtvYurge#E!YX(CJ+J-G@c*RcWj(74Ki2By+Lj-E#~ofPmF>>B&Hs!i-+sU54`t^ZjTj;j zx^x3Z6Y5~IReuTXlZHfNF^`-&jn-w-Cl3ETUa>Eo4pkr@Z;_Ge;oKnNWYI_k#(s=3 zW?B8{>aVr^gK9c4h|?>=7xc-I0iu9hX3H5Qh3It=-=TNZ!Npb&#y5z7gTr%!Ly>F& z@MVKjNb`P9=5mTmWzNdG$Wt``8UXRSI(X>aMl6&t+)3-ObH08Uf4WuXq9=q!s4m^+ z@Cf4R36F5o!`2_53N<>Fw_{n4xeuS`8@G+EFBD{Ir`gUA>FfW)^auaGZ`%EN%%OOt zKem5gb6S5M8%sK0;H&3)zy64C-WOycag`M#@Jjj%iBJ@OA!hQIu-VM_I1W#g2W43Q zg?*#rkF*5;pZ6>-_2VD4jRWDY+0FWsDJyo;axS9p{NFyvzPtOvC3)ak-Y2bYqDq;rYIYXhqI5 z6w(fdZtJxXH(VJ#hz=GBbB&0b#Q;IX%^SRn5I1Xc1cDAz$+D7PF140A)g+KNSH=T< zVWjZu=AjOtl^oshSouBZ6zPfgY8L_s0u!7eVrbqpObFx~7gj*T35#}ThK$ZtY;y^B zYL(?sGWZ;-vra$fiaJ0{kj=k!UB&H7+8#Yak&D4LIS|fbWn98rkW|MuLXcQZi>~rqY4q&GwkiInH;+8-3B+f14s(%q zjBl-{ORK#q(}|Q8q^E@h%@Xt__5j;L)`mB;M9n%$=b03uc(678bNNgM+W5=`Z*Mj0 zw>>Y1tJ&0@h_~i0%ZT`+7)t#K zMP%W3Ci=G&@zekGgT8O*&U?5p9{-j+{djYs{WxD9zmtgvO#~7KqrJ-*cPyJ27p{}T z06F@O$KSaYaoL$(7faRO`34UG$sGIh*<5(Tdw<7&%AAY=#R`|JFk{6g>H;VoA?yEu zy%F35TrP`8I;=@UP)@Czj4Pa>oP3BHRt$7b4Xns0M`3$nI!jgfHsX262PCJoUKyl{ zj@33aTwXj zX3u=1^+`gA59Xftu!V=sME!nK6P{_kTqi5=9j4?V8~gzQ|L1t9BAYNjA%6V7xe5jF zCtM7tCQ!1M&JzCU%o`ep{%t*HUY*p}V13J`XzjJi2q(p|IYwP4r%L_KnJYU0T}=%m z`#Hctd&EfOm>mw!^gqM4xGOwS^ad07F*xDbyZC;&F%f}$bXNu$MUFo&Pf##m&VI3! z3-ES1GT1`&3=|nWvD~=c|4dzms2vW3|13p@<@tVR-%e9{bD+bi`xD?u?i%Zurj

zzsTbIH&;2*ysHy^PJGHo!>pv_Hz#kUEN6D4T&bTjdP|67{d>AVKxaV|wcl^;*(jtdKvIl#PYS;#y-~ZF z?aYw%Ke9+Kbyl?~4}L@e++7AB>xLpeHjJLjN9Ad7lO6uG1r$QQKAe=Iw~AGlBXa_>f5L*3u z0wJES$haWv-dZbilui&1S*u32onPbmISL-2wx4P0 z!V9<}g^8r6+ec*CdXj4awAdkz08WVAxj#M^ADm(TNS3i?$kWNO><6VkwI1JC5r$Bp zS{M4oi|murTD(7-NpW>O;tBlzA0$zqJMrJPf9BZ>91}7$=kc~@$9XoAe3tmsy}vnr zZ=FeE!w3EdT0F4y>Qnov+#|r{jWddc)T`YRU=V2uN@6MQ>z?=a--lY(5u#M--Uvhyt_s9B&4NE_66# z;Dba-YoptJMduF1qj8v~QyL_y-~UWsf^+KmV?dav2M@}tU4q*<@~^{WN`4=W#y#s- zn+vmGZv4;i;x0G?y7D(X59j)ysqsGh1_}c54>LXZf7J3QLqAeSLqwFbCg|s3*o7K6 zvRlL0a9&F~r|5=^Tm8=*i^!cv;?en^IT|5O(WuSg?DjviI~vbiU*~_OTbK;Zjg(0p zPILc`$tlgv@;^O6w-2Xk)?ko!$s4lbeNHXQh$N&rrrqL2C9G3Yd|Gs#+~7P(3qt;U?GlcL2oEZ9E$noYNB6`6aFx^GZCZeLW{9qL4b>;|>Q^ZQjkC zDo;c%Ulz*(2Z8RKMKMR@5n4%kGY5`c0R393KyI=?&mTShr*}mM+~OLYC0cHKJ-#_5 zQN^K?(%J<0*uhK;(xS0KVR6B_w}wc(a~wI?4=kbYjvF=J1~Fy%zTiXn(_T%rZckQZ zuRo-NxJbIyp+*)lrUlJim38K)$+I(RuJ#(A_L;Zk8><7ol{dSL+X`FE`|}JUXrTqY zzaYA6rW1opRBMThZAeA|4?vSYt_$^G5ZSkxLBc7^0W4<{l2ola;ugWfh<@5^y)%)> zjZOF`h&srq5+Uvz{He@WvB)i8+Xn;h(-|-tjP_~Fvqmn({ zF$rGjmb1zd=&U%w#>bW+&CY>?nxippJpoY-j&;uM5Tb$U|09xdVq)nd@&aA|1xKWu z@f>Qed-V~SSk=vqEtVo3jOqh6MXC&Xh0}}^j#dP}l$u$0K@W@PC%_P$K~ZBh66%nA{&U!od9L>s%q zxU}dk>^9W+>BH!5Sr9OSVtRGLqfQ1v1$fkgyb0uKSrApN*PlF(B&30HX z{WTF-TN3OtF-t}nip!=#aV-d0KgGjvMc*qI15aRu6w`s8&oN6 z(zMg;UE?;3kYJNl@r83~4X&~qwA=epsy*x#>F2mjdJ~cYA1tKiB&{E<7wr?O^5d%1 z9xGk3UiqwyT}Nusqt?x@9y8uI;b;ZkNql(qgakfh{Y1MFQr_2gk^kvUPkvW({@>*y zSXI#IH@Sa;e+l9=Nqv6sO^V9>;Ii*sB25bk{4@#jrp5*VNzK_-YTLn09b*S)dM<)b z$AoB6gLUauY$EM*o-&1#WsgHT@_PO(w(fofTR3?pKuY_M_8RyUDHO8yWqD=0+vXVU zK1|7M;keJ7;{pjFN$@sUJ49!kY9=cw*JXo&Xo-0FZ%j49i38boj+=xT<8<|+PHv-9 zjUG)r#kB9TbnC{SY(!m&op@UwzH!E)fH@~e+6`Hyy4_K+S0s|XFH3q?OiYD>R>5SO z-__|{bo{;DGl~-N_n_C{X}_BxU504z8rf;xwZ8j8w#y1_8Xdz+2v~pz_Tqfo+!9^4 z0LjT{xX60+Z9#dXC8tSReaK(^a{S%}M$?Ej@fxi}>g=Y4u+NB$3}!pzN^f}`xlmK_ zNyQ>*T>+s>d&_Tj3BiyGR(dKyEu3-)&NOO)dM_lGV&w}MHNLOfXy{@w8iK^BD>p*b zv2snYKn*2{Tv<;{nInb+#}KMiNW&aq^c$?=V;rOPdB#*nOPxj;+lz$np(lQw+RxFU z>J&XO#`d_KZF^J#lM~C+KQ*|Me|^?n%h}NFL%iBaI+atU;m?= z|BxX&d97)WJz}vz@yN6>=eo_bKAou#o!x>{c7#?eL9T8!!pPh6&v-wQlZG#gQ{x>g zthKXE1ouQY25=44g2%|@n22tPT6FSbEKY~ywR7|(&*(H#Ni9p5ght=ZUR%HUU3(wp z@U43Lf_*e`r<`AjJp&dzYOM!hE?1b6Mux=Vb{WDH2rf;T>0|uNY7c%O=gfj-NNxTX zc1hvwOMohG*}Gu^k|UnVPI6Y+(O5>=yMzI5KT>use4W}|6pIdkIJ4HzP}vDS5hig> zp8uIeBo=U(z^rJ@!zV35dRVh@_9!{riyXsf+F$mrzvD1HR%g=HNpPtdr zCj;I0p^LK4+1UxHZye$?;I>z(wfzAsr{DSyEnj)=2cE!G`u6{av&zAj?3dQ`{gUFQ zhZ|wxoP58W!c2r11LqtNfq%cVktxA~?Pry^zy?P&HfUoHvqZNZjkfo@B8&e5>)=wL zx&wbl`8wT##gSJ1A`ZHP{TFhUE`(N8%ho@78fN9I&uRj~#&_RJA5UG{{vU5VbFl|Y zp}0&v9*v_CDDFua9R8u2zPy5U2c9y5Pl>AKNoyK1Mbap$;FBz_iFm_`lp`myLOAvMYl3bN8g+o`^;4w0oV%bt#ux z9lQ@WmEe;h>yI>+tc>kW2284iH4(4(oVmd#b^NuA>yN3(4nzwx)AV=w+G+d83XT~a@?n}402xAK?9h1iri(2Cr;GDCbctk@(` z<;`TYiAnex`WpK)waS}WY(-wD&2&3`ZKGo?vPfeQ+Vkme~b2`1^+x0RSANwQE2e=9*<`& zr|EZL8Zd#liem=Yi>~WZL>78oC;0JyPtD(Z)3fm7Y{U8;&gq0hj3dXafIy|&6LEQ5`+2mACs=_7Vy{?1=g7!(8^gR=UN z;<4>~11fsq&l(k}NFVslGaN@8(!R%Nf6j<>CmukPOXLqCh(0CVaB_U{_DTfCwsFIy zHga@+dz0o3^e9UlWPA9|48B6gkD7}Lak1S;-|PD`RQ-O65a7^LR^bib;*h-M_SBZ^ zsl^%mDB*e%Nvp~O(F#w#la5=Hs%QXvA(AEk&QYSKKhwxu%cD`8odUL7P@P*P9QG~{ z6Fx!LfWtF7ku)UUb0O=gU+dWy$Zp}SYJcve5OAu!Te}eILE}JpsqH{$54u(ct=$7W z8Zz%~_;HEOiy_ouI^AY77oS4Frw`hC_?s0L(ork+w;Z&e_(`@av?3q}!7GSC9hAa; ziVmeXj8VrKF8VHpzDrBGpDC$79ElPdevO4ZZbW7JlQ{LE{YoyRdb;e zC#Y*Wn`5{0?cUS6KYS}zqW+H81sv~dBZ_{E193L0E&uc6A$sMLwp;4nIKdZ#FH&`n zQ}vgVRd=->6_r|n89c%Qaa3v$SZ455SuknpwNHwAtyt7+OK2b-IclBVBU9zY%^Y3q znEIzA>sReZ&QrL3uQZ`>3&@tLx!FB8*zfPmlu5=Lxi3z5rC;7@y~y4WMN7h}7I-K8 z4JF_Rln8c}zPa8t*8uV`(MKxcWxFGnV=GGhpc>)_5i{uBxWD?S092|`H6n2Tl$5?h zG>wsq2=4b{gLOrj4J9lGkErGXbK$(X6T{aN_}bTXnaVEf2~Rd^LR3refefSO4sDYw zF$HR7FO7+*h|8&82Rs_nU-4hpW}ta$Db&*lv7u&~RT3;x5CzAHHmEc_EEkdtFU?38 z2mXifl4=)%T?rexk0x5o2Z$S)UG@&%rtjcw+Jm=gf7w3r3`$YFO?&LnkhS94ZC&|g zH2=3tSVyvZo4#qP71nXooaZLKQG>`}nh5b2vc4gjs`^uoG)DTO#WZLLmKzlrN$Jd@ z(J0axQhaEa(rR@UA$}GXKaO-J%huHaVA%Ous!UdtEfv*fP;MC#Sw~r7J@RFEqSt>k zhL(~oWuH%fPRH-Fpjs~=SB%fw@rX;vt2|(AAc~t0QGL4vX_r{C!svv6@#=1Z_fcClGFDVj^x-)E9Vz4C@y`9!sSl0fA`lzrH)=o4K_yIz zFcqotRFdotXZL$HOV zoRcZdCfHg`vjFsBb#ZE|PPw%yTDh|+TKz0RpXT#8s?$&=g;rPEHC%tpI)$8M48dtn z%Wj*3a~cvYhsLOOyZz|XguYwpQtP~SkxbIn_;QzctRvD}5Y@v!W%L_!qC|>(==Efw$F7~Z)Dgdu-yB{DjPG;KtTW4HFxQLzx2Ed%~<#B1nZ=Guc! z1+bp`$mBbCFCnZuCQHa7CxEy8Lp?lMz9wE_xn1SY+}8iW42(Byr_I-SJx;*y4{);6 z!3-OJ>?~FZW_bG1T{%wak*e)bKVB9$0g8?{$~g@*YieT z(yl`%-~M6l-sNxqa7+cP^9K2cMt;KW=Qyym`?^CII2U_;e=oJZqeJt?L1zf>vrG2= zhu-|F$ewnKFY^pR=SW+H1aDG5w)4?9E(HV4z<@!b9pRKJBRc>(442gCU`6$Fx z9pvf2>8^_KHAM- zCpvm3v7``UG^;kBQCkjpj78ORv+zr5xkD`yzoaRt*pO+1A@!Yr>#G*}*3lE-_NniX;487>SXml**iAfPgFK-F`IUpkRlvnZjKKAwXj{;*RtmZ|B6Ks%LY%! zvGTJony-!3YI7V`1P-8foCv~E%-881HFczOEq;*unnRC$#FwNG-Y0&>S)+ZAL=Y9K ze1>Y7tu8k`lVEQyHLK!;MZ^Rv84K{_qjX*tV8jclf70NWTIQ1-n3=Y|CZ*Pw>_=6* zAaY5_dcaoOi7DW2)chwG@bPWN2|*U@|8lp;6blJ6j1_3@p$<*Sau?Ah=StP zHHA>+q_I!?f$nAXrH7u+^J2{N4#?>|0CAKtMUXYZkCyEb3!u=Ipp6R{S z(~~jRFNkmd1v;YRuCM#O79$Mi3&YlI?Ghzfa6h#qY7nVH1eyF$0EvfMR=PSHO-<&3 z!K}=BOCpbCsu16H+YFzU6!epB)vPVY|K7H(%+b+JHvtMH33G!m=LYwQ8iW1R*mSgL z*WiSr9tntogOZ3ii~2Hm;Yn4&uC!*;D~%zqwx=WDOh@M$SQv>6WM|yFFFm(3fpErp z9Nss$NEpz5-LO4X{^yGacRRmTgb*rNN!Rxmy_q@Od3wV%TJ%3(Jte-7Sa%<{(c9?_ z6DTnFd;imsR|XBF4|B0PI-f=rqE4I1R{ysx6tIfEgW_528631BjGe=XVkVRbO-Ei4 zH_SE{Y(1(`T%~%tRHBG(XlfAD<0p}eu9Jxqmk?v zgmM^MX7e*k68y}fG5m}>!OzT$_op}+{o(nX%*#K7B6jtrb28MA74C=2?^^319INUj ztro^OdcZpTk6_;V0T?UKIGN+dN(MET`2Mtl=5VHe&!H70(@Bq+q!r+Bo@-2wo$%k zk02NleeBcjir$V161v^J`RvO)1nV~k5RRCYB7dpu^FQsGn|W}nT?XUV{IY}oj?1Z2 zWEb<3&%;*HL5MJa2S!Z^^j3DrQ4OPk7G_KJ`YZQ|;7z&-%mooa!e)tP>ZnzL>5rCI zIw+8b-PQtlLbLNJx+feiTfIA`f64TQVx3~kM>=~>_?wt zd3DNTo2ipK?dNAd6Q)igrTTar{l#baD@>iR@!>DviR`MV{M>FWfM5p!Pdg!$KLeGU` zvZKoCaf(`G1ht5a$@UdsNV1=q$aOr^%8`bb1^Q!^BT2OOr8jJ}rm?o>u5H}U6vW6|r+gmC}+@8~6C*6(3D=4?%FM&#tVXA_Ycgnq-#XUN-#!EQa0^Nmy2 z6W1s*NdgT!+dle0DF$Z>+tqFc1EmV-ON>Pwuat-}mqF2^+8;)g*10zk;SuptSx;J! zM_gvB3YzT*k2^sHstV_EZ1hG6@>oAYK*TC1!sC@3doK!-)&U;p33KU0Le$Y6qle-I zcqH&7F&_7B+`N9e#CU82xbTNy+al2Tv_nq6seQbsRXVTtC{o88=!Mxh8}eI+EB$y` zk9w0hr3g$$VZy9HvY$j?EIQ|OaxlxRnk|v$h{u8kCVaQL-Dg(Ko9m8TrmB3Z@eXyn z(BfW3#2?1(G6Ik!;D@y{mv4)&S+GLxSGt?6A7E04l}+Yw(a6p6EOHs4!e2+8K9y2< zL6B0T2O^Tg<)uh|CF4x!BaMThdE_mzr>M!X3+o?(vg)l;v-WT|$}nBM(Z~B7ve;mQ8zG?NTq>Qb->G<_m?xYYzx% zP70i2iJaRsjMF$qC0WX)0z~jS%uluJapH+GZ=Lb=i*?r*AUCYyt~-2l**hDj5L|S4 z4e~7`LiU^yiQb4DaoD;AC9?{il9ksK$b5|+Vr%M});{tvtW68ufkAA|y@QkaL&aC< ziZ4^zBK)FI^GbK4wedo4l*8Oe|> zQ|r;UH?vf4#j9MumVAPBb<|0X*+-N;(zbB}f z&izem3P6iE^EH!TRG zFIvK%1&>}R9{{*9m-owlQU-V=e-FQbb!kid;`PX$)NuUbyes_yoC>pf)WM_ll-4_o z!@24CC2V@+&nbFjjQ)~IB?(CC3nbxAqyW z`;GSglgF3=qxHGoV7D8ABgX*0UBVd#j}&khY836^QTa0J*UuSoCZg3znldwjU zRq(ix740RM-Tpyr{*H$*GwZX0_;aiFeihj-^3g`C#qQ2eM8()gXJ01uV|%~d6D6bU zR&O&ZAmA#C><=%9->}lPA|AiO6~DMkCgCV+Znn|7qc`{z=_hv5%}fBL>Sn@FDvCU#TD$r5V@2<(-O>LZ-5l4pr~$PER5AljuUl(7K1!U-%dvqG z_8?th=r9M@h!G~{2G*3XabO<(LE@|v7QvqHk55kHpJ%6t&(vg_#CZ(%$tpvaDom>Y z*E%3zf+IreAZf6tQVNdhYu&KDq4?rJT4!uF)aNwl$4a%#)V7D!i&E=DvgWdnK zYhBvxSeA4auuR;vFlSSmE(@j1ypi?=hln-gKYWt?r#2$wyHSZ`qL8kwD3?FQ@<)Dhz!L`jywP4z-j>NG%5vsPf6uQk9`PkgjAsv? zE}?-S2?)H1W;K%K-!g+K!{^`kD~uyyMBlrgj*nWs7=G!KMrEB>7|FNTrib#KqF0Su zR3r)&7%JO^4?AT~zj9u+x>#XooT4u#i~0i<#j)UVSu?TVfLt(8-tQzWboe6Cpbg0@ zM`aZYo|0c$u0c^bx!6m+h7J?mJ*M%!$9 z(M)ElQln+wrbRjKt%PaFI(_Ji-8V#k>yGZt%Is4f^N#hPyMxGMB~oIwguocHrnXk( zY)2j%tI!*9d!gLw%{a5z+3{T!Iao5=+dft?b`zJ=UADB|ud#|c`_}^dqBkxl;Mf5) zZv9lw>D_@y4jWgM2aJm1)4L1rbbjU;6>}Oa14atZHv2!u3+3Oe*34n&T>~{B!9h5P za$2nKZ09(^;0NQ3#!yRqF~PMsqQ&Qd6E~q-(ccqqScn}VxX%1d!2k53JnINJ*#F~N zZxJdFHE#z*?Y(M^2l?KjS!D+z%kZr%tMWx!%-Y$}v(wfR(L&`Ceq!}h{?@`vtZ zJc{VK(eMphy*EvaToXO_f8nC7b?%#PbE6hGcP>1AYhA`ow`D{oN6$etZ!OQfsWLO1 zLp$nLsLV&4{*D2W?B5)g!+aspTAJ|+TH;an`c#9r?CsSv+B{{ito?|#Aq3w|>ang+ zzRl6!o{Jn`x(q7~8GA{0+1qVzkk#jvHOCQ^4jxmO45qd{^^e`}Zb&9fos1?6s9t1{ ztVaw`I*!;o&g;T6{*<#VnvMDsC8s6A!bl4TeEm?#F$|zQOm}pm+h{$C;WWy1s_`q| zxA7_dt$Wfw!}smMYsp!&k6wnaI_-9cKZ1^k0bU~aQ=|Lb2CAxa(W}n!IC|wdDAv<1 zviS~Dt5_lZj_c`c9=yhlL}Kzi8hy)6WjZ%#1k!$p-)i31%{gD^b@ac_Dc@I0rqFhY z?@<&Ek%7V0H2$XBoM%#li#wHfBQ2V9wi->xSv;>re|HYoFy*^~S|=ScF5yl!9j699 zmH}KLZA^4WXPnbtx+lG)UNflUcjt`O_DRFi;6E6?8`ZlC+ZcMu=nojaM@tSz zr?{inoFgX5+ZX3>n`bxpm&P z**Zw?;H7GnujE+SYPgbtwu!6d)tb!ciy)p8J%d+p@B|O2Gg$f)_r&uU8o-m7a`19L zWGucSSeA}P3(tvp%#()`^E!5aVK?tJAIP`8Pgc5DoVXQeABMpt94O{gY zxrtTjb3InI!v1xSeOYB+!uDmIeOa$B(M@vUzgV=xzTvJbdG~PgZd>y1vE~AjH2`{@u^Nz5M$F|1z1;YxvjBzo+<@ zTnyZ>9ypuYeIm|MH*!v(MUQy5PU+Yy;p)p>U+BJ-8!og~PfCfMP`GTfu`XV;XD>dL$wIpLbd}Eyx{d^}!g?`JYdQu+ z^wDhnRR8iQL>QokTEb%7$)Z58R%URHu3DnX?=n3P5vdkv^a;2(U5$&li zdl5U!P`D^`kE#!39yHe7W7MrOeK#3(Va-PQA_sLYM2G$rNd&G{%kF})TA^x}+^*(4 z#^^pZcf;(+9h)}fxYkPs648v5t3`KVuH3SO^Mi#V`H1Guc`)oPC&J!o4!ikg-h;-X zyNde47n>f9?n7p!2QAVch=;(AaKb-!9*aDtYFBW2Wy=hs2emIYmaDa~Trx(!yc20& zcen(3y{f&N?x~t;e)~_?gxnFrNZ$Gm)YZlEj8v64=l(ekAb{ zeJIPn!VvX3Nv&|!TLZM0Ss%x@nPe4Tkm_X7)pT(TuS-oqI_!#K$0i|;Uywn3bOEhp)p3@MuXS5*9RXfCtaeqefSG) z%|6{f(+wZ}xc|GmGM4rX5XH$8J?wH<8?R+7o0f~6Xb>09QDP439s>pW#@6J7L2Wx1)U^~%>Jp_kqgh?7#Iam8BS z&Rl+I@nXOgy|2&}_U$B?T;hqUx|?$@t~}d}ib9St5WG>5FF7zPNPs?5Awkuma_scJ z%2&|e3(3zB4_~hIfv!AVpb&RmAwDis>j*ZIH@IMKvnQNQVghx;;HR;3;)oy{rdg9$ zghl84YQ)c(?SW7(=}{K?7L)OP8fzCJHi|R<3&k{{zogZ{%T>E53h+Fo#U z*~UbpaW-RvrqUtMG>tASZNRnDml{`cfdjATP@bv?b1s3$?pxIxj3c_p4W2SRTM*5l z#P1LjJrO8kUKJ#)=t!gTmmE_K1?t{9vNM#u)Rsm5$X*;bht+Fh9u#g?^RYvAa|HJ1 zk}H(xq|w9iXixmip=f{n%KDKr{WI`L98rCwX?=_HKlg0{YL~s$b`fNM-x}Z6ruYu` z#Qv_P_~6CdU*B!t=Kv~xs>m=7oMr7pe(i&QXXoj*Nvk>c;%%Oe!(m@C#TmjPc#88K zLKv?TFGtohk#;gPKMAf5Pgqi<&G&See`PjIms{spRG74T;k*lTYI z^oLB(gXI1qHew6zvmNs^8ALuQ>?TG<;C=~Q3r`d_+}jG60d^F@3~wtyV#fG9VIDy)HEM$1dTRJ;KwRxc+4yaw3tOv3c_QY8$SfZVInYAO;JR$Q)<-%ZA(TN7|nG7KvhV?4uqQRMqN0EG#jn65&fX zpMByAL>}4C%4KkBv)U) zAy^|k6)*HrKA`A5MKvoldY!5ZnG5f>I^-l7K~)i-ggwPd@qt*m1oGdS#*r*UQ@8=T z0C3Sk=8!^CcLuFs{9w4?8k-n4FaD6AbEkq7aJbX>q7Z0n zD%fF7-y|+T06g=zr-W+`h}gcLKv*1gosUsZX?>o*Q&yn*r%n77v+IuMm<#ogz|h>V zzNpp{?bYDZ=WjCxn|J@KfY0A~4=MmlEoUj1|<*^4E*OdYi6FO?UE%`nyfiaLszwK0}P#eJa)Th&@o|wM;)< zb5n^-1(FTym>SH#dxQ^-R$_32pN6dILz<492?WqjC*Z=zV(f?Kk`DUhKr1owQ?eHX zX35>a8q+hG0ze_``-WL;1Yp2%VSSxV4b?T(S;KiQvu2hARv0lk)AjC{`GgGe0n|R25;ooq>g$`R#vU=CLP9fQ%-d$e%4+&& znq%vw!%T~ylRbo2`T9vup!ScRK!@{BHiGOoF{OxZqw=DtFbB=%&$_taEHoAae1{EB zM?RzeQA&vtQJ^NS85*Kq7KBC(v#e{rO>fRa4I+glW}C;jJc%5{HYT3H3Nr6C9$DH> zmu(rP-k&TeOpwXY4cN%oNQ-n&c;kyWY0QQ0tywkDb7zatQxI!iqeXx49a)f3KyTK@ zJ7fONb=*eJ%~(5m*-nX1s*yoHD*P2pn=ApI=cPZt$85N}i2gR6YBWEkA%PL_N>8KO zXFUqEfkYY2sfu;co>c~!%qs|N=w35Lm$4#tiOWd&)v$62Mkjgy1W5Xf`h09v2q5LY z({^8_0}z6!93g;N4_KU#f4YJKg(2fUuXT&) zxM;Vg$Z9;u3cf~E1DAQ^IgmIT692uA^u&W4uRDL0~2I%H+xy; z!>7M-me$sc)BVP6Uf4eZ5DEw3Fn~t;QNo$12Zc*Cf;heQ6J*Dz?`Ct(Q#t0U>avC2 zwMBUNNyxV_2EvdZPL&PKi>-4wV$x^9Lx0F%f|@K&s9^sfakjhFH)I#62W7FFo+zqx z39tW;Qmh1f4+2)Y{2lG`^R~N%@9=Dfy2K|$P|XCy@X!K#6;C!4s^*zS`wm5tu*iT~ zm1jhbYntvUMG_mRc5-td_i7);fUjnv7>n>xd7XcYL^oPZK!Xu~bTPL@!I3gZ!v|}m zNs6qhHXEet+^!lyey564?f4QDXc&KA0S&TfS|2O11Ae`F*y7 z@NQy{*Cb&OB zKvEj{6{Q(5V>g1^H}}ZbiokopC(R&!@WJgN>&KFQOdnKkX=4!%lprxog)!>c2l}lv znvVK^Tz^EOyQ~Yy*h6`Y9d$_NS$O*-4Cq4B@w7g$eztrBT((+wWXnZ@)`HI=jNiJz z8{c%+igjDII3<7tIAcXY0um{x<(_p z{vV@F2zDFy*BPa;au02z4@&L;W`xvRi5XeGZSDVh0@bXZZ*hH&fBD0nfX2VGkk~|D z5E9B2!5veC8N1b%P5dm`+o+bUmuyz8Ft}`zqq0dR0^Md?9;YT@s04hp;zr#&(}ZNh z3=01KFrTYXK)sgvseCoRAh(V{MY9L-P#iAi z0lbmAL4*UJlSywq#e4vYveu*iPPaU%9|qs_XozXN2R!8%6ZIoHb&fDe@!6a_!QP6V zo7VP`<^~ddhpcjxZeXY0>RUW6<3^b{;Z#sBG=MFwU61KQ2rgTOr(Z!+Kv~~tm$T8V zo0a5 z*Zly95S01M6J)ALwl}7TPZzO%MG42c0$JUZpWC)D;zyHSIaSbK4i7{qS_+Qk!9n}D zw`L3rY3J|EqrXB=v)<+B1b#O1y8}!vRy-W8RTG`VRg{&SNxg&@$C5g+?^R56~pjd7!L48iw1@x&#!b_JHG!eegGVeL)Q1WWfAaRs49G|ll^t( zA#suU@A0*stY-DfGeipz7f#AKC=Emrs;AdoNHmK~K)L(<-g9{D#;TCDbQ^P>02$>Z+HsZbLEbNLXxKnyqixVEK8sn+!rP#^vopGnzoZ62Bf98)G-V=VS?Bb?3hH#)mzc^{5UUQFXTG=B2` zVejqZqpGg`;dxCanSnD%&>$eeKt+QU3ANyWCV@!;8c4(>S_JH^rCdsHDa-)AAQR7w zZV&v&hTW- z7Y8f#Zvt_F*`t9@K;!tI`Dv7K8jwH%sZXd!yQoGSEOP{MT$IWIYS}R%j%ynO1+{BL z*6gZsWnNXeR#h$*Pp4-56s6E6P>T206w&bsqLET5%BV;SexjV##P@kx%?pFYrXy3#O@$U+@q0hXSowHH}A&T{d@Ehg6WX4q5+fR zwLN{jW(^vz!7i5P)h*NLpcbsrX+I*c1xGT%RKJZeE5kq~HaPUDKyz^f8VbGh=(Fiv z0li!QfXD<0D~Uly#?r82k)tM2iSxyjNESWcvPp|FE&$-HoNo+}HEIRc#W4E5`1-4b zy-F;eh5@hCLsI)Shx;gM#o)V)7`jgQ!oyml?Ro*t)NcpTvh#3(Lm$ToW1Q25c*S&D zNg+dkV62i5RbF^Hgd{fW!i-whr5^%C5{#|l@G%`;{0T0eS<%S;4xhPw5tRLkq`N^q$3VU!d)}stJRccOcF3(SA)mSv=bn;SV}?bO_|lb*FGYai0DT@Z-vNIRXv}ym z@&bHnz?EF!O2$gyn5cC49-;Z6s7vUv_yJnx;_WSj4|D(vRFqW_WJPcg&@%}o(RdrzAin8g6wKR2+xl(_U$H*%) zuZCSrUx*I`10$6U{21|}2IVA5o<})(l51uC{g-o7GyhV%HM#kb3J7O+)IO z{i7taC8^G35@X2oRpp(dKw}C!aXRyAl39C?qsVlwW)j4Ap1hbKO8m|nnerbWx_@yn zJtRt44c{Oyh#}fU>dp=Vh{iC5&C68@Z2uhAF$A*$ahn4S1sS4iAMovtIH96koo`b$NWi_Q?=a)2jMEsm#=J!Z}*Z1`!Use&o<9Q_^$PDo7|4^J7h zF<^<`K?dxkkHn!^;}-Fdl&xEEGj!s_*XKhVPch0`gboK;H0R6{f5Mz`;*&vBWdVxe zsd9K=s=S2tfV8Pn`5U$P&{bL*qF%#4V#Fw=;*`G8X3Q8>x{k8iPktSgXN{=G<`boy0C~)hNU= zplt#0AplVz>|5Dvwc47BZ8pTSlz0{e9mvF3V*KS-n8V0SO|40i5PFa#L~zrRgoJZ} zI5ZbcMlUS-bq84`Gw1N)RrV&V3zd<4{28-#A!6DLnyr!#&3Hmi)*%5TFkgkW20`z^ zWg5JYan~u}D=_okR+%`?`iipqXi@5c?e|cX&(qfT#pE|Wk(SPMC&FJ3V0bekOm=2K z=|u2Hl#4JSj%Ev4g9b2X3|ED_^yKo+!F!_MCdG2h>c5Bg1G|Z}KWvIWQG((_j59Pk*s^zV_fM zZP6N0Ru0V{y(znuep9^xX&()>bOK73YUx0GA)10LOLL<%ttS05k_Q+hJBMGwAJ|Xy z&|I?fE8mq-jRrE%d$YU{GRX2qu5;C$r~DiFq#5&Q8U6_QaTt(gqi0=)y4eMvkRf&A zJ@nhZbN;g4^dV+jbH=SfoB&>$3kbtpAeRB}f?a|Q8RP?=0e%Qc_M$LfX-1-ED-~k= z0tF`9hw+g`>)%G|fIVU7PlvZBpuLsp{ID0z8Ibn|@x!y)uG>L!0Z|Yg9Lh0w3)&9u z2nWsP$V|M!rxtC;9h9d!SKBd-ZfXMKy7RjAC-tqetw{WDO><`9_EIkRggqisH-l9Aap~m8=T~ytpMfyP7WzV&Ug_==ZE*9LXMP0bZ@uFJ9L5bYL zs%VsQS2YwtTRp12%xZWoHIR!Gj#p^tFmOC-!t+Y+uP~Af#JD~}ix#1zo#?~Q&#sDjr>-$h#mB4-0;#lUSkn6Odo~p*?X=;LB??w ze`%yRIWU^ulW8h@Pd>fhP45{$y4yk>*3f}-_1PtY8`EU#Dv_vzV2_+7EhR&y$TmD- zi6N3fS=<KYH1dhe}P=?)Rs74n7joU6B)wV6Y( z+wsbu3D+Hw-fXW|w8V`|Xg2smT18kek}A7Bhu%gOLQY27ijWpvgRUaT#Vc>&#oWhH zp|bT5{%TReJ1shu|4!z=1U4;N$$xYC?;QNaBG}J2I=y>{X&c|eAJG;+JwiR1X?(5( z4>-yobB;au0PLPTyQ~;IBx(L_&`@2EX*}_?9e1N3QN7LhYcal2M0|4Q9BZ&lVoKbw zs~rp1+Ff$_oA$>axMD zndgzZ$zkbyn40oKyw>*3M~U$HS0X{&U=u+j`i7^k(bHlOVue9KcxK-@QN(eqox99~ zqjc&0E*c(j!RY=xRb*Gf*K>_yl?V+C_b_q=W#O8Y-9;{AG;)}=Sc7@-)4A$N#qHVA z8&teFKzw(ZU2Vs6gr0G}v8ctG`!>K!3Ex+Q)^5hVO$m>Lykfk9>8bWF4BoifW}d(K zLvVZ8cgcBnCtj`wPzjuRcp!Z{(nT|d*EmGvi~7AemGm5v2r%mBU@u5$o5M6vQw5I$ z)+jN|*t`^_rqvyoh?zzW#2!1~Mf=TM82t02G-!yvLj53QN9GZn*B=sbs<#@I2tL?J z*}c#%?sK42R5i3<8n;ohYO{_9xQ=Wk!dA}+)kEbull|C57NIhS7NLni#zTx46DL^S z2rD&?f39bK(_#UHA`c^bHzxrG_tLj=G?^@m&Efb5W5AOd{(UVzt#|EZl&%I!$KCSi z+xK1Z(_`#-Vsdrb=6uc4K4mi8vf>h}boQoBliNjRz%B9d{sfGPCDI=yVZ^)HMmH^8H(wGkC5Ve0n@TL@s&HlF(ijgHHg<_Ki(yv82@K!MGGGcS72vEmM zDH%Lou_WeRZ?QO(h(l&Hew57e5gAZx9mX~!Tr?F3Auf{>No>IxD`BVtgnD1)uSY47 zUG()9hs=Wagd94CgFd`%(1$qCE4WSKRzs=1-Y@3Zf@7L&D@#DLOz8pzdr)v;>^YR+ z3T+lHWqzX@J}V(2gJg2<3sZGg3QF*Fd50z{3oi7b34)Y<@>Ho~0^8AN^ zA4MAXbFG*Ff4G2JnWTUq$d|&uO^}ak9DD_M57sgm^@++g)Dgl7K7$%FU`J!U)qc>F zN7}RuX*+HutcegkRNGx` zr`3}VcWc{eZ3poqQ5}X;!7jSROLrI0+0Bwd+Xwl(sJ6JCi&Thklw~f@p@%O6`1ec! z^owLd#pC_&o*IMOMrM8FBO zZbDSi3?~C*Mx9(?lq$^VjP4BqJW^0W7u0?*zdVR^%I=MJqQ*SFvRHhH#fut`yVMo^ zR@f9OcF_1sF+;sz4K5tihbw0Xx1~c>_MxFsV_C(R0vB*{P86i-Q%63fsPi4sw`J`7v)(M|8b4`jk?f4;5q() zzyR%d0$p%yaB}!sS-Q4^NV3_6@?;$W^n;L-9XjH=6X>+N5z>i-04y8~BT0opvjh(W zgznoxjRTH3R&4VzrFDE7ya^l+yKzCNcQn>@SS)!iAbiyEH#E-TKFEzBxs(PA{#6)g zrL3`DjzaYngsj%UBw6DeD~o>|%*&5qu-J)e8qa@`sHwbv3ioRN$s;W|a@<*ulw6j&47j$JIC(VQSAg9w;t5$0gwU(ua1 z`y5Q{skjA8z@8|YMl)Fsa-TJ#)HxP@h$~H1c9(#fkt8!%>buWDGLNJMksAnD*g;R3 z2ZSm)Cy`MKLXzE`2c;AXv0u_%;sRV{=S^*b0f!}Gh+C$pPkO~WyTB2oOb7bXG7_o@ zd@;gOLczFceh7hMvBVFy{MRp-!*bH3tXo*puh0~6jVn7dU&X6Vp+muWNv49eqI*6>^&`V_1C}f;ks6_4r ztcA3t*huTb;V9>jQsR{lF?wJu{2P|8Brbu-vVatN(C&H>Km%oIqRGoF8YCJgYORp% z0hEBikX4|~T}MPBjW;Ucw@I=d%o)x8o-M@IJcMo-Dl-++O#dTZs=W}7CR5v3ID%w^ zN=Pr613mPjFAHO6Dku-g1B3t+aXsx>=^uyj2ep&jPU0*`MUm?<>;=0Z@m~3Pk2ikG zt2~QTcbEHu#)Mkqn1sd)V=*fI2LJ&j0%s=@9k7jX_c_dBa|Vc+Jd@SKU)O>mNqhyX zOmLEQFLG5@X;C8lT7-y>eu#ZXpn(*Ws2AUc+G)p&pCf{n%#(|$(`7yzOHMre^_ z(&X7vX8qj^;3Erg$SgmnxglRZikEf$ZQSf9so7p zh$WEU0fMRR7)mgMqf_i|;ME|i*o8H8)*T0T?s61qieZn$yZ1Q27;G4$!99=hOwXMNlRUqiJR zhNC=#C7xkmcim9Ls3pXJq{lMpAXpkdo{s)OV!dEu17|Tbq^kXy%EQEm3AXP&I!+WcF&B^mmG~8<)i~-pNZ|qzt2;l5d>a{6(EwvY-yk`Vshu&F z>l=mhxOv)AH9PN4RdYKP*+d-g5hBab3$K+(jEQw)C5Uk$G7OScrJ<4rb@z3I)Ec^> zL_AauV}J6)3s~VE{zIxQpKG&X+cS#_l2wvi3f@ff4Vy<=kxz-#q7o?npuJy!UdG0a z$5ApS5Rsnv#38JLsV`N~2tq|%Zi%$mtid<3eW0FsU@ssp>8uonI_8@oTU(fH0fmWk z+FLlq#^jbd{drcOp}1U*5@p%mRN1gY!SGerY!58hLJ;f z0G`rv25n?xl~l3FWc3WCZFCUAM0V1>v{^}U3@m`mR@*6EQl4}14{~KA?nffoeSQo{ z4j~%ZBqsJ%qE;yoLT+mVG`VqP|7sQI49j?Gi8c5QB2TQPk{%7ao*aN@ND^UdU3cj$ zYhZ>HLSS|r0A3Pm2Z_Wy$B;HvY{Q0b4&v$r&3mt<8qv>JL5IyT{mX=8#=)uzjp`Ya z^I(*V{1Ev?ElEXXF5}VBaK2^gO(8^0V|-p*cVJ7z=aOVSV=}^sZ;Q1%JfDXh7wRfo z!yvmDM}WbC)m&sqr2;a9crfbbPR3yp+cY-d02+6%w$|!@x+^t>Mp08_rJM!Ub=2z& zowo(t-L14MBXr(@2>h7C7IFhf8mhl$Z0a zfDqP>#UKb_28xwmf}WF#u!bYLwK!h-AZt4-_n3JXL?P>t85srVj>ulO^52Q z#@5)|G*$<&S%8g2b*C(tU0lXCuI?1ZU|j{LWP@E{tghdJ zZbR5sV@^A#QCG=8O*=Xwm*Axdx-AYhHcexBMp%5LJi*P#a~s|lJs{@niD0i&e^oNK z8iO+^;j%P9h_XCi2D$=UQdw?+e_H{YYGn@Nn_S0qWX5{&b%?V8rHynfi5^!8UX)5% z_OZ+?SF5bXI?xbIwYzwhHFyJ# zzgl_{MG#L4UMbjOU)O&fKpMzW`+Z8}>jYh{##qaM=25BG2Fb}D$NCsP78PN5i$lU% zqVA(%umlz+!Ae@{ToI*InPeJRTfFtzf|or)hE3x!uvKiUUuabuZRy6$&NVbH?*mto zC1T1ek>f~Ee?cSnAp%kJAYrsVV~Av3n#TqOIk~za>yZsI8^^Q{6WT`}*nuzHhCthJ z{p7_>EMrVVed%i*wFx#j$z_fj-42I6_2sET+M-*UOUu#9WayOUWFQp`KRQ#hs$kI? zETYd|2%qGIUN+M0ef?3^dw2HULL<1+# zAXu#KBeG(_&RFhVlclIgu7%2W)!v46SH0so*|PtIcap3GTXx7ehg!t0A{6ihksDbA zkzWg_(rP$`HCYtczAHlZE($pv#zez3tH*(fQEDkUz+}9GBIT-aDST!Mis21R?<(o# zf;$P$z)m;`)i{j_v^F9~fiVvo8ZGq{`FEhWXaAfmPBaZI?UOtB5HIX$VY?f+SMV#! zZdfo$V}mUQ_UzkHGq^yyn{DSc>S-ISSAi+ez5;ne^2lH>2s0cBWfM5I4J;rLm+U54 zlvJl*zDG@`;=7AxK@k5gJ(qb3kGgAdObCRGJiOX+`va~zsG9J0z(gYnxUd^LCf#dY z>JiJ9FFt?~OKhAjNxGDsGX@yAyUG2UDHllri0Y?cr+c8mSd42>AsflZg3}D=l_-58U%^^vzRhBCL>voJhmVPX68S2Q72`*+wg`gMRFNYmREOxgzvbXWq$p6qPEpxGClXxXVTb| zi!YN+e9URF1q*}(IZB5iWj8`Z4=e$awRExk)_5l$A0~d1flYBY?ad=_!t{c6x|HzC z9jGZK3M%1e@JvhZSY4o%W)>b$IBYe>ce#`&GBKMYr|7flZF?u7FqCB6hj)T`R^9t# zDFVu<2@voXk+1F)L$#lqe3e}97p+hP(wqD5Y0aHZ74>s-v-e(!8Vurob^WsHubWj< zgjcFM0mYRu`9CCPwqjwJ5kcZ87I85;&`7l%gn3dhnagdNgl(+pN-DKs0c0;SbA*kB zAiK)$3+nqyvpZao{M}snz^A!1HxVbCYmi1&|;Id$S%S+ir1G4ir2_7 zFKAUyK-`ig*;tg!vP(&(RW=Rp;iFSf=^a;|Q@~4JeI@I8X~Kgx@99l*Tr!31$HM7fBp7vGXF- zoH&>ykD%F1s7Z+VTadobKujCgwTedi{{cOJiV6umFLV6==vnah(K7)@cWGq$KcXkI zjud+S0W>a&ox2H2ss^yjJa^~uxZp|({KoDeAh|7$SY^T zE3udSiX;>QcqQegJZm67xy*!`q=^cvIh$a7syj@E732AlCN8 z(pP)T?wN~ZQV`>#`+TjMT$Cm@fA>NCLTf;&wDU$ITUtO7-{xQ?JQtbgc_A}MKApAW#Bt5y5%!hJ)%^r{IT zs7I72GFscar0^!K_{NjKL`F$EmIoV1zIO}z1BExx;|>;qY5n9yjIIl8nFd)7nhT3+ zSX`5UmJl}fLE4qrNMi^|9C55+2LlVjG8EO_V)}Mr^m!5Mwzuh^F?c6P=@tv*kl@&d z3jTwaqp)6MBcuWb=6kQBMSNy%t!_mt$s+c$Bi=sFEe%jW2QtAE9VYP&BJ_EbuJ&J| zM4q5eWfd?If~Sj-aMPR7(jA|uM7H5&Pa~;MN+d)XkLc$XNT;Z8(PJh&A;wz*?z!;N zL6&8dhKicZN*?7(+_0+wlClzx{}Gu<8QFCa4g{v@G-WAed`_DD$WVGAWhVtvCJn5n zecoJ}XI2US6Y@Q&W8aeu8V*G5pmCLcSYU5a&-A3@)gP#BaJg#q6xCxRIC)%=V-<|V zXQj)e=|1Hd>^|k1ap1;-DfcOMxq^okyH8o4w%*t%J*uQ37V2Lm)IXwNa=p2}LP#MN zrn_|$G_nf_UNDlW(W*WyJV-+xMjp6KpDN+QFv-D`1j#Mr7pB9N65cax>Q9l{P$8s& z0Uw17t0^~|g>6L!l$0_}85@wm2=`;6YH)v4B0F%GK3owzV;sztw;`tI2kjW1L8fPl zn$1FRMXJPksS?FaqFMS)UPoy)4)sEY63M4~sAO=QRfFey{3Y=Im!Z9S<@kDJY!h}?Uy(q%DhU>H~-gAG`D=)}Ld8F9uUgeKkPDt0o6=)Jfz! zR64H!b=r|y7~@HroQbLBkl%w6QUFU{&E42%g0F@?Hm&FqZtg}oPlK1Hvr_q45k8ZX z*=Eedy~sp`a=0gFVm{D9_ABW9pj96tjDVzEPM{OE2|Lm>?tgUEo>t1nNwSOu4%GC6 zW9USj7H5q@UXy{7(!)qgnmjaS;Ih4F68zcNlLUweA5>PqrGriQueAPRc#~ub<-Lm( z@`d;c@Y0kIa-`E#8`fk&$FYTnO&qc%Uep>b!J$$iwgDMspqcCn({nV{oCCaqKq5uG zoZg?&AP2rjz{g~R;97C+H7XIEp2!2{;Pn`?3QTGz4fg)%1afPU zt)*e8!9p^%0v?7bE<-UG$&HIVb0E_&n2eKHQ>p7GEhTu1q%dZYgSB62^?4A+n>(n~ zqzA7o46D{$n8{eLMlYgOR$62%5>d*p-b*9d+D78iV!H{`lr;ip5unBC4V8=OWoR0l zq?O3`@S$9elmoGqo|!`qX(WP^hTu4u>M`-vpMYR7?W;6sFm z_UwN>6-nIAn|dGtS`t`QC)*Sbt&HrlgAPeYuMWjMGfEo2K{h64`X9EUsx2PVF3x#KLsVujtQMf5Dc8!q9_)w(-zXpo%7-aV?*4$TfV#j~2#wq_Ym$Uw0kV3C zf;F5w&maX$x;-()N=@R_`nRM9ozrDE<-`S*;E5{@g)#@TSA_H}GkpX>Dja^`zOy;zMHs3HqSYZ#%~hye$J9h*R6Fx80|NJWHw^X?;0uGy@Z1hV(Qi_Bsy zLES22xiwgt?l2X|Q#WrL#^qMn(0$`sFx3HHRn@-@(F7^|$CS=n%2t7OE0O1bFa)kd zfR1~N{DvN-QH^CIUMhe^Y`pJ6Fc)r+>qe{nE*PdL+gU8ZLTTxoG6=^1idXP>vR{C+ z6XOVH%X8Ho-j3W*p8v6_*n-^-?$_d{?aBFgHyGAXQCodKlcjC@5y;yWAt`K2T7=0p zXvf0;lgKTFUkKj+oXEWt#WZ4_LST9w1kE)c7SQW(9ARybKZ@aE;vQ%^BhX(|^nzi|`ZKw8X=8`(0F=I#U7o_jZP9X33i%L)N;qXX~Z_LX{dme7*CIrfl|8*wRLD+<|v&L=72-k#`Q@@eq=RWOY;4)toLtZu-cYjteQGjMa*Il){ph zFO_}nVYCxr>=rxf;<0<|7LM03_sl?IYXFIV#q-<`@dy4t^eN?jonE|!GzN;%0;FT^qs)f+ei7ChR?0OrP zZspp&@e|0a42-w1N-cqrQc=8Ug(=G}m&~X}|Lu*Sf%{lgM8G*#bEIoA_;0*@jJqW% zBv*vkFTz}|zbz@{);MSiN+DFPhGl0Z zrIfBjv?lb%G%anQItF^fuu2-304O$kr66O9#oX>BJf-bvGe{fBKt(C?F+4fjh1ER? zum%Yw(%&CPA^>Sz$$opokg$m;eOL?ysbJFf>?@RE6M&ko1(5Lm9tac}KSzUpkVk41 zIRQlD8??$d80qDBad}^(@}x8;9a(GSXHwiCMJc7uq+8%Na%EV=j$taB?UCD#wm51? zd17GcKcyWI?C3Jj+`G9wm2$mg0DH+92@D3fLnJ9egyOZmTZqv!NuZK2sw*Ki;6S3} z*K%nsxgT^O^$<7b0f1-kgVv(7a<7%;9=GNVE_Wo#C8(99GZQ&wY5`Tfowg-#4-ow` zL~S)Tp{QE@s$`{s<#<7r87uGtKn*T2(V7qytd2KGg1+gGrpg+LPq>TC1~sfkKaqNc zP4*#fWwUV!wYgtT@j6myU8cTM=0MxR)V!bIJ7sqlS}6VA_*rG z@^>+7%#*vC^`AhF2s79I_4vb%^vV*^1e4*%oj(pr53nogbo)aP+-xdq*{ZU>00$Vr%#W(Y?c zp&t@yC^qrZ0ch7^bo5V9lpIE=&6tze1jt|0XdMRP6YfEemze$lmx6r-uf_?_UgBoN zs2L#cNrIJ*tu*=HM~kTH;dYJ|m<5K{y-m$72Y{19n9{Y$H#3mK;FD0}x`{Bl#{cRpO9wr}T7Gg5m;XtTk-pjoT#{Dm&SS~IFn2Q%o%%YNr z@Ch7+7$)a%^A95eMG#DGkchoRJ^ejC2m1USTzHdP$SgvxyC7Z{ZLZH!!V|d26To#P z@(mOzBQgMiAaWlv_ejajQRxU_#^Erxq%h`^@lagAwiMT6@l!6lX_&LgeJP_akUk(c zr~C$WiO4h>3;60}#@n;(O>!t{*CZB&Q4O z`EAHnVD)_$D}HX?FAEvZB*@r!POVovTyBJ&7_>(|52G=hJ?B%5Gs)GNzrWSJdfPv~ z&t0zI{2$dx4~#b#tCQWZQ(c_ePDcLETETe*83w77&me(qj&Hv}V@+sF1np8H((PNM z2aa6jn$6xg(4OF4k2p%$Y>lx!`+rluMKFA^kqZl6_1NMaKogARV}TeldJp2cWK4l) ziq#C(6UW2dmMp1y#pC}y9r>M8Xr0kalZq{;BW7AQ%ox{5?JM4qTX*2)_Dz;}yQ{E8 z%cdnXHhr6w?j%#Tbp1u8t{L$r+bc8A*OypXTfmB&eNgs$lQy33@g(CJzr|5WGDkW5 z54P#~*P7fH2kx4)Xr|l>Idd0Hb1-Y;smZjkPg1)6@w8-i?75X}Vo>%{%D)BqQ>r^j zY^x}Nc|R2O&D$swaWafyE#8o9h1iss-qbwf3O6Nz^?&$WBEbtUR!)Ip`!-T&kINB! zsvBsEER^+taoDPky6s#b)a2h$-e4Gd680(_%BB`k@yc#&&w2gbfVDBX z70Be=4XM0r;SZxi(xMdL@Vep$razb@TY;YJ0 zsl;^lV$%L=UVO!x$9AW5I+t8lC^45_4D!%RZe=wo7AqZ6gE8KQYW5HG?H^@GPsp+c z`o8nZWa~vXV*Y%dL*4+um3uM$Sd1#g9oE!YgQaEl`KA>0dCGC>X6aaOWP*;GQqN5V zNrX~%_v+K}WZKiE=+hg2f1JC=6pAsXN z$_pwi3>T$FR+evk8}CU5T52|A$~AbF%7@^R}7@yNJTIMR%3|$w3}K-b6Y<(H65>B$J1xw zRp-_J$h47U>(iwjGEUn9^Ljr(#d+9yh& zc4XRRpS!?QMBG?LI%EF=B~m~c@QNijY+G3=ODpnWXul+fomLmpW-}Oe2^Jv;uc%ll z@<9l+k%u%-Fj|XtA(Jr@oAlIPkfK+fK`o&5jih3AIDi@03}-QZPs#tlY~;!=lK(_D z>VUsZyd%qgINok5Gj-=F0xZ;JIpK=Z`Yz?m4XC>AyoO9lr^2D1pT85qoqhmqdXFd|&Unp9R(!rn)KO=@d6HV_*D z(ML&Zsi$&R6)&ENDCLzL$8`FKAG1XC1wdN>A${m&uOzx}hELyI4SAHv)xSq$FV2VF z(_!c)S-BSSl9VurAxy;6XHMJ;>sGHm=Mwt)59nku-WVlG+ZETfxPl z@+&T`d_Wu#8M0i6C8iJ|a#%WHSwgm1Qt^x0`yq&d9ITYSDMrEP971sXWS0H795YE} z;H@A>wC)0pp%VTrTxuoBf)g^1#^!c%+t36FlQLS>-lxl;_F)7%eC z(I72%r(l{Ry_?u=Mv46IQ-rmQ&ubm*Ei+t%s|JnyJ)$-3a>UFZ{ZHmb7EXfRBWU0R^|@0QKE55FWMv>P1RnP@^FwO&3hfjH}OmEC`-+m z1mT2~b84T=9f$UHoU|`WCQB<&8>E?3fn~WUqfweFi6ST}j zZE%-LZk6x&E$$DXL1YFtet97Yk%1Y+Gl!=Pf|<5RwJjk2H})ON781}hD8KBIa`}9MN@jSjRtt+{Zr@-*meR; z$riX$E%D^QhuC&+}%b~YpB?s zCeEBA5^;P$nBn=eBbP=z#W*I2;)@uwWMR*ZF{Kq}Ot{TyT>; zF&XTT=?o*|x%lZz&@519FkX;oQ^_$G!fvGrkS0lv2hAWHYc(eqW|VB)1ZtcVClCAv z&45nK?2I!LPlKF&4inJ$BXG*3zXu?g4Di_J@$}E|*sS10ss+Iy(HL3KvkqJXdP1v-_GQ5*g4vm16;yT}|5tiZth&$w==&?;)2a#Y3vcEDtihhDkkF%C*%`5b6`K zFaBOO1f>jo>rboDEZguAiD1DS0i4k9IdDtv--)yt;<#ihrt~7iDelNaWkl*_web(e zr_iMcwj2`Fq($era3om(u#W}UV5p%ecd`O8`Z2Ht>Bq@ie&s$G3G6R?T7M*lo6<8w zBulPpJT@u`;S$jVl?aRp2HRnvLX7}C2r$Xf0&HX{ByLXcO#!y=SI9a{5$3>f5nNna zL#T+qNIn4FSxWq$R)n0b?_lN)F}gj$1;FTbAGbiVo1p@cu?e|k^9FIhh&L?D2?ud#`yUZE5w#%HjPLqO3u#sm&EyOVh^TpzeXY_L5!4- zWR~~gW;b|RBt;6yCj-s87_C2LS~ME#x>KWf(=U_Yx%hk85aT^C4R#i}g!1yVYxZvg z@>q;{Xc|UEiS+yeuTthv1?3kafQ^hw!8YW%6dhy(PSAuXPyNI}nEXq{$mj{tijbZ~ zvInm@NV^oV;&w~V8|IEx_M{tkRPFGpC%x{!75tFv(n-sP)x@ zuy`(uM<%Zl*6<@<6FGnCBj2ji*wi#qWBDPlip#lMixOE%ItSC{oMR`I7Y<@W?0W1O z?i{Jc`{ErFaQ?c*QnYcVU?S#gQ%cN=;mMOo{Foh!;Iu8l5Y0uJ^1^|5#|U@4^V&UE z<6GnO&rnMn1=Sf5KRrS1K%{KDou9|59S(b&-LWG?MrdA_U@Ao2&}C|o(>9GHG`Im-6`{6ogd{*HN1g>K;$Zw6AvYdL)Ts_(VILZ(Kjh}E#^PX4 z-)Q&JxmTG0=-QGo0L-ZBad;xt4ZXC-0- z_)55ex;xnMZ47A1TJ^j$00-`%8`-fkW!y}@H0WnDAWNgyi+wPph3K#T5c8CEUxd1$ zlw<9_UfM}PfOQnr+hi)%T@YKv=!L6`d^HV0Y_$83=rrC}q?LNHE zFy`a^&gqEv4H*HNpSaf}uE)kU4r;^O8pXcbQKYuZgTLKn*kaGG0(s`9`4Qv=<_{xY zw!;ZfYByq_jStBkg##RjDn~pqQR96}V#72u`tgG4c|_aeBVR?L?=>a-8yJgdW9S(CnjuR#;L2)8rC2aczqO7xPeo#n6C6RX2;XFQ z0E&AOcgj#DC95bfN_x~59E{B66f9hm7T+ZmA?3ZtP>i|t1be^;B9)?PaG;bt2)}@! zz6nyH42Gf==b6i?RgyL4h7KwZDZl7rw9l`J-Sd~n_Z5#v4iF6c6Soh-295xx1rC{9}QL?I_ zU+f}Ei;x8cn*5FT)Y~0uz=BOT(k&J_MXx4${PLn_h}ZhCH;B8UeYBX ztsD@Ex)p+E$6feHTSxO&g5;m`rXKO^aHG=$L;uCg-yKN(%+YB=hC!pV3kf1Z(=ZLz z;pl#X6jK47Ni<0wMknDGmA&WlxG|pj5pwLCitidS=X@=&CT(oz0(3iz0(Va7LB@JS z6)Or>NK1`LyD8R0uqe9N>N^-1f%CN+to6l-V&B1F_d+b2NOFD7*Ap0}Obnq2OG9a* zK4X!uC)nMT@wF1fQI1- z{MBcLI$xG+FIgj7SkMRy6!9oyCYlp1StG-kVF7}ssc{0-Mw>ye$KdtOB3Mo25(JnG zM+%7+Pc?1@iN^d_o-Ou>-tU{9E8K3W-m1TtgR<-z4~2~SC6CEf8Ds6i{2t63J0`|n z@~D!Fh!C`_Ofgmu(` zc-;gju*QkRBQK9S{tDh?p=v4JZ0$C}`{6j{*i;|kHhK>}V3s{a@<_8R$tum#Oh)NL zf#z$;Db3d=pB#_ZJEsS)CseIKAVj+Z=-g0jn@mT9*?3GO@*;E{mPd&BW*G02W1$&2 zfg(<|zl3KL5KI+NY8GHJm1Ge#I~esk?Z_;urbX|aCLY=jFhm>b@wWh$F*7`!b^RE` z;BrJurdH|`uo6Zr^gBSL&q zh^E`_lbmz|aXyZ(6D?U~>I~_e6LUpSY_tY$ZqnF16L3%Cqs&@ynw-_*a5NWrEP1GR z7v+(_X;|dGrV9O)ns)`o=LmmeZVg;g{{Rn5N`aa z;>nok0}MTfd<~&TVa9%i@Rmt}3^lkrRsbWA55>YLO;}ri(-*z?HDl39hSR_~>LZun zMSWy6{$gnABV%wQWv(iT#5mEDz9nz59QwucrTmO-?O8QAcDz=ohUgzxiE);T?ECSj9$f%(Xt#0;cQ|;Z!{t8Grq^|ls*I|qyD0sA(w^N%+?0t{F4oo@0A#2m6OjaM2cwl4_2o{9rV{VM2b8b{3pEmDrExnYW`@p#66&z|vvfm$ zO5iU?0LM0PsT{{oyXw90v6H14&(i|IVbRoPpp8)5J4kayvzj>}k8b7I8SW{hqw?Ms z_YryI8X78Ck3e%_^L*ka=&CpxmH;AWSi2HGm5YwRqlXk%nOS)@MxJ+A2PW0V7T0FT z{z*N0pqH2P+QnUH{BXUr{WHD%(~|@+g0u|Xg+tY5uoMeb86yX68OIdas<#a&%#u)6 z+N1CY=e`i!>$#XuYtdS~{fFT`51ChPKaubBURUV!MzWpW|G?FR%i?x=*WePk-o`b_ zdbX|zl`hJu}<%LTt7s)rB^t;t+>`rbb9M?y^ZTDc~0+kT$ax{ zz2|UUd6m<-S8*N06`$$!mVd$NJ&Ef#H#ohY;QH5DPVYmw_RV&B zC*FuQ;(FVMvghI*E_adBdkHSbJg4`k_&tH^hGM68N{Q2Z1Xl~Lw{g8yjy~X8jjIpW zPFyeJ+PJ{!J&UVhq0`%eYZ1!1az5^H-RF0D?=EwC-^Z_di_`19)#-f@SIZ*Q`&Gbq zvD15frPI62yw>CQ_qf(oIlYTuH|oVzj_VwrJzqxMxOe`G z)B708UGf#c5!Z9LsK0&pIK7tv23Mn=!hqA8JfT#cCmKpWpOaR1KIME)Y|tPEuiiHe zRzn=2>NJjmvV}IgY|7S`affp{DPZEm&)_~qP#X8eB$$avQX>F?P?-Ryrz`3 zMm>M}HY9)h!Ga47*60FjeMYHz+8X>QT9O61`GhQGJGQD`f;hTGXhx0x2z)yrP1t+P zl8=jWMEzT%tqqu`6XPUt#K{~e4*7T}#Sk7ekpN^v;xnyga462c4?_h?vcy7NmYApOX5d5H2~u9IgUy7(+% z!XY}}*6*4^YmROl?C6>@5$t-|zyY!Xi372DiXHA^54_0tC(+ORURY8mvphQZ1YIh> z!X=6wKA=q&_8`@DP-IROEbr0ymGNZ*CCMU($sv%v;Y`hM9T zw1>W$Yo?~v@~P#+o{VUa7d2^cdA!OusE32!KVs)r45`oWO16grexjAby(g&5wPHGa z%6smQ+|D)h`)Zf(kr0q+W*f~#N#QW9OM9`(rBUzS|iY!(ts0=!@8WFzIi=+HCBIrfj_RrPOXP)F| zE_m7EoNBDXyy*ATR95NhDwsT=+mxE@0KNx4NBudK@;q-{KouW6o=Z@H2d78#a;jOr>OH|{ZqS7AlsADq#nXosbD3`8gu%;S*25*$z2*u`T(55{==SoJ) zacoxxHkCGnIKc`M9hkXzr803oi~x69qZ{abbOAYw!pVvA6ho7sPm<48^+Rj$*ox(a zF^r)X&7dJ%e@oPHGgqF0$_aRZ*`SaoxHNe4Ik;rAzB$UmlvT(O+t z&c!Ezg3;0o9I1*ifBdBRSK2jd6@Z=v`sr*}f(Msi5OT$An9xIjO6&`fDK0`FR{oddS z;}z7ROf14`-}8q6rk-~fAy5PJK55Q+j$qhxQoL@i%g6U}whmgTzm-72aG08Pla90)u8>RG+bz^sL$JW2=-(SKD~Oe&304 z2MUhoqvLB)mc7l~H^$3?_G7o12ma0@4hoZJ@X~0Rb;a_fqN1*C!na~rb_*<^Jwx-Q{CjT?(k7xsd@E~$}@G{J}Iie@J$jbQBkWq@G5zZH! z1%;YI6iOV_DV!>(vU>&3FeXPhbzQIGHhNYJqEI~F#)BrM&o?ZG>z^bNAWUaP1w56z z@PJdjSnb{jK?#7)15u@oEdqol1GH?-ONf6jg}`wZYyTx@qD%msaX9P9w2C!*~}z zdhZ8#Cu?{;8tKDBvW`_2K%!FE6YCvni>*?BU}*Vu3Cgj)kVy6SP!@zkf|NL{e}pGM zWKQL#N^QfXQ95?63!>+`Y(&QuV@0W}b7b^Ekj6Lm z5IW$cy4eM<-#%?wueSMP1dX8DmU(=yZ&+Ff7$y1@mA2wW=M|~#u}aPF(tq%E3^DBt z*D5>+9vi+LuQ96NnEEU~UR8MT4s4-ZTkcq)A%tAKDPy9x$g{l3F&4o4U*hJ}qEXsd z(cI*ih-ql1)?YCsVGlK+VE=5tM^XPm4fA{K`=fVQeap~Zmsr-TJpA93yt$8M98v8m z^Ytnvy}k?UOMn=N;l2JEXhGx~0D}s4723#u7Mxi=x$x8*|Iq91EyEYy=yRwJk@4|e z!gpcamRkL()iihx^csltP4KyomsINic{4+ux}3E{_X8ohzg_6Ky`q=;>O!5=alZ@w zr+&LEc7JbL*DukmO^#WRAAAFS&lsA*j9G%qBt85?150(g6B|5wGh>%yg|Q9MC6pdYN}(oe4Zfp?+BvYg~M^-K;}8zc7;aiXSHtcQXq?svtF3CG$s ze=pAUt?2c&X`8#S^Ij>zL9u5*^AYzLwwG(V6YAoCt-FwVOuZA6%V@a%$C-`PDM z(Ot>ef<|B0#?|(7(Na&PKK@^UVy%EURs(B8vkz(~!eRZ?6d zr-tZWmx+oqE3_q;KW-ef-N>z@7DW;IKGboyaiCeCfw-qo7I>@eK!`(*@~G1 zf3anRl_P}AC(uXJ(x^{ z`4Gy*k)9LH89&D`k2?T-ryDY#TDr=84M&Aq#xe zRNbSMxES$qq9UU^w0||`wm0^)<;S%QQNn0lgB=EVEOo3Hq)H^)$8B5Nhe(X2gqBXN z1e9DWmP7BY(I*u#jgWn!`390(Qwu}PW@=YCtR`M@y}cOsIG?0Ho4uBRqseiTWrb+sW(}4j(%_9rE#}FYfe2Xu6&hfz zQ6k^QZEdriAlN*Q0ogo{K}XSbrc-p-o_Rz;yuneG`dv3mLf3@!lby5V`0{2w9NL3S z7I6zh@MLsdBD&DsbKKsNe^_&ia+>nmJQqLSf;}GS@+F`nm3p>WB2t1M08dCa<=`jT z*r3)Z+Mo({qfoAc#)eAnIgYZ2DVe7)E6ji|%~YOvm)5M@4&<-Ye|*zG<3CuwdO8L2 zTmm|dk%IwA%UmIKZGst%&zW3cFzDcUnmGuG-PiLqEJ-iU(SJM{QO%!%e|v?epbHbr z@w8?|P;<}I33!l~Iea*M?_sF;P%p~HJQo5`mPGHc`QA{<-tfJyJUj<)gyZdN{!OUo4gkF_%F3+aVE68lIwh26mu&nb5} zUU_`B;ytI_>74a##jD?O1-eq*i{0Z`sCT^mBr4E~y$$Nq{|@!DIHxdHf9Duf2HY&& zF2+9`c{6Z>SdX6dd>P$ZkRyD0Q$9+l=o8gl%2UNI^v&@&M~w?1ka#` zB9!85T=#smIM>$|7#qbdbNquFAQ8k%sWUZtC*iB#vvkFB$-L^$hmdFE1aRjCal^TE zg_z&qz|``4v_ONy%!HS9ai(-e2I8Czp9!gPGylLH#;dCED49&HJwd2wUSNCAQ4C%$ za9*^apO9{R$JdWciEofVJQjP<>pQHdq^y%uW9DAM;m+&T^Df*IGwPh8p7-LOcxUHW z^?VWTi|Bp?x{HBapT)|K@9_E@-;t<8iRNTsXS_J*JG|~g5JX>m{ZbKEp7MKq@pa*7 zg_nR+ssEOo!`ZLn8=y^Mo@qhE!Jh2L9v6kXJO zm`y1jHDK5#6yEZ^@fI4F)EJDp$cfm40t z6mqeqk9pIQq*vyldtLAms`i4#i6$q~L(tlR-=Y-ea#&4ncCREUVtk>5>=Y;t$ z!|8q-zXU_X5C6mIjrzMP^&gO1S;fbYaq^pvwPS!l8#M%_B`}3HCmg|P>L+7@SE-vn zb_OTWSR7V6>~*L55)&=)j?3MLSHwH)%Qe^2RuZrFuUI}K#y9YFnu{vvT5et`dWT7~ zEC+LDGXgZtbJ%AwfGlS_2=I=^<37QF8H$`^)1pRFA z=eRPTX2l(~rf0lnAmdSFTq*oHE3<~rnt%Xdmia4!sXr$zBN_#4Sdt0i3j?55;nIR1 zljZ`Hhz0IPULeA3f8WNn4L}S+fVCL3LdMa;Si!;kCZM5-0Kr=?9()M!T>>RmxFpWD zBnm3}@QMCwP*;+I4+7Tthd~ANTdDHuUSDg_;X52ylL9g7yKZQGXl;I*yEXWRh-3c; zkfeZ!H6s6_gpc71Q|*1Rh`Jgt2=+m1{mTTrJ*;O?rV5uY9{eeYFDm*^@Bp9|d}lC3 zKpHHsIB9uBjr#j4^{t?}`F`l#upi!%k$+tOC5j=?Wz|Av;o*N9W1jIHr}raV*PFj| zPuG`lndIZuX6t;g6cKMOma0TCs}ckAQ@$T~2EFO_L!1z2n=|OkfP1y4MxT&Fgv`Z~ zi6douP128Q(5IkFDlPEC%)l!7@@4yB&|n=6wkLO+p>|k{;~mb zh7Vj-DzWlXge#F4a~Db^p(~gLJBS2eZDE4#eL4He(M?Q&o}>Ag=Zy$?)TTodXovp4 z+7k8fdEg?hw&Zm;T5+C1Wldtt-6&3*zmE`gQkj~tt=kLAr`bW{YqWWe#F+7TpCsw~ z!Ev(^!QRA}dytBc0W)c;mxVoW8q-``&TS*kA- zVF<}+Nb%1mqX2D09{zGQd#S*!RxyUse?rLvBpUUtvV`DQg+(w|V$2<=sOR-@F}1y4 zjoAQmyk~W3#+!*7WEUXN?0yrXF^`%u|HSN!fE!Ju-T@wt@SB0G<#HUB?H{7ZLMR-- zG>M@!p4Aj0?;Au1V0|Vz?ZrHdCxi?2{fW`>^-y(=^E6aS&Ve@-94lqn z?#H@7Un>_5X#5E*qf%c@nk z16y$j&v#&l3>h$m~IW3Oft zj=iG#3{~8y;Wn;jTTybS2P(@M{V^;~5HZ-S7am1fvlly9+EV7X3D1p~=k6BGbEBwk z7yh>(Rn8WRa>Rw%UtdW?u?2P!c;&0I)L(lxKsCY{~)o=7M z(|jG+yaLP;@I#jh4=vYUxFiWfi9S-kFCT#alEODlz>2uG>@6ZpI3C--Cwhw&x^3`f zwJ8V0Ut89q1>2kbuM*{`jc)!JLH-|p6=Z08)IsJ=i?-}N41{i2Ne?w1_OeE+N1c@K;MJ<`>a{Q#;T#Iipy ziAo!v2*#G^2yV$n9hl7C6NuVjh0gBkoGbjV17B~Td~i~26>aF9sCa=o=x?P#)>Hif zKB{i3dZpRJM$Jkc&bBhX0u^8{!Qaj-zyOm4?|_HuoSUp7*sg4yO}KLzRQ6yy+I&B^ z8EYq^5zQ3K-eU50vR`fQ6Z2;|3JHWgZ(x7f$-ct*H$s;7y@UAO1So$?H25*7oxcmS z6%)ri;v43tc2ScvdlZemZxo$2Pyk!xM3M6_9Rt?y`vZN%5=T}pBqfPO*01=WPH zPJfBik)Z3PyTQ>S-LUIvPyqe?&}?fRVucImNkdL))6rvC^}yPIg_h_;5C;*>pcg)Y z31wquv?LK}3_zcQeBKwG7n>VHCM3^GMD_=q&llmT$4^3pcMnZLWqud9e7jSP&C!C8 zc5kVM&5R@$ZL>~Be6qJk7ki;0R7E$=QATAZ#;jsy)~l7x0=*}lxQ}{@`pUon&S+&* zqX_+hU1-7H=CWz{+|pbI$pCY51x{rXN1BUz=}8=GE+VYAz>rXshs|td%|-3>++6e? z{jAg~_4@MDO+}qZVcObU)Ft0D-Szda`#r>RU@?JL#7Sx(i-jMy%%#niN`O$Nn1m*s z-axQ{W-q)D`RXoEP9^*riWUoJHJ8YyR`k}8(eO7&EsQMzBx}w62jae&*p>c8sD!sj z{3y+ff5oI%*6HjGTeaHCN|8{e|>Exq6YsQe~I{h6nQha zAE1K>Dylz5h^*#J>YQp=o6Cr(0cb4gHJ5qhle89><;th=^h45iMX$mxG=Tq#rDA%t z)C*o7zzEgov$-l(>66@&?I~pM6Uk-|wD~CZ+;W?Fi>_>Q_cUsA7yhEnEW!a_Nip$= zjb8OZmnCS|u+@qd@RiEi=z{6`ljtxw7+FakB=+XiHhDU2+D!>~iI+{bmgeBE8Y6q^ zim2n2BJ{#qIzA~JVvLBN`#sE%NJ6YB?2g205d=nzze0VtpXNU7#h%<~POdl)at`7o z2{V{hHs29F1*r!0xvHPEv1Ks9VC5cU7wQyD)hGM$T6lg?*aCvmVJ-ChK=aTuk+~xp zenF_N>`#dpJU?eG5o56;Q}+qsO3<^16iLQ65AY3^=*`~6%}64eV_I6pEiU`{o)h`! zwaqQT5i3%1EleHKS6~AY$>Yi_rY5?cWXm;jYKf(@ZV`VFm9AqaAp(qzF2=T8*u`JZ zZ}A-oWVW4#Uw!a22uu83=VJREGr@tCXXkkvZn*@gIr`ZD$J^V0S5;jJ|M%weh6K(9 z0tQ8h5+n+0G^k*LhJ>4d61apWv1-Jrj*Y3Ep>Qvt5=giS$;shX+QE^wTJ6+n?P#m5 zhzN)Yp$T7=D6~eQHGYhqG_GXP^DC_Sf2L@4fcg zYkj8I3TDeCwx2;E^zy?7CiF^Az`#p{GdJfc`8h@@%Y!d;I?FplpP$Lv3Q@Q!2>hu$&ta|cPMPyyKdH@gmQgUV z?{cH|lu^}xx+Ie+{1xdC&&e<6j}3f1^UL0!sQzJg*&m!Jvfv0o6?NwwT9r)6X{-&eu|X3C%`bT~#nu#XcgWqcV9fmZ_M@imIc$wY`qx~#*rxkTeGq&0?wmgg zQ>crzkW2*s1PHG=gJ?22c+5`E3F%K^kKQKGJp(n#OIaHPJzZYk1T+1wRH%zcLd*=$ zF`>6CQpTIcUkG4v#QM?Xyi+eF$b{=FmRAN;H3vkyU>t<><}!26*>fS|5IG{o&iZH+ z*%-CQjDobkJx}{^96M1Wc=|aA9HU&vgn{g#7xv4J$g~6&JjfXJTu4y$5*9#RI?F(r zxag-7dI`O9STD)aOJ?XLGo^SXvsf?>1QVL|WfLv>%<42up0lO;;i;`8-~3Qiag@3P z`-H?zZ_^j&0EqI23ix%$x68ouu*K3E8dZ~=GCpU2WE^6jv@;W*>F+SIW|zCQ!g4oR zs!b0)1A|NWdBzc=w&!S1N^+o+xz;@$Gdw*QANTB+-P7gVpJunUpJl*)8pgAqxWW7; z*&oY33ciHwqb&X)v1A{W!o2O~bVafA!P59c(9;hlw|$m)^h2W{pNgcU?_g#!3f<26 z8P40XjoY$diWFx1wZPXhztC^X(F9u7%t3g|WUD->>to;u}#9$IlCdu^zv zqQ~iq9-kjdj}siiG-Jn}8Z3!pK2%GB7}^>vP372hNw6p<29)|IH&x@7Zpga%V|VoIDpd_U15YS6RO)0gIJ zyIb4N#kGBy7!S6?89P;I9Gre6G=BzQnYqEOE9Ylid3&~TB=6CjO0DSjoY2Zy`t3Qh zm(J9Rmd@0d&NQFwr*xiERyVOOOGE1>odhSnC|^kAW$8Ntk7hgklZ>J)y=bOh1nkT} z&ljCVY9SNY@6?Mj`w{}T(<8O#MSHA_EH7AJ6oyIu|M_~YW zu#`wvtBUz9HVBIoZ0}BWFy;s?PNNyFEJ@$d3Nbcr&*JQrfdK<{dYiL^4bpk&#JSUI zNfzmB8v|{&n1x?P8*9FkMh0B&p-AQ$iexU%@X|0sQ)%7}%hWR9e<5OCLNO1(y zW*M~uq%1MsL9}H0TV+>zGp<~kZ4~9??T6ilHbTMFN5RxbXX=m61ar;L{v^mcunRKI zCc-!x##Io6wui8k!lhdPc>!xtRtLHHW8%?|m^_WS`6&}OgOq^<;HgdiuM!gCFzz5N za;j^f*XNBRpz0~@#acni_%#_I2Q&WPo{v<dv`Wr6^m?P=$7w zw&@kx_Ls81BReg>D_9&aM_KKh_E$D`V9u#_B1XPeU9|bFKgV++%(ePVU#jt?Wo+ri z+KJlkH!(cj*s}2&|9l%cIxsqqR{T8=8lX=3s zF01{e@sm~KTTPF=r)v3D-?b?GTYVL4zes!5aEN5JrtB-M2K7>uF;uXsU14j4`)BVL z+-zymD-9;v<~kZH?=M>5J>G_wo2S2$COphnU_B&C?dXgWIbd)EeZNJ0o!Jl2ssRO^6cFd+Xj|&-8vpwP~lgCY-|m zrrp0UysaAWjXLa0`o~pNJ8W!7h{SxBf?X0UnGp;33gD_NE9}BRZOyj;#c7O`B%Gso z?~Hm|`=|Poo2YJ-rN;0P`7=x1Vr6L68WHUHcyba#G6}EAu2Ysw>Ux_RxVq9$Exb>k zm;E|>C%9g^@AbM84m|o#7rUJPiuaIG zi~HWRZq8Zi^AJjkKh7T4%FfEkzXbvSw;fr$AAXsrIIJ;86um!qFGkwk?(a-FKVWMp zqLw$n=dN4xrNcL)ZcWJHn_4#u{XcbUoDQEm&>@5o`5@MyD~|W220G&Vk^&uZeNL9> z3~?8|p2#xY@50<#gPcLKf7>~OcLyiN&`V|}&C`{8oH(2>X7I<~o{392%avg}5u>FHu+=gU zkHoin1#Qfqs&xLZ8Ko1wve;{j_oOcoj5}hUw1P_LomqVvVmnX^^9-~CAh4~{Ub|TG zDj%Q*YpKBqslomtgnY{f0-s~;IG;|bL68MdqXA`~MukVKYTuerb!+VXC$Zih!KQvB zWnrh?|6{Uoz^e*A-Yi>}+H44u;hDijo@)7Cl!FjC4!+m$;+hY?nVpTxdBp<{`D*1Y zi5=66eZeItt+|&E8VDhDag4EVKWSV;^<<#$6Hjflhw;PrL|o4(S0=8PaPex@+y!pl zUA)D+hr?x~P=Q9PfU=Qx6%%{570E)(JA0usMo zr2Z$(5dP`6Ju*ewt4e3pRi(FrjSq^~n_O0s#w+v6 zRVAsMxf*mF=62HJ&(&~>GJh=kK>s>4&3*rmqvI zwK09Fiq)YKAjsrV+&$CyjWkk%RZ>Ma&G}F)3XzsAWY(_2O#EaFELvETgg`oZM*7+6 zap_R2$Fpz^*W-*7y-^xbaHvt?kaVkRZ_j2rRl@A+ z*IV7&Z|-GkMfhOorLwJOW4ev`v;Jfb8|+9AotN{xv|!^YkVc6JsE#?tS4X4#(ol^b z3qmc<>1;fKBc9ZHV~>g;i4cdHn__%5fia;6yYL7GB^`9++QVS(DpY(bUj+>sS{b_0 zYi?1DOt&5NW+K0hN~_RnZ{0_TFSnoRu5k#9yv8w~W80ugTH!Spu}^5R;2?Az>?WIh zh0Obnr&Jz~{}wN;=y56Ck}@OSI27`ND^ecwM^LrM)DRf38b!6o4E6%i_NV|gI~q@& zk(!NeJjPp^g$BY!z4-;8{CeE95ROb}Z<@3c?iweJ#5*34rUpe+$IRCl$t^04@pw0Z z$eq!^wFbOM6dxr>9?C z_;Y*uwb9N_hb*_D3EK7r@kq&1XAwzI(R5JSJ|^t+49M7uOcr+9vLR_j3d@g0yMDR! z_unK=V$Xri7Hpg*(HCr%(_Z^`fbH18Dxz=1Yhqn`$1}LGKo6q@Qo}JBWn3geJ~15= z?H@Y3v*0T^uOzxV3-0LICa=3UtJl5mBl2~>;}b3=TRp1!Gbf7N+_^&-kL9Xcuj-Oj zoWHx03oR4ju^S^$;lL(}4dN_oE7H>7JjU%P%^ioOX2{wJF7RsGtJ0Ah*0#6Eid(Nb zhW|-z`!4xHJ+s#IH7XP=>cPGG_O=gQn2O=*>e2dhmuEQ~zUz2j!TZYkb6N7fjPGpT z6Zn?*=sg`ouRnJMAC`C)OwHckAlCtR&DNmY@KgFH?+D^|MV-b#u;>UIqt%o4Nbho| z$@eBH_WYC&n1ymFwf8Yn2aAr1AlCFs^ZAj$;)q%73aTAMUgsqT>OWw(V!>77!`be= zTP68TVBk8f>AU3CQtW!|d(ua(DjUtiH7S?Ya4!@KSop@|_ga96#OS>UAP66>o)8En zz}Kc!2VzQfR+yYsC#gqy_YQRrw&=*7eZQ7TBY^1jo+i>0w5nPM{@G4f+UT$@lgTcIkx9{X|z^V(T!gh zKYw?yP?}0>60TyTl_OABVb6pNB+4q61>Ap6rCFXvT4_?FJ#y2yal8O5@0OZ0jl{i6 zH7^wq(M8pOr=-5+-KzN%FzWdcevz2J<0DvTb%cO0+UZppa8uQNTN&Q|5qsVsR_}8H z%X6&dyV=aPEp_r+ckU|x1NqanMmbFhCZx11a&dvAXaGGNCi$;U+tWnA&UJKD--tc+ z;;zBnaNxBEosLY+^Vh&Y<_^gXIUixSN?TIGTga)>+?z@zsBm}hbiV7(P50lQf0h4U zP$fRZkwnqiw>}G|-Ad)jra?gat!!$=EeO`ox`ZsuM}Pxx)pi#AKM+H;Tc)<*x43sn zX{6)#^O46?aRkxjLy?Qxu+mf~`)5mL6TC%cVk$2=_1bM%9_#e%rg0%@t#a?F)AN$RYWDnK zvnY)7wG>S8wd9~Ji#Y6teUHk|&HQMMdnLNsRm)fjewB-ZYiRH{1P63w=}#}MgJhfdYHTyvK%c zmRgcdOr(sBM7oRBjOICH&bA{Ri$+Qi4RInIuf2NP9n(uU`DY5E<{k)o4mY0mlBilJ zxp}RXvf+JV%FbBfZ_1x7{1w@P6KCGFJHK>*&d)tS_uI_{zqs+V;pyS50C)@sDt*{n zy-wi1lddYRZmdV({_;;@xGjYvZ!R3M;(Ft@OgS`!?|InD#RhGoSt-k;lT54R0QlZH zbfHlww_0*pMCBg%UgK%J=}JhILo&C!Q>w@Azb4uATE%GGMFiAd!=|}uk963gGo6k) z$jOx41G@j2U{Q4=o%W<^mW6bcIm=ELAa1-^B7f6>X@eOVnpHZ;PH`fdB1xt2mus&U zk1`HDKpAhQjNgkXU-b`wY?qMIna9RT6ZtNSG|zWWhMPx4HSbdq{BfM*hS^2`9ElR8 zAZq>OiyEV;r0xdC>(XRo!KffYbhFebJ2(uxybQzv8&t0rbyo@`aoq) z&}H75apsq!?Ga5t?&1R4#AWxfUC@s{wEe11)x# zanKe!%&b9Xk(HBnb^SK9U(rO7)HV^ehL25()ew?FY82he#^WVtr)Qt^W~WCcYhFsY zsM)jCmiJNg+JIggIlj`MXA6~wl>j+Iq<*V8>2Hj|+AW;;01C9W z%l@Vk5K9$^>Hf5xZN%Co_P_f^sM77Sb_|k`-G!*I`zS*e zy3POR=*GP|S*`S|+F#40dU^XVX`M>1WhTnnJHj2YiBwa=Nw zWV`w%-=xG*tX$>@dDNO7veIukpwh45MR!8aVBo9NU**h&bDXO7#7^#s%xO`HZn6?R zdr&26=A{zFg%f3k6Gh9CsGvQn0w@a#$K#aGS-MHVui*qw`FtAjarRzGjcZ)h-UV*A z3fslZree>L`%zj`AI0&#oVcG`W^;b8iYEMF+T-3ss%Sa9DB4b1l5^U4jK-Dh^;X|| zyAAH4FgS@L!w7)`D~??jS*2N}i>uCDXs5a{oQm_zy0GVE5l?6J#Bg!bBA)TpUANiE z&rlc(rnA~NKc=JZQJG2OIIFkB26(~&iL+r*1_mC{nqHC0Zm+xlu&QPOFACFDYG<(} zoJF)=;ks`Vz;Slk=Mofme0hm~czTMZe9B9gKAz56^j?k3d_8GvWWyUtC-Q|Nn=7@$uYklQMk2 zGtvD=-uaYe3D3hkR=JY?|N0YcG5^%)aH`yCJWWjGr@ zu6wqLV6tAmV|IDEwy_gB66lPF|4{P96i-^q;xCVy+@TKzdL6z?;XL@)A;0a}T~pvS zAO7j*+^F3V^zVkI_FZh8VOgJEhtc2^@VFR<|6DOFeE&)D%QZ^36$Z|6Az=r43=^m6OP*S9DxmsQKsdKdALh zd!Tj)27_yAIj?@x{09qW><;jocD(2cLDnCo=-W}E47sO8y2w>I+n>IwNX{@Pvzv-7 z<|qp!(z!0L*UKG=8po7QDgWcYQibKNh`SiME3SU}(^s@hLCp7FQp~Mbem!z)Zne^0 zdh|nC&AV=^5Uy0YoNLVXOkDLKQt09P1Am?JxA=Z!Qeqmb8HlvZLO5yc2uF(qLs9|1 z{&NL#2TroL4o#qlPuhJgyrD~ z4R(aXc7)M(gtg%a_t_D|o{T^kX-8-dM<}!-v=9LXOe;;?@NGt^(fQg|;PEp?xu{MIPHAJ~3kcq_H$Ys#<5_Pa#+tyX?3@l#?nZ<^IO`_ijlvN9ZD zXIMst$iH+`L-TiIr7~#{s;eRxvgADrLzYzUPzfu{&A@@ANtMTu7;aZ-&+O7nZQ~YJ zxW>CXMUt-VqlEaX6C9HT^5_r5h`5%wqizoJ0BA1UYxP32q8eIb7oo5LxPSk#YSJFQ z?Iu+M`*4XdH|Sq<+LIRNn{Sk#Q0!5oHdA=6S;=j^8Qh9bmP-wXjCTWj-J$>zNXLLl zt>~j$|0V@ieRRJRvFeyn+ZCwoacGT7q=*}i1upPEOJkS%0A090+=c(CND79*C0VH% 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�fV5xQkzrn+5i4=#P(aB|#P3DP&BvzQ2g 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 z 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 Ao_%u3=hv0H=k8$&fr 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%0DW?u#ue1F+Sn+C- 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

>@>P9q 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˛CO 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 z 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⁣n)Ny7>8!7IU#<5I`su~m+nTfAqE~b3 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�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%0DCG(x~Hz>4m;_LNXMrJCc{q8 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%0AIhp5RNEkx5%yC%iV>giwkGl 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
>R<1|>xSM-3=Y*hH2he&YpA~26+buR|ALUe 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 literal 0 HcmV?d00001 diff --git a/t6/scripts/.vs/scripts/v17/.wsuo b/t6/scripts/.vs/scripts/v17/.wsuo new file mode 100644 index 0000000000000000000000000000000000000000..32c435d3786ebac14cbe74988d0dc0312e66727e GIT binary patch literal 28160 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 literal 0 HcmV?d00001 diff --git a/t6/scripts/AATs_Perks.gsc b/t6/scripts/AATs_Perks.gsc new file mode 100644 index 0000000..1625951 --- /dev/null +++ b/t6/scripts/AATs_Perks.gsc @@ -0,0 +1,3346 @@ +#include maps\mp\_utility; +#include common_scripts\utility; +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\gametypes_zm\_spawnlogic; +#include maps\mp\animscripts\traverse\shared; +#include maps\mp\animscripts\utility; +#include maps\mp\zombies\_load; +#include maps\mp\_createfx; +#include maps\mp\_music; +#include maps\mp\_busing; +#include maps\mp\_script_gen; +#include maps\mp\gametypes_zm\_globallogic_audio; +#include maps\mp\gametypes_zm\_tweakables; +#include maps\mp\_challenges; +#include maps\mp\gametypes_zm\_weapons; +#include maps\mp\_demo; +#include maps\mp\gametypes_zm\_hud_message; +#include maps\mp\gametypes_zm\_spawning; +#include maps\mp\gametypes_zm\_globallogic_utils; +#include maps\mp\gametypes_zm\_spectating; +#include maps\mp\gametypes_zm\_globallogic_spawn; +#include maps\mp\gametypes_zm\_globallogic_ui; +#include maps\mp\gametypes_zm\_hostmigration; +#include maps\mp\gametypes_zm\_globallogic_score; +#include maps\mp\gametypes_zm\_globallogic; +#include maps\mp\zombies\_zm; +#include maps\mp\zombies\_zm_ai_faller; +#include maps\mp\zombies\_zm_spawner; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\zombies\_zm_pers_upgrades; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\animscripts\zm_run; +#include maps\mp\animscripts\zm_death; +#include maps\mp\zombies\_zm_blockers; +#include maps\mp\animscripts\zm_shared; +#include maps\mp\animscripts\zm_utility; +#include maps\mp\zombies\_zm_ai_basic; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\zombies\_zm_net; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\gametypes_zm\_zm_gametype; +#include maps\mp\_visionset_mgr; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm_power; +#include maps\mp\zombies\_zm_server_throttle; +#include maps\mp\gametypes\_hud_util; +#include maps\mp\zombies\_zm_unitrigger; +#include maps\mp\zombies\_zm_zonemgr; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm_melee_weapon; +#include maps\mp\zombies\_zm_audio_announcer; +#include maps\mp\zombies\_zm_magicbox; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_ai_dogs; +#include maps\mp\zombies\_zm_game_module; +#include maps\mp\zombies\_zm_buildables; +#include codescripts\character; +#include maps\mp\zombies\_zm_weap_riotshield; +#include maps\mp\zombies\_zm_weap_riotshield_tomb; +#include maps\mp\zombies\_zm_weap_riotshield_prison; +#include maps\mp\zm_transit_bus; +#include maps\mp\zm_transit_utility; +#include maps\mp\zombies\_zm_equip_turret; +#include maps\mp\zombies\_zm_mgturret; +#include maps\mp\zombies\_zm_weap_jetgun; + +#include maps\mp\zombies\_zm_ai_sloth; +#include maps\mp\zombies\_zm_ai_sloth_ffotd; +#include maps\mp\zombies\_zm_ai_sloth_utility; +#include maps\mp\zombies\_zm_ai_sloth_magicbox; +#include maps\mp\zombies\_zm_ai_sloth_crawler; +#include maps\mp\zombies\_zm_ai_sloth_buildables; + +#include maps\mp\zombies\_zm_tombstone; +#include maps\mp\zombies\_zm_chugabud; + +#include maps\mp\zm_nuked_perks; + +#include maps\mp\zm_tomb_utility; +#include maps\mp\zm_tomb_gamemodes; +#include maps\mp\zm_tomb_fx; +#include maps\mp\zm_tomb_ffotd; +#include maps\mp\zm_tomb_tank; +#include maps\mp\zm_tomb_quest_fire; +#include maps\mp\zm_tomb_capture_zones; +#include maps\mp\zm_tomb_teleporter; +#include maps\mp\zm_tomb_giant_robot; +#include maps\mp\zm_tomb_amb; +#include maps\mp\zombies\_zm_ai_mechz; +#include maps\mp\zombies\_zm_ai_quadrotor; +#include maps\mp\zm_tomb_vo; +#include maps\mp\zombies\_zm_perk_divetonuke; +#include maps\mp\zombies\_zm_perk_electric_cherry; +#include maps\mp\zombies\_zm_weap_one_inch_punch; +#include maps\mp\zombies\_zm_weap_staff_fire; +#include maps\mp\zombies\_zm_weap_staff_water; +#include maps\mp\zombies\_zm_weap_staff_lightning; +#include maps\mp\zombies\_zm_weap_staff_air; +#include maps\mp\zm_tomb; +#include maps\mp\zm_tomb_achievement; +#include maps\mp\zm_tomb_distance_tracking; +#include maps\mp\zombies\_zm_magicbox_tomb; +#include maps\mp\zm_tomb_challenges; +#include maps\mp\zombies\_zm_perk_random; +#include maps\mp\_sticky_grenade; +#include maps\mp\zombies\_zm_weap_beacon; +#include maps\mp\zombies\_zm_weap_claymore; +#include maps\mp\zombies\_zm_weap_staff_revive; +#include maps\mp\zombies\_zm_weap_cymbal_monkey; +#include maps\mp\zm_tomb_ambient_scripts; +#include maps\mp\zm_tomb_dig; +#include maps\mp\zm_tomb_main_quest; +#include maps\mp\zm_tomb_ee_main; +#include maps\mp\zm_tomb_ee_side; +#include maps\mp\zm_tomb_chamber; +#include character\c_usa_dempsey_dlc4; +#include character\c_rus_nikolai_dlc4; +#include character\c_ger_richtofen_dlc4; +#include character\c_jap_takeo_dlc4; +#include maps\mp\zombies\_zm_powerup_zombie_blood; +#include maps\mp\zombies\_zm_devgui; +#include maps\mp\zombies\_zm_challenges; +main() +{ + replaceFunc( maps\mp\animscripts\zm_utility::wait_network_frame, ::wait_network_frame_override ); + replaceFunc( maps\mp\zombies\_zm_utility::wait_network_frame, ::wait_network_frame_override ); +// replaceFunc( maps\mp\zombies\_zm_afterlife::afterlife_give_loadout, ::afterlife_giveback); +// if(getdvar("mapname") != "zm_prison") //[ Hotfix ] disabled in motd because afterlife doesnt work with it +// register_player_damage_callback( ::player_aat_damage_respond ); //moved to main from init because of it not loading in origins + + maps\mp\zombies\_zm_spawner::register_zombie_damage_callback( ::aat_zombie_damage_response ); + +} + +init() +{ + if (level.script != "zm_prison") + { + maps\mp\zombies\_zm::register_player_damage_callback( ::playerdamagelastcheck ); + } + + + setDvar("isPanzer", ""); + setDvar("isBus", ""); + precacheshader("menu_mp_lobby_icon_film"); + precacheshader( "menu_mp_lobby_icon_customgamemode" ); + precacheshader( "waypoint_revive" ); + + precacheshader("specialty_quickrevive_zombies_pro"); +precacheshader( "specialty_marathon_zombies" ); + precacheshader("specialty_instakill_zombies"); + + precacheshader( "zom_icon_player_life" ); + precacheshader( "killiconheadshot" ); + precacheshader( "menu_lobby_icon_twitter" ); + precacheshader( "hud_grenadeicon" ); + precacheshader( "menu_mp_weapons_1911" ); + precacheshader( "menu_mp_lobby_icon_screenshot" ); + precacheshader( "damage_feedback" ); + precacheshader( "zombies_rank_1" ); + precacheshader( "zombies_rank_3" ); + precacheshader( "zombies_rank_2" ); + precacheshader( "zombies_rank_4" ); + precacheshader( "menu_mp_weapons_xm8" ); + precacheshader( "faction_cdc" ); + precacheshader( "menu_mp_weapons_hamr" ); + precacheshader( "zombies_rank_5" ); + precacheshader( "hud_icon_sticky_grenade" ); + precacheshader( "specialty_instakill_zombies" ); + precacheshader( "menu_mp_weapons_1911" ); + precacheshader( "hud_icon_colt" ); + precachemodel("p6_zm_buildable_sq_meteor"); + precachemodel( "collision_player_wall_512x512x10" ); + precachemodel( "collision_physics_512x512x10" ); + precachemodel( "t5_foliage_tree_burnt03" ); + precachemodel( "p_rus_door_roller" ); + precachemodel( "ch_tombstone1" ); + precachemodel( "collision_geo_256x256x10_standard" ); + precachemodel( "zombie_vending_tombstone_on" ); + precachemodel( "zombie_vending_revive_on" ); + precachemodel( "zombie_vending_sleight_on" ); + precachemodel( "zombie_vending_doubletap2_on" ); + precachemodel( "zombie_pickup_perk_bottle" ); + precachemodel( "zm_collision_perks1" ); + precachemodel( "p6_zm_screecher_hole" ); + precachemodel( "p_cub_door01_wood_fullsize" ); + precachemodel( "veh_t6_civ_microbus_dead" ); + precachemodel( "p_rus_door_white_window_plain_left" ); + if (level.script != "zm_prison") + { + level._effect["fx_zombie_cola_revive_on"] = loadfx( "misc/fx_zombie_cola_revive_on" ); + level._effect["fx_zombie_cola_dtap_on"] = loadfx( "misc/fx_zombie_cola_dtap_on" ); + } + + level._effect["fx_zombie_cola_on"] = loadfx( "misc/fx_zombie_cola_on" ); + if (!(level.script == "zm_tomb" || level.script == "zm_prison")) + { + level._effect["fx_zmb_wall_buy_taseknuck"] = loadfx( "maps/zombie/fx_zmb_wall_buy_taseknuck" ); + level._effect["fx_zmb_wall_buy_bowie"] = loadfx( "maps/zombie/fx_zmb_wall_buy_bowie" ); + } + // level._effect["fx_default_explosion"] = loadfx( "explosions/fx_default_explosion" ); + + + if( level.script == "zm_buried" || level.script == "zm_tomb" ) + { + level._effect["fx_default_explosion"] = level._effect[ "divetonuke_groundhit"]; + } + else + { + level._effect["fx_default_explosion"] = loadfx( "explosions/fx_default_explosion" ); + } + + + level.ta_vaultfee = 1000; + + if ( !isdefined( level.ta_tellerfee ) ) + level.ta_tellerfee = 1000; + + + // level.town = 1; + // level.diner = 0; + + isTown(); + + //level thread perk_machine_removal( "specialty_scavenger" ); + init_custom_map(); + + if(level.script != "zm_buried" && level.script != "zm_highrise" && level.script != "zm_tomb") + level.get_player_weapon_limit = ::custom_get_player_weapon_limit; + + level.zombie_last_stand = ::LastStand; + level.custom_vending_precaching = ::default_vending_precaching; + + + + + level.player_out_of_playable_area_monitor = 0; + level.perk_purchase_limit = 50; + +//--------------------------ENDCUSTOMPERKS-------------------------------------------------- + + + + + + + + + onplayerconnect_callback( ::watch_weapon_changes ); + +// if( getdvar( "mapname" ) == "zm_transit" && getdvar ( "g_gametype" ) == "zstandard") +// level._effect[ "jetgun_smoke_cloud" ] = loadfx( "weapon\thunder_gun\fx_thundergun_smoke_cloud" ); + + thread new_pap_trigger(); + level._poi_override = ::turned_zombie; + + +} + +wait_network_frame_override() +{ + wait .1; +} + + + +//-------------------CUSTOMPERK------------------------ + +onPlayerConnect(player) +{ + player thread onPlayerSpawned(); +} + +onPlayerSpawned() +{ + self endon( "disconnect" ); + level endon( "game_ended" ); + self waittill( "spawned_player" ); + //self.flags = xor(self.flags, 0x2000); + + self.bleedout_time = 30; + self.ignore_lava_damage = 0; + self.has_timeslip = 0; + self.savedaat = []; + self.shouldkeepperk = 1; + self.perkarray = []; + self.dying_wish_on_cooldown = 0; + self.perk_reminder = 0; + self.perk_count = 0; + self.num_perks = 0; + self.weapons_aat_cooldown = []; + self.weapons_aat_cooldown[0] = 0; + self.weapons_aat_cooldown[1] = 0; + self.weapons_aat_cooldown[2] = 0; + self.is_aat_blinking = 0; + self.aat_remaining_cooldown = 1; + self.aat_cooldown_duration = 1; + self.aat_color = (0, 0, 0); + self.aat_remaining_cooldown = []; + self.aat_remaining_cooldown[0] = 1; + self.aat_remaining_cooldown[1] = 1; + self.aat_remaining_cooldown[2] = 1; + self.aat_cooldown_duration = []; + self.aat_cooldown_duration[0] = 1; + self.aat_cooldown_duration[1] = 1; + self.aat_cooldown_duration[2] = 1; + + + self thread removeperkshader(); + self thread perkboughtcheck(); + self thread damagehitmarker(); + + +/* if (level.script == "zm_prison") + { + for (;;) + { + // perk_array = maps\mp\zombies\_zm_perks::get_perk_array( 1 ); + if (isdefined(self.perkarray)) + { + for ( i = 0; i < self.perkarray.size; i++ ) + { + iprintln(self.perkarray[i].name); + iprintln(self.perkarray[i]); + // self unsetperk( perk ); + // self set_perk_clientfield( perk, 0 ); + } + wait 5; + } + } + }*/ +} + + + +/*afterlife_giveback() +{ + self takeallweapons(); + loadout = self.loadout; + primaries = self getweaponslistprimaries(); + + if ( loadout.weapons.size > 1 || primaries.size > 1 ) + { + foreach ( weapon in primaries ) + self takeweapon( weapon ); + } + + for ( i = 0; i < loadout.weapons.size; i++ ) + { + if ( !isdefined( loadout.weapons[i] ) ) + continue; + + if ( loadout.weapons[i] == "none" ) + continue; + + weapon = loadout.weapons[i]; + stock_amount = loadout.stockcount[i]; + clip_amount = loadout.clipcount[i]; + + if ( !self hasweapon( weapon ) ) + { + self giveweapon( weapon, 0, self maps\mp\zombies\_zm_weapons::get_pack_a_punch_weapon_options( weapon ) ); + self setweaponammostock( weapon, stock_amount ); + self setweaponammoclip( weapon, clip_amount ); + + if ( weaponisdualwield( weapon ) ) + { + weapon_dw = weapondualwieldweaponname( weapon ); + self setweaponammoclip( weapon_dw, loadout.clipcount2[i] ); + } + + weapon_alt = weaponaltweaponname( weapon ); + + if ( weapon_alt != "none" ) + { + self setweaponammostock( weapon_alt, loadout.stockcountalt[i] ); + self setweaponammoclip( weapon_alt, loadout.clipcountalt[i] ); + } + } + } + + self setspawnweapon( loadout.weapons[loadout.current_weapon] ); + self switchtoweaponimmediate( loadout.weapons[loadout.current_weapon] ); + + if ( isdefined( self get_player_melee_weapon() ) ) + self giveweapon( self get_player_melee_weapon() ); + + self maps\mp\zombies\_zm_equipment::equipment_give( self.loadout.equipment ); + + if ( isdefined( loadout.hasclaymore ) && loadout.hasclaymore && !self hasweapon( "claymore_zm" ) ) + { + self giveweapon( "claymore_zm" ); + self set_player_placeable_mine( "claymore_zm" ); + self setactionslot( 4, "weapon", "claymore_zm" ); + self setweaponammoclip( "claymore_zm", loadout.claymoreclip ); + } + + if ( isdefined( loadout.hasemp ) && loadout.hasemp ) + { + self giveweapon( "emp_grenade_zm" ); + self setweaponammoclip( "emp_grenade_zm", loadout.empclip ); + } + + if ( isdefined( loadout.hastomahawk ) && loadout.hastomahawk ) + { + self giveweapon( self.current_tomahawk_weapon ); + self set_player_tactical_grenade( self.current_tomahawk_weapon ); + self setclientfieldtoplayer( "tomahawk_in_use", 1 ); + } + + self.score = loadout.score; + perk_array = maps\mp\zombies\_zm_perks::get_perk_array( 1 ); + + for ( i = 0; i < perk_array.size; i++ ) + { + perk = perk_array[i]; + self unsetperk( perk ); + self set_perk_clientfield( perk, 0 ); + } + + if ( isdefined( self.keep_perks ) && self.keep_perks && isdefined( loadout.perks ) && loadout.perks.size > 0 ) + { + for ( i = 0; i < loadout.perks.size; i++ ) + { + if ( self hasperk( loadout.perks[i] ) ) + continue; + + if ( loadout.perks[i] == "specialty_quickrevive" && flag( "solo_game" ) ) + level.solo_game_free_player_quickrevive = 1; + + if ( loadout.perks[i] == "specialty_finalstand" ) + continue; + + maps\mp\zombies\_zm_perks::give_perk( loadout.perks[i] ); + } + } + + self.keep_perks = undefined; + self set_player_lethal_grenade( self.loadout.lethal_grenade ); + + if ( loadout.grenade > 0 ) + { + curgrenadecount = 0; + + if ( self hasweapon( self get_player_lethal_grenade() ) ) + self getweaponammoclip( self get_player_lethal_grenade() ); + else + self giveweapon( self get_player_lethal_grenade() ); + + self setweaponammoclip( self get_player_lethal_grenade(), loadout.grenade + curgrenadecount ); + } +}*/ + + +damagehitmarker() +{ + self endon ("disconnect"); + level endon( "end_game" ); + self thread startwaiting(); + self.hitmarker = newdamageindicatorhudelem( self ); + self.hitmarker.horzalign = "center"; + self.hitmarker.vertalign = "middle"; + self.hitmarker.x = -12; + self.hitmarker.y = -12; + self.hitmarker.alpha = 0; + self.hitmarker setshader( "damage_feedback", 24, 48 ); + +} + +startwaiting() +{ + self endon ("disconnect"); + level endon( "end_game" ); + while( 1 ) + { + foreach( zombie in getaiarray( level.zombie_team ) ) + { + if( !(IsDefined( zombie.waitingfordamage )) ) + { + zombie thread hitmark(); + } + } + wait 0.25; + } +} + +hitmark() +{ + self endon ("disconnect"); + level endon( "end_game" ); + self endon( "killed" ); + + self.waitingfordamage = 1; + while( 1 ) + { + self waittill( "damage", amount, attacker, dir, point, mod ); + attacker.hitmarker.alpha = 0; + if(!isDefined(attacker.aat_actived)) + attacker.aat_actived = 0; + if( isplayer( attacker ) ) + { + if(attacker.aat_actived) + { + attacker.hitmarker.alpha = 1; + for(i = 0; i < 20; i++) + { + r = randomfloatrange(0.1, 0.9); + g = randomfloatrange(0.1, 0.9); + b = randomfloatrange(0.1, 0.9); + attacker.hitmarker.color = ( r, g, b ); + if(i > 5) + attacker.hitmarker.alpha -= .075; + + wait .1; + } + attacker.hitmarker.alpha = 0; + attacker.aat_actived = 0; + self.waitingfordamage = 0; + break; + } + if( isalive( self ) ) + { + attacker.hitmarker.color = ( 1, 1, 1 ); + attacker.hitmarker.alpha = 1; + attacker.hitmarker fadeovertime( 1 ); + attacker.hitmarker.alpha = 0; + } + else + { + attacker.hitmarker.color = ( 1, 0, 0 ); + attacker.hitmarker.alpha = 1; + attacker.hitmarker fadeovertime( 1 ); + attacker.hitmarker.alpha = 0; + self notify( "killed" ); + } + } + } +} + + + + +init_custom_map() +{ + if( level.script == "zm_transit" ) + { + if (getdvar("net_port") != "30011") + { + perk_system( "script_model", ( 901.86, -1575.574, -47.875 ), "zombie_vending_tombstone_on", ( 0, 180, 0 ), "custom", "mus_perks_deadshot_sting", "^8Widow's Wine^7", 4000, "tombstone_light", "WIDOWS_WINE" ); + perk_system( "script_model", ( 450, -300.574, -61.875 ), "zombie_vending_tombstone_on", ( 0, 45, 0 ), "custom", "mus_perks_packa_sting", "^5Electric ^1Cherry^7", 2000, "tombstone_light", "ELECTRIC_CHERRY" ); // 613,-250,z 0,0,0 + perk_system( "script_model", ( 1069, -1133, 120.125 ), "zombie_vending_tombstone_on", ( 0, 180, 0 ), "custom", "mus_perks_doubletap_sting", "^6Time Slip^7", 2500, "tombstone_light", "Time_Slip" ); + perk_system( "script_model", ( 1823.86, 670.574, -55.875 ), "zombie_vending_tombstone_on", ( 0, 45, 0 ), "custom", "mus_perks_doubletap_sting", "^2Mule Kick^7", 4000, "tombstone_light", "MULE" ); + perk_system( "script_model", ( 840, 603.809, -40.875 ), "zombie_vending_tombstone_on", ( 0, 0, 0 ), "custom", "mus_perks_packa_sting", "^6PhD Flopper^7", 2500, "tombstone_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( 2358, -87, -55.875 ), "zombie_vending_tombstone_on", ( 0, -90, 0 ), "custom", "mus_perks_doubletap_sting", "^5Downer's Delight^7", 2000, "tombstone_light", "Downers_Delight" ); + } + perk_system( "script_model", ( 1856, -810.722, -55.875), "zombie_vending_tombstone_on", ( 0, 180, 0 ), "custom", "mus_perks_deadshot_sting", "^5Momentum ^3Mocha^7", 4000, "tombstone_light", "Momentum_Mocha" ); + perk_system( "script_model", ( 2460, -780, -55.875 ), "zombie_vending_tombstone_on", ( 0, 225, 0 ), "custom", "mus_perks_doubletap_sting", "^1Burn Heart^7", 2500, "jugger_light", "Burn_Heart" ); + perk_system( "script_model", ( 2015, 858, -56.875 ), "zombie_vending_tombstone_on", ( 0, -90, 0 ), "custom", "mus_perks_doubletap_sting", "^5Dying Wish^7", 6000, "tombstone_light", "Dying_Wish" ); + perk_system( "script_model", ( 559, -1364, 120.125 ), "zombie_vending_tombstone_on", ( 0, 180, 0 ), "custom", "mus_perks_doubletap_sting", "^9Ammo Regen^7", 3000, "tombstone_light", "Ammo_Regen" ); + perk_system( "script_model", ( 1971.3, -144.641, -55.875 ), "zombie_vending_jugg_on", ( 0, 0, 0 ), "custom", "mus_perks_doubletap_sting", "^9Bandolier Bandit^7", 3500, "tombstone_light", "Bandolier_Bandit" ); + } + if( level.script == "zm_highrise") + { + perk_system( "script_model", ( 1884.42, 491.946, 1298.72), "zombie_vending_jugg_on", ( 0, 418.728, 0 ), "custom", "mus_perks_deadshot_sting", "^5Momentum ^3Mocha^7", 4000, "tombstone_light", "Momentum_Mocha" ); +// perk_system( "script_model", ( 2764.64, 1868.03, 1391.01 ), "zombie_vending_jugg_on", ( 0, 384.236, 0 ), "custom", "mus_perks_doubletap_sting", "^1Burn Heart^7", 2500, "jugger_light", "Burn_Heart" ); + perk_system( "script_model", ( 1978.25, 597.657, 2704.13 ), "zombie_vending_jugg_on", ( 0, 329.291, 0 ), "custom", "mus_perks_deadshot_sting", "^8Widow's Wine^7", 4000, "tombstone_light", "WIDOWS_WINE" ); +// perk_system( "script_model", ( 1415.64, 2108.36, 3220.26 ), "zombie_vending_jugg_on", ( 0, 406.661, 0 ), "custom", "mus_perks_packa_sting", "^5Electric ^1Cherry^7", 2000, "tombstone_light", "ELECTRIC_CHERRY" ); // 613,-250,z 0,0,0 + perk_system( "script_model", ( 1901.97, 1431.36, 3216.13 ), "zombie_vending_jugg_on", ( 0, 404.762, 0 ), "custom", "mus_perks_doubletap_sting", "^6Time Slip^7", 2500, "tombstone_light", "Time_Slip" ); +// perk_system( "script_model", ( 1891.64, 1119.64, 3048.36 ), "zombie_vending_jugg_on", ( 0, 45, 0 ), "custom", "mus_perks_doubletap_sting", "^2Mule Kick^7", 4000, "tombstone_light", "MULE" ); + perk_system( "script_model", ( 1429.29, -453.397, 2880.13 ), "zombie_vending_jugg_on", ( 0, 149.1426, 0 ), "custom", "mus_perks_packa_sting", "^6PhD Flopper^7", 2500, "tombstone_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( 1109.64, 2701.36, 3043.82 ), "zombie_vending_jugg_on", ( 0, 394.926, 0 ), "custom", "mus_perks_doubletap_sting", "^5Downer's Delight^7", 2000, "tombstone_light", "Downers_Delight" ); + perk_system( "script_model", ( 1706.28, 1055.64, 3395.1 ), "zombie_vending_jugg_on", ( 0, 180, 0 ), "custom", "mus_perks_doubletap_sting", "^5Dying Wish^7", 6000, "tombstone_light", "Dying_Wish" ); + perk_system( "script_model", ( 2269.17, 182.377, 2880.13 ), "zombie_vending_jugg_on", ( 0, 418.596, 0 ), "custom", "mus_perks_doubletap_sting", "^9Ammo Regen^7", 3000, "tombstone_light", "Ammo_Regen" ); + perk_system( "script_model", ( 1565.64, 1897.78, 3402.84 ), "zombie_vending_jugg_on", ( 0, 90, 0 ), "custom", "mus_perks_doubletap_sting", "^9Bandolier Bandit^7", 3500, "tombstone_light", "Bandolier_Bandit" ); + } + if( level.script == "zm_buried") + { + perk_system( "script_model", ( 1618.14, 1513.46, 200.62), "zombie_vending_jugg_on", ( 0, 250.147, 0 ), "custom", "mus_perks_deadshot_sting", "^5Momentum ^3Mocha^7", 4000, "sleight_light", "Momentum_Mocha" ); +// perk_system( "script_model", ( -1176.36, 508.26, 144.125 ), "zombie_vending_jugg_on", ( 0, 448.269, 0 ), "custom", "mus_perks_doubletap_sting", "^1Burn Heart^7", 2500, "sleight_light", "Burn_Heart" ); + perk_system( "script_model", ( -1176.36, 510.625, 144.125 ), "zombie_vending_jugg_on", ( 0, 449.412, 0 ), "custom", "mus_perks_deadshot_sting", "^8Widow's Wine^7", 4000, "sleight_light", "WIDOWS_WINE" ); +// perk_system( "script_model", ( -448.859, 131.435, 143.491 ), "zombie_vending_jugg_on", ( 0, 180.3, 0 ), "custom", "mus_perks_packa_sting", "^5Electric ^1Cherry^7", 2000, "sleight_light", "ELECTRIC_CHERRY" ); // 613,-250,z 0,0,0 + perk_system( "script_model", ( 890.359, -840.206, -22.8006 ), "zombie_vending_jugg_on", ( 0, 270.367, 0 ), "custom", "mus_perks_doubletap_sting", "^6Time Slip^7", 2500, "sleight_light", "Time_Slip" ); +// perk_system( "script_model", ( 1891.64, 1119.64, 3048.36 ), "zombie_vending_jugg_on", ( 0, 45, 0 ), "custom", "mus_perks_doubletap_sting", "^2Mule Kick^7", 4000, "sleight_light", "MULE" ); + perk_system( "script_model", ( 572.507, -712.359, 149.95 ), "zombie_vending_jugg_on", ( 0, 178.4505, 0 ), "custom", "mus_perks_packa_sting", "^6PhD Flopper^7", 2500, "sleight_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( 488.324, 727.641, 176.125 ), "zombie_vending_jugg_on", ( 0, 178.9998, 0 ), "custom", "mus_perks_doubletap_sting", "^5Downer's Delight^7", 2000, "sleight_light", "Downers_Delight" ); + perk_system( "script_model", ( -1298.32, -837.178, -23.875 ), "zombie_vending_jugg_on", ( 0, 91.37286, 0 ), "custom", "mus_perks_doubletap_sting", "^5Dying Wish^7", 6000, "sleight_light", "Dying_Wish" ); + perk_system( "script_model", ( -122.161, -1469.21, 168.125 ), "zombie_vending_jugg_on", ( 0, 448.841, 0 ), "custom", "mus_perks_doubletap_sting", "^9Ammo Regen^7", 3000, "sleight_light", "Ammo_Regen" ); + perk_system( "script_model", ( 1195.22, 1493.46, -19.875 ), "zombie_vending_jugg_on", ( 0, -20, 0 ), "custom", "mus_perks_deadshot_sting", "^9Bandolier Bandit^7", 3500, "sleight_light", "Bandolier_Bandit" ); + } + if( level.script == "zm_nuked") + { + perk_system( "script_model", ( 28.8155, -356.18, -65.8346 ), "zombie_vending_jugg_on", ( 0, 129.8755, 0 ), "custom", "mus_perks_deadshot_sting", "^5Momentum ^3Mocha^7", 4000, "sleight_light", "Momentum_Mocha" ); +// perk_system( "script_model", ( ), "zombie_vending_jugg_on", ( ), "custom", "mus_perks_doubletap_sting", "^1Burn Heart^7", 2500, "sleight_light", "Burn_Heart" ); + perk_system( "script_model", ( -954.194, 714.594, 84.0385 ), "zombie_vending_jugg_on", ( 0, 429.46, 0 ), "custom", "mus_perks_deadshot_sting", "^8Widow's Wine^7", 4000, "sleight_light", "WIDOWS_WINE" ); + perk_system( "script_model", ( 683.524, 618.635, -56.875 ), "zombie_vending_jugg_on", ( 0, 102.5635, 0 ), "custom", "mus_perks_packa_sting", "^5Electric ^1Cherry^7", 2000, "sleight_light", "ELECTRIC_CHERRY" ); // 613,-250,z 0,0,0 + perk_system( "script_model", ( 1420.35, -21.4313, -63.8849 ), "zombie_vending_jugg_on", ( 0, 194.085, 0 ), "custom", "mus_perks_doubletap_sting", "^6Time Slip^7", 2500, "sleight_light", "Time_Slip" ); + perk_system( "script_model", ( 618.292, -188.322, -56.3686 ), "zombie_vending_jugg_on", ( 0, 105.5011, 0 ), "custom", "mus_perks_doubletap_sting", "^2Mule Kick^7", 4000, "sleight_light", "MULE" ); + perk_system( "script_model", ( 1152.5, 160.6, 79.125 ), "zombie_vending_jugg_on", ( 0, 392.541, 0 ), "custom", "mus_perks_packa_sting", "^6PhD Flopper^7", 2500, "sleight_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( 156.738, 513.899, -62.3141 ), "zombie_vending_jugg_on", ( 0, 101.8164, 0 ), "custom", "mus_perks_doubletap_sting", "^5Downer's Delight^7", 2000, "sleight_light", "Downers_Delight" ); + perk_system( "script_model", ( -646.863, 271.522, -55.875 ), "zombie_vending_jugg_on", ( 0, 160.8405, 0 ), "custom", "mus_perks_doubletap_sting", "^5Dying Wish^7", 6000, "sleight_light", "Dying_Wish" ); + perk_system( "script_model", ( -1582.46, 112.604, -63.2092 ), "zombie_vending_jugg_on", ( 0, 250.829, 0 ), "custom", "mus_perks_doubletap_sting", "^9Ammo Regen^7", 3000, "sleight_light", "Ammo_Regen" ); + perk_system( "script_model", ( -229.945, 999.865, -63.875 ), "zombie_vending_jugg_on", ( 0, 25, 0 ), "custom", "mus_perks_deadshot_sting", "^9Bandolier Bandit^7", 3500, "sleight_light", "Bandolier_Bandit" ); + } + if( level.script == "zm_tomb") + { + perk_system( "script_model", ( 184.995, -2422.49, 50.125), "zombie_vending_jugg_on", ( 0, 369.091, 0 ), "custom", "mus_perks_deadshot_sting", "^5Momentum ^3Mocha^7", 4000, "sleight_light", "Momentum_Mocha" ); + perk_system( "script_model", ( 160.359, 3781.17, -351.875 ), "zombie_vending_jugg_on", ( 0, 266.122, 0 ), "custom", "mus_perks_deadshot_sting", "^8Widow's Wine^7", 4000, "sleight_light", "WIDOWS_WINE" ); + perk_system( "script_model", ( 375.771, 2119.22, -122.951 ), "zombie_vending_jugg_on", ( 0, 179.5935, 0 ), "custom", "mus_perks_doubletap_sting", "^6Time Slip^7", 2500, "sleight_light", "Time_Slip" ); + //perk_system( "script_model", ( -335.604, -187.006, 325.273 ), "zombie_vending_jugg_on", ( 0, 132.9565, 0 ), "custom", "mus_perks_packa_sting", "^6PhD Flopper^7", 2500, "sleight_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( 924.47, 360.72, 131.005 ), "zombie_vending_jugg_on", ( 0, 373.266, 0 ), "custom", "mus_perks_doubletap_sting", "^5Downer's Delight^7", 2000, "sleight_light", "Downers_Delight" ); + perk_system( "script_model", ( 1345.09, -3822.62, 302.125 ), "zombie_vending_jugg_on", ( 0, 270.593, 0 ), "custom", "mus_perks_doubletap_sting", "^5Dying Wish^7", 6000, "sleight_light", "Dying_Wish" ); + perk_system( "script_model", ( 2972.36, 5218.91, -378.566 ), "zombie_vending_jugg_on", ( 0, 270.379, 0 ), "custom", "mus_perks_doubletap_sting", "^9Ammo Regen^7", 3000, "sleight_light", "Ammo_Regen" ); + perk_system( "script_model", ( -104.105, -765.843, 224.125 ), "zombie_vending_jugg_on", ( 0, 90, 0 ), "custom", "mus_perks_deadshot_sting", "^9Bandolier Bandit^7", 3500, "sleight_light", "Bandolier_Bandit" ); + } + if( level.script == "zm_prison") + { + perk_system( "script_model", ( 3763.64, 9669.99, 1704.13 ), "p6_zm_al_vending_jugg_on", ( 0, 90, 0 ), "custom", "mus_perks_deadshot_sting", "^8Widow's Wine^7", 4000, "sleight_light", "WIDOWS_WINE" ); + perk_system( "script_model", ( 2160.71, 9247.64, 1558.13 ), "p6_zm_al_vending_jugg_on", ( 0, 179.1815, 0 ), "custom", "mus_perks_doubletap_sting", "^6Time Slip^7", 2500, "sleight_light", "Time_Slip" ); + perk_system( "script_model", ( 597.633, 8546.86, 832.125 ), "p6_zm_al_vending_jugg_on", ( 0, 221.984, 0 ), "custom", "mus_perks_doubletap_sting", "^2Mule Kick^7", 4000, "sleight_light", "MULE" ); + perk_system( "script_model", ( 456.359, 8679.51, 1128.13 ), "p6_zm_al_vending_jugg_on", ( 0, 269.533, 0 ), "custom", "mus_perks_packa_sting", "^6PhD Flopper^7", 2500, "sleight_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( -685.943, 9199.64, 1336.13 ), "p6_zm_al_vending_jugg_on", ( 0, 178.5443, 0 ), "custom", "mus_perks_doubletap_sting", "^5Downer's Delight^7", 2000, "sleight_light", "Downers_Delight" ); + perk_system( "script_model", ( 2998.88, 10048.4, 1336.3 ), "p6_zm_al_vending_jugg_on", ( 0, 357.896, 0 ), "custom", "mus_perks_doubletap_sting", "^5Dying Wish^7", 6000, "sleight_light", "Dying_Wish" ); + perk_system( "script_model", ( 1367.28, 10096.4, 1128.13 ), "p6_zm_al_vending_jugg_on", ( 0, 358.687, 0 ), "custom", "mus_perks_doubletap_sting", "^9Ammo Regen^7", 3000, "sleight_light", "Ammo_Regen" ); + + wait 0.1; + if (check_for_botb_port() == true) + { + perk_system( "script_model", ( -1928, -3382, -8448 ), "p6_zm_al_vending_jugg_on", ( 0, 90, 0 ), "custom", "mus_perks_deadshot_sting", "^5Momentum ^3Mocha^7", 4000, "sleight_light", "Momentum_Mocha" ); + perk_system( "script_model", ( -1916, -3786, -8448 ), "p6_zm_al_vending_jugg_on", ( 0, 90, 0 ), "custom", "mus_perks_deadshot_sting", "^9Bandolier Bandit^7", 3500, "sleight_light", "Bandolier_Bandit" ); + } + else + { + perk_system( "script_model", ( -1344.65, 5598.31, -71.875 ), "p6_zm_al_vending_jugg_on", ( 0, 98.34412, 0 ), "custom", "mus_perks_deadshot_sting", "^5Momentum ^3Mocha^7", 4000, "sleight_light", "Momentum_Mocha" ); + perk_system( "script_model", ( 1418.77, 9047.64, 1336.13 ), "p6_zm_al_vending_jugg_on", ( 0, 180, 0 ), "custom", "mus_perks_deadshot_sting", "^9Bandolier Bandit^7", 3500, "sleight_light", "Bandolier_Bandit" ); + } + } +} + +play_fx( fx ) +{ + playfxontag( level._effect[ fx ], self, "tag_origin" ); +} + +defaulth_vending_precaching() +{ + level._effect[ "sleight_light" ] = loadfx( "misc/fx_zombie_cola_on" ); + level._effect[ "tombstone_light" ] = loadfx( "misc/fx_zombie_cola_on" ); + level._effect[ "revive_light" ] = loadfx( "misc/fx_zombie_cola_revive_on" ); + level._effect[ "marathon_light" ] = loadfx( "maps/zombie/fx_zmb_cola_staminup_on" ); + level._effect[ "jugger_light" ] = loadfx( "misc/fx_zombie_cola_jugg_on" ); + level._effect[ "doubletap_light" ] = loadfx( "misc/fx_zombie_cola_dtap_on" ); + level._effect[ "deadshot_light" ] = loadfx( "misc/fx_zombie_cola_dtap_on" ); + level._effect[ "additionalprimaryweapon_light" ] = loadfx( "misc/fx_zombie_cola_arsenal_on" ); + level._effect[ "packapunch_fx" ] = loadfx( "maps/zombie/fx_zombie_packapunch" ); + level._effect[ "wall_taseknuck" ] = loadfx( "maps/zombie/fx_zmb_wall_buy_taseknuck" ); +} + + +playchalkfx(effect, origin, angles) +{ + fx = SpawnFX(level._effect[ effect ], origin,AnglesToForward(angles),AnglesToUp(angles)); + TriggerFX(fx); + level waittill("connected", player); + fx Delete(); +} + + + +perk_system( script, pos, model, angles, type, sound, name, cost, fx, perk) +{ + col = spawn( script, pos); + col setmodel( model ); + col.angles = angles; + x = spawn( script, pos ); + x setmodel( "zm_collision_perks1" ); + x.angles = angles; + col thread buy_system( perk, sound, name, cost, type ); + col thread play_fx( fx ); +} + +buy_system( perk, sound, name, cost, type ) +{ + level endon("end_game"); + self endon("disconnect"); + self endon( "game_ended" ); + while( 1 ) + { + foreach( player in level.players ) + { + if(!isdefined(player.machine_is_in_use) || player.machine_is_in_use == 0) + { + if( distance( self.origin, player.origin ) <= 70 ) + { + if (check_for_botb_port() == true) + { + if (name == "^9Bandolier Bandit^7") + { + cost = 0; + player thread SpawnHint( self.origin, 30, 30, "HINT_ACTIVATE", "Hold ^3&&1^7 for ^5Super ^9Bandolier^7 [Cost: ^3-35 percent Speed^7]\n^1 ^1Permanent Debuff^7" ); + } + else if (name == "^5Momentum ^3Mocha^7") + { + cost = 0; + player thread SpawnHint( self.origin, 30, 30, "HINT_ACTIVATE", "Hold ^3&&1^7 for ^5Super ^3Mocha^7 [Cost: ^1HP set to 100^7]\n ^1Permanent Debuff^7" ); + } + } + else + { + player thread SpawnHint( self.origin, 30, 30, "HINT_ACTIVATE", "Hold ^3&&1^7 for " + name + " [Cost: " + cost + "]" ); + } + if(player usebuttonpressed() && !player hasperk(perk) && !player hascustomperk(perk) && player.score >= cost && !player maps\mp\zombies\_zm_laststand::player_is_in_laststand()) + { + if (check_for_botb_port() == true) + { + if (name == "^9Bandolier Bandit^7") + { + player thread speed_debuff(); + } + else if (name == "^5Momentum ^3Mocha^7") + { + player thread hp_debuff(); + } + } + player.machine_is_in_use = 1; + player playsound( "zmb_cha_ching" ); + player.score -= cost; + player playsound( sound ); + player thread drawshader_and_shadermove( perk, 1, 1, type ); + wait 4; + player.machine_is_in_use = 0; + } + else + { + if( player usebuttonpressed() && player.score < cost ) + { + player maps\mp\zombies\_zm_audio::create_and_play_dialog( "general", "perk_deny", undefined, 0 ); + } + } + } + } + } + wait 0.1; + } +} + +speed_debuff() +{ + if (!(isdefined(self.old_speed))) + self.old_speed = self GetMoveSpeedScale(); + for(;;) + { + if (!isdefined(level.final_wave)) + self SetMoveSpeedScale(self.old_speed * 0.65); + wait 1; + } +} + +hp_debuff() +{ + self.old_maxhealth = self.maxhealth; + self.old_health = self.health; + + self.maxhealth = 100; + self.health = 100; + + for (;;) + { + if (self.maxhealth != 100) + { + self.maxhealth = 100; + self.health = 100; + } + wait 1; + } +} + +hascustomperk(perk) +{ + for(i = 0; i < self.perkarray.size; i++) + { + if(self.perkarray[i].name == perk) + { + return 1; + } + } + return 0; +} + +removeperkshader() +{ + self endon ("disconnect"); + level endon( "end_game" ); + common_scripts\utility::flag_wait( "initial_blackscreen_passed" ); + for(;;) + { + for (;;) + { + if (self maps\mp\zombies\_zm_laststand::player_is_in_laststand() || self.sessionstate == "spectator") + { + if (level.script == "zm_prison") + { + if (self.shouldkeepperk == 0) + { + if (isdefined(self.has_bandolier) && self.has_bandolier == 1) + { + self.has_bandolier = 0; + self thread bandolier(); + } + + self.num_perks = 0; + self.perk_reminder = 0; + self.perk_count = 0; + self.dying_wish_on_cooldown = 0; + self removeallcustomshader(); + self.perkarray = []; + self notify( "stopcustomperk" ); + self.bleedout_time = 30; + self.ignore_lava_damage = 0; + self setclientfieldtoplayer( "deadshot_perk", 0 ); + self.shouldkeepperk = 1; + wait 0.1; + /*if (isdefined(self.old_health) && isdefined(self.old_maxhealth)) + { + self.maxhealth = self.old_maxhealth; + self.health = self.old_health; + } + if (isdefined(self.old_speed)) + { + self SetMoveSpeedScale(self.old_speed); + }*/ + } + } + else + { + if (isdefined(self.has_bandolier) && self.has_bandolier == 1) + { + self.has_bandolier = 0; + self thread bandolier(); + } + self.num_perks = 0; + self.perk_reminder = 0; + self.perk_count = 0; + self.dying_wish_on_cooldown = 0; + self removeallcustomshader(); + self.perkarray = []; + self notify( "stopcustomperk" ); + self.has_timeslip = 0; + self.bleedout_time = 30; + self.ignore_lava_damage = 0; + self setclientfieldtoplayer( "deadshot_perk", 0 ); + self.shouldkeepperk = 1; + } + break; + } + wait 1; + } + for (;;) + { + if (!(self maps\mp\zombies\_zm_laststand::player_is_in_laststand()) && self.sessionstate != "spectator") + break; + wait 1; + } + wait 1; + } +} + +removeallcustomshader() +{ + for(i = 0; i < self.perkarray.size; i++) + { + self.perkarray[i] destroy(); + } +} + +drawshader( shader, x, y, width, height, color, alpha, sort ) +{ + level endon("end_game"); + self endon("disconnect"); + hud = newclienthudelem( self ); + hud.elemtype = "icon"; + hud.color = color; + hud.alpha = alpha; + hud.sort = sort; + hud.children = []; + hud.hidewheninmenu = 1; + hud setparent( level.uiparent ); + hud setshader( shader, width, height ); + hud.x = x; + hud.y = y; + return hud; +} + +perkboughtcheck() +{ + self endon("death"); + self endon("disconnect"); + for(;;) + { + self.perk_reminder = self.num_perks; + self waittill("perk_acquired"); + n = 1; + if(!(self.num_perks > self.perk_reminder)) + { + n = (self.num_perks - self.perk_reminder); + self.num_perks = (self.perk_reminder + n); + } + self.perk_reminder = self.num_perks; + self.perk_count += n; + self drawshader_and_shadermove("none", 0, 0, "normal"); //modified to remove perk alignement since 2 perk lines Added "normal" for type check + } +} + +drawshader_and_shadermove(perk, custom, print, type) +{ + level endon("end_game"); + self endon("disconnect"); + if(custom) + { + if (!isdefined(self.has_timeslip) || self.has_timeslip == 0) + { + self allowProne(false); + self allowSprint(false); + self disableoffhandweapons(); + self disableweaponcycling(); + weapona = self getcurrentweapon(); + weaponb = "zombie_perk_bottle_jugg"; + self giveweapon( weaponb ); + self switchtoweapon( weaponb ); + self waittill( "weapon_change_complete" ); + self enableoffhandweapons(); + self enableweaponcycling(); + self takeweapon( weaponb ); + self switchtoweapon( weapona ); + self maps\mp\zombies\_zm_audio::playerexert( "burp" ); + self setblur( 4, 0.1 ); + wait 0.1; + self setblur( 0, 0.1 ); + self allowProne(true); + self allowSprint(true); + } + else + { + self maps\mp\zombies\_zm_audio::playerexert( "burp" ); + self setblur( 4, 0.1 ); + wait 0.1; + self setblur( 0, 0.1 ); + } + } + + yPerk = 325; + if (level.script == "zm_buried") + { + yPerk = 300; + } + if (level.script == "zm_tomb") + { + yPerk = 275; + } + + x = -408; + for(i = 0; i < self.perkarray.size; i++) + { + if (type == "custom") + { + x += 15; + } + } + /*if (perk == "custom") + { + for(i = 0; i < self.perkarray.size; i++) + { + self.perkarray[i].x = self.perkarray[i].x + 30; + } + }*/ + if(perk == "Downers_Delight") + { + self.perk1back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk1front = self drawshader( "waypoint_revive", x, yPerk, 23, 23, ( 0, 1, 1 ), 100, 0 ); + self.perk1front.name = perk; + self.perkarray[self.perkarray.size] = self.perk1front; + self.perk1back.name = perk; + self.perkarray[self.perkarray.size] = self.perk1back; + self.num_perks++; + self thread DDown(); + if(print) + { + self iprintln("^5Downer's Delight"); + wait 0.2; + self iprintln("This Perk will increase players bleedout time by 10 seconds and current weapons is used in laststand."); + } + } + if(perk == "MULE") + { + self.perk2back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk2front = self drawshader( "menu_mp_weapons_1911", x, yPerk, 22, 22, ( 0, 1, 0 ), 100, 0 ); + self.perk2front.name = perk; + self.perkarray[self.perkarray.size] = self.perk2front; + self.perk2back.name = perk; + self.perkarray[self.perkarray.size] = self.perk2back; + self.num_perks++; + if(print) + { + self iprintln("^2Mule Kick"); + wait 0.2; + self iprintln("This Perk enables additional primary weapon slot for player. "); + } + } + if(perk == "PHD_FLOPPER") + { + self.perk3back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk3front = self drawshader( "hud_icon_sticky_grenade", x, yPerk, 23, 23, (1, 0, 1 ), 100, 0 ); + self.perk3front.name = perk; + self.perkarray[self.perkarray.size] = self.perk3front; + self.perk3back.name = perk; + self.perkarray[self.perkarray.size] = self.perk3back; + self.num_perks++; + if(print) + { + self iprintln("^6PhD Flopper"); + wait 0.2; + self iprintln("This Perk removes explosion and fall damage also player creates explosion when dive to prone."); + } + } + if(perk == "Victorious_Tortoise") + { + self.perk4back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 200, 0 ), 100, 0 ); + self.perk4front = self drawshader( "zombies_rank_2", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk4front.name = perk; + self.perkarray[self.perkarray.size] = self.perk4front; + self.perk4back.name = perk; + self.perkarray[self.perkarray.size] = self.perk4back; + self.num_perks++; + self thread start_vt(); + if(print) + { + self iprintln("^9Victorious Tortoise"); + wait 0.2; + self iprintln("This Perk allows shield block damage from all directions when in use."); + } + } + if(perk == "ELECTRIC_CHERRY") + { + self.perk5back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 200 ), 100, 0 ); + self.perk5front = self drawshader( "zombies_rank_5", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk5front.name = perk; + self.perkarray[self.perkarray.size] = self.perk5front; + self.perk5back.name = perk; + self.perkarray[self.perkarray.size] = self.perk5back; + self.num_perks++; + self thread start_ec(); + if(print) + { + self iprintln("^5Electric ^1Cherry"); + wait 0.2; + self iprintln("This Perk creates an electric shockwave around the player whenever they reload."); + } + } + if(perk == "WIDOWS_WINE") + { + self.perk6back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk6front = self drawshader( "zombies_rank_3", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk6front.name = perk; + self.perkarray[self.perkarray.size] = self.perk6front; + self.perk6back.name = perk; + self.perkarray[self.perkarray.size] = self.perk6back; + self.num_perks++; + self takeweapon( self get_player_lethal_grenade() ); + self set_player_lethal_grenade( "sticky_grenade_zm" ); + self giveweapon("sticky_grenade_zm"); + self thread ww_nades(); + if(print) + { + self iprintln("^8Widow's Wine"); + wait 0.2; + self iprintln("This Perk damages zombies around the player when player is hit and grenades are upgraded."); + } + } + if(perk == "Time_Slip") + { + self.perk7back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 200, 0, 0 ), 100, 0 ); + self.perk7front = self drawshader( "zombies_rank_4", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk7front.name = perk; + self.perkarray[self.perkarray.size] = self.perk7front; + self.perk7back.name = perk; + self.perkarray[self.perkarray.size] = self.perk7back; + self.num_perks++; + + self.has_timeslip = 1; + if(print) + { + self iprintln("^6Time Slip"); + wait 0.2; + self iprintln("Increase Box speed, PaP speed, reduce AATs cooldown"); + wait 0.2; + self iprintln("Remove perk drinking & knuckle crack animation"); + } + } + if(perk == "Ammo_Regen") + { + self.perk8back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk8front = self drawshader( "menu_mp_lobby_icon_customgamemode", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk8front.name = perk; + self.perkarray[self.perkarray.size] = self.perk8front; + self.perk8back.name = perk; + self.perkarray[self.perkarray.size] = self.perk8back; + self.num_perks++; + self thread ammoregen(); + self thread grenadesregen(); + if(print) + { + self iprintln("^9Ammo Regen"); + wait 0.2; + self iprintln("This Perk will slowly regenerades players ammonation and grenades."); + } + } + if(perk == "Burn_Heart") + { + self.perk9back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 200, 0, 0 ), 100, 0 ); + self.perk9front = self drawshader( "faction_cdc", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk9front.name = perk; + self.perkarray[self.perkarray.size] = self.perk9front; + self.perk9back.name = perk; + self.perkarray[self.perkarray.size] = self.perk9back; + self.num_perks++; + self.ignore_lava_damage = 1; + if(print) + { + self iprintln("^1Burn Heart"); + wait 0.2; + self iprintln("This Perk removes lava damage."); + } + } + if(perk == "Dying_Wish") + { + self.perk10back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 200, 0, 0 ), 100, 0 ); + self.perk10front = self drawshader( "zombies_rank_5", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk10front.name = perk; + self.perkarray[self.perkarray.size] = self.perk10front; + self.perk10back.name = perk; + self.perkarray[self.perkarray.size] = self.perk10back; + self.num_perks++; + self thread dying_wish_checker(); + if(print) + { + self iprintln("^3Dying Wish"); + wait 0.2; + self iprintln("This Perk allow player to go berserker mode for 9 seconds instead of laststand."); + wait 0.1; + self iprintln("Cooldown : 5 minutes. Increased by 30s every time the perk is used. Max 10 mins"); + } + } + if(perk == "Momentum_Mocha") + { + + self.perk11back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk11front = self drawshader("specialty_quickrevive_zombies_pro", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk11front.name = perk; + self.perkarray[self.perkarray.size] = self.perk11front; + self.perk11back.name = perk; + self.perkarray[self.perkarray.size] = self.perk11back; + self.num_perks++; + + self thread mocha(); + if(print) + { + self iprintln("^5Momentum ^3Mocha"); + wait 0.2; + self iprintln("Gradually increase your speed while sprinting."); + } + } + if(perk == "Bandolier_Bandit") + { + self.perk11back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 0 ), 100, 0 ); + //self.perk11front = self drawshader(, x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk11front = self drawshader("specialty_instakill_zombies", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + + self.perk11front.name = perk; + self.perkarray[self.perkarray.size] = self.perk11front; + self.perk11back.name = perk; + self.perkarray[self.perkarray.size] = self.perk11back; + self.num_perks++; + + self.has_bandolier = 1; + if (!isdefined(level.first_purchase)) + { + level.first_purchase = 1; + if (check_for_botb_port() == true) + SetDvar( "player_clipsizemultiplier", 2 ); + else + SetDvar( "player_clipsizemultiplier", 1.5 ); + level thread bandolier_watcher(); + } + + self notify("bandolier_purchased"); + + for (;;) + { + if (self GetCurrentWeapon() != "zombie_perk_bottle_jugg" && self GetCurrentWeapon() != "knife_zm") + break; + wait 0.1; + } + wait 0.1; + if (!isdefined(self.got_bb)) + { + primaryweapons = self getweaponslistprimaries(); + foreach(weapon in primaryweapons) + { + self SetWeaponAmmoStock(weapon, 99999); + self SetWeaponAmmoClip(weapon, 99999); + } + self.got_bb = 1; + } + + + if(print) + { + self iprintln("^9Bandolier Bandit"); + wait 0.2; + self iprintln("Increase weapon clip & stock ammo capacity."); + } + } +} + +bandolier_watcher() +{ + level endon("game_ended"); + + foreach(player in level.players) + { + if (!isdefined(player.has_bandolier) || (player.has_bandolier == 0)) + player thread bandolier(); + } + for (;;) + { + level waittill("connected", player); + player thread bandolier(); + } +} + +bandolier() +{ + self endon("disconnect"); + level endon("game_ended"); + self endon("bandolier_purchased"); + + self thread reload_watcher(); + for (;;) + { + weapon = self GetCurrentWeapon(); + if (weapon == "m32_zm" || weapon == "m32_upgraded_zm" + || weapon == "judge_zm" || weapon == "judge_upgraded_zm" + || weapon == "python_zm" || weapon == "python_upgraded_zm" + || weapon == "870mcs_zm" || weapon == "870mcs_upgraded_zm") + { + wait 0.1; + continue; + } + stockmax = weaponmaxammo( weapon ) / float(getdvar("player_clipsizemultiplier")); + clipmax = weaponclipsize( weapon ) / float(getdvar("player_clipsizemultiplier")); + if (clipmax < 1) + clipmax = 1; + if (weapon == "minigun_alcatraz_zm") + { + stockmax = 300; + clipmax = 150; + } + if (weapon == "minigun_alcatraz_upgraded_zm") + { + stockmax = 550; + clipmax = 550; + } + if (weapon == "raygun_mark2_upgraded_zm") + stockmax = 159; + if (weapon == "raygun_mark2_zm") + stockmax = 141; + if (weapon == "ray_gun_zm") + stockmax = 140; + if (weapon == "raygun_mark2_zm") + stockmax = 160; + if (weapon == "slipgun_zm") + stockmax = 30; + if (weapon == "knife_ballistic_zm" || weapon == "knife_ballistic_bowie_zm") + stockmax = 3; + if (weapon == "knife_ballistic_zm" || weapon == "knife_ballistic_bowie_upgraded_zm") + stockmax = 8; + if (self GetWeaponAmmoStock(weapon) > int(stockmax)) + self SetWeaponAmmoStock(weapon, int(stockmax)); + if (self GetWeaponAmmoClip(weapon) > int(clipmax)) + self SetWeaponAmmoClip(weapon, int(clipmax)); + wait .05; + } +} + +reload_watcher() +{ + self endon("disconnect"); + level endon("game_ended"); + self endon("bandolier_purchased"); + + while ( true ) + { + self waittill("reload"); + weapon = self GetCurrentWeapon(); + if (weapon == "m32_zm" || weapon == "m32_upgraded_zm" + || weapon == "judge_zm" || weapon == "judge_upgraded_zm" + || weapon == "python_zm" || weapon == "python_upgraded_zm" + || weapon == "870mcs_zm" || weapon == "870mcs_upgraded_zm") + { + wait 0.1; + continue; + } + current_stock_ammo = int(self GetWeaponAmmoStock(weapon)); + current_clip_ammo = self GetWeaponAmmoClip(weapon); + max_clip_ammo = weaponclipsize( weapon ) / float(getdvar("player_clipsizemultiplier")); + self SetWeaponAmmoStock(weapon, int(current_stock_ammo + (current_clip_ammo - max_clip_ammo))); + + } +} + +mocha() +{ + level endon("game_ended"); + self endon("disconnected"); + self endon("stopcustomperk"); + + for (;;) + { + if (check_for_botb_port() == true && isdefined(level.final_wave)) + { + return; + } + if (!self SprintButtonPressed()) + { + if (!isdefined(self.base_speed)) + self.base_speed = self GetMoveSpeedScale(); + if (isdefined(self.old_speed)) + self SetMoveSpeedScale(self.old_speed * 0.65); + else if (self HasPerk("specialty_longersprint")) + self SetMoveSpeedScale(self.base_speed + 0.07); + else + self SetMoveSpeedScale(self.base_speed); + } + else + { + speed = self GetMoveSpeedScale(); + if (check_for_botb_port() == true) + { + if (isdefined(self.old_speed)) + { + if (speed > 1.1) + speed = 1.1; + speed += 0.02; + } + else + { + if (speed > 1.7) + speed = 1.7; + speed += 0.03; + } + + } + else + { + if (speed > 1.5) + speed = 1.5; + speed += 0.01; + } + + self SetMoveSpeedScale(speed); + } + wait 0.25; + } +} + +custom_get_player_weapon_limit( player ) +{ + level endon("end_game"); + self endon("disconnect"); + weapon_limit = 2; + if ( player hascustomperk("MULE") ) + { + weapon_limit = 3; + } + else + { + weapons = self getWeaponsListPrimaries(); + if(weapons.size > 2) + { + self takeWeapon(weapons[2]); + } + } + return weapon_limit; +} + +ammoregen() +{ + self endon( "disconnect" ); + level endon( "end_game" ); + self endon( "stopcustomperk" ); + for(;;) + { + curr_weapon = self GetCurrentWeapon(); + if (curr_weapon == "time_bomb_zm" || curr_weapon == "time_bomb_detonator_zm" + || curr_weapon == "cymbal_monkey_zm" || curr_weapon == "beacon_zm") + { + wait 2; + } + else if (curr_weapon == "ray_gun_upgraded_zm" || curr_weapon == "ray_gun_zm" || curr_weapon == "raygun_mark2_zm" || curr_weapon == "raygun_mark2_upgraded_zm" + || curr_weapon == "m1911_upgraded_zm" || curr_weapon == "usrpg_upgraded_zm" || is_grenade_launcher( curr_weapon)) + { + stockcount = self getweaponammostock( curr_weapon ); + self setWeaponAmmostock( curr_weapon, stockcount + 1 ); + wait 2; + } + else if(!curr_weapon == "" && curr_weapon != "slipgun_zm" + && curr_weapon != "staff_fire_zm" && curr_weapon != "staff_fire_upgraded_zm" + && curr_weapon != "staff_air_zm" && curr_weapon != "staff_air_upgraded_zm" + && curr_weapon != "staff_water_zm" && curr_weapon != "staff_water_upgraded_zm" + && curr_weapon != "staff_lightning_zm" && curr_weapon != "staff_lightning_upgraded_zm" + && curr_weapon != "blundersplat_upgraded_zm" && curr_weapon != "blundersplat_zm") + { + stockcount = self getweaponammostock( curr_weapon ); + self setWeaponAmmostock( curr_weapon, stockcount + 5 ); + wait 2; + } + wait 0.1; + } +} + +grenadesregen() +{ + self endon( "disconnect" ); + level endon( "end_game" ); + self endon( "stopcustomperk" ); + for(;;) + { + grenades = self get_player_lethal_grenade(); + grenade_count = self getweaponammoclip(grenades); + if(grenade_count < 4) + { + self setweaponammoclip(grenades, (grenade_count + 1)); + } + tactical_grenades = self get_player_tactical_grenade(); + tactical_grenade_count = self getweaponammoclip(tactical_grenades); + if(tactical_grenade_count < 3 ) + { + self setweaponammoclip(tactical_grenades, (tactical_grenade_count + 1)); + } + wait 300; + } +} + +start_ec() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("stopcustomperk"); + for(;;) + { + self waittill( "reload_start" ); + playfxontag( level._effect[ "poltergeist"], self, "J_SpineUpper" ); + self EnableInvulnerability(); + RadiusDamage(self.origin, 120, 200, 100, self); + self DisableInvulnerability(); + self playsound( "zmb_turbine_explo" ); + wait 1; + } +} + +start_vt() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("stopcustomperk"); + for(;;) + { + if(self getcurrentweapon() == "riotshield_zm" ) + { + self enableInvulnerability(); + self.shielddamagetaken += 100; + wait 0.9; + } + else + { + self disableInvulnerability(); + } + wait 0.1; + } +} + +start_er() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("stopcustomperk"); + for(;;) + { + if (self hascustomperk("Ethereal_Razor") && self ismeleeing()) + { + self.health += 20; + if(self.health > self.maxhealth) + { + self.health = self.maxhealth; + } + while(self ismeleeing()) + { + wait 0.1; + } + } + wait 0.05; + } +} + +LastStand() +{ + level endon("end_game"); + self endon("disconnect"); + if(self hascustomperk("Downers_Delight")) + { + self.customlaststandweapon = self getcurrentweapon(); + self switchtoweapon( self.customlaststandweapon ); + self setweaponammoclip( self.customlaststandweapon, 150 ); + self.bleedout_time = 40; + } + else + { + self maps\mp\zombies\_zm::last_stand_pistol_swap(); + } +} + +DDown() +{ + self endon( "disconnect" ); + level endon( "end_game" ); + self endon( "stopcustomperk" ); + for(;;) + { + self waittill("player_downed"); + self playsound( "zmb_phdflop_explo" ); + playfx(loadfx("explosions/fx_default_explosion"), self.origin, anglestoforward( ( 0, 45, 55 ) ) ); + RadiusDamage(self.origin, 150, 600, 400, self); + wait 0.1; + } +} + +doGivePerk(perk) +{ + self endon("disconnect"); + self endon("death"); + level endon("game_ended"); + self endon("perk_abort_drinking"); + if (!(self hasperk(perk) || (self maps\mp\zombies\_zm_perks::has_perk_paused(perk)))) + { + gun = self maps\mp\zombies\_zm_perks::perk_give_bottle_begin(perk); + // evt = self waittill_any_return("fake_death", "death", "player_downed", "weapon_change_complete"); + // if (evt == "weapon_change_complete") + self thread maps\mp\zombies\_zm_perks::wait_give_perk(perk, 1); + self maps\mp\zombies\_zm_perks::perk_give_bottle_end(gun, perk); + if (self maps\mp\zombies\_zm_laststand::player_is_in_laststand() || isDefined(self.intermission) && self.intermission) + return; + self notify("burp"); + } +} + + +SpawnHint( origin, width, height, cursorhint, string ) +{ + level endon("end_game"); + self endon("disconnect"); + hint = spawn( "trigger_radius", origin, 1, width, height ); + hint setcursorhint( cursorhint, hint ); + hint sethintstring( string ); + hint setvisibletoall(); + wait 0.2; + hint delete(); +} + + +ww_points( player ) +{ + level endon("end_game"); + self endon("disconnect"); + for(i = 0; i < 3; i++) + { + self maps\mp\zombies\_zm_utility::set_zombie_run_cycle("walk"); + player scripts\points_multiplier::doublepoints(player, 0, 10); + PlayFXOnTag(level.effect_WebFX,self,"j_spineupper"); + self doDamage(150, (0, 0, 0)); + wait 1; + } +} + +ww_nade_explosion() +{ + level endon("end_game"); + self endon("disconnect"); + wait 2; + // if( self maps/mp/zm_transit_lava::object_touching_lava()) +// { + // self delete(); + // return 0; + // } + foreach(zombie in getAiArray(level.zombie_team)) + { + if( distance( zombie.origin, self.origin ) < 210 ) + { + zombie thread ww_points( self ); + } + } + self delete(); +} + +ww_nades() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("stopcustomperk"); + for(;;) + { + self waittill( "grenade_fire", grenade, weapname ); + if( weapname == "sticky_grenade_zm" ) + { + ww_nade = spawnsm( grenade.origin, "zombie_bomb" ); + ww_nade hide(); + ww_nade linkto( grenade ); + ww_nade thread ww_nade_explosion(); + } + } +} + +spawnsm( origin, model, angles ) +{ + level endon("end_game"); + self endon("disconnect"); + ent = spawn( "script_model", origin ); + ent setmodel( model ); + if( IsDefined( angles ) ) + { + ent.angles = angles; + } + return ent; +} + +dying_wish_checker() +{ + level endon("end_game"); + self endon("disconnect"); + self endon( "stopcustomperk" ); + self.dying_wish_uses = 0; + for(;;) + { + self.dying_wish_on_cooldown = 0; + self.perk10back.alpha = 1; + self.perk10front.alpha = 1; + self waittill("dying_wish_charge"); + self.perk10back.alpha = 0.3; + self.perk10front.alpha = 0.4; + self.dying_wish_uses++; + if (check_for_botb_port() == true || getDvar("isPanzer") == "1") + { + self.perk10back.alpha = 0; + self.perk10front.alpha = 0; + for (;;) + { + self.dying_wish_on_cooldown = 1; + wait 1; + } + return; + } + self.dying_wish_on_cooldown = 1; + delay = 300 + (self.dying_wish_uses * 30); + if(delay >= 600) + delay = 600; + wait delay; + } +} + +dying_wish_effect() +{ + level endon("end_game"); + self endon("disconnect"); + self enableInvulnerability(); + self.ignoreme = 1; + self thread perma_ignore(); + self useServerVisionSet(true); + self setvisionsetforplayer( "zombie_death", 0 ); + // self freezeControls(1); disabled + // wait 1; + // self freezeControls(0); + wait 8; + self notify("afk_end"); + if (getDvar("isBus") == "1") + { + self.health = 150; + } + else if (getDvar("isBus") == "0") + { + self.health = 1; + } + self disableInvulnerability(); + self.ignoreme = 0; + self useServerVisionSet(false); + self setvisionsetforplayer("remote_mortar_enhanced", 0); +} + +perma_ignore() +{ + self endon("afk_end"); + self endon("disconnected"); + + for (;;) + { + self.ignoreme = 1; + wait 0.5; + } +} +//-------------------ENDCUSTOMPERK------------------------ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +playerdamagelastcheck( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime ) +{ + players = get_players(); + for(i=0;i 0) + { + self PlaySound("zmb_elec_jib_zombie"); + self setweaponammoclip(grenades, (grenade_count - 1)); + zombie thread ww_points( self ); + } + } + } + } + if(self hascustomperk("PHD_FLOPPER")) + { + if( smeansofdeath == "MOD_FALLING" ) + { + if(isDefined( self.divetoprone ) && self.divetoprone == 1 ) + { + radiusdamage( self.origin, 300, 5000, 1000, self, "MOD_GRENADE_SPLASH" ); + playfx(loadfx("explosions/fx_default_explosion"), self.origin, anglestoforward( ( 0, 45, 55 ) ) ); + self playsound( "zmb_phdflop_explo" ); + } + return 0; + } + if( smeansofdeath == "MOD_PROJECTILE" || smeansofdeath == "MOD_PROJECTILE_SPLASH" || smeansofdeath == "MOD_GRENADE" || smeansofdeath == "MOD_GRENADE_SPLASH" && eattacker == self) + { + return 0; + } + } + if(idamage > self.health && !self.dying_wish_on_cooldown && self hascustomperk("Dying_Wish") ) + { + self notify("dying_wish_charge"); + self thread dying_wish_effect(); + return 0; + } + +//-------------------ENDCUSTOMPERK------------------------ + if (level.script == "zm_prison") + { + // scripts\zm\zm_prison\motd_perk_back::playerDamageLastCheckMOTD(einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime); + } + return idamage; +} + +vector_scal( vec, scale ) +{ + vec = ( vec[ 0] * scale, vec[ 1] * scale, vec[ 2] * scale ); + return vec; +} + +vending_weapon_upgrade_cost() +{ + level endon("end_game"); + for( ;; ) + { + level waittill( "powerup bonfire sale" ); + level._bonfire_sale = 1; + level waittill( "bonfire_sale_off" ); + level._bonfire_sale = 0; + } +} + +pap_off() +{ + level endon("end_game"); + wait 5; + for(;;) + { + level waittill("Pack_A_Punch_on"); + wait 1; + level notify("Pack_A_Punch_off"); + } +} + +new_pap_trigger() +{ + level endon("end_game"); + flag_wait( "initial_blackscreen_passed" ); + + if (check_for_botb_port() == true) + return; + for (;;) + { + if (getDvar("isPanzer") == "1") + { + return; + } + else if (getDvar("isPanzer") == "0") + { + break; + } + wait 0.5; + } + for (;;) + { + if (getDvar("isBus") == "1") + { + return; + } + else if (getDvar("isBus") == "0") + { + break; + } + wait 0.5; + } + if(getDvar( "g_gametype" ) == "zgrief") + return; + thread vending_weapon_upgrade_cost(); + level waittill("Pack_A_Punch_on"); + wait 2; + + if(getdvar( "mapname" ) != "zm_transit" && getdvar ( "g_gametype") != "zstandard") + { + level notify("Pack_A_Punch_off"); + level thread pap_off(); + } + + if( getdvar( "mapname" ) == "zm_nuked" ) + level waittill( "Pack_A_Punch_on" ); + + perk_machine = getent( "vending_packapunch", "targetname" ); + pap_triggers = getentarray( "specialty_weapupgrade", "script_noteworthy" ); + pap_triggers[0] delete(); + if( getdvar( "mapname" ) == "zm_transit" && getdvar ( "g_gametype") == "zclassic" ) + { + if(!level.buildables_built[ "pap" ]) + level waittill("pap_built"); + } + wait 1; + self.perk_machine = perk_machine; + perk_machine_sound = getentarray( "perksacola", "targetname" ); + packa_rollers = spawn( "script_origin", perk_machine.origin ); + packa_timer = spawn( "script_origin", perk_machine.origin ); + packa_rollers linkto( perk_machine ); + packa_timer linkto( perk_machine ); + if( getdvar( "mapname" ) == "zm_highrise" ) + { + Trigger = spawn( "trigger_radius", perk_machine.origin, 1, 60, 80 ); + Trigger enableLinkTo(); + Trigger linkto(self.perk_machine); + } + else + Trigger = spawn( "trigger_radius", perk_machine.origin, 1, 35, 80 ); + + + Trigger SetCursorHint( "HINT_NOICON" ); + Trigger sethintstring( " Hold ^3&&1^7 for Pack-a-Punch [Cost: 5000] \n Weapons can be pack a punched multiple times" ); + + cost = 5000; + + Trigger usetriggerrequirelookat(); + for(;;) + { + Trigger waittill("trigger", player); + current_weapon = player getcurrentweapon(); + if(current_weapon == "saritch_upgraded_zm+dualoptic" || current_weapon == "dualoptic_saritch_upgraded_zm+dualoptic" || current_weapon == "slowgun_upgraded_zm" || current_weapon == "staff_air_zm" || current_weapon == "staff_lightning_zm" || current_weapon == "staff_fire_zm" || current_weapon == "staff_water_zm" ) + { + Trigger sethintstring( "^1This weapon can not be upgraded." ); + wait .05; + continue; + } + + if(player UseButtonPressed() && player.score >= cost && current_weapon != "riotshield_zm" && player can_buy_weapon() && !player.is_drinking && !is_placeable_mine( current_weapon ) && !is_equipment( current_weapon ) && level.revive_tool != current_weapon && current_weapon != "none" ) + { + player.score -= cost; + player thread maps\mp\zombies\_zm_audio::play_jingle_or_stinger( "mus_perks_packa_sting" ); + trigger setinvisibletoall(); + upgrade_as_attachment = will_upgrade_weapon_as_attachment( current_weapon ); + + player.restore_ammo = undefined; + player.restore_clip = undefined; + player.restore_stock = undefined; + player.restore_clip_size = undefined; + player.restore_max = undefined; + + player.restore_clip = player getweaponammoclip( current_weapon ); + player.restore_clip_size = weaponclipsize( current_weapon ); + player.restore_stock = player getweaponammostock( current_weapon ); + player.restore_max = weaponmaxammo( current_weapon ); + + if (!isdefined(player.has_timeslip) || player.has_timeslip == 0) + player thread maps\mp\zombies\_zm_perks::do_knuckle_crack(); + wait .1; + player takeWeapon(current_weapon); + current_weapon = player maps\mp\zombies\_zm_weapons::switch_from_alt_weapon( current_weapon ); + self.current_weapon = current_weapon; + upgrade_name = maps\mp\zombies\_zm_weapons::get_upgrade_weapon( current_weapon, upgrade_as_attachment ); + player third_person_weapon_upgrade( current_weapon, upgrade_name, packa_rollers, perk_machine, self ); + trigger sethintstring( &"ZOMBIE_GET_UPGRADED" ); + trigger thread wait_for_pick(player, current_weapon, self.upgrade_name); + + if ( isDefined( player ) ) + { + Trigger setinvisibletoall(); + Trigger setvisibletoplayer( player ); + } + self thread wait_for_timeout( current_weapon, packa_timer, player ); + self waittill_any( "pap_timeout", "pap_taken", "pap_player_disconnected" ); + self.current_weapon = ""; + + if ( isDefined( self.worldgun ) && isDefined( self.worldgun.worldgundw ) ) + self.worldgun.worldgundw delete(); + + if ( isDefined( self.worldgun ) ) + self.worldgun delete(); + + Trigger setinvisibletoplayer( player ); + wait 1.5; + Trigger setvisibletoall(); + + self.current_weapon = ""; + self.pack_player = undefined; + flag_clear( "pack_machine_in_use" ); + } + weapon = player getcurrentweapon(); + if(isdefined(level._bonfire_sale) && level._bonfire_sale) + { + Trigger sethintstring( " Hold ^3&&1^7 for Pack-a-Punch [Cost: 1000] \n Weapons can be pack a punched multiple times" ); + cost = 1000; + } + else if(is_weapon_upgraded(weapon)) + { + Trigger sethintstring( " Hold ^3&&1^7 for Pack-a-Punch [Cost: 2500] \n Weapons can be pack a punched multiple times" ); + cost = 2500; + } + else + { + Trigger sethintstring( " Hold ^3&&1^7 for Pack-a-Punch [Cost: 5000] \n Weapons can be pack a punched multiple times" ); + cost = 5000; + } + wait .1; + } +} + +wait_for_pick(player, weapon, upgrade_weapon) +{ + level endon( "pap_timeout" ); + level endon("end_game"); + for (;;) + { + self playloopsound( "zmb_perks_packa_ticktock" ); + self waittill( "trigger", user ); + if(user UseButtonPressed() && player == user) + { + self stoploopsound( 0.05 ); + player thread do_player_general_vox( "general", "pap_arm2", 15, 100 ); + + base = get_base_name(weapon); + if(is_weapon_upgraded( weapon )) + { + player.restore_ammo = 1; + + if( weapon == "galil_upgraded_zm+reflex" || weapon == "fnfal_upgraded_zm+reflex" || base == "ak74u_upgraded_zm" || base == "galil_upgraded_zm" || base == "fnfal_upgraded_zm") + player thread give_aat(weapon); //Alternative ammo type for galil and fnfal upgraded + else + player thread give_aat(upgrade_weapon); //Alternative ammo type for all other weapons + } + else if( weapon == "galil_upgraded_zm+reflex" || weapon == "fnfal_upgraded_zm+reflex" || base == "ak74u_upgraded_zm" ) + { + player giveweapon( weapon, 0, player maps\mp\zombies\_zm_weapons::get_pack_a_punch_weapon_options( weapon )); + player switchToWeapon( weapon ); + } + + weapon_limit = get_player_weapon_limit( player ); + player maps\mp\zombies\_zm_weapons::take_fallback_weapon(); + primaries = player getweaponslistprimaries(); + + if ( isDefined( primaries ) && primaries.size >= weapon_limit ) + player maps\mp\zombies\_zm_weapons::weapon_give( upgrade_weapon ); + else + player giveweapon( upgrade_weapon, 0, player maps\mp\zombies\_zm_weapons::get_pack_a_punch_weapon_options( upgrade_weapon )); + + player switchToWeapon( upgrade_weapon ); + x = upgrade_weapon; + + if ( isDefined( player.restore_ammo ) && player.restore_ammo ) + { + new_clip = player.restore_clip + ( weaponclipsize( x ) - player.restore_clip_size ); + new_stock = player.restore_stock + ( weaponmaxammo( x ) - player.restore_max ); + player setweaponammostock( x, new_stock ); + player setweaponammoclip( x, new_clip ); + } + level notify( "pap_taken" ); + player notify( "pap_taken" ); + break; + } + wait .1; + } +} + +aat_zombie_damage_response( mod, hit_location, hit_origin, attacker, amount ) +{ + weapons_inventory = attacker GetWeaponsListPrimaries(); + current_weapon = attacker GetCurrentWeapon(); + index = 0; + weapon_match = 0; + for (i = 0; i < weapons_inventory.size; i++) + { + if (current_weapon == weapons_inventory[i]) + { + index = i; + weapon_match = 1; + break; + } + } + if (weapon_match == 0) + return; + + if(!can_aat_damage(self)) + return 0; + + player = attacker; + if(isdefined( self.damageweapon )) + { + if(isdefined( attacker ) && isplayer( attacker )) + { + zombies = getaiarray( level.zombie_team ); + + if(self turned_zombie_validation() && !is_true(player.active_turned) && isdefined(player.aat[self.damageweapon]) && player.aat[self.damageweapon] == "Turned") + { + attacker.aat_activated = 1; + attacker thread Cooldown("Turned"); + self thread turned( attacker ); + return 1; + } + if(isdefined(attacker.aat[self.damageweapon]) && attacker.aat[self.damageweapon] == "Cluster") + { + attacker.aat_activated = 1; + attacker thread Cooldown("Cluster"); + self thread cluster( attacker ); + return 1; + } + if(player.weapons_aat_cooldown[index] == 0 && isdefined(player.aat[self.damageweapon]) && player.aat[self.damageweapon] == "Headcutter") + { + attacker.aat_activated = 1; + attacker thread Cooldown("Headcutter"); + max_kills = 12; + killed = 0; + for( i = 0; i < zombies.size; i++ ) + { + if (killed >= max_kills) + break; + if(distance(self.origin, zombies[i].origin) <= 300) + { + if(!zombies[i].done && can_aat_damage(zombies[i])) + { + zombies[i].done = 1; + zombies[i] thread Headcutter(attacker); + killed++; + } + } + } + return 1; + } + if(player.weapons_aat_cooldown[index] == 0 && isdefined(player.aat[self.damageweapon]) && player.aat[self.damageweapon] == "Thunder Wall") + { + attacker.aat_activated = 1; + attacker setclientdvar( "ragdoll_enable", 1); + attacker thread Cooldown("Thunder Wall"); //switched cuz thunderwall thread prolly crashing and not going on cd + self thread thunderwall(attacker); + return 1; + } + if(player.weapons_aat_cooldown[index] == 0 && isdefined(player.aat[self.damageweapon]) && player.aat[self.damageweapon] == "Blast Furnace") + { + attacker.aat_activated = 1; + attacker thread Cooldown("Blast Furnace"); + PlayFXOnTag(level._effect[ "character_fire_death_torso" ], self, "j_spinelower"); + PlayFXOnTag(level._effect[ "character_fire_death_sm" ], self, "j_spineupper"); + max_kills = 12; + killed = 0; + for( i = 0; i < zombies.size; i++ ) + { + if (killed >= max_kills) + break; + if(distance(self.origin, zombies[i].origin) <= 300 && can_aat_damage(zombies[i])) + { + zombies[i] thread flames_fx(attacker); + killed++; + } + } + return 1; + } + if(player.weapons_aat_cooldown[index] == 0 && isdefined(player.aat[self.damageweapon]) && player.aat[self.damageweapon] == "Fireworks") + { + attacker.aat_activated = 1; + attacker thread Cooldown("Fireworks"); + self thread spawn_weapon( attacker ); + self thread fireworks(); + return 1; + } + if(player.weapons_aat_cooldown[index] == 0 && isdefined(player.aat[self.damageweapon]) && player.aat[self.damageweapon] == "Cryo Freeze" ) + { + self thread cryofreeze_zombie_damage_response(attacker); + return true; + } + if(player.weapons_aat_cooldown[index] == 0 && isdefined(player.aat[self.damageweapon]) && player.aat[self.damageweapon] == "Dead Wire" ) + { + attacker.aat_actived = 1; + attacker thread Cooldown("Dead Wire"); + self thread deadwire_zombie_damage_response(attacker); + return true; + } + } + } + return 0; +} + +deadwire_zombie_damage_response(attacker) +{ + level endon("end_game"); + attacker endon("disconnect"); + + max_kills = 12; + ai_zombies = get_array_of_closest( self.origin, getaiarray( level.zombie_team ), undefined, undefined, 300); + for ( i = 0; i < ai_zombies.size; i++ ) + { + if (i >= max_kills) + break; + ai_zombies[i] thread deadwire_fx(); +/* if (is_true( ai_zombies[i].has_legs )) + ai_zombies[i].deathanim = "zm_death_tesla"; + else + ai_zombies[i].deathanim = "zm_death_tesla_crawl";*/ + ai_zombies[i] DoDamage( ai_zombies[i].health + 666, ai_zombies[i].origin); + attacker.kills++; + attacker scripts\points_multiplier::doublepoints(attacker, 0, 50); + wait 0.20; + } +} + +deadwire_fx() +{ + fx = Spawn( "script_model", self GetTagOrigin( "j_spinelower" ) ); + fx.angles = self GetTagAngles( "j_spinelower" ); + fx SetModel( "tag_origin" ); + fx LinkTo( self, "j_spinelower" ); + + PlayFxOnTag( level._effect["elec_md"] , fx, "tag_origin" ); + + self playsound ("zmb_elec_jib_zombie"); + wait 2.5; + fx delete(); +} + +cryofreeze_zombie_damage_response(attacker) +{ + r = randomint(20); + if ( r > 18) + { + attacker.aat_actived = 1; + self thread cryofreeze_explosion_fx(); + + ai_zombies = getaispeciesarray("axis", "all"); + if ( !isDefined( ai_zombies ) ) + return; + max_kills = 12; + + ai_zombies = get_array_of_closest( self.origin, getaiarray( level.zombie_team ), undefined, undefined, 300); + for ( i = 0; i < ai_zombies.size; i++ ) + { + if (i >= max_kills) + break; + ai_zombies[i] DoDamage( ai_zombies[i].health + 666, ai_zombies[i].origin, attacker, attacker, "none", "MOD_IMPACT" ); + } + attacker thread Cooldown("Cryo Freeze"); + return; + } + self thread cryofreeze_slow_fx(); + self set_zombie_run_cycle("walk"); +} + +cryofreeze_slow_fx() +{ + fx = Spawn( "script_model", self GetTagOrigin( "J_SpineLower" ) ); + fx.angles = self GetTagAngles( "J_SpineLower" ); + fx SetModel( "tag_origin" ); + fx LinkTo( self, "J_SpineLower" ); + fx.origin += (0, 0, -20); + + PlayFxOnTag( level._effect["fx_moon_lamp_glow"] , fx, "tag_origin" ); + self playsound("wpn_thundergun_proj_impact_zombie"); + wait 2; + fx delete(); +} + +cryofreeze_explosion_fx() +{ + fx = Spawn( "script_model", self GetTagOrigin( "J_SpineLower" ) ); + fx.angles = self GetTagAngles( "J_SpineLower" ); + fx SetModel( "tag_origin" ); + fx LinkTo( self, "J_SpineLower" ); + fx.origin += (0, 0, -20); + + PlayFxOnTag( level._effect["rise_burst_water"] , fx, "tag_origin" ); + self playsound("wpn_thundergun_proj_impact_zombie"); + wait 5; + fx delete(); +} + +Cooldown(aat) +{ + cooldown_time = 0; + weapons_inventory = self GetWeaponsListPrimaries(); + current_weapon = self GetCurrentWeapon(); + index = 0; + weapon_match = 0; + + for (i = 0; i < weapons_inventory.size; i++) + { + if (current_weapon == weapons_inventory[i]) + { + index = i; + weapon_match = 1; + break; + } + } + if (weapon_match == 0) + return; + self.weapons_aat_cooldown[index] = 1; + + self.aat_cooldown_duration[index] = 25; + if (aat == "Thunder Wall") + self.aat_cooldown_duration[index] = 40; + + if (isdefined(self.has_timeslip) && self.has_timeslip == 1) + self.aat_cooldown_duration[index] = int(self.aat_cooldown_duration[index] * 0.8); + + for (i = 0; i < (self.aat_cooldown_duration[index] * 20); i++) + { + self.aat_remaining_cooldown[index] = (i / 20); + wait .05; + } + + self.weapons_aat_cooldown[index] = 0; + + weapons_inventory = self GetWeaponsListPrimaries(); + current_weapon = self GetCurrentWeapon(); + + for (i = 0; i < weapons_inventory.size; i++) + { + if (current_weapon == weapons_inventory[i]) + { + if (i != index) + return; + else + break; + } + } + self.is_aat_blinking = 1; + self playsound ("zmb_cha_ching"); + previous_alpha = self.aat_hud.alpha; + for (i = 0; i < 7; i++) + { + self.aat_hud.alpha = 1; + wait 0.1; + self.aat_hud.alpha = 0.7; + wait 0.1; + } + if (previous_alpha == 0) + { + self.aat_hud fadeovertime( 0.75 ); + self.aat_hud.alpha = 0; + } + else + self.aat_hud.alpha = 0.8; + self.is_aat_blinking = 0; +} + +explosive_bullet() +{ + level endon("end_game"); + self endon("disconnect"); + for( ;; ) + { + self waittill( "weapon_fired", weapon); + index = 0; + weapons_inventory = self GetWeaponsListPrimaries(); + + for (i = 0; i < weapons_inventory.size; i++) + { + if (weapon == weapons_inventory[i]) + { + index = i; + break; + } + } + if(getdvar("mapname") == "zm_tomb" || getdvar("mapname") == "zm_buried") + fx = level._effect[ "divetonuke_groundhit" ]; + else + fx = level._effect[ "def_explosion" ]; + + if(self.weapons_aat_cooldown[index] == 0 && isdefined(self.aat[weapon]) && self.aat[weapon] == "Explosive") + { + self.aat_activated = 1; + self thread Cooldown("Explosive"); + forward = self gettagorigin( "tag_weapon_right" ); + end = self thread vector_scal( anglestoforward( self getplayerangles() ), 1000000 ); + crosshair_entity = bullettrace(self gettagorigin("tag_weapon_right"),self gettagorigin("tag_weapon_right")+anglestoforward(self getplayerangles())*1000000,true,self)["entity"]; + crosshair = bullettrace( forward, end, 0, self )[ "position"]; + magicbullet( self getcurrentweapon(), self gettagorigin( "j_shouldertwist_le" ), crosshair, self ); + self enableInvulnerability(); + + if(isdefined(crosshair_entity)) + { + crosshair_entity playsound( "zmb_phdflop_explo" ); + playfx(fx, crosshair_entity.origin, anglestoforward( ( 0, 45, 55 ) ) ); + + ai_zombies = get_array_of_closest( crosshair_entity.origin, getaiarray( level.zombie_team ), undefined, undefined, 300); + if (!isdefined(ai_zombies)) + continue; + max_kills = 12; + for ( i = 0; i < ai_zombies.size; i++ ) + { + if (i >= max_kills) + break; + ai_zombies[i] DoDamage(ai_zombies[i].health + 666, ai_zombies[i].origin); + self scripts\points_multiplier::doublepoints(self, 0, 25); + self.kills++; + } + } + else + { + crosshair playsound( "zmb_phdflop_explo" ); + playfx(fx, crosshair, anglestoforward( ( 0, 45, 55 ) ) ); + ai_zombies = get_array_of_closest( crosshair, getaiarray( level.zombie_team ), undefined, undefined, 300); + if (!isdefined(ai_zombies)) + continue; + max_kills = 12; + for ( i = 0; i < ai_zombies.size; i++ ) + { + if (i >= max_kills) + break; + ai_zombies[i] DoDamage(ai_zombies[i].health + 666, ai_zombies[i].origin); + self scripts\points_multiplier::doublepoints(self, 0, 25); + self.kills++; + } + } + wait .5; + self disableInvulnerability(); + } + wait .1; + } +} + +flames_fx(attacker) +{ + for(i = 0; i < 5; i++) + { + PlayFXOnTag(level._effect[ "character_fire_death_sm" ], self, "j_spineupper"); + + if(i < 3) + { + self dodamage(self.health / 2, (0,0,0)); + attacker scripts\points_multiplier::doublepoints(attacker, 0, 10); + } + else + { + self dodamage(self.maxhealth + 666, (0,0,0)); + attacker scripts\points_multiplier::doublepoints(attacker, 0, 50); + attacker.kills++; + } + wait 1; + } +} + +fireworks() +{ + level endon("end_game"); + origin = self.origin; + + if(getdvar("mapname") == "zm_buried") + { + for(i=0;i<10;i++) + { + x = randomintrange(-40, 40); + y = randomintrange(-40, 40); + + up_in_air = origin + (0,0,65); + up_in_air2 = origin + (x,y,randomintrange(45, 66)); + up_in_air3 = origin + (x,y,randomintrange(45, 66)); + + firework = Spawn( "script_model", origin ); + firework SetModel( "tag_origin" ); + + firework2 = Spawn( "script_model", origin ); + firework2 SetModel( "tag_origin" ); + + firework3 = Spawn( "script_model", origin ); + firework3 SetModel( "tag_origin" ); + + fx = PlayFxOnTag( level._effect[ "fx_wisp_m" ], firework, "tag_origin"); + fx2 = PlayFxOnTag( level._effect[ "fx_wisp_m" ], firework2, "tag_origin"); + fx3 = PlayFxOnTag( level._effect[ "fx_wisp_m" ], firework3, "tag_origin"); + + firework moveto(up_in_air, 1); + firework2 moveto(up_in_air2, randomfloatrange(0.4, 1.1)); + firework3 moveto(up_in_air3, randomfloatrange(0.4, 1.1)); + + wait .5; + firework delete(); + firework2 delete(); + firework3 delete(); + fx delete(); + fx2 delete(); + fx3 delete(); + } + } + + if(getdvar("mapname") == "zm_highrise") + { + for(i=0;i<22;i++) + { + firework = Spawn( "script_model", origin ); + firework SetModel( "tag_origin" ); + firework.angles = (0,0,0); + fx = PlayFxOnTag( level._effect[ "sidequest_dragon_spark_max" ], firework, "tag_origin"); + wait .25; + firework delete(); + fx delete(); + } + } + + if(getdvar("mapname") == "zm_tomb") + { + for(i=0;i<20;i++) + { + firework = Spawn( "script_model", origin ); + firework SetModel( "tag_origin" ); + firework.angles = (-90,0,0); + fx = PlayFxOnTag( level._effect[ "fire_muzzle" ], firework, "tag_origin"); + wait .25; + firework delete(); + fx delete(); + } + } + else if(getdvar("mapname") == "zm_transit" && getdvar ( "g_gametype") == "zclassic" ) + { + for(i=0;i<5;i++) + { + up_in_air = origin + (0,0,65); + firework = Spawn( "script_model", origin ); + firework SetModel( "tag_origin" ); + fx = PlayFxOnTag( level._effect[ "richtofen_sparks" ], firework, "tag_origin"); + firework moveto(up_in_air, 1); + wait 1; + firework delete(); + fx delete(); + } + } +} + +spawn_weapon(attacker) +{ + origin = self.origin; + weapon = attacker getCurrentWeapon(); + + attacker.firework_weapon = spawn( "script_model", origin ); + attacker.firework_weapon.angles = (0,0,0); + attacker.firework_weapon setmodel( GetWeaponModel( weapon ) ); + attacker.firework_weapon useweaponhidetags( weapon ); + + attacker.firework_weapon MoveTo( origin + (0, 0, 45), 0.5, 0.25, 0.25 ); + attacker.firework_weapon waittill( "movedone" ); + max_kills = 12; + zombie_killed = 0; + for(i=0;i<100;i++) + { + zombies = get_array_of_closest( attacker.firework_weapon.origin, getaiarray( level.zombie_team ), undefined, undefined, 300 ); + forward = attacker.firework_weapon.origin; + + if( can_aat_damage( zombies[ 0 ] ) ) + { + end = zombies[ 0 ] gettagorigin( "j_spineupper" ); + crosshair = bullettrace( forward, end, 0, self )[ "position" ]; + attacker.firework_weapon.angles = VectorToAngles( end - attacker.firework_weapon.origin ); + + if( distance(zombies[ 0 ].origin, attacker.firework_weapon.origin) <= 300) + { + magicbullet( weapon, attacker.firework_weapon.origin, crosshair, attacker.firework_weapon ); + zombies[0] DoDamage(zombies[0].health + 666, zombies[0].origin); + attacker scripts\points_multiplier::doublepoints(attacker, 0, 50); + attacker.kills++; + zombie_killed++; + if (zombie_killed >= max_kills) + break; + } + } + wait .05; + } + attacker.firework_weapon MoveTo( origin, 0.5, 0.25, 0.25 ); + attacker.firework_weapon waittill( "movedone" ); + attacker.firework_weapon delete(); +} + +thunderwall( attacker ) +{ + ai_zombies = get_array_of_closest( self.origin, getaiarray( level.zombie_team ), undefined, undefined, 250 ); + + if ( !isDefined( ai_zombies ) ) + return; + + flung_zombies = 0; + max_kills = 25; + // max_kills = randomIntRange(5,25); + for ( i = 0; i < ai_zombies.size; i++ ) + { + if( can_aat_damage(ai_zombies[i]) ) + { + n_random_x = RandomFloatRange( -180, 180 ); //base value was -3 3 + n_random_y = RandomFloatRange( -180, 180 ); + ai_zombies[i] StartRagdoll(); + ai_zombies[i] LaunchRagdoll( (n_random_x, n_random_y, 300) ); //was 300 before aprile + + if(getdvar("mapname") == "zm_transit") + playfxontag( level._effect[ "jetgun_smoke_cloud"], ai_zombies[i], "J_SpineUpper" ); + else if(getdvar("mapname") == "zm_tomb") + playfxontag( level._effect[ "air_puzzle_smoke" ], ai_zombies[i], "J_SpineUpper" ); + else if(getdvar("mapname") == "zm_buried") + playfxontag( level._effect[ "rise_billow_foliage" ], ai_zombies[i], "J_SpineUpper" ); + + ai_zombies[i] DoDamage( ai_zombies[i].health + 666, ai_zombies[i].origin); + attacker.kills++; + attacker scripts\points_multiplier::doublepoints(attacker, 0, 25); + flung_zombies++; + if ( flung_zombies >= max_kills ) + break; + } + } +} + +Headcutter(attacker) +{ + self endon("death"); + + self thread on_headcutter_death(attacker); + self maps\mp\zombies\_zm_spawner::zombie_head_gib(); + for(;;) + { + wait 1; + damage = 100 * level.round_number; + self dodamage( damage, self.origin, attacker, attacker, "none", "MOD_IMPACT" ); + } +} + +on_headcutter_death(attacker) +{ + level endon("game_ended"); + + self waittill("death"); + attacker.kills++; + attacker scripts\points_multiplier::doublepoints(attacker, 0, 50); +} + +cluster( attacker ) +{ + if(level.round_number < 10) + amount = randomIntRange(1, (level.round_number * 2)); + else + amount = randomIntRange(5, level.round_number); + + random_x = RandomFloatRange( -5, 5 ); + random_y = RandomFloatRange( -5, 5 ); + attacker.gluster_grenade = attacker; + for(i = 0; i < amount; i++) + { + attacker.gluster_grenade MagicGrenadeType( "frag_grenade_zm", self.origin + (random_x, random_y, 10), (random_x, random_y, 0), 2 ); + wait .1; + } +} + +supersprint() +{ + level endon("game_ended"); + self endon("death"); + for(;;) + { + if(!isDefined(self.cloned_distance)) + self.cloned_distance = self.origin; + else if(distance(self.cloned_distance, self.origin) > 15) + { + self.cloned_distance = self.origin; + if (cycle != "super_sprint") + { + self maps\mp\zombies\_zm_utility::set_zombie_run_cycle("super_sprint"); + cycle = "super_sprint"; + } + } + else if(distance(self.cloned_distance, self.origin) <= 15) + { + self.cloned_distance = self.origin; + if (cycle != "run") + { + self maps\mp\zombies\_zm_utility::set_zombie_run_cycle("run"); + cycle = "run"; + } + } + wait 0.25; + } +} + +turned( attacker ) +{ + self.is_turned = 1; + self.actor_damage_func = ::turned_damage_respond; + self.health = 999999; + + attacker.active_turned = 1; + self.turned_zombie_kills = 0; + self.max_kills = 18; + + self thread supersprint(); + self SetMoveSpeedScale(20); + self.custom_goalradius_override = 1000000; + + if(getdvar("mapname") == "zm_tomb") + turned_fx = playfxontag(level._effect[ "staff_soul" ], self, "j_head"); + else + turned_fx = playfxontag(level._effect["powerup_on_solo"], self, "j_head"); + + enemyoverride = []; + self.team = level.players; + self.ignore_enemy_count = 1; + + if(getdvar("mapname") == "zm_tomb") + attackanim = "zm_generator_melee"; + else + attackanim = "zm_riotshield_melee"; + + if ( !self.has_legs ) + attackanim += "_crawl"; + + while(isAlive(self)) + { + ai_zombies = get_array_of_closest( self.origin, getaiarray( level.zombie_team ), undefined, undefined, undefined ); + if(isdefined(ai_zombies[1]) && can_aat_damage(ai_zombies[1])) + { + enemyoverride[0] = ai_zombies[1].origin; + enemyoverride[1] = ai_zombies[1]; + } + else + { + enemyoverride[0] = ai_zombies[0].origin; + enemyoverride[1] = ai_zombies[0]; + } + self.enemyoverride = enemyoverride; + if(distance(self.origin, ai_zombies[1].origin) < 40 && isalive(ai_zombies[1]) ) + { + angles = VectorToAngles( ai_zombies[1].origin - self.origin ); + self animscripted( self.origin, angles, attackanim ); + ai_zombies[1] DoDamage( ai_zombies[1].health + 666, ai_zombies[1].origin); + attacker.kills++; + attacker scripts\points_multiplier::doublepoints(attacker, 0, 50); + self.turned_zombie_kills++; + + if(self.turned_zombie_kills > self.max_kills) + { + turned_fx delete(); + self.is_turned = 0; + wait .1; + self dodamage(self.health + 666, self.origin); + } + + wait 0.5; + } + else + self stopanimscripted(); + + wait .05; + } + attacker.active_turned = 0; + self.is_turned = 0; + + if(isdefined(turned_fx)) + turned_fx delete(); +} + +turned_damage_respond( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime, boneindex ) +{ + if(self.is_turned) + return 0; +} + +turned_zombie() +{ + if(self.turned) + { + //attack zombies + } + else + zombie_poi = self get_zombie_point_of_interest( self.origin ); + + return zombie_poi; +} + +turned_zombie_validation() +{ + if( IS_TRUE( self.barricade_enter ) ) + return false; + + if ( IS_TRUE( self.is_traversing ) ) + return false; + + if ( !IS_TRUE( self.completed_emerging_into_playable_area ) ) + return false; + + if ( IS_TRUE( self.is_leaping ) ) + return false; + + if ( IS_TRUE( self.is_inert ) ) + return false; + + return true; +} + +is_true(check) +{ + return(IsDefined(check) && check); +} + +give_aat(weapon) +{ + if(!isDefined(self.aat)) + self.aat = []; + + if(isdefined(self.old_aat)) + { + if(self.old_aat == "Thunder Wall") + self.old_aat = 0; + else if(self.old_aat == "Fireworks") + self.old_aat = 1; + else if(self.old_aat == "Turned") + self.old_aat = 2; + else if(self.old_aat == "Cluster") + self.old_aat = 3; + else if(self.old_aat == "Headcutter") + self.old_aat = 4; + else if(self.old_aat == "Explosive") + self.old_aat = 5; + else if(self.old_aat == "Blast Furnace") + self.old_aat = 6; + else if(self.old_aat == "Cryo Freeze") + self.old_aat = 7; + else if(self.old_aat == "Dead Wire") + self.old_aat = 8; + } + + name = undefined; + + number = randomint(8); + + while(isdefined(self.old_aat) && number == self.old_aat) + { + number = randomint(8); + wait .05; + } + if(number == 0) + name = "Dead Wire"; + else if(number == 1) + name = "Fireworks"; + else if(number == 2) + name = "Thunder Wall"; //Cluster disabled was thunder + else if(number == 3) + name = "Headcutter"; + else if(number == 4) + name = "Explosive"; + else if(number == 5) + name = "Blast Furnace"; + else if (number == 6) + name = "Cryo Freeze"; + else if(number == 7) + name = "Turned"; + self.aat[weapon] = name; + self.old_aat = name; + +} + +tombstone_timeout() +{ + level endon("end_game"); + self endon("dance_on_my_grave"); + self endon("disconnect"); + self endon("revived_player"); + + self waittill("spawned_player"); + wait 60; + self notify("tombstone_timedout"); + wait 1; + weapon = self getCurrentWeapon(); + self notify("weapon_change", weapon); +} + +watch_weapon_changes() +{ + level endon( "end_game" ); + self endon( "disconnect" ); + self waittill("spawned_player"); + flag_wait("initial_blackscreen_passed"); + + if(level.script == "zm_prison") //prevent triggering weapon change when spawning in motd + { + level waittill("start_of_round"); + } + + self thread explosive_bullet(); //start explosive bullet background + while( isdefined( self ) ) + { + result = self waittill_any_return( "weapon_change", "fake_death", "player_downed" ); + weapon = self getCurrentWeapon(); + if(result == "player_downed" || result == "fake_death") + { + if(self hasperk("specialty_scavenger") || self hasperk("specialty_finalstand")) + { + if(self hasperk("specialty_scavenger")) + self thread tombstone_timeout(); + + self waittill_any("player_revived", "dance_on_my_grave", "tombstone_timedout", "chugabud_bleedout", "chugabud_effects_cleanup"); + } + } + // if(isdefined(self.afterlife) && self.afterlife) + // self waittill("spawned_player"); + // if (isdefined(self.aat_bar.bar)) + // { + if( IsDefined( self.aat[weapon] ) ) + { + self.aat_bar.alpha = 1; + self.aat_bar.bar.alpha = 1; + name = self.aat[weapon]; + self aat_hud(name); + } + else + { + self.aat_hud.alpha = 0; + self.aat_bar.alpha = 0; + self.aat_bar.bar.alpha = 0; + } + if( IsDefined( self.aat ) ) + { + keys = GetArrayKeys( self.aat ); + foreach( aat in keys ) + { + if(IsDefined( self.aat[aat] ) && isdefined( aat ) && !self hasweapon( aat )) + self.aat[aat] = undefined; + } + } + // } + } +} + +aat_hud(name) +{ + self endon("disconnect"); + level endon("game_ended"); + + if(isdefined(self.aat_hud)) + { + self.aat_hud destroy(); + self notify("hud_destroyed"); + } + + if(isDefined(name)) + { + if(name == "Thunder Wall") + { + label = &"Thunder Wall"; + color = (0,1,1); + } + else if(name == "Fireworks") + { + label = &"Fireworks"; + color = (0,1,0); + } + else if(name == "Turned") + { + label = &"Turned"; + color = (1,0.5,0.5); + } + else if(name == "Cluster") + { + label = &"Cluster"; + color = (0.4,0.4,0.2); + } + else if(name == "Headcutter") + { + label = &"Headcutter"; + color = (1,0,1); + } + else if(name == "Explosive") + { + label = &"Explosive"; + color = (0,0,1); + } + else if(name == "Blast Furnace") + { + label = &"Blast Furnace"; + color = (1,0,0); + } + else if(name == "Cryo Freeze") + { + label = &"Cryo Freeze"; + color = (0, 0.5, 1); + } + else if(name == "Dead Wire") + { + label = &"Dead Wire"; + color = (0.8, 0.75, 1); + } + else + { + color = (0, 0, 0); + } + + self.aat_hud = newClientHudElem(self); + self.aat_hud.alignx = "right"; + self.aat_hud.aligny = "bottom"; + self.aat_hud.horzalign = "user_right"; + self.aat_hud.vertalign = "user_bottom"; + if( getdvar( "mapname" ) == "zm_transit" || getdvar( "mapname" ) == "zm_highrise" || getdvar( "mapname" ) == "zm_nuked") + { + self.aat_hud.x = -85; + self.aat_hud.y = -22; + } + else if( getdvar( "mapname" ) == "zm_tomb" ) + { + self.aat_hud.x = -110; + self.aat_hud.y = -80; + } + else + { + self.aat_hud.x = -95; + self.aat_hud.y = -80; + } + self.aat_hud.archived = 1; + self.aat_hud.fontscale = 1.25; + self.aat_hud.alpha = 1; + self.aat_hud.color = color; + self.aat_hud.hidewheninmenu = 1; + self.aat_hud.label = label; + self thread aat_cooldown_hud_watcher(); + if (!(isdefined(self.aat_lock))) + { + self thread aat_loading_bar(); + self.aat_lock = 1; + } + + } +} + +aat_loading_bar() +{ + self endon("disconnect"); + level endon("game_ended"); + + if (getdvar("net_port") == "30010" || getdvar("net_port") == "30011" || check_for_botb_port() == true) + { + return; + } + level.primaryprogressbarwidth = 60; + level.primaryprogressbarheight = 5; + self.aat_bar = self createprimaryprogressbar(); + self.aat_bar setpoint(undefined, "BOTTOM", 320, 20); + self.aat_bar.hidewheninmenu = 1; + self.aat_bar.bar.hidewheninmenu = 1; + self.aat_bar.barframe.hidewheninmenu = 1; + + level.primaryprogressbarwidth = 400; + level.primaryprogressbarheight = 15; + for (;;) + { + current_weapon = self getCurrentWeapon(); + weapons_inventory = self GetWeaponsListPrimaries(); + + for (i = 0; i < weapons_inventory.size; i++) + { + if (current_weapon == weapons_inventory[i]) + { + index = i; + break; + } + else + { + wait .05; + continue; + } + } + self.aat_bar updatebar(self.aat_remaining_cooldown[index] / self.aat_cooldown_duration[index]); + if(isdefined(self.aat_hud.color)) + self.aat_bar.bar.color = self.aat_hud.color; + wait .05; + } +} + +aat_cooldown_hud_watcher() +{ + self endon("disconnect"); + level endon("game_ended"); + self endon("hud_destroyed"); + + for (;;) + { + if (self.is_aat_blinking == 1) + { + wait 1; + continue; + } + index = 0; + current_weapon = self getCurrentWeapon(); + weapons_inventory = self GetWeaponsListPrimaries(); + weapon_match = 0; + + for (i = 0; i < weapons_inventory.size; i++) + { + if (current_weapon == weapons_inventory[i]) + { + index = i; + weapon_match = 1; + break; + } + } + + if (!IsDefined( self.aat[current_weapon] )) + self.aat_hud.alpha = 0; + else if (weapon_match != 0) + { + if (self.weapons_aat_cooldown[index] == 0) + self.aat_hud.alpha = 0.8; + else + self.aat_hud.alpha = 0.2; + } + wait 0.1; + } +} + +can_aat_damage(ai_zombies) +{ + if(isdefined(ai_zombies.is_turned) && ai_zombies.is_turned) + return 0; + + if(isdefined(level.sloth) && ai_zombies == level.sloth) + return 0; + + if(isDefined(ai_zombies.is_avogadro) && ai_zombies.is_avogadro || isDefined(ai_zombies.is_brutus) && ai_zombies.is_brutus || isDefined(ai_zombies.is_mechz) && ai_zombies.is_mechz ) + return 0; + + return 1; +} + +solo_tombstone_removal() +{ + level notify( "tombstone_on" ); +} + +turn_tombstone_on() +{ + level endon("end_game"); + self endon("disconnect"); + level endon("end_game"); + while ( 1 ) + { + machine = getentarray( "vending_tombstone", "targetname" ); + machine_triggers = getentarray( "vending_tombstone", "target" ); + i = 0; + while ( i < machine.size ) + { + machine[ i ] setmodel( level.machine_assets[ "tombstone" ].off_model ); + i++; + } + level thread do_initial_power_off_callback( machine, "tombstone" ); + array_thread( machine_triggers, ::set_power_on, 0 ); + level waittill( "tombstone_on" ); + i = 0; + while ( i < machine.size ) + { + machine[ i ] setmodel( level.machine_assets[ "tombstone" ].on_model ); + machine[ i ] vibrate( vectorScale( ( 0, -1, 0 ), 100 ), 0,3, 0,4, 3 ); + machine[ i ] playsound( "zmb_perks_power_on" ); + machine[ i ] thread perk_fx( "tombstone_light" ); + machine[ i ] thread play_loop_on_machine(); + i++; + } + level notify( "specialty_scavenger_power_on" ); + array_thread( machine_triggers, ::set_power_on, 1 ); + if ( isDefined( level.machine_assets[ "tombstone" ].power_on_callback ) ) + { + array_thread( machine, level.machine_assets[ "tombstone" ].power_on_callback ); + } + level waittill( "tombstone_off" ); + if ( isDefined( level.machine_assets[ "tombstone" ].power_off_callback ) ) + { + array_thread( machine, level.machine_assets[ "tombstone" ].power_off_callback ); + } + array_thread( machine, ::turn_perk_off ); + players = get_players(); + _a1718 = players; + _k1718 = getFirstArrayKey( _a1718 ); + while ( isDefined( _k1718 ) ) + { + player = _a1718[ _k1718 ]; + player.hasperkspecialtytombstone = undefined; + _k1718 = getNextArrayKey( _a1718, _k1718 ); + } + } +} + +perk_machine_spawn_init() +{ + level endon("end_game"); + self endon("disconnect"); + level endon("end_game"); + 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 + "_perks_" ) + location; + pos = []; + if ( isDefined( level.override_perk_targetname ) ) + { + structs = getstructarray( level.override_perk_targetname, "targetname" ); + } + else + { + structs = getstructarray( "zm_perk_machine", "targetname" ); + } + _a3578 = structs; + _k3578 = getFirstArrayKey( _a3578 ); + while ( isDefined( _k3578 ) ) + { + struct = _a3578[ _k3578 ]; + if ( isDefined( struct.script_string ) ) + { + tokens = strtok( struct.script_string, " " ); + _a3583 = tokens; + _k3583 = getFirstArrayKey( _a3583 ); + while ( isDefined( _k3583 ) ) + { + token = _a3583[ _k3583 ]; + if ( token == match_string ) + { + pos[ pos.size ] = struct; + } + _k3583 = getNextArrayKey( _a3583, _k3583 ); + } + } + else pos[ pos.size ] = struct; + _k3578 = getNextArrayKey( _a3578, _k3578 ); + } + if ( !isDefined( pos ) || pos.size == 0 ) + { + return; + } + precachemodel( "zm_collision_perks1" ); + i = 0; + while ( i < pos.size ) + { + 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.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 ) + { + bump_trigger = undefined; + } + else + { + 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" ) + { + 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.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 ) ) + { + use_trigger.blocker_model = pos[ i ].blocker_model; + } + if ( isDefined( pos[ i ].script_int ) ) + { + perk_machine.script_int = pos[ i ].script_int; + } + if ( isDefined( pos[ i ].turn_on_notify ) ) + { + perk_machine.turn_on_notify = pos[ i ].turn_on_notify; + } + if ( perk == "specialty_scavenger" || perk == "specialty_scavenger_upgrade" ) + { + use_trigger.script_sound = "mus_perks_tombstone_jingle"; + use_trigger.script_string = "tombstone_perk"; + use_trigger.script_label = "mus_perks_tombstone_sting"; + use_trigger.target = "vending_tombstone"; + perk_machine.script_string = "tombstone_perk"; + perk_machine.targetname = "vending_tombstone"; + if ( isDefined( bump_trigger ) ) + { + bump_trigger.script_string = "tombstone_perk"; + } + } + 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 ); + } + } + i++; + } +} + +isTown() +{ + level endon("end_game"); + self endon("disconnect"); + if (isDefined(level.zombiemode_using_tombstone_perk) && level.zombiemode_using_tombstone_perk) + { + level thread perk_machine_spawn_init(); + thread solo_tombstone_removal(); + thread turn_tombstone_on(); + } +} + +check_for_botb_port() +{ + found = 0; + foreach(port in level.net_port_botb) + { + if (getdvar("net_port") == port) + found = 1; + } + if (found == 0) + return false; + return true; +} \ No newline at end of file diff --git a/t6/scripts/_clientids.gsc b/t6/scripts/_clientids.gsc new file mode 100644 index 0000000..4ebcd70 --- /dev/null +++ b/t6/scripts/_clientids.gsc @@ -0,0 +1,240 @@ +#include maps\mp\_utility; +#include common_scripts\utility; +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\zombies\_zm; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\gametypes_zm\_hud_message; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_score; + +init() +{ + //level thread playerBank(); // Bank plugin + level thread onPlayerConnect(); + level thread roundLogger(); // Stats plugin +} + +onPlayerConnect() +{ + level endon( "end_game" ); + self endon( "disconnect" ); + for (;;) + { + level waittill( "connected", player ); + + // --- start stats plugin --- + player thread statsUpdate(); + player thread downLogger(); + player thread reviveLogger(); + // --- end stats plugin --- + + // --- start bank plugin --- + /* player thread setPlayerMoney(); + player thread endPlayerMoney(); + player thread endPlayerMoney2();*/ + // --- end bank plugin --- + } +} + +// -- end bank plugin -- + +// -- start stats plugin -- +arr2json(arr) { + if (isObj(arr)) { + return obj2json(arr); + } + keys = getArrayKeys(arr); + string = "["; + for (i = 0; i < keys.size; i++) { + key = keys[i]; + if (!isObj(arr[key])) { + if (isInt(arr[key])) { + string += arr[key]; + } else { + string += "\"" + arr[key] + "\""; + } + } else { + string += obj2json(arr[key]); + } + if (i < keys.size - 1) { + string += ", "; + } + } + string += "]"; + return string; +} + +isInt(var) { + return int(var) == var; +} + +json_encode(obj) { + if (!IsArray(obj)) { + return "\"" + obj + "\"\n"; + } + if (!isObj(obj)) { + return arr2json(obj) + "\n"; + } + return obj2json(obj) + "\n"; +} + +obj2json(obj) { + string = "{"; + keys = getArrayKeys(obj); + if (!isDefined(keys)) { + return "{ struct }"; + } + for (i = 0; i < keys.size; i++) { + key = keys[i]; + if (IsArray(obj[key])) { + string += "\"" + key + "\": " + arr2json(obj[key]); + } else { + if (!isInt(obj[key])) { + string += "\"" + key + "\": \"" + obj[key] + "\""; + } else { + string += "\"" + key + "\": " + obj[key]; + } + } + if (i < keys.size - 1) { + string += ", "; + } + } + string += "}"; + return string; +} + +isObj(obj) { + keys = getArrayKeys(obj); + if (!isDefined(keys)) { + return false; + } + for (i = 0; i < keys.size; i++) { + if (int(keys[i]) == 0 && keys[i] != 0) { + return true; + } + } + return false; +} + +playersToArr() { + players = []; + for (i = 0; i < level.players.size; i++) { + players[i] = []; + players[i]["Name"] = level.players[i].name; + players[i]["Guid"] = level.players[i] getGuid(); + players[i]["Clientslot"] = level.players[i] getEntityNumber(); + players[i]["Stats"] = level.players[i] getPlayerStats(); + + } + return players; +} + +statsUpdate() { + self endon("disconnect"); + for (;;) { + obj = []; + obj["event"] = "update_stats"; + obj["player"] = []; + obj["player"]["Guid"] = self.guid; + obj["player"]["Clientslot"] = self getEntityNumber(); + obj["player"]["Stats"] = self getPlayerStats(); + logPrint(json_encode(obj)); + wait 60; + } +} + +getPlayerStats() { + stats = []; + stats["Kills"] = self.pers["kills"]; + stats["Downs"] = self.pers["downs"]; + stats["Revives"] = self.pers["revives"]; + stats["Headshots"] = self.pers["headshots"]; + stats["Score"] = self.score_total; + return stats; +} + +reviveLogger() { + for (;;) { + self waittill("player_revived"); + obj = []; + obj["event"] = "player_revived"; + obj["player"] = []; + obj["player"]["Name"] = self.name; + obj["player"]["Guid"] = self.guid; + obj["player"]["Clientslot"] = self getEntityNumber(); + obj["player"]["Stats"] = self getPlayerStats(); + logPrint(json_encode(obj)); + } +} + +downLogger() { + for (;;) { + self waittill("player_downed"); + obj = []; + obj["event"] = "player_downed"; + obj["player"] = []; + obj["player"]["Name"] = self.name; + obj["player"]["Guid"] = self.guid; + obj["player"]["Clientslot"] = self getEntityNumber(); + obj["player"]["Stats"] = self getPlayerStats(); + logPrint(json_encode(obj)); + } +} + +roundLogger() { + if (check_for_botb_port() == true) + return; + for (;;) + { + if (getDvar("isPanzer") == "1") + { + return; + } + else if (getDvar("isPanzer") == "0") + { + break; + } + wait 0.5; + } + for (;;) + { + if (getDvar("isBus") == "1") + { + return; + } + else if (getDvar("isBus") == "0") + { + break; + } + wait 0.5; + } + for (;;) { + level waittill( "start_of_round" ); + obj = []; + obj["event"] = "round_start"; + obj["players"] = playersToArr(); + obj["round"] = level.round_number; + logPrint(json_encode(obj)); + } +} +// -- end stats plugin -- + +check_for_botb_port() +{ + found = 0; + if (isdefined(level.net_port_botb)) + { + foreach(port in level.net_port_botb) + { + if (getdvar("net_port") == port) + found = 1; + } + } + if (found == 0) + return false; + return true; +} diff --git a/t6/scripts/announcements.gsc b/t6/scripts/announcements.gsc new file mode 100644 index 0000000..012ed23 --- /dev/null +++ b/t6/scripts/announcements.gsc @@ -0,0 +1,105 @@ +#include maps\mp\_utility; +#include maps\mp\gametypes_zm\_hud_util; + +init() +{ + setDvar("bold", ""); + setDvar("ln", ""); + level thread checkRestartTime(); + level thread AnnouncementWatcher(); +} + +AnnouncementWatcher() +{ + for (;;) + { + if (getDvar("bold") != "") { + printBold = getDvar("bold"); + setDvar("bold", ""); + level thread TriplePrint(printBold); + + } + if (getDvar("ln") != "") { + printLn = getDvar("ln"); + setDvar("ln", ""); + level thread DoublePrint(printLn); + } + wait 0.5; + } +} + +DoublePrint(printLn) +{ + level endon("game_ended"); + iprintLn(printLn); + wait 5; + iprintLn(printLn); + return; +} + +TriplePrint(printBold) +{ + level endon("game_ended"); + iprintLnBold(printBold); + wait 2; + iprintLnBold(printBold); + wait 2; + iprintLnBold(printBold); + return; +} + +checkRestartTime() +{ + restart_interval = 21600000; //(12h) + restart_minus_10m = restart_interval - 600000; + restart_minus_5m = restart_interval - 300000; + restart_minus_2m = restart_interval - 120000; + restart_minus_1m = restart_interval - 60000; + + + level endon("game_ended"); + for (;;) + { + time = getTime(); + if (time >= restart_minus_10m) + { + printRestart("10 minutes."); + restart_minus_10m = restart_interval + 10000; //disable + } + if (time >= restart_minus_5m) + { + printRestart("5 minutes."); + restart_minus_5m = restart_interval + 10000; //disable + } + if (time >= restart_minus_2m) + { + printRestart("2 minutes."); + restart_minus_2m = restart_interval + 10000; //disable + } + if (time >= restart_minus_1m) + { + printRestart("1 minute."); + restart_minus_1m = restart_interval + 10000; //disable + } + wait 60; + } +} + +printRestart(msg) +{ + text = "Server ^3restarting^7 in ^1" + msg + " ^7Use ^2.d all^7 & ^2.save^7"; + TriplePrint(text); + DoublePrint(text); + wait 6; + DoublePrint(text); + TriplePrint(text); +} + +getPlayerByGuid(guid) { + for (i = 0; i < level.players.size; i++) { + if (isAlive(level.players[i]) && int(level.players[i] getGuid()) == int(guid)) { + return level.players[i]; + } + } + return false; +} \ No newline at end of file diff --git a/t6/scripts/bankv2.gsc b/t6/scripts/bankv2.gsc new file mode 100644 index 0000000..b31e023 --- /dev/null +++ b/t6/scripts/bankv2.gsc @@ -0,0 +1,258 @@ +#include maps\mp\zombies\_zm_power; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\zombies\_zm_chugabud; +#include maps\mp\zombies\_zm_afterlife; +#include maps\mp\zombies\_zm_tombstone; +#include maps\mp\zombies\_zm_perk_vulture; +#include maps\mp\zombies\_zm_weap_time_bomb; +#include maps\mp\_demo; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\gametypes_zm\_gameobjects; +#include maps\mp\zombies\_zm_buildables; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm_clone; +#include maps\mp\zombies\_zm_weap_cymbal_monkey; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm; +#include maps\mp\_visionset_mgr; +//motd +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_craftables; +#include maps\mp\zm_alcatraz_utility; +#include maps\mp\zm_alcatraz_gamemodes; +#include maps\mp\zm_prison_fx; +#include maps\mp\zm_prison_ffotd; +#include maps\mp\animscripts\zm_death; +#include maps\mp\zm_alcatraz_amb; +#include maps\mp\zombies\_load; +#include maps\mp\zm_prison_achievement; +#include maps\mp\gametypes_zm\_spawning; +#include maps\mp\zombies\_zm_perk_electric_cherry; +#include maps\mp\zombies\_zm_perk_divetonuke; +#include maps\mp\zm_alcatraz_distance_tracking; +#include maps\mp\zm_alcatraz_traps; +#include maps\mp\zm_alcatraz_travel; +#include maps\mp\zombies\_zm_magicbox_prison; +#include maps\mp\zombies\_zm_ai_basic; +#include maps\mp\zombies\_zm_weap_claymore; +#include maps\mp\zombies\_zm_weap_riotshield_prison; +#include maps\mp\zombies\_zm_weap_blundersplat; +#include maps\mp\zombies\_zm_weap_tomahawk; +#include maps\mp\zombies\_zm_zonemgr; +#include maps\mp\zm_alcatraz_weap_quest; +#include maps\mp\zm_alcatraz_grief_cellblock; +#include maps\mp\zm_prison; +#include character\c_zom_arlington; +#include character\c_zom_deluca; +#include character\c_zom_handsome; +#include character\c_zom_oleary; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_blockers; + +//points +#include common_scripts\utility; +#include maps\mp\_utility; + + +//timebomb +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\zombies\_zm_weapon_locker; +#include maps\mp\zombies\_zm_magicbox; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_spawner; + +init() { + level thread playerBank(); + setDvar("bank_withdraw", ""); + setDvar("bank_deposit", ""); + + if(getdvar("0_can_use_bank") != "") + setDvar("0_can_use_bank", ""); + if(getdvar("1_can_use_bank") != "") + setDvar("1_can_use_bank", ""); + if(getdvar("2_can_use_bank") != "") + setDvar("2_can_use_bank", ""); + if(getdvar("3_can_use_bank") != "") + setDvar("3_can_use_bank", ""); + if(getdvar("4_can_use_bank") != "") + setDvar("4_can_use_bank", ""); + if(getdvar("5_can_use_bank") != "") + setDvar("5_can_use_bank", ""); + if(getdvar("6_can_use_bank") != "") + setDvar("6_can_use_bank", ""); + if(getdvar("7_can_use_bank") != "") + setDvar("7_can_use_bank", ""); + if ( level.script == "zm_buried") + { + level thread checkTimeBombActive(); + } + if (level.script == "zm_buried" || level.script == "zm_tranzit" || level.script == "zm_highrise") + { + level.ta_tellerfee = 6942000; + level.ta_vaultfee = 1000; + } +} + +onPlayerConnect(player) +{ + player thread endPlayerMoney2(); + player thread endPlayerMoney(); // probably not necessary + player thread setPlayerMoney(); + player thread onPlayerSpawned(); + + if (level.script == "zm_prison") + { + player thread checkAfterlifeActive(); + } +} + +onPlayerSpawned() +{ + self endon( "disconnect" ); + level endon( "game_ended" ); + for(;;) + { + self waittill( "spawned_player" ); + if(self.score < 3000) + { + self.score = 3000; + } + } +} + +checkAfterlifeActive() +{ + level endon ("game_ended"); + self endon("disconnect"); + for (;;) + { + if (self.afterlife == 1) + { + if(getdvar(self getEntityNumber() + "_can_use_bank") != "1") + setDvar(self getEntityNumber() + "_can_use_bank", "1"); + } + else + { + if(getdvar(self getEntityNumber() + "_can_use_bank") != "") + setDvar(self getEntityNumber() + "_can_use_bank", ""); + } + wait 0.05; + } +} + +checkTimeBombActive() +{ + for (;;) + { + if (time_bomb_save_exists()) + { + if(getdvar("0_can_use_bank") != "0") + setDvar("0_can_use_bank", "0"); + if(getdvar("1_can_use_bank") != "0") + setDvar("1_can_use_bank", "0"); + if(getdvar("2_can_use_bank") != "0") + setDvar("2_can_use_bank", "0"); + if(getdvar("3_can_use_bank") != "0") + setDvar("3_can_use_bank", "0"); + if(getdvar("4_can_use_bank") != "0") + setDvar("4_can_use_bank", "0"); + if(getdvar("5_can_use_bank") != "0") + setDvar("5_can_use_bank", "0"); + if(getdvar("6_can_use_bank") != "0") + setDvar("6_can_use_bank", "0"); + if(getdvar("7_can_use_bank") != "0") + setDvar("7_can_use_bank", "0"); + } + else + { + if(getdvar("0_can_use_bank") != "") + setDvar("0_can_use_bank", ""); + if(getdvar("1_can_use_bank") != "") + setDvar("1_can_use_bank", ""); + if(getdvar("2_can_use_bank") != "") + setDvar("2_can_use_bank", ""); + if(getdvar("3_can_use_bank") != "") + setDvar("3_can_use_bank", ""); + if(getdvar("4_can_use_bank") != "") + setDvar("4_can_use_bank", ""); + if(getdvar("5_can_use_bank") != "") + setDvar("5_can_use_bank", ""); + if(getdvar("6_can_use_bank") != "") + setDvar("6_can_use_bank", ""); + if(getdvar("7_can_use_bank") != "") + setDvar("7_can_use_bank", ""); + } + wait 0.2; + } +} + +time_bomb_save_exists() +{ + return isdefined( level.time_bomb_save_data ) && isdefined( level.time_bomb_save_data.save_ready ) && level.time_bomb_save_data.save_ready; +} + + +endPlayerMoney() +{ + self endon("disconnect"); + for (;;) { + level waittill("end_game"); + setDvar(self getEntityNumber() + "_money", 0); + } +} + +endPlayerMoney2() +{ + self endon("disconnect"); + for (;;) { + level waittill("_zombie_game_over"); + setDvar(self getEntityNumber() + "_money", 0); + } +} + + +setPlayerMoney() +{ + level endon("end_game"); + level endon("_zombie_game_over"); + for (;;) { + if (!isAlive(self)) { + setDvar(self getEntityNumber() + "_money", 0); + } else { + setDvar(self getEntityNumber() + "_money", self.score); + } + wait 0.05; + } +} + +getPlayerByGuid(guid) +{ + for (i = 0; i < level.players.size; i++) { + if (isAlive(level.players[i]) && int(level.players[i] getGuid()) == int(guid)) { + return level.players[i]; + } + } + return false; +} + +playerBank() +{ + for (;;) { + if (getDvar("bank_withdraw") != "") { + withdraw = strTok(getDvar("bank_withdraw"), ";"); + setDvar("bank_withdraw", ""); + getPlayerByGuid(withdraw[0]).score += int(withdraw[1]); + getPlayerByGuid(withdraw[0]) iPrintLn("Withdrew ^2$" + int(withdraw[1]) + "^7 from your bank account!"); + } + if (getDvar("bank_deposit") != "") { + deposit = strTok(getDvar("bank_deposit"), ";"); + setDvar("bank_deposit", ""); + getPlayerByGuid(deposit[0]).score -= int(deposit[1]); + getPlayerByGuid(deposit[0]) iPrintLn("Deposited ^2$" + int(deposit[1]) + "^7 into your bank account!"); + } + wait 0.05; + } +} \ No newline at end of file diff --git a/t6/scripts/dev.gsc b/t6/scripts/dev.gsc new file mode 100644 index 0000000..ce4b935 --- /dev/null +++ b/t6/scripts/dev.gsc @@ -0,0 +1,4 @@ +init() +{ + setdvar("developer", "0"); +} \ No newline at end of file diff --git a/t6/scripts/difficulty_selector.gsc b/t6/scripts/difficulty_selector.gsc new file mode 100644 index 0000000..e69de29 diff --git a/t6/scripts/disable_lunge.gsc b/t6/scripts/disable_lunge.gsc new file mode 100644 index 0000000..e40a4f1 --- /dev/null +++ b/t6/scripts/disable_lunge.gsc @@ -0,0 +1,15 @@ +init() +{ + level thread on_player_connect(); +} + +on_player_connect() +{ + level endon("game_ended"); + + for(;;) + { + level waittill("connected", player); + player setClientDvar( "aim_automelee_enabled", 0 ); + } +} \ No newline at end of file diff --git a/t6/scripts/disable_revive_money.gsc b/t6/scripts/disable_revive_money.gsc new file mode 100644 index 0000000..23caf2c --- /dev/null +++ b/t6/scripts/disable_revive_money.gsc @@ -0,0 +1,188 @@ +#include maps\mp\zombies\_zm_power; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\zombies\_zm_chugabud; +#include maps\mp\zombies\_zm_afterlife; +#include maps\mp\zombies\_zm_tombstone; +#include maps\mp\zombies\_zm_perk_vulture; +#include maps\mp\zombies\_zm_weap_time_bomb; +#include maps\mp\_demo; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\gametypes_zm\_gameobjects; +#include maps\mp\zombies\_zm_buildables; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm_clone; +#include maps\mp\zombies\_zm_weap_cymbal_monkey; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm; +#include maps\mp\_visionset_mgr; +//motd +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_craftables; +#include maps\mp\zm_alcatraz_utility; +#include maps\mp\zm_alcatraz_gamemodes; +#include maps\mp\zm_prison_fx; +#include maps\mp\zm_prison_ffotd; +#include maps\mp\animscripts\zm_death; +#include maps\mp\zm_alcatraz_amb; +#include maps\mp\zombies\_load; +#include maps\mp\zm_prison_achievement; +#include maps\mp\gametypes_zm\_spawning; +#include maps\mp\zombies\_zm_perk_electric_cherry; +#include maps\mp\zombies\_zm_perk_divetonuke; +#include maps\mp\zm_alcatraz_distance_tracking; +#include maps\mp\zm_alcatraz_traps; +#include maps\mp\zm_alcatraz_travel; +#include maps\mp\zombies\_zm_magicbox_prison; +#include maps\mp\zombies\_zm_ai_basic; +#include maps\mp\zombies\_zm_weap_claymore; +#include maps\mp\zombies\_zm_weap_riotshield_prison; +#include maps\mp\zombies\_zm_weap_blundersplat; +#include maps\mp\zombies\_zm_weap_tomahawk; +#include maps\mp\zombies\_zm_zonemgr; +#include maps\mp\zm_alcatraz_weap_quest; +#include maps\mp\zm_alcatraz_grief_cellblock; +#include maps\mp\zm_prison; +#include character\c_zom_arlington; +#include character\c_zom_deluca; +#include character\c_zom_handsome; +#include character\c_zom_oleary; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_blockers; + +//points +#include common_scripts\utility; +#include maps\mp\_utility; + + +//timebomb +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\zombies\_zm_weapon_locker; +#include maps\mp\zombies\_zm_magicbox; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_spawner; + +main() +{ + replaceFunc( maps\mp\zombies\_zm_score::player_add_points, ::disablerevivemoney); +} + +disablerevivemoney(event, mod, hit_location, is_dog, zombie_team, damage_weapon) +{ + if ( level.intermission ) + return; + + if ( !is_player_valid( self ) ) + return; + + player_points = 0; + team_points = 0; + multiplier = get_points_multiplier( self ); + + switch ( event ) + { + case "death": + player_points = get_zombie_death_player_points(); + team_points = get_zombie_death_team_points(); + points = self player_add_points_kill_bonus( mod, hit_location ); + + if ( level.zombie_vars[self.team]["zombie_powerup_insta_kill_on"] == 1 && mod == "MOD_UNKNOWN" ) + points *= 2; + + player_points += points; + + if ( team_points > 0 ) + team_points += points; + + if ( mod == "MOD_GRENADE" || mod == "MOD_GRENADE_SPLASH" ) + { + self maps\mp\zombies\_zm_stats::increment_client_stat( "grenade_kills" ); + self maps\mp\zombies\_zm_stats::increment_player_stat( "grenade_kills" ); + } + + break; + case "ballistic_knife_death": + player_points = get_zombie_death_player_points() + level.zombie_vars["zombie_score_bonus_melee"]; + self score_cf_increment_info( "death_melee" ); + break; + case "damage_light": + player_points = level.zombie_vars["zombie_score_damage_light"]; + self score_cf_increment_info( "damage" ); + break; + case "damage": + player_points = level.zombie_vars["zombie_score_damage_normal"]; + self score_cf_increment_info( "damage" ); + break; + case "damage_ads": + player_points = int( level.zombie_vars["zombie_score_damage_normal"] * 1.25 ); + self score_cf_increment_info( "damage" ); + break; + case "rebuild_board": + case "carpenter_powerup": + player_points = mod; + break; + case "bonus_points_powerup": + player_points = mod; + break; + case "nuke_powerup": + player_points = mod; + team_points = mod; + break; + case "thundergun_fling": + case "riotshield_fling": + case "jetgun_fling": + player_points = mod; + break; + case "hacker_transfer": + player_points = mod; + break; + case "reviver": + player_points = 0; + break; + case "vulture": + player_points = mod; + break; + case "build_wallbuy": + player_points = mod; + break; + default: + assert( 0, "Unknown point event" ); + break; + } + + player_points = multiplier * round_up_score( player_points, 5 ); + team_points = multiplier * round_up_score( team_points, 5 ); + + if ( ( event == "death" || event == "ballistic_knife_death" ) && isdefined( self.point_split_receiver )) + { + split_player_points = player_points - round_up_score( player_points * self.point_split_keep_percent, 10 ); + self.point_split_receiver add_to_player_score( split_player_points ); + player_points -= split_player_points; + } + + if ( is_true( level.pers_upgrade_pistol_points ) ) + player_points = self maps\mp\zombies\_zm_pers_upgrades_functions::pers_upgrade_pistol_points_set_score( player_points, event, mod, damage_weapon ); + + self add_to_player_score( player_points ); + self.pers["score"] = self.score; + + if ( isdefined( level._game_module_point_adjustment ) ) + level [[ level._game_module_point_adjustment ]]( self, zombie_team, player_points ); +} + +get_points_multiplier( player ) +{ + multiplier = level.zombie_vars[player.team]["zombie_point_scalar"]; + + if ( isdefined( level.current_game_module ) && level.current_game_module == 2 ) + { + if ( isdefined( level._race_team_double_points ) && level._race_team_double_points == player._race_team ) + return multiplier; + else + return 1; + } + + return multiplier; +} \ No newline at end of file diff --git a/t6/scripts/dropweapon.gsc b/t6/scripts/dropweapon.gsc new file mode 100644 index 0000000..4df475d --- /dev/null +++ b/t6/scripts/dropweapon.gsc @@ -0,0 +1,141 @@ +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\gametypes_zm\_weapon_utils; +#include maps\mp\gametypes_zm\_weaponobjects; +#include maps\mp\_sticky_grenade; +#include maps\mp\_bb; +#include maps\mp\gametypes_zm\_weapons; +#include maps\mp\_challenges; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\gametypes_zm\_globallogic_utils; +#include maps\mp\gametypes_zm\_shellshock; +#include maps\mp\gametypes_zm\_gameobjects; + +main() +{ + setDvar("drop", "0"); + replaceFunc(maps\mp\gametypes_zm\_weapons::dropweapontoground, ::dropweapon); +} + +init() +{ + level thread dropPlayerWeapon(); +} + +dropPlayerWeapon() +{ + level waittill("initial_blackscreen_passed"); + level endon("game_ended"); + + for(;;) + { + if (getDvar("drop") != "0") + { + drop = strTok(getDvar("drop"), ";"); + setDvar("drop", "0"); + + if (!getPlayerByGuid(drop[0]) maps\mp\zombies\_zm_laststand::player_is_in_laststand() && getPlayerByGuid(drop[0]) getcurrentweapon() != "syrette_zm" && getPlayerByGuid(drop[0]) getcurrentweapon() != "syrette_afterlife_zm" && getPlayerByGuid(drop[0]) getcurrentweapon() != "zombie_tomahawk_flourish") + { + getPlayerByGuid(drop[0]) dropweapon(getPlayerByGuid(drop[0]) GetCurrentWeapon()); + iPrintLn("^5" + getPlayerByGuid(drop[0]).name + "^7 dropped a ^5weapon^7 on the ground!"); + } + } + wait 0.1; + } +} + +getPlayerByGuid(guid) { + for (i = 0; i < level.players.size; i++) { + if (isAlive(level.players[i]) && int(level.players[i] getGuid()) == int(guid)) { + return level.players[i]; + } + } + return false; +} + + +dropweapon(weapon) +{ + if ( !isdefined( weapon ) ) + { +/# + if ( getdvar( _hash_8F7FC88 ) == "1" ) + println( "didn't drop weapon: not defined" ); +#/ + return; + } + if (weapon == "syrette_zm" || weapon == "syrette_afterlife_zm" ) + { + return; + } + if ( weapon == "none" ) + { +/# + if ( getdvar( _hash_8F7FC88 ) == "1" ) + println( "didn't drop weapon: weapon == none" ); +#/ + return; + } + + if ( !self hasweapon( weapon ) ) + { +/# + if ( getdvar( _hash_8F7FC88 ) == "1" ) + println( "didn't drop weapon: don't have it anymore (" + weapon + ")" ); +#/ + return; + } + + if ( !self anyammoforweaponmodes( weapon ) ) + { +/# + if ( getdvar( _hash_8F7FC88 ) == "1" ) + println( "didn't drop weapon: no ammo for weapon modes" ); +#/ + switch ( weapon ) + { + case "mp40_blinged_mp": + case "minigun_mp": + case "m32_mp": + case "m220_tow_mp": + case "m202_flash_mp": + self takeweapon( weapon ); + break; + default: + break; + } + + return; + } + + + clipammo = self getweaponammoclip( weapon ); + stockammo = self getweaponammostock( weapon ); + clip_and_stock_ammo = clipammo + stockammo; + + if ( !clip_and_stock_ammo ) + { +/# + if ( getdvar( _hash_8F7FC88 ) == "1" ) + println( "didn't drop weapon: no ammo" ); +#/ + return; + } + + stockmax = weaponmaxammo( weapon ); + + if ( stockammo > stockmax ) + stockammo = stockmax; + + item = self dropitem( weapon ); +/# + if ( getdvar( _hash_8F7FC88 ) == "1" ) + println( "dropped weapon: " + weapon ); +#/ + droplimitedweapon( weapon, self, item ); + item itemweaponsetammo( clipammo, stockammo ); + item.owner = self; + item thread watchpickup(); + item thread deletepickupafterawhile(); + +} \ No newline at end of file diff --git a/t6/scripts/dvar.gsc b/t6/scripts/dvar.gsc new file mode 100644 index 0000000..35bd80b --- /dev/null +++ b/t6/scripts/dvar.gsc @@ -0,0 +1,30 @@ +#include common_scripts\utility; + +init() +{ + setdvar("ee_speedrun", "0"); + setdvar("upgraded_tomahawk", "0"); + setdvar("golden_spork", "0"); + setdvar("botb_hitless", "0"); + + setDvar("gamemode_speedrun_quest_pia", "0"); + setDvar("gamemode_speedrun_quest_titb", "0"); + setDvar("gamemode_speedrun_quest_botb", "0"); + setDvar("ee_speedrun_quest_transit", "0"); + setDvar("ee_speedrun_quest_tomb", "0"); + setDvar("ee_speedrun_quest_prison", "0"); + setDvar("ee_speedrun_quest_highrise", "0"); + setDvar("ee_speedrun_quest_buried", "0"); + setdvar("raid_boss_quest", "0"); + + setdvar("guild_modifier", "0"); + setdvar("skill_cooldown", "0"); + setdvar("hat", "0"); + + setdvar("player_backSpeedScale", "1"); + setdvar("player_strafeSpeedScale", "1"); + setdvar("player_sprintStrafeSpeedScale", "1"); + + flag_wait("initial_blackscreen_passed"); + setdvar("restart1", "1"); +} \ No newline at end of file diff --git a/t6/scripts/ee_timer.gsc b/t6/scripts/ee_timer.gsc new file mode 100644 index 0000000..9a9e2be --- /dev/null +++ b/t6/scripts/ee_timer.gsc @@ -0,0 +1,134 @@ +#include maps\mp\_utility; +#include common_scripts\utility; + +init() +{ + setDvar("EE_Completion", "0"); + level thread onEECompletion(); + + flag_wait("initial_blackscreen_passed"); + level.start_time = GetTime(); +} + +onEECompletion() +{ + flag_wait("initial_blackscreen_passed"); + if (level.script == "zm_tomb") + { + level endon( "game_ended" ); + level waittill("tomb_sidequest_complete"); + setDvar("EE_Completion", "1"); + max_time = (35 * 60 * 1000); + if (GetTime() - level.start_time < max_time) + { + str = ""; + foreach(index, player in level.players) + { + str += player getguid(); + if (index + 1 < level.players.size) + str += ";"; + } + setdvar("ee_speedrun", str); + } + txt = ""; + index = 0; + foreach(player in level.players) + { + txt += player getguid() + "-" + player.kills; + index++; + if (index < level.players.size) + txt += ";"; + } + setdvar("ee_speedrun_quest_tomb", ((GetTime() - level.start_time) / 1000 / 60) + ";" + txt); + print_time(); + return; + } + else if (level.script == "zm_prison") + { + level waittill("start_of_round"); + for (;;) + { + if (isdefined(level.final_flight_activated) && level.final_flight_activated == 1 && getDvar( "g_gametype" ) != "zgrief") + { + setDvar("EE_Completion", "3"); + txt = ""; + index = 0; + foreach(player in level.players) + { + txt += player getguid() + "-" + player.kills; + index++; + if (index < level.players.size) + txt += ";"; + } + setdvar("ee_speedrun_quest_prison", ((GetTime() - level.start_time) / 1000 / 60) + ";" + txt); + print_time(); + return; + } + wait 0.5; + } + } + else if (level.script == "zm_transit") + { + level waittill( "transit_sidequest_achieved" ); + setDvar("EE_Completion", "1"); + txt = ""; + index = 0; + foreach(player in level.players) + { + txt += player getguid() + "-" + player.kills; + index++; + if (index < level.players.size) + txt += ";"; + } + setdvar("ee_speedrun_quest_transit", ((GetTime() - level.start_time) / 1000 / 60) + ";" + txt); + print_time(); + return; + } + else if (level.script == "zm_buried") + { + level endon( "game_ended" ); + level waittill_any( "sq_richtofen_complete", "sq_maxis_complete" ); + setDvar("EE_Completion", "4"); + txt = ""; + index = 0; + foreach(player in level.players) + { + txt += player getguid() + "-" + player.kills; + index++; + if (index < level.players.size) + txt += ";"; + } + setdvar("ee_speedrun_quest_buried", ((GetTime() - level.start_time) / 1000 / 60) + ";" + txt); + print_time(); + return; + } + else if (level.script == "zm_highrise") + { + level endon( "game_ended" ); + level waittill( "highrise_sidequest_achieved" ); + setDvar("EE_Completion", "2"); + txt = ""; + index = 0; + foreach(player in level.players) + { + txt += player getguid() + "-" + player.kills; + index++; + if (index < level.players.size) + txt += ";"; + } + setdvar("ee_speedrun_quest_highrise", ((GetTime() - level.start_time) / 1000 / 60) + ";" + txt); + print_time(); + return; + } +} + +print_time() +{ + iprintln("^3EE completed^7 in : ^2" + ((GetTime() - level.start_time) / 1000 / 60) + "^7 minutes !"); + iprintln("^3EE completed^7 in : ^2" + ((GetTime() - level.start_time) / 1000 / 60) + "^7 minutes !"); + iprintln("^3EE completed^7 in : ^2" + ((GetTime() - level.start_time) / 1000 / 60) + "^7 minutes !"); + wait 5; + iprintln("^3EE completed^7 in : ^2" + ((GetTime() - level.start_time) / 1000 / 60) + "^7 minutes !"); + iprintln("^3EE completed^7 in : ^2" + ((GetTime() - level.start_time) / 1000 / 60) + "^7 minutes !"); + iprintln("^3EE completed^7 in : ^2" + ((GetTime() - level.start_time) / 1000 / 60) + "^7 minutes !"); +} \ No newline at end of file diff --git a/t6/scripts/faster_revive.gsc b/t6/scripts/faster_revive.gsc new file mode 100644 index 0000000..23ccda0 --- /dev/null +++ b/t6/scripts/faster_revive.gsc @@ -0,0 +1,181 @@ +#include maps\mp\zombies\_zm_laststand; +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\_demo; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\gametypes_zm\_gameobjects; +#include maps\mp\zombies\_zm_buildables; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm_chugabud; +#include maps\mp\zombies\_zm_perks; + +main() +{ + replacefunc(maps\mp\zombies\_zm_laststand::revive_do_revive, ::revive_do_revive_custom); +} + +revive_do_revive_custom( playerbeingrevived, revivergun ) +{ + assert( self is_reviving( playerbeingrevived ) ); + revivetime = 3; + + if ( self hasperk( "specialty_quickrevive" ) ) + revivetime /= 2; + + if ( self maps\mp\zombies\_zm_pers_upgrades_functions::pers_revive_active() ) + { + if (check_for_botb_port() == true || check_for_pia_port() == true || check_for_titb_port() == true && isdefined(self.perma_quick)) + revivetime *= 0.3; + else + revivetime *= 0.5; + } + + if (isdefined(level.faster_revive)) + { + revivetime *= 0.5; + } + if (isdefined(self.healer_multiplier)) + { + if (self.kills >= 200) + revivetime = 0; + else + revivetime *= (1 - float(self.kills / 200)); + } + timer = 0; + revived = 0; + playerbeingrevived.revivetrigger.beingrevived = 1; + playerbeingrevived.revive_hud settext( &"ZOMBIE_PLAYER_IS_REVIVING_YOU", self ); + playerbeingrevived revive_hud_show_n_fade( 3.0 ); + playerbeingrevived.revivetrigger sethintstring( "" ); + + if ( isplayer( playerbeingrevived ) ) + playerbeingrevived startrevive( self ); + + if ( !isdefined( self.reviveprogressbar ) ) + self.reviveprogressbar = self createprimaryprogressbar(); + + if ( !isdefined( self.revivetexthud ) ) + self.revivetexthud = newclienthudelem( self ); + + self thread laststand_clean_up_on_disconnect( playerbeingrevived, revivergun ); + + if ( !isdefined( self.is_reviving_any ) ) + self.is_reviving_any = 0; + + self.is_reviving_any++; + self thread laststand_clean_up_reviving_any( playerbeingrevived ); + self.reviveprogressbar updatebar( 0.01, 1 / revivetime ); + self.revivetexthud.alignx = "center"; + self.revivetexthud.aligny = "middle"; + self.revivetexthud.horzalign = "center"; + self.revivetexthud.vertalign = "bottom"; + self.revivetexthud.y = -113; + + if ( self issplitscreen() ) + self.revivetexthud.y = -347; + + self.revivetexthud.foreground = 1; + self.revivetexthud.font = "default"; + self.revivetexthud.fontscale = 1.8; + self.revivetexthud.alpha = 1; + self.revivetexthud.color = ( 1, 1, 1 ); + self.revivetexthud.hidewheninmenu = 1; + + if ( self maps\mp\zombies\_zm_pers_upgrades_functions::pers_revive_active() ) + self.revivetexthud.color = ( 0.5, 0.5, 1.0 ); + + self.revivetexthud settext( &"ZOMBIE_REVIVING" ); + self thread check_for_failed_revive( playerbeingrevived ); + + while ( self is_reviving( playerbeingrevived ) ) + { + wait 0.05; + timer += 0.05; + + if ( self player_is_in_laststand() ) + break; + + if ( isdefined( playerbeingrevived.revivetrigger.auto_revive ) && playerbeingrevived.revivetrigger.auto_revive == 1 ) + break; + + if ( timer >= revivetime ) + { + revived = 1; + break; + } + } + + if ( isdefined( self.reviveprogressbar ) ) + self.reviveprogressbar destroyelem(); + + if ( isdefined( self.revivetexthud ) ) + self.revivetexthud destroy(); + + if ( isdefined( playerbeingrevived.revivetrigger.auto_revive ) && playerbeingrevived.revivetrigger.auto_revive == 1 ) + { + + } + else if ( !revived ) + { + if ( isplayer( playerbeingrevived ) ) + playerbeingrevived stoprevive( self ); + } + + playerbeingrevived.revivetrigger sethintstring( &"ZOMBIE_BUTTON_TO_REVIVE_PLAYER" ); + playerbeingrevived.revivetrigger.beingrevived = 0; + self notify( "do_revive_ended_normally" ); + self.is_reviving_any--; + + if ( !revived ) + playerbeingrevived thread checkforbleedout( self ); + + return revived; +} + +check_for_titb_port() +{ + found = 0; + foreach(port in level.net_port_titb) + { + if (getdvar("net_port") == port) + found = 1; + } + if (found == 0) + return false; + return true; +} + +check_for_botb_port() +{ + found = 0; + if (isdefined(level.net_port_botb)) + { + foreach(port in level.net_port_botb) + { + if (getdvar("net_port") == port) + found = 1; + } + } + if (found == 0) + return false; + return true; +} + +check_for_pia_port() +{ + found = 0; + if (isdefined(level.net_port_pia)) + { + foreach(port in level.net_port_pia) + { + if (getdvar("net_port") == port) + found = 1; + } + } + if (found == 0) + return false; + return true; +} \ No newline at end of file diff --git a/t6/scripts/fastwavespawn.gsc b/t6/scripts/fastwavespawn.gsc new file mode 100644 index 0000000..018c444 --- /dev/null +++ b/t6/scripts/fastwavespawn.gsc @@ -0,0 +1,104 @@ +#include maps\mp\gametypes_zm\_globallogic_player; +#include maps\mp\gametypes_zm\_spawning; +#include maps\mp\gametypes_zm\_globallogic_audio; +#include maps\mp\gametypes_zm\_globallogic_utils; +#include maps\mp\gametypes_zm\_globallogic; +#include maps\mp\gametypes_zm\_hud_message; +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\gametypes_zm\_globallogic_ui; +#include maps\mp\gametypes_zm\_globallogic_defaults; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\gametypes_zm\_globallogic_score; +#include maps\mp\gametypes_zm\_hostmigration; +#include maps\mp\gametypes_zm\_globallogic_spawn; +#include maps\mp\gametypes_zm\_spectating; +#include maps\mp\_demo; +#include maps\mp\gametypes_zm\_weapons; +#include maps\mp\gametypes_zm\_spawnlogic; +#include maps\mp\_challenges; +#include maps\mp\gametypes_zm\_tweakables; + +#include common_scripts\utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_ffotd; +#include maps\mp\zombies\_zm; +#include maps\mp\_visionset_mgr; +#include maps\mp\zombies\_zm_devgui; +#include maps\mp\zombies\_zm_zonemgr; +#include maps\mp\zombies\_zm_unitrigger; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_blockers; +#include maps\mp\zombies\_zm_bot; +#include maps\mp\zombies\_zm_clone; +#include maps\mp\zombies\_zm_buildables; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\zombies\_zm_magicbox; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm_playerhealth; +#include maps\mp\zombies\_zm_power; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_spawner; +#include maps\mp\zombies\_zm_gump; +#include maps\mp\zombies\_zm_timer; +#include maps\mp\zombies\_zm_traps; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_tombstone; +#include maps\mp\zombies\_zm_pers_upgrades; +#include maps\mp\gametypes_zm\_zm_gametype; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\zombies\_zm_melee_weapon; +#include maps\mp\zombies\_zm_ai_dogs; +#include maps\mp\zombies\_zm_pers_upgrades_system; +#include maps\mp\zombies\_zm_ai_basic; +#include maps\mp\zombies\_zm_game_module; + +init() +{ + //level.zombie_vars["zombie_between_round_time"] = 1; + //level.zombie_vars["zombie_intermission_time"] = 1; + // level.zombie_vars["zombie_move_speed_multiplier"] = 3600; + level thread SpawnRate(); + if (level.script == "zm_transit") + { + level.zombie_vars["riotshield_hit_points"] = 30000; + } + +} + +SpawnRate() +{ + level endon("game_ended"); + level.zombie_vars["zombie_spawn_delay"] = 1.5; + + lock = 0; + for (;;) + { + if (lock == 2 && level.round_number >= 15) + { + level.zombie_vars["zombie_spawn_delay"] = 0; + iPrintLn("^3The zombies are ^1REALLY angry ^7! Spawn rate ^1maxed out^7"); + wait 5; + iPrintLn("^3The zombies are ^1REALLY angry ^7! Spawn rate ^1maxed out^7"); + lock = 3; + } + if (lock == 1 && level.round_number >= 10) + { + level.zombie_vars["zombie_spawn_delay"] = 0.5; + lock = 2; + iPrintLn("^3The zombies are ^1angry ^7! Spawn rate ^3increased^7"); + wait 5; + iPrintLn("^3The zombies are ^1angry ^7! Spawn rate ^3increased^7"); + } + if (lock == 0 && level.round_number >= 5) + { + level.zombie_vars["zombie_spawn_delay"] = 1; + lock = 1; + iPrintLn("^3The zombies are ^1pissed ^7! Spawn rate ^3increased^7"); + wait 5; + iPrintLn("^3The zombies are ^1pissed ^7! Spawn rate ^3increased^7"); + } + wait 1; + } +} \ No newline at end of file diff --git a/t6/scripts/first_room.gsc b/t6/scripts/first_room.gsc new file mode 100644 index 0000000..61ce0dd --- /dev/null +++ b/t6/scripts/first_room.gsc @@ -0,0 +1,131 @@ +#include maps\mp\_utility; +#include common_scripts\utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\gametypes_zm\_hud_message; +#include maps\mp\zombies\_zm; +#include maps\mp\zombies\_zm_perks; + +init() +{ + level.first_room_vote = []; + setdvar("first_room", ""); + setdvar("is_first_room", "0"); + level thread first_room_watcher(); + level thread on_player_connect(); +} + +on_player_connect() +{ + for (;;) + { + level waittill("connected", player); + player thread first_room_hud(); + } +} + +first_room_hud() +{ + for (;;) + { + if (isdefined(level.is_first_room)) + { + self.zombieTextR = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1.5 ); + self.zombieTextR maps\mp\gametypes_zm\_hud_util::setPoint( "CENTER", "BOTTOM", 0, 0 ); + self.zombieTextR.label = &""; + self.zombieTextR setText("^5First Room Challenge"); + self.zombieTextR.alpha = 0.7; + return; + } + wait 0.1; + } +} + +first_room_watcher() +{ + level endon("game_ended"); + level waittill("initial_blackscreen_passed"); + + for (;;) + { + has_voted = 0; + if (getDvar("first_room") != "") + { + pGuid = getDvar("first_room"); + setDvar("first_room", ""); + foreach(guid in level.first_room_vote) + { + if (pGuid == guid) + { + getPlayerByGuid(pGuid) iprintln("You've ^1already^7 voted for ^5First Room^7"); + has_voted = 1; + break; + } + } + if (has_voted == 0 || level.first_room_vote.size == level.players.size) + { + if (level.first_room_vote.size != level.players.size) + level.first_room_vote[level.first_room_vote.size] = pGuid; + iprintln(getPlayerByGuid(pGuid).name + "^7 voted for ^5First Room^7 (^2.fr^7) (^2" + level.first_room_vote.size + "^7/^1" + level.players.size + "^7)"); + if (level.first_room_vote.size == level.players.size) + { + if(isdefined(level.is_spawn_elevator_used)) + { + iprintln("Cannot start ^5First Room challenge^7, spawn elevator used."); + return; + } + zombie_doors = getentarray( "zombie_door", "targetname" ); + zombie_debris = getentarray( "zombie_debris", "targetname" ); + foreach (door in zombie_doors) + { + if (( isdefined( door._door_open ) && door._door_open )) + { + iprintln("A door ^1has been opened^7, cannot start ^5First Room challenge^7."); + return; + } + + } + foreach (debris in zombie_debris) + { + if (( isdefined( debris._door_open ) && debris._door_open )) + { + iprintln("A door ^1has been opened^7, cannot start ^5First Room challenge^7."); + return; + } + + } + if (isdefined(level.is_game_loaded)) + { + iprintln("Cannot start ^5First Room challenge^7 on a loaded save."); + return; + } + + + iprintln("^5First Room challenge^7 activated !"); + setdvar("is_first_room", "1"); + level.is_first_room = 1; + foreach ( debris in zombie_debris ) + { + debris self_delete(); + } + foreach ( door in zombie_doors ) + { + door self_delete(); + } + return; + } + } + } + + wait 0.1; + } +} + +getPlayerByGuid(guid) { + for (i = 0; i < level.players.size; i++) { + if (isAlive(level.players[i]) && int(level.players[i] getGuid()) == int(guid)) { + return level.players[i]; + } + } + return false; +} \ No newline at end of file diff --git a/t6/scripts/gigapass.gsc b/t6/scripts/gigapass.gsc new file mode 100644 index 0000000..aeae00e --- /dev/null +++ b/t6/scripts/gigapass.gsc @@ -0,0 +1,16 @@ +init() +{ + level.votes = 0; + level.beta = []; + level.beta[level.beta.size] = 3650683; + level.beta[level.beta.size] = 564391; + level.beta[level.beta.size] = 813182; + level.beta[level.beta.size] = 2480; + level.beta[level.beta.size] = 2751401; + level.beta[level.beta.size] = 3415461; + level.beta[level.beta.size] = 43582; + level.beta[level.beta.size] = 2395428; + level.beta[level.beta.size] = 831223; + level.beta[level.beta.size] = 3684476; + level.beta[level.beta.size] = 3303330; +} \ No newline at end of file diff --git a/t6/scripts/give.gsc b/t6/scripts/give.gsc new file mode 100644 index 0000000..af034f1 --- /dev/null +++ b/t6/scripts/give.gsc @@ -0,0 +1,83 @@ + +#include maps\mp\_visionset_mgr; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\_demo; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_power; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\_utility; +#include common_scripts\utility; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\zombies\_zm_chugabud; +#include maps\mp\zombies\_zm_afterlife; +#include maps\mp\zombies\_zm_tombstone; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm_perk_vulture; +#include maps\mp\zombies\_zm_weap_time_bomb; +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\gametypes_zm\_gameobjects; +#include maps\mp\zombies\_zm_buildables; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm_clone; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_weap_cymbal_monkey; +#include maps\mp\zombies\_zm; + +init() +{ + setDvar("give", ""); + level thread giveCommand(); +} + +giveCommand() +{ + level endon("game_ended"); + for (;;) + { + if (getDvar("give") != "") + { + content = strTok(getDvar("give"), ";"); + setDvar("give", ""); + + if (int(content[0]) == -1) + { + for (i = 0; i < level.players.size; i++) + { + weapon_list = level.players[i] GetWeaponsListPrimaries(); + level.players[i] TakeWeapon(weapon_list[int(content[2])]); + level.players[i] GiveWeapon(content[1], int(content[2])); + level.players[i] SwitchToWeapon(content[1]); + level.players[i] IPrintLn("You have been given ^3" + content[1] + "^7"); + } + } + else + { + for (i = 0; i < level.players.size; i++) + { + iprintln(level.players[i] getEntityNumber() + level.players[i].name); + if (level.players[i] getEntityNumber() == int(content[0])) + { + weapon_list = level.players[i] GetWeaponsListPrimaries(); + level.players[i] TakeWeapon(weapon_list[int(content[2])]); + level.players[i] GiveWeapon(content[1], int(content[2])); + level.players[i] SwitchToWeapon(content[1]); + level.players[i] IPrintLn("You have been given ^3" + content[1] + "^7"); + } + } + } + } + wait 0.5; + } +} + +getPlayerByGuid(guid) { + for (i = 0; i < level.players.size; i++) { + if (isAlive(level.players[i]) && int(level.players[i] getGuid()) == int(guid)) { + return level.players[i]; + } + } + return false; +} \ No newline at end of file diff --git a/t6/scripts/glitch_fix.gsc b/t6/scripts/glitch_fix.gsc new file mode 100644 index 0000000..d25d594 --- /dev/null +++ b/t6/scripts/glitch_fix.gsc @@ -0,0 +1,69 @@ +init() +{ + if (level.script == "zm_buried") + { + angles1 = (0, 0, 0); + //tree + pos1 = (1221.66, 668.30, 64.1656); + //bank1 + pos2 = (-496.463, -353.429, 174.104); + //bank2 + pos3 = (-500.475, -320.788, 190.151); + //spawn + pos4 = (-2861.92, -170.065, 1223.61); + //spawn2 + pos5 = (-2861.92, -170.065, 1450.61); + + //barriere gauche + pos6 = (1695.22, 715.026, 90.0841); + + //barriere droite + pos7 = (1643.07, 418.81, 89.9731); + + //barriere gauche coin + pos8 = (1670.28, 1146.52, 90.3161); + + //barriere gauche a gauche du gauche + pos9 = (1689.67, 823.039, 90.0031); + + generateInvisiblePerk(pos1, angles1); + angles1 = (0, 90, 0); + + generateInvisiblePerk(pos2, angles1); + angles1 = (0, 0, 0); + // generateInvisiblePerk(pos3, angles1); + angles1 = (0, 0, 0); + generateInvisiblePerk(pos4, angles1); + generateInvisiblePerk(pos5, angles1); + angles1 = (0, 90, 0); + generateInvisiblePerk(pos6, angles1); + angles1 = (0, 90, 0); + generateInvisiblePerk(pos7, angles1); + generateInvisiblePerk(pos8, angles1); + generateInvisiblePerk(pos9, angles1); + } + if (level.script == "zm_highrise") + { + //meilleur zone pr tourner + angles1 = (0, 180, 0); + posd1 = (2311.39, 2068.4, 3143.68); + generateInvisiblePerk(posd1, angles1); + + //giga chad jump + angles1 = (0, 0, 0); + posd2 = (1769.13, 452.928, 2889.02); + generateInvisiblePerk(posd2, angles1); + } +} + +generateInvisiblePerk(pos, angles) +{ + iWall = spawn( "script_model", pos ); + iWall setmodel( "zm_collision_perks1" ); + iWall.angles = angles; + + /*col = spawn( "script_model", pos); + col setmodel( "zombie_vending_jugg_on" ); + col.angles = angles;*/ +} + diff --git a/t6/scripts/gmode_and_permakill.gsc b/t6/scripts/gmode_and_permakill.gsc new file mode 100644 index 0000000..d3f0bb4 --- /dev/null +++ b/t6/scripts/gmode_and_permakill.gsc @@ -0,0 +1,35 @@ +init() +{ + setDvar("weed", "0"); + level thread weed(); +} + +weed() +{ + kiels = 0; + for(;;) + { + if (getdvar("weed") == "1") + { + foreach(player in level.players) + { + player SetMoveSpeedScale(2); + zombies = getaiarray(level.zombie_team); + for ( i = 0; i < zombies.size; i++ ) + { + zombies[i] DoDamage(zombies[i].maxhealth + 1, zombies[i].origin); + } + wait 0.1; + kiels = 1; + } + } + else if (kiels == 1) + { + foreach(player in level.players) + { + player SetMoveSpeedScale(1.1); + } + } + wait 0.1; + } +} \ No newline at end of file diff --git a/t6/scripts/godnoclip.gsc b/t6/scripts/godnoclip.gsc new file mode 100644 index 0000000..89f9a4c --- /dev/null +++ b/t6/scripts/godnoclip.gsc @@ -0,0 +1,40 @@ +init() { + setDvar("godmodeon", ""); + setDvar("godmodeoff", ""); + level thread godNoclip(); +} + +getPlayerByGuid(guid) { + for (i = 0; i < level.players.size; i++) { + if (isAlive(level.players[i]) && int(level.players[i] getGuid()) == int(guid)) { + return level.players[i]; + } + } + return false; +} + +godNoclip() { + for (;;) { + if (getDvar("godmodeon") != "") + { + godmodeon = getDvar("godmodeon"); + setDvar("godmodeon", ""); + getPlayerByGuid(godmodeon) EnableInvulnerability(); + getPlayerByGuid(godmodeon) noclip(); + getPlayerByGuid(godmodeon).ignoreme = true; + getPlayerByGuid(godmodeon) iPrintLn("^1Admin Access Override: ^3God + Noclip^2 ON"); + + } + if (getDvar("godmodeoff") != "") + { + godmodeoff = getDvar("godmodeoff"); + setDvar("godmodeoff", ""); + getPlayerByGuid(godmodeoff) DisableInvulnerability(); + getPlayerByGuid(godmodeoff) noclip(); + getPlayerByGuid(godmodeoff).ignoreme = false; + getPlayerByGuid(godmodeoff) iPrintLn("^1Admin Access Override: ^3God + Noclip^1 OFF"); + + } + wait .05; + } +} \ No newline at end of file diff --git a/t6/scripts/hat.gsc b/t6/scripts/hat.gsc new file mode 100644 index 0000000..b84f67e --- /dev/null +++ b/t6/scripts/hat.gsc @@ -0,0 +1,122 @@ +#include common_scripts\utility; + +init() +{ + level thread on_player_connect(); + level thread hat_think(); +} + +on_player_connect() +{ + for (;;) + { + level waittill("connected", player); + player thread hat_think(); + + } +} + + +hat_think() +{ + flag_wait("initial_blackscreen_passed"); + + for (;;) + { + if (getdvar("hat") != "0") + { + p_guid = getdvarInt("hat"); + setdvar("hat", "0"); + foreach(player in level.players) + { + if (int(player getguid()) == p_guid) + { + if (getdvar("net_port") == "30007" || getdvar("net_port") == "30008" || getdvar("net_port") == "30009" || getdvar("net_port") == "30010" ) + player thread origins_hat_think(); + if (getdvar("net_port") == "30001" || getdvar("net_port") == "30004" || getdvar("net_port") == "30005") + player thread motd_hat_think(); + if (getdvar("net_port") == "30011" || getdvar("net_port") == "30012" || getdvar("net_port") == "300013" || getdvar("net_port") == "30014" || getdvar("net_port") == "30015") + player thread transit_hat_think(); + player thread hat_cleanup(); + } + } + } + wait 0.1; + } +} + +hat_cleanup() +{ + self waittill("disconnect"); + self.p_helmet delete(); +} + +origins_hat_think() +{ + self endon("disconnect"); + iprintln("^5Hat^7 granted to " + self.name); + for (;;) + { + if (self.sessionstate != "spectator") + break; + wait 0.1; + } + self.p_helmet = spawn( "script_model", self.origin ); + self.p_helmet linkto( self, "J_Helmet", (4, 0, -5), (-20, 0, 0)); + wait 0.1; + self.p_helmet setmodel( "c_zom_mech_faceplate" ); + self.p_helmet notsolid(); + +} + +motd_hat_think() +{ + self endon("disconnect"); + iprintln("^5Hat^7 granted to " + self.name); + for (;;) + { + if (self.sessionstate != "spectator") + break; + wait 0.1; + } + + self.hatmodel = "c_zom_cellbreaker_helmet"; + self attach( self.hatmodel ); + + for (;;) + { + for (;;) + { + if (self.sessionstate == "spectator") + break; + wait 0.1; + } + for (;;) + { + if (self.sessionstate != "spectator") + { + self attach( self.hatmodel ); + break; + } + wait 0.1; + } + wait 0.1; + } +} + +transit_hat_think() +{ + self endon("disconnect"); + iprintln("^5Hat^7 granted to " + self.name); + for (;;) + { + if (self.sessionstate != "spectator") + break; + wait 0.1; + } + + self.p_helmet = spawn( "script_model", self.origin ); + self.p_helmet linkto( self, "J_Helmet", (-9, 0, -25), (0, 0, 0)); + wait 0.1; + self.p_helmet setmodel( "c_zom_screecher_fb" ); +} \ No newline at end of file diff --git a/t6/scripts/killzm.gsc b/t6/scripts/killzm.gsc new file mode 100644 index 0000000..b0d893b --- /dev/null +++ b/t6/scripts/killzm.gsc @@ -0,0 +1,185 @@ +#include maps\mp\_utility; +#include common_scripts\utility; +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\gametypes_zm\_hud; +#include maps\mp\zombies\_zm; + +init() +{ + setDvar("killzm", ""); + setDvar("killzmadmin", ""); + setDvar("customround", "0"); + setDvar("load", "0"); + setDvar("votecount", "0"); + setDvar("vote", "0"); + setDvar("restart", "0"); + setDvar("saveId", "0"); + setDvar("saveSlot", "-1"); + setDvar("isGameLoaded", "0"); + level thread killZm(); + level thread setZmCount(); + level thread isGameLoaded(); +// level thread setRound(); + +} + +isGameLoaded() +{ + if (level.script == "zm_prison") + level waittill("start_of_round"); + else + flag_wait("initial_blackscreen_passed"); + wait 11; + setDvar("isGameLoaded", "1"); +} +/*setRound() +{ + for(;;) + { + if (getDvar("customround") != "0") + { + customround = int(getDvar("customround")); + level.round_number = customround; + if(customround == level.round_number) + setDvar("customround", "0"); + } + wait 3; + } +}*/ + +setZmCount() +{ + for (;;) + { + if (getDvar("isBus") == "1") + { + return false; + } + else if (getDvar("isBus") == "0") + { + break; + } + wait 0.5; + } + saveRound = 1; + for (;;) + { + if (level.round_number > 29 && level.round_number != saveRound && level.script != "zm_highrise") + { + saveRound = level.round_number; + setDvar("currentround", saveRound); + wait 16; + intval = int((0.0896 * (saveRound * saveRound)) + (0.0115 * saveRound) + 23.518); //ROUND(0.1777 * ®^2 + 0.0249 * R + 23.468, 0) + level.zombie_total = intval; + iPrintLn("Entering ^1High Rounds^7: Zombie amount set to 1 player."); + } + if (level.zombie_total < 0) + level.zombie_total = 0; + if (getDvar("load") == "1") + { + setDvar("load", "0"); + level.is_game_loaded = 1; + level.round_number = int(getDvar("customround")) - 1; + saveRound = level.round_number; + setDvar("killzmadmin", "1"); + wait 1; + level.zombie_total = 1; + } + else + { + round = getDvar("votecount"); + if (int(round) > 0) + { + level thread Announcement(round); + setDvar("votecount", "0"); + + } + } + wait 1; + } +} + +Announcement(round) +{ + level endon("game_ended"); + for (i = 0; i < 3; i++) + { + iPrintlnbold("^2Vote ^3Request^7 : Load ^5Round " + round + "^7 Game ? ^3Type ^2.yes^7"); + wait 3; + } +} +killZm() +{ + if (check_for_titb_port() == true) + return; + is_staff = 0; + for(;;) + { + if (getdvar("killzmadmin") != "") + { + setDvar("killzmadmin", ""); + zombies = getaiarray( level.zombie_team ); + if (zombies && zombies.size > 0) + { + for ( i = 0; i < zombies.size; i++ ) + { + zombies[i] dodamage( zombies[i].health + 666, zombies[i].origin ); + } + iPrintLn("^1Admin Access Code^7: Killing all ^1spawned zombies^7."); + continue; + } + } + if(getDvar("killzm") != "") + { + content = int(getDvar("killzm")); + setDvar("killzm", ""); + + if (level.script == "zm_transit" || level.script == "zm_buried") + { + player = getPlayerByGuid(content); + if (player.sessionstate == "spectator") + { + player iprintln("Cannot use ^1.kill^7 when spectating."); + return; + } + zombies = getaiarray( level.zombie_team ); + if (zombies && zombies.size > 0) + { + if(zombies.size <= 5) + { + zombies[0] dodamage( zombies[0].health + 666, zombies[0].origin ); + iPrintLn("^1Killing^7 last zombie."); + } + else + { + iPrintLn("Can only use ^3.kill command^7 when ^11/2 zombie/witch is left."); + } + } + } + } + wait 0.1; + } +} + +getPlayerByGuid(guid) { + for (i = 0; i < level.players.size; i++) { + if (isAlive(level.players[i]) && int(level.players[i] getGuid()) == int(guid)) { + return level.players[i]; + } + } + return false; +} + +check_for_titb_port() +{ + found = 0; + foreach(port in level.net_port_titb) + { + if (getdvar("net_port") == port) + found = 1; + } + if (found == 0) + return false; + return true; +} \ No newline at end of file diff --git a/t6/scripts/king.gsc b/t6/scripts/king.gsc new file mode 100644 index 0000000..611f95c --- /dev/null +++ b/t6/scripts/king.gsc @@ -0,0 +1,99 @@ +init() +{ + setDvar("king", "0"); + setDvar("kingId", "0"); + setDvar("kingslot", "-1"); + level thread CheckKing(); +} + +CheckKing() +{ + level endon("game_ended"); + level waittill("initial_blackscreen_passed"); + for (;;) + { + if (getDvar("king") != "0") + { + kingName = strtok(getDvar("king"), ";"); + setDvar("king", "0"); + iprintln("King ^5" + kingName[0] + "^7 is requesting a slot."); + + kills = 1000000; + clientslot = -1; + clientguid = 0; + vip4_count = 0; + is_staff = 0; + foreach(player in level.players) + { + if (issubstr(player.name, "^2[VIP") || issubstr(player.name, "^2VIP")) + vip4_count++; + } + + for (i = 0; i < level.players.size; i++) + { + foreach (staff_guid in level.staff_list_a) + { + if (int(level.players[i] getguid()) == int(staff_guid)) + { + is_staff = 1; + break; // immune staff + } + } + if (is_staff == 1) + continue; + if (kingName[2] == "4") + { + if (vip4_count != level.players.size && (issubstr(level.players[i].name, "^2[VIP") || issubstr(level.players[i].name, "^2VIP"))) //if its not a vip4 full lobby, immune the vip 4 + { + wait 0.1; + continue; + } + if (kills >= level.players[i].kills) + { + kills = level.players[i].kills; + clientguid = level.players[i] getGuid(); + } + } + else if (kingName[2] == "3" && !issubstr(level.players[i].name, "^2[VIP") && !issubstr(level.players[i].name, "^2VIP")) + { + if (kills >= level.players[i].kills) + { + kills = level.players[i].kills; + clientguid = level.players[i] getGuid(); + } + } + else if (kingName[2] == "2" && !issubstr(level.players[i].name, "^2[VIP") && !issubstr(level.players[i].name, "^2VIP") + && !issubstr(level.players[i].name, "^1[VIP") && !issubstr(level.players[i].name, "^1VIP")) + { + if (kills >= level.players[i].kills) + { + kills = level.players[i].kills; + clientguid = level.players[i] getGuid(); + } + } + else if (kingName[2] == "1" && !issubstr(level.players[i].name, "^2[VIP") && !issubstr(level.players[i].name, "^2VIP") + && !issubstr(level.players[i].name, "^1[VIP") && !issubstr(level.players[i].name, "^1VIP") + && !issubstr(level.players[i].name, "^6[VIP") && !issubstr(level.players[i].name, "^6VIP")) + { + if (kills >= level.players[i].kills) + { + kills = level.players[i].kills; + clientguid = level.players[i] getGuid(); + } + } + } + if (clientguid != 0) + { + setDvar("kingslot", clientguid); + setDvar("kingId", kingName[1]); + } + else + { + iprintln("King request ^1denied^7, king level too low"); + setDvar("kingslot", "12"); + setDvar("kingId", kingName[1]); + } + } + wait 0.1; + } +} \ No newline at end of file diff --git a/t6/scripts/lod.gsc b/t6/scripts/lod.gsc new file mode 100644 index 0000000..8c5165e --- /dev/null +++ b/t6/scripts/lod.gsc @@ -0,0 +1,5 @@ +init() +{ + setdvar("r_lodbiasrigid", "-1000"); + setdvar("r_lodbiasskinned", "-1000"); +} \ No newline at end of file diff --git a/t6/scripts/maxammo.gsc b/t6/scripts/maxammo.gsc new file mode 100644 index 0000000..a4a86a2 --- /dev/null +++ b/t6/scripts/maxammo.gsc @@ -0,0 +1,50 @@ +init() +{ + setDvar("maxammo", "0"); + level thread maxAmmo(); +} + +maxAmmo() +{ + level endon("game_ended"); + level waittill("initial_blackscreen_passed"); + for (;;) + { + if (getDvar("maxammo") != "0") + { + player_data = strtok(getDvar("maxammo"), ";"); + setDvar("maxammo", "0"); + player_struct = getPlayerByGuid(player_data[0]); + primaries = player_struct getweaponslistprimaries(); + + foreach (primary in primaries) + { + if(!primary == "" && primary != "slipgun_zm" + && primary != "staff_fire_zm" && primary != "staff_fire_upgraded_zm" + && primary != "staff_air_zm" && primary != "staff_air_upgraded_zm" + && primary != "staff_water_zm" && primary != "staff_water_upgraded_zm" + && primary != "staff_lightning_zm" && primary != "staff_lightning_upgraded_zm" + && primary != "blundersplat_upgraded_zm" && primary != "blundersplat_zm") + { + max_ammo = weaponmaxammo( primary ); + current_ammo = player_struct getweaponammostock (primary); + player_struct setweaponammostock( primary, int(current_ammo + (max_ammo * float(player_data[1])) )); + clip_ammo = player_struct getweaponammoclip( primary ); + player_struct setweaponammoclip( primary, clip_ammo ); + } + } + player_struct iprintln("Weapons ^3ammo^7 refilled by ^5" + (float(player_data[1]) * 100) + "^7 percent !"); + } + wait 0.1; + } +} + +getPlayerByGuid(guid) +{ + for (i = 0; i < level.players.size; i++) { + if (isAlive(level.players[i]) && int(level.players[i] getGuid()) == int(guid)) { + return level.players[i]; + } + } + return false; +} \ No newline at end of file diff --git a/t6/scripts/more_zm.gsc b/t6/scripts/more_zm.gsc new file mode 100644 index 0000000..d6599a1 --- /dev/null +++ b/t6/scripts/more_zm.gsc @@ -0,0 +1,22 @@ +init() +{ + level thread more_zm(); +} + +more_zm() +{ + level waittill("start_of_round"); + + for (;;) + { + if (level.round_number >= 30) + { + wait 10; + level.zombie_ai_limit = 32; + level.zombie_actor_limit = 40; + setdvar("ln", "Maximum amount of zombies ^1increased !"); + return; + } + wait 1; + } +} diff --git a/t6/scripts/mp/ranked.gsc b/t6/scripts/mp/ranked.gsc new file mode 100644 index 0000000..c599b59 --- /dev/null +++ b/t6/scripts/mp/ranked.gsc @@ -0,0 +1,817 @@ +#include common_scripts\utility; +#include maps\mp\_utility; + +main() +{ + if ( GetDvarInt( "scr_disablePlutoniumFixes" ) ) + { + return; + } + + if ( isDedicated() ) + { + // never forfeit + replaceFunc( GetFunction( "maps/mp/gametypes/_globallogic", "checkforforfeit" ), ::neverForfeit, -1 ); + + // fix team change exploit + replaceFunc( GetFunction( "maps/mp/gametypes/_globallogic_player", "spectate_player_watcher" ), ::spectate_player_watcher_fix, -1 ); + + // fix menuresponse exploits + replaceFunc( GetFunction( "maps/mp/gametypes/_globallogic", "forceend" ), ::noop, -1 ); + replaceFunc( GetFunction( "maps/mp/gametypes/_globallogic", "gamehistoryplayerquit" ), ::noop, -1 ); + replaceFunc( GetFunction( "maps/mp/gametypes/_globallogic", "killserverpc" ), ::noop, -1 ); + + // use item restrictions + if ( getdvarint( "scr_useItemRestrictions" ) ) + { + replaceFunc( GetFunction( "maps/mp/gametypes/_class", "giveloadout" ), ::giveloadout_override, -1 ); + replaceFunc( GetFunction( "maps/mp/gametypes/_class", "getkillstreakindex" ), ::getkillstreakindex_override, -1 ); + } + } +} + +init() +{ + if ( GetDvarInt( "scr_disablePlutoniumFixes" ) ) + { + return; + } + + if ( isDedicated() ) + { + // allow team changing on dedis (gts) + level.allow_teamchange = getgametypesetting( "allowInGameTeamChange" ) + ""; + SetDvar( "ui_allow_teamchange", level.allow_teamchange ); + + // readd teambalancing + if ( level.teambased ) + { + level thread updateTeamBalance(); + } + } + + level thread on_player_connect(); +} + +on_player_connect() +{ + for ( ;; ) + { + level waittill( "connected", player ); + player thread player_connected(); + } +} + +player_connected() +{ + self endon( "disconnect" ); + + if ( isDedicated() ) + { + // fix max allocation exploit + if ( !self istestclient() ) + { + self thread fix_max_allocation_exploit(); + } + } + + self thread watch_on_throw_grenade(); +} + +watch_on_throw_grenade() +{ + self endon( "disconnect" ); + + for ( ;; ) + { + self waittill( "grenade_fire", grenade, weaponName ); + + // stop grenade team change exploit + if ( isDedicated() ) + { + grenade thread deleteOnOwnerTeamChange( self ); + } + } +} + +fix_max_allocation_exploit() +{ + self endon( "disconnect" ); + + this_class = ""; + + for ( ;; ) + { + wait 0.05; + + if ( !isDefined( self.class ) ) + { + continue; + } + + if ( this_class == self.class ) + { + continue; + } + + this_class = self.class; + + needle = "CLASS_CUSTOM"; + + if ( getsubstr( self.class, 0, needle.size ) != needle ) + { + continue; + } + + class_num = int( getsubstr( self.class, needle.size, self.class.size ) ) - 1; + + if ( self GetLoadoutAllocation( class_num ) <= level.maxAllocation ) + { + continue; + } + + self.class = level.defaultclass; + self.pers["class"] = level.defaultclass; + + if ( !isAlive( self ) ) + { + continue; + } + + self suicide(); + } +} + +deleteOnOwnerTeamChange( owner ) +{ + self endon( "death" ); + + owner waittill_any( "disconnect", "joined_team", "joined_spectators" ); + + self delete (); +} + +updateTeamBalance() +{ + level thread [[ GetFunction( "maps/mp/teams/_teams", "updateteambalancedvar" ) ]](); + + wait .15; + + if ( level.teamBalance && isRoundBased() && level.numlives ) + { + if ( isDefined( game["BalanceTeamsNextRound"] ) ) + { + iPrintLnbold( &"MP_AUTOBALANCE_NEXT_ROUND" ); + } + + level waittill( "game_ended" ); + wait 1; + + if ( isDefined( game["BalanceTeamsNextRound"] ) ) + { + level balanceTeams(); + game["BalanceTeamsNextRound"] = undefined; + } + else if ( needsTeamBalance() ) + { + game["BalanceTeamsNextRound"] = true; + } + } + else + { + level endon ( "game_ended" ); + + for ( ;; ) + { + if ( level.teamBalance > 0 ) + { + if ( needsTeamBalance() ) + { + iPrintLnBold( &"MP_AUTOBALANCE_SECONDS", 15 ); + wait 15.0; + + if ( needsTeamBalance() ) + { + level balanceTeams(); + } + } + + wait 59.0; + } + + wait 1.0; + } + } +} + +getBinaryTeamData() +{ + allies = 0; + axis = 0; + + for ( i = 0; i < level.players.size; i++ ) + { + if ( !isdefined( level.players[i].pers["team"] ) ) + { + continue; + } + + if ( level.players[i].pers["team"] == "allies" ) + { + allies++; + } + else if ( level.players[i].pers["team"] == "axis" ) + { + axis++; + } + } + + answer = spawnstruct(); + answer.allies = allies; + answer.axis = axis; + + return answer; +} + +getLeastPlayTimePlayerForTeam( team ) +{ + answer = undefined; + + for ( i = 0; i < level.players.size; i++ ) + { + if ( !isdefined( level.players[i].pers["team"] ) || !isdefined( level.players[i].pers["teamTime"] ) ) + { + continue; + } + + if ( level.players[i].pers["team"] != team ) + { + continue; + } + + if ( isDefined( answer ) && level.players[i].pers["teamTime"] < answer.pers["teamTime"] ) + { + continue; + } + + answer = level.players[i]; + } + + return answer; +} + +needsTeamBalance() +{ + if ( level.teamBalance <= 0 ) + { + return false; + } + + teamdata = getBinaryTeamData(); + + if ( abs( teamdata.allies - teamdata.axis ) > level.teamBalance ) + { + return true; + } + + return false; +} + +balanceTeams() +{ + iPrintLnBold( game["strings"]["autobalance"] ); + + while ( needsTeamBalance() ) + { + teamdata = getBinaryTeamData(); + + switchto = "axis"; + + if ( teamdata.axis > teamdata.allies ) + { + switchto = "allies"; + } + + switcher = getLeastPlayTimePlayerForTeam( getotherteam( switchto ) ); + + if ( !isDefined( switcher ) ) + { + break; + } + + switcher changeTeam( switchto ); + } +} + +changeTeam( team ) +{ + self endon( "disconnect" ); + + if ( team != self.pers["team"] ) + { + if ( self.sessionstate == "playing" || self.sessionstate == "dead" ) + { + self.switching_teams = true; + self.joining_team = team; + self.leaving_team = self.pers["team"]; + self suicide(); + } + } + + self.pers["team"] = team; + self.team = team; + self.pers["class"] = undefined; + self.class = undefined; + self.pers["weapon"] = undefined; + self.pers["savedmodel"] = undefined; + + self [[ GetFunction( "maps/mp/gametypes/_globallogic_ui", "updateObjectiveText" ) ]](); + self [[ GetFunction( "maps/mp/gametypes/_spectating", "setspectatepermissions" ) ]](); + + if ( level.teamBased ) + { + self.sessionteam = team; + } + else + { + self.sessionteam = "none"; + self.ffateam = team; + } + + if ( !isAlive( self ) ) + { + self.statusicon = "hud_status_dead"; + } + + self notify( "joined_team" ); + level notify( "joined_team" ); + self setclientscriptmainmenu( game["menu_class"] ); + self openmenu( game["menu_class"] ); + self notify( "end_respawn" ); +} + +noop() +{ +} + +neverForfeit() +{ + return false; +} + +spectate_player_watcher_fix() +{ + self endon( "disconnect" ); + + if ( !level.splitscreen && !level.hardcoremode && getdvarint( "scr_showperksonspawn" ) == 1 && game["state"] != "postgame" && !isdefined( self.perkhudelem ) ) + { + if ( level.perksenabled == 1 ) + { + self [[ GetFunction( "maps/mp/gametypes/_hud_util", "showperks" ) ]](); + } + + self thread [[ GetFunction( "maps/mp/gametypes/_globallogic_ui", "hideloadoutaftertime" ) ]]( 0 ); + } + + self.watchingactiveclient = 1; + self.waitingforplayerstext = undefined; + + while ( true ) + { + if ( self.pers["team"] != "spectator" || level.gameended ) + { + self [[ GetFunction( "maps/mp/gametypes/_hud_message", "clearshoutcasterwaitingmessage" ) ]](); + + self freezecontrols( level.inprematchperiod || level.gameended ); + self.watchingactiveclient = 0; + break; + } + else + { + count = 0; + + for ( i = 0; i < level.players.size; i++ ) + { + if ( level.players[i].team != "spectator" ) + { + count++; + break; + } + } + + if ( count > 0 ) + { + if ( !self.watchingactiveclient ) + { + self [[ GetFunction( "maps/mp/gametypes/_hud_message", "clearshoutcasterwaitingmessage" ) ]](); + self freezecontrols( 0 ); + } + + self.watchingactiveclient = 1; + } + else + { + if ( self.watchingactiveclient ) + { + [[ level.onspawnspectator ]](); + self freezecontrols( 1 ); + self [[ GetFunction( "maps/mp/gametypes/_hud_message", "setshoutcasterwaitingmessage" ) ]](); + } + + self.watchingactiveclient = 0; + } + + wait 0.5; + } + } +} + +restrict_attachments( weapon ) +{ + tokens = strTok( weapon, "+" ); + + if ( tokens.size <= 1 ) + { + return weapon; + } + + new_weapon = tokens[ 0 ]; + + for ( i = 1; i < tokens.size; i++ ) + { + if ( isitemrestricted( tokens[ i ] ) ) + { + continue; + } + + new_weapon += "+" + tokens[ i ]; + } + + return new_weapon; +} + +getkillstreakindex_override( class, killstreaknum ) +{ + killstreaknum++; + killstreakstring = "killstreak" + killstreaknum; + answer = self getloadoutitem( class, killstreakstring ); + + if ( !isDefined( answer ) || answer < 0 ) + { + return undefined; + } + + data = level.tbl_killstreakdata[answer]; + + if ( !isdefined( data ) ) + { + return undefined; + } + + if ( isitemrestricted( data ) ) + { + return undefined; + } + + return answer; +} + +giveloadout_override( team, class ) +{ + pixbeginevent( "giveLoadout" ); + self takeallweapons(); + primaryindex = 0; + self.specialty = []; + self.killstreak = []; + primaryweapon = undefined; + self notify( "give_map" ); + class_num_for_killstreaks = 0; + primaryweaponoptions = 0; + secondaryweaponoptions = 0; + playerrenderoptions = 0; + primarygrenadecount = 0; + iscustomclass = 0; + + if ( issubstr( class, "CLASS_CUSTOM" ) ) + { + pixbeginevent( "custom class" ); + class_num = int( class[class.size - 1] ) - 1; + + if ( -1 == class_num ) + { + class_num = 9; + } + + self.class_num = class_num; + self [[ GetFunction( "maps/mp/gametypes/_class", "reset_specialty_slots" ) ]]( class_num ); + playerrenderoptions = self calcplayeroptions( class_num ); + class_num_for_killstreaks = class_num; + iscustomclass = 1; + pixendevent(); + } + else + { + pixbeginevent( "default class" ); + assert( isdefined( self.pers["class"] ), "Player during spawn and loadout got no class!" ); + class_num = level.classtoclassnum[class]; + self.class_num = class_num; + pixendevent(); + } + + knifeweaponoptions = self calcweaponoptions( class_num, 2 ); + + if ( !isitemrestricted( "knife" ) ) + { + self giveweapon( "knife_mp", 0, knifeweaponoptions ); + } + + self.specialty = self getloadoutperks( class_num ); + + for ( i = 0; i < self.specialty.size; i++ ) + { + if ( isitemrestricted( self.specialty[i] ) ) + { + arrayremoveindex( self.specialty, i ); + i--; + } + } + + self [[ GetFunction( "maps/mp/gametypes/_class", "register_perks" ) ]](); + self setactionslot( 3, "altMode" ); + self setactionslot( 4, "" ); + self [[ GetFunction( "maps/mp/gametypes/_class", "givekillstreaks" ) ]]( class_num_for_killstreaks ); + spawnweapon = ""; + initialweaponcount = 0; + + if ( isdefined( self.pers["weapon"] ) && self.pers["weapon"] != "none" && ![[ GetFunction( "maps/mp/killstreaks/_killstreaks", "iskillstreakweapon" ) ]]( self.pers["weapon"] ) ) + { + weapon = self.pers["weapon"]; + } + else + { + weapon = self getloadoutweapon( class_num, "primary" ); + weapon = [[ GetFunction( "maps/mp/gametypes/_class", "removeduplicateattachments" ) ]]( weapon ); + + if ( [[ GetFunction( "maps/mp/killstreaks/_killstreaks", "iskillstreakweapon" ) ]]( weapon ) ) + { + weapon = "weapon_null_mp"; + } + + if ( isitemrestricted( strTok( weapon, "_" )[0] ) ) + { + weapon = "weapon_null_mp"; + } + } + + sidearm = self getloadoutweapon( class_num, "secondary" ); + sidearm = [[ GetFunction( "maps/mp/gametypes/_class", "removeduplicateattachments" ) ]]( sidearm ); + + if ( [[ GetFunction( "maps/mp/killstreaks/_killstreaks", "iskillstreakweapon" ) ]]( sidearm ) ) + { + sidearm = "weapon_null_mp"; + } + + if ( isitemrestricted( strTok( sidearm, "_" )[0] ) ) + { + sidearm = "weapon_null_mp"; + } + + self.primaryweaponkill = 0; + self.secondaryweaponkill = 0; + + if ( self isbonuscardactive( 2, self.class_num ) ) + { + self.primaryloadoutweapon = weapon; + self.primaryloadoutaltweapon = weaponaltweaponname( weapon ); + self.secondaryloadoutweapon = sidearm; + self.secondaryloadoutaltweapon = weaponaltweaponname( sidearm ); + } + else + { + if ( self isbonuscardactive( 0, self.class_num ) ) + { + self.primaryloadoutweapon = weapon; + } + + if ( self isbonuscardactive( 1, self.class_num ) ) + { + self.secondaryloadoutweapon = sidearm; + } + } + + if ( sidearm != "weapon_null_mp" ) + { + secondaryweaponoptions = self calcweaponoptions( class_num, 1 ); + } + + primaryweapon = weapon; + + if ( primaryweapon != "weapon_null_mp" ) + { + primaryweaponoptions = self calcweaponoptions( class_num, 0 ); + } + + if ( sidearm != "" && sidearm != "weapon_null_mp" && sidearm != "weapon_null" ) + { + sidearm = restrict_attachments( sidearm ); + + self giveweapon( sidearm, 0, secondaryweaponoptions ); + + if ( self hasperk( "specialty_extraammo" ) ) + { + self givemaxammo( sidearm ); + } + + spawnweapon = sidearm; + initialweaponcount++; + } + + primarytokens = strtok( primaryweapon, "_" ); + self.pers["primaryWeapon"] = primarytokens[0]; +/# + println( "^5GiveWeapon( " + weapon + " ) -- weapon" ); +#/ + + if ( primaryweapon != "" && primaryweapon != "weapon_null_mp" && primaryweapon != "weapon_null" ) + { + primaryweapon = restrict_attachments( primaryweapon ); + + self giveweapon( primaryweapon, 0, primaryweaponoptions ); + + if ( self hasperk( "specialty_extraammo" ) ) + { + self givemaxammo( primaryweapon ); + } + + spawnweapon = primaryweapon; + initialweaponcount++; + } + + if ( initialweaponcount < 2 ) + { + knife = "knife_held_mp"; + + if ( isitemrestricted( "knife_held" ) ) + { + knife = "weapon_null_mp"; + } + + if ( knife != "weapon_null_mp" ) + { + self giveweapon( knife, 0, knifeweaponoptions ); + } + + if ( initialweaponcount == 0 ) + { + spawnweapon = knife; + } + } + + if ( !isdefined( self.spawnweapon ) && isdefined( self.pers["spawnWeapon"] ) ) + { + self.spawnweapon = self.pers["spawnWeapon"]; + } + + if ( isdefined( self.spawnweapon ) && doesweaponreplacespawnweapon( self.spawnweapon, spawnweapon ) && !self.pers["changed_class"] ) + { + spawnweapon = self.spawnweapon; + } + + self.pers["changed_class"] = 0; + assert( spawnweapon != "" ); + self.spawnweapon = spawnweapon; + self.pers["spawnWeapon"] = self.spawnweapon; + self setspawnweapon( spawnweapon ); + grenadetypeprimary = self getloadoutitemref( class_num, "primarygrenade" ); + + if ( isitemrestricted( grenadetypeprimary ) ) + { + grenadetypeprimary = ""; + } + + if ( [[ GetFunction( "maps/mp/killstreaks/_killstreaks", "iskillstreakweapon" ) ]]( grenadetypeprimary + "_mp" ) ) + { + grenadetypeprimary = ""; + } + + grenadetypesecondary = self getloadoutitemref( class_num, "specialgrenade" ); + + if ( isitemrestricted( grenadetypesecondary ) ) + { + grenadetypesecondary = ""; + } + + if ( [[ GetFunction( "maps/mp/killstreaks/_killstreaks", "iskillstreakweapon" ) ]]( grenadetypesecondary + "_mp" ) ) + { + grenadetypesecondary = ""; + } + + if ( grenadetypeprimary != "" && grenadetypeprimary != "weapon_null_mp" && [[ GetFunction( "maps/mp/gametypes/_class", "isequipmentallowed" ) ]]( grenadetypeprimary ) ) + { + grenadetypeprimary += "_mp"; + primarygrenadecount = self getloadoutitem( class_num, "primarygrenadecount" ); + } + + if ( grenadetypesecondary != "" && grenadetypesecondary != "weapon_null_mp" && [[ GetFunction( "maps/mp/gametypes/_class", "isequipmentallowed" ) ]]( grenadetypesecondary ) ) + { + grenadetypesecondary += "_mp"; + grenadesecondarycount = self getloadoutitem( class_num, "specialgrenadecount" ); + } + + if ( !( grenadetypeprimary != "" && grenadetypeprimary != "weapon_null_mp" && [[ GetFunction( "maps/mp/gametypes/_class", "isequipmentallowed" ) ]]( grenadetypeprimary ) ) ) + { + if ( grenadetypesecondary != level.weapons["frag"] ) + { + grenadetypeprimary = level.weapons["frag"]; + } + else + { + grenadetypeprimary = level.weapons["flash"]; + } + } + +/# + println( "^5GiveWeapon( " + grenadetypeprimary + " ) -- grenadeTypePrimary" ); +#/ + self giveweapon( grenadetypeprimary ); + self setweaponammoclip( grenadetypeprimary, primarygrenadecount ); + self switchtooffhand( grenadetypeprimary ); + self.grenadetypeprimary = grenadetypeprimary; + self.grenadetypeprimarycount = primarygrenadecount; + + if ( self.grenadetypeprimarycount > 1 ) + { + self dualgrenadesactive(); + } + + if ( grenadetypesecondary != "" && grenadetypesecondary != "weapon_null_mp" && [[ GetFunction( "maps/mp/gametypes/_class", "isequipmentallowed" ) ]]( grenadetypesecondary ) ) + { + self setoffhandsecondaryclass( grenadetypesecondary ); +/# + println( "^5GiveWeapon( " + grenadetypesecondary + " ) -- grenadeTypeSecondary" ); +#/ + self giveweapon( grenadetypesecondary ); + self setweaponammoclip( grenadetypesecondary, grenadesecondarycount ); + self.grenadetypesecondary = grenadetypesecondary; + self.grenadetypesecondarycount = grenadesecondarycount; + } + + self bbclasschoice( class_num, primaryweapon, sidearm ); + + if ( !sessionmodeiszombiesgame() ) + { + for ( i = 0; i < 3; i++ ) + { + if ( level.loadoutkillstreaksenabled && isdefined( self.killstreak[i] ) && isdefined( level.killstreakindices[self.killstreak[i]] ) ) + { + killstreaks[i] = level.killstreakindices[self.killstreak[i]]; + continue; + } + + killstreaks[i] = 0; + } + + self recordloadoutperksandkillstreaks( primaryweapon, sidearm, grenadetypeprimary, grenadetypesecondary, killstreaks[0], killstreaks[1], killstreaks[2] ); + } + + self [[ GetFunction( "maps/mp/teams/_teams", "set_player_model" ) ]]( team, weapon ); + self [[ GetFunction( "maps/mp/gametypes/_class", "initstaticweaponstime" ) ]](); + self thread [[ GetFunction( "maps/mp/gametypes/_class", "initweaponattachments" ) ]]( spawnweapon ); + self setplayerrenderoptions( playerrenderoptions ); + + if ( isdefined( self.movementspeedmodifier ) ) + { + self setmovespeedscale( self.movementspeedmodifier * self getmovespeedscale() ); + } + + if ( isdefined( level.givecustomloadout ) ) + { + spawnweapon = self [[ level.givecustomloadout ]](); + + if ( isdefined( spawnweapon ) ) + { + self thread [[ GetFunction( "maps/mp/gametypes/_class", "initweaponattachments" ) ]]( spawnweapon ); + } + } + + self [[ GetFunction( "maps/mp/gametypes/_class", "cac_selector" ) ]](); + + if ( !isdefined( self.firstspawn ) ) + { + if ( isdefined( spawnweapon ) ) + { + self initialweaponraise( spawnweapon ); + } + else + { + self initialweaponraise( weapon ); + } + } + else + { + self seteverhadweaponall( 1 ); + } + + self.firstspawn = 0; + pixendevent(); +} diff --git a/t6/scripts/music.gsc b/t6/scripts/music.gsc new file mode 100644 index 0000000..bb9ae76 --- /dev/null +++ b/t6/scripts/music.gsc @@ -0,0 +1,128 @@ +#include common_scripts\utility; +#include maps\mp\_utility; + + +init() +{ + setdvar("song", "0"); + flag_wait("initial_blackscreen_passed"); + level thread MusicPlayer(); +} + +MusicPlayer() +{ + if( getdvar( "mapname" ) == "zm_transit" ) + { + for(;;) + { + if (getdvar("song") == "1") + { + playsoundatposition( "mus_zmb_secret_song", ( 0, 0, 0 ) );//260 + wait 260; + setdvar("song", "0"); + } + wait 0.1; + } + } + if( getdvar( "mapname" ) == "zm_nuked" ) + { + for(;;) + { + if (getdvar("song") == "1") + { + playsoundatposition( "zmb_nuked_song_1", ( 0, 0, 0 ) );//88 + wait 88; + setdvar("song", "0"); + } + if (getdvar("song") == "2") + { + playsoundatposition( "zmb_nuked_song_2", ( 0, 0, 0 ) );//60 + wait 60; + setdvar("song", "0"); + } + if (getdvar("song") == "3") + { + playsoundatposition( "zmb_nuked_song_3", ( 0, 0, 0 ) );//80 + wait 80; + setdvar("song", "0"); + } + if (getdvar("song") == "4") + { + playsoundatposition( "mus_zmb_secret_song", ( 0, 0, 0 ) );//260 + wait 260; + setdvar("song", "0"); + } + wait 0.1; + } + } + if( getdvar( "mapname" ) == "zm_highrise" ) + { + for(;;) + { + if (getdvar("song") == "1") + { + playsoundatposition( "mus_zmb_secret_song", ( 0, 0, 0 ) );//190 + wait 190; + setdvar("song", "0"); + } + wait 0.1; + } + } + if( getdvar( "mapname" ) == "zm_prison" ) + { + for(;;) + { + if (getdvar("song") == "1") + { + playsoundatposition( "mus_zmb_secret_song", ( 0, 0, 0 ) );//170 + wait 170; + setdvar("song", "0"); + } + if (getdvar("song") == "2") + { + playsoundatposition( "mus_zmb_secret_song_2", ( 0, 0, 0 ) );//150 + wait 150; + setdvar("song", "0"); + } + wait 0.1; + } + } + if( getdvar( "mapname" ) == "zm_buried" ) + { + for(;;) + { + if (getdvar("song") == "1") + { + playsoundatposition( "mus_zmb_secret_song", ( 0, 0, 0 ) );//363 + wait 363; + setdvar("song", "0"); + } + wait 0.1; + } + } + if( getdvar( "mapname" ) == "zm_tomb" ) + { + for(;;) + { + if (getdvar("song") == "1") + { + playsoundatposition( "mus_zmb_secret_song", ( 0, 0, 0 ) );//310 + wait 310; + setdvar("song", "0"); + } + if (getdvar("song") == "2") + { + playsoundatposition( "mus_zmb_secret_song_aether", ( 0, 0, 0 ) );//135 + wait 135; + setdvar("song", "0"); + } + if (getdvar("song") == "3") + { + playsoundatposition( "mus_zmb_secret_song_a7x", ( 0, 0, 0 ) );//352 + wait 352; + setdvar("song", "0"); + } + wait 0.1; + } + } +} \ No newline at end of file diff --git a/t6/scripts/no_fog.gsc b/t6/scripts/no_fog.gsc new file mode 100644 index 0000000..79166d4 --- /dev/null +++ b/t6/scripts/no_fog.gsc @@ -0,0 +1,14 @@ +init() +{ + setdvar("r_fog", "0"); + level thread onPlayerConnect(); +} + +onplayerconnect() +{ + while( 1 ) + { + level waittill( "connected", player ); + player SetClientDvar("r_fog", "0"); + } +} \ No newline at end of file diff --git a/t6/scripts/on_player_connect.gsc b/t6/scripts/on_player_connect.gsc new file mode 100644 index 0000000..9c0c26f --- /dev/null +++ b/t6/scripts/on_player_connect.gsc @@ -0,0 +1,17 @@ +init() +{ + level thread on_player_connect(); +} + +on_player_connect() +{ + for(;;) + { + level waittill("connected", player); + scripts\AATs_Perks::onPlayerConnect(player); + scripts\bankv2::onPlayerConnect(player); + scripts\stam_mule_no_whoswho::onPlayerConnect(player); + scripts\vipperks::onPlayerConnect(player); + scripts\zmcounterhealthwatermark::onPlayerConnect(player); + } +} \ No newline at end of file diff --git a/t6/scripts/perkaholic.gsc b/t6/scripts/perkaholic.gsc new file mode 100644 index 0000000..2dcf411 --- /dev/null +++ b/t6/scripts/perkaholic.gsc @@ -0,0 +1,71 @@ +#include scripts\AATs_Perks; +#include common_scripts\utility; + +init() +{ +// if (getdvar("net_port") != "30003") + return; + level thread on_player_connect(); +} + +on_player_connect() +{ + for(;;) + { + level waittill("connected", player); + player thread perkaholic(); + } +} + +perkaholic() +{ + self endon("disconnect"); + flag_wait("initial_blackscreen_passed"); + + perk_list_c = []; + perk_list_c[perk_list_c.size] = "Downers_Delight"; + perk_list_c[perk_list_c.size] = "MULE"; + perk_list_c[perk_list_c.size] = "PHD_FLOPPER"; + perk_list_c[perk_list_c.size] = "ELECTRIC_CHERRY"; + perk_list_c[perk_list_c.size] = "WIDOWS_WINE"; + perk_list_c[perk_list_c.size] = "Time_Slip"; + perk_list_c[perk_list_c.size] = "Ammo_Regen"; + perk_list_c[perk_list_c.size] = "Burn_Heart"; + perk_list_c[perk_list_c.size] = "Dying_Wish"; + perk_list_c[perk_list_c.size] = "Momentum_Mocha"; + perk_list_c[perk_list_c.size] = "Bandolier_Bandit"; + + perk_list = []; + perk_list[perk_list.size] = "specialty_quickrevive"; + perk_list[perk_list.size] = "specialty_armorvest"; + perk_list[perk_list.size] = "specialty_fastreload"; + perk_list[perk_list.size] = "specialty_rof"; + perk_list[perk_list.size] = "specialty_longersprint"; + perk_list[perk_list.size] = "specialty_flakjacket"; + perk_list[perk_list.size] = "specialty_deadshot"; + perk_list[perk_list.size] = "specialty_additionalprimaryweapon"; + + for(;;) + { + foreach(perk in perk_list) + { + if (!self HasPerk(perk)) + { + self thread maps\mp\zombies\_zm_perks::give_perk(perk, 0); + iprintln("draw2"); + } + + wait 0.3; + } + foreach(perk in perk_list_c) + { + if (!(self HascustomPerk(perk))) + { + self thread drawshader_and_shadermove( perk, 0, 0, "custom" ); + iprintln("draw"); + } + wait 0.3; + } + wait 1; + } +} \ No newline at end of file diff --git a/t6/scripts/points_multiplier.gsc b/t6/scripts/points_multiplier.gsc new file mode 100644 index 0000000..5d31df5 --- /dev/null +++ b/t6/scripts/points_multiplier.gsc @@ -0,0 +1,189 @@ +#include maps\mp\zombies\_zm_power; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\zombies\_zm_chugabud; +#include maps\mp\zombies\_zm_afterlife; +#include maps\mp\zombies\_zm_tombstone; +#include maps\mp\zombies\_zm_perk_vulture; +#include maps\mp\zombies\_zm_weap_time_bomb; +#include maps\mp\_demo; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\gametypes_zm\_gameobjects; +#include maps\mp\zombies\_zm_buildables; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm_clone; +#include maps\mp\zombies\_zm_weap_cymbal_monkey; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm; +#include maps\mp\_visionset_mgr; +//motd +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_craftables; +#include maps\mp\zm_alcatraz_utility; +#include maps\mp\zm_alcatraz_gamemodes; +#include maps\mp\zm_prison_fx; +#include maps\mp\zm_prison_ffotd; +#include maps\mp\animscripts\zm_death; +#include maps\mp\zm_alcatraz_amb; +#include maps\mp\zombies\_load; +#include maps\mp\zm_prison_achievement; +#include maps\mp\gametypes_zm\_spawning; +#include maps\mp\zombies\_zm_perk_electric_cherry; +#include maps\mp\zombies\_zm_perk_divetonuke; +#include maps\mp\zm_alcatraz_distance_tracking; +#include maps\mp\zm_alcatraz_traps; +#include maps\mp\zm_alcatraz_travel; +#include maps\mp\zombies\_zm_magicbox_prison; +#include maps\mp\zombies\_zm_ai_basic; +#include maps\mp\zombies\_zm_weap_claymore; +#include maps\mp\zombies\_zm_weap_riotshield_prison; +#include maps\mp\zombies\_zm_weap_blundersplat; +#include maps\mp\zombies\_zm_weap_tomahawk; +#include maps\mp\zombies\_zm_zonemgr; +#include maps\mp\zm_alcatraz_weap_quest; +#include maps\mp\zm_alcatraz_grief_cellblock; +#include maps\mp\zm_prison; +#include character\c_zom_arlington; +#include character\c_zom_deluca; +#include character\c_zom_handsome; +#include character\c_zom_oleary; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_blockers; + +//points +#include common_scripts\utility; +#include maps\mp\_utility; + + +//timebomb +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\zombies\_zm_weapon_locker; +#include maps\mp\zombies\_zm_magicbox; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_spawner; + +init() +{ + level._game_module_point_adjustment = ::doublepoints; + level.is_private = 0; + if (getdvar("net_port") == "30005") + level.is_private = 1; +} + +doublepoints(player, zombie_team, player_points) +{ + if (player_points != 0) + { + tag = strTok(player.name, "]"); + if (tag[0] == "[^9F^7") + { + player maps\mp\zombies\_zm_score::add_to_player_score( player_points ); + player.pers[ "score" ] = player.score; + } + else if (tag[0] == "[^8E^7") + { + player maps\mp\zombies\_zm_score::add_to_player_score( player_points * 3); + player.pers[ "score" ] = player.score; + } + else if (tag[0] == "[^2D^7") + { + player maps\mp\zombies\_zm_score::add_to_player_score( player_points * 3); + player.pers[ "score" ] = player.score; + } + else if (tag[0] == "[^4C^7") + { + player maps\mp\zombies\_zm_score::add_to_player_score( player_points * 4); + player.pers[ "score" ] = player.score; + } + else if (tag[0] == "[^5B^7") + { + player maps\mp\zombies\_zm_score::add_to_player_score( player_points * 4); + player.pers[ "score" ] = player.score; + } + else if (tag[0] == "[^6A^7") + { + player maps\mp\zombies\_zm_score::add_to_player_score( player_points * 5); + player.pers[ "score" ] = player.score; + } + else if (tag[0] == "[^3S^7") + { + player maps\mp\zombies\_zm_score::add_to_player_score( player_points * 6); + player.pers[ "score" ] = player.score; + } + else if (tag[0] == "[^3SS^7") + { + player maps\mp\zombies\_zm_score::add_to_player_score( player_points * 7); + player.pers[ "score" ] = player.score; + } + else if (tag[0] == "[^3SSS^7") + { + player maps\mp\zombies\_zm_score::add_to_player_score( player_points * 9); + player.pers[ "score" ] = player.score; + } + else if (tag[0] == "[^6 I ^7") + { + player maps\mp\zombies\_zm_score::add_to_player_score( player_points * 10); + player.pers[ "score" ] = player.score; + } + else if (tag[0] == "[^6II^7") + { + player maps\mp\zombies\_zm_score::add_to_player_score( player_points * 11); + player.pers[ "score" ] = player.score; + } + else if (tag[0] == "[^6III^7") + { + player maps\mp\zombies\_zm_score::add_to_player_score( player_points * 12); + player.pers[ "score" ] = player.score; + } + else if (tag[0] == "[^5IV^7") + { + player maps\mp\zombies\_zm_score::add_to_player_score( player_points * 13); + player.pers[ "score" ] = player.score; + } + else if (tag[0] == "[^5V^7") + { + player maps\mp\zombies\_zm_score::add_to_player_score( player_points * 13); + player.pers[ "score" ] = player.score; + } + else if (tag[0] == "[^5VI^7") + { + player maps\mp\zombies\_zm_score::add_to_player_score( player_points * 13); + player.pers[ "score" ] = player.score; + } + else if (tag[0] == "[^5VII^7") + { + player maps\mp\zombies\_zm_score::add_to_player_score( player_points * 14); + player.pers[ "score" ] = player.score; + } + else if (tag[0] == "[^1IIX^7") + { + player maps\mp\zombies\_zm_score::add_to_player_score( player_points * 15); + player.pers[ "score" ] = player.score; + } + else if (tag[0] == "[^1IX^7") + { + player maps\mp\zombies\_zm_score::add_to_player_score( player_points * 15); + player.pers[ "score" ] = player.score; + } + else if (tag[0] == "[^1-X-^7") + { + player maps\mp\zombies\_zm_score::add_to_player_score( player_points * 20); + player.pers[ "score" ] = player.score; + } + if (tag[1]) + { + if(tag[1] == "[^3VIP^7" || tag[1] == "^3[VIP" || tag[1] == "^6[VIP" || tag[1] == "[^6VIP^7" || tag[1] == "^1[VIP" || tag[1] == "[^1VIP^7") + { + player maps\mp\zombies\_zm_score::add_to_player_score( player_points * 3); + player.pers[ "score" ] = player.score; + } + } + if (level.is_private == 1) + { + player maps\mp\zombies\_zm_score::add_to_player_score( player_points * 7); + player.pers[ "score" ] = player.score; + } + } +} \ No newline at end of file diff --git a/t6/scripts/rank_requirements.gsc b/t6/scripts/rank_requirements.gsc new file mode 100644 index 0000000..9c92edc --- /dev/null +++ b/t6/scripts/rank_requirements.gsc @@ -0,0 +1,134 @@ +#include common_scripts\utility; + +init() +{ + setdvar("melee_only", "0"); + setdvar("first_room_30", "0"); + setdvar("oneshot_50", "0"); + if (getdvar("net_port") == "30010" || getdvar("net_port") == "30011" || check_for_botb_port() == true) + return; + level thread melee_challenge_watcher(); + level thread first_room_challenge_watcher(); + level thread round_watcher(); +} + +first_room_challenge_watcher() +{ + for (;;) + { + if (isdefined(level.is_first_room) && level.is_first_room == 1) + { + if (level.round_number >= 30) + { + iprintln("First Room Round 30 ^3successful !"); + iprintln("First Room Round 30 ^3successful !"); + iprintln("First Room Round 30 ^3successful !"); + + setdvar("first_room_30", "1"); + return; + } + } + wait 1; + } +} + +melee_challenge_watcher() +{ + melee_round = 30; + start_round = 0; + total_hits_end_round = 0; + + for (;;) + { + if (level.round_number >= melee_round) + { + /* if (!isdefined(level.lock)) + { + start_round = level.round_number; + level.lock = 1; + }*/ + level.players_melee_only = 0; + level.players_hit_only = 0; + if (level.round_number == melee_round) + { + wait 0.1; + continue; + } + + foreach(player in level.players) + { + player.total_hits_start_round = player maps\mp\gametypes_zm\_globallogic_score::getpersstat( "hits" ); + } + if (isdefined(level.is_game_loaded) && level.is_game_loaded == 1 && !isdefined(level.lock2)) + { + level waittill("start_of_round"); + level.lock2 = 1; + continue; + } + level waittill("start_of_round"); + players = getplayers(); + + foreach(player in level.players) + { + total_hits_end_round = player maps\mp\gametypes_zm\_globallogic_score::getpersstat( "hits" ); + + if (total_hits_end_round - player.total_hits_start_round == 0) + level.players_melee_only++; + + } + + if (level.players_melee_only == level.players.size) + { + iprintln("Melee only round ^3successful !"); + iprintln("Melee only round ^3successful !"); + iprintln("Melee only round ^3successful !"); + + setdvar("melee_only", "1"); + } + } + wait 1; + } +} + +round_watcher() +{ + flag_wait("initial_blackscreen_passed"); + foreach(player in level.players) + { + player.og = 1; + } + for (;;) + { + str = ""; + if (level.round_number >= 50 && (!isdefined(level.is_game_loaded) || level.is_game_loaded == 0)) + { + foreach(index, player in level.players) + { + if (isdefined(player.og)) + { + str += player getguid(); + if (index + 1 < level.players.size) + str += ";"; + } + level.r50 = 1; + } + if (isdefined(level.r50)) + setdvar("oneshot_50", str); + return; + } + wait 1; + } +} + +check_for_botb_port() +{ + found = 0; + foreach(port in level.net_port_botb) + { + if (getdvar("net_port") == port) + found = 1; + } + if (found == 0) + return false; + return true; +} \ No newline at end of file diff --git a/t6/scripts/spectatormode.gsc b/t6/scripts/spectatormode.gsc new file mode 100644 index 0000000..b274f2e --- /dev/null +++ b/t6/scripts/spectatormode.gsc @@ -0,0 +1,75 @@ +#include maps\mp\_utility; +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\_busing; +#include common_scripts\utility; +#include maps\mp\gametypes_zm\_tweakables; +#include maps\mp\gametypes_zm\_globallogic_ui; +#include maps\mp\gametypes_zm\_globallogic_audio; +#include maps\mp\gametypes_zm\_globallogic_spawn; +#include maps\mp\gametypes_zm\_globallogic_score; +#include maps\mp\gametypes_zm\_globallogic_defaults; +#include maps\mp\gametypes_zm\_hud_message; +#include maps\mp\gametypes_zm\_globallogic_utils; +#include maps\mp\_demo; +#include maps\mp\gametypes_zm\_globallogic_player; +#include maps\mp\gametypes_zm\_weapons; +#include maps\mp\_music; +#include maps\mp\_challenges; +#include maps\mp\gametypes_zm\_hud; +#include maps\mp\gametypes_zm\_serversettings; +#include maps\mp\gametypes_zm\_clientids; +#include maps\mp\gametypes_zm\_weaponobjects; +#include maps\mp\gametypes_zm\_scoreboard; +#include maps\mp\gametypes_zm\_shellshock; +#include maps\mp\gametypes_zm\_spectating; +#include maps\mp\gametypes_zm\_gameobjects; +#include maps\mp\gametypes_zm\_spawnlogic; +#include maps\mp\gametypes_zm\_dev; +#include maps\mp\gametypes_zm\_hostmigration; +#include maps\mp\gametypes_zm\_globallogic; + + +init() +{ + setDvar("spectator", ""); + level thread playerSpectator(); +} + +playerSpectator() { + for (;;) { + if (getDvar("spectator") != "") { + spectator = strTok(getDvar("spectator"), ";"); + setDvar("spectator", ""); + if (isAlive(getPlayerByGuid(spectator[0]))) + { + getPlayerByGuid(spectator[0]) maps\mp\gametypes_zm\_globallogic_spawn::respawn_asspectator(0, 0); + getPlayerByGuid(spectator[0]) iPrintLn("^3Spectator mode set.^7"); + getPlayerByGuid(spectator[0]) thread perma_spec(); + } + } + wait 0.05; + } +} + +getPlayerByGuid(guid) { + for (i = 0; i < level.players.size; i++) { + if (isAlive(level.players[i]) && int(level.players[i] getGuid()) == int(guid)) { + return level.players[i]; + } + } + return false; +} + +perma_spec() +{ + self endon("disconnect"); + + for(;;) + { + if (self.sessionstate != "spectator") + { + self maps\mp\gametypes_zm\_globallogic_spawn::respawn_asspectator(0, 0); + } + wait 0.05; + } +} \ No newline at end of file diff --git a/t6/scripts/staff.gsc b/t6/scripts/staff.gsc new file mode 100644 index 0000000..469edd7 --- /dev/null +++ b/t6/scripts/staff.gsc @@ -0,0 +1,7 @@ +init() +{ + level.staff_list_a = []; + + // Add the .id of players to grant them staff permissions (must also be done on ClanTag, ZombieBank, ZombieRank) + level.staff_list_a[level.staff_list_a.size] = 12; +} \ No newline at end of file diff --git a/t6/scripts/stam_mule_no_whoswho.gsc b/t6/scripts/stam_mule_no_whoswho.gsc new file mode 100644 index 0000000..0a89be1 --- /dev/null +++ b/t6/scripts/stam_mule_no_whoswho.gsc @@ -0,0 +1,213 @@ +#include common_scripts\utility; +#include maps\mp\_demo; +#include maps\mp\_utility; +#include maps\mp\_visionset_mgr; +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\gametypes_zm\_weapons; +#include maps\mp\gametypes_zm\_zm_gametype; +#include maps\mp\zombies\_zm; +#include maps\mp\zombies\_zm_ai_basic; +#include maps\mp\zombies\_zm_ai_dogs; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_audio_announcer; +#include maps\mp\zombies\_zm_blockers; +#include maps\mp\zombies\_zm_bot; +#include maps\mp\zombies\_zm_buildables; +#include maps\mp\zombies\_zm_clone; +#include maps\mp\zombies\_zm_devgui; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm_ffotd; +#include maps\mp\zombies\_zm_game_module; +#include maps\mp\zombies\_zm_gump; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\zombies\_zm_magicbox; +#include maps\mp\zombies\_zm_melee_weapon; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm_pers_upgrades; +#include maps\mp\zombies\_zm_pers_upgrades_system; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\zombies\_zm_playerhealth; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\zombies\_zm_power; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_sidequests; +#include maps\mp\zombies\_zm_spawner; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zombies\_zm_timer; +#include maps\mp\zombies\_zm_tombstone; +#include maps\mp\zombies\_zm_traps; +#include maps\mp\zombies\_zm_unitrigger; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_zonemgr; + +init() +{ +} + +onPlayerConnect(player) +{ + player thread onPlayerSpawned(); +} + +onPlayerSpawned() +{ + level endon("end_game"); + self endon("disconnect"); + for(;;) + { + self waittill("spawned_player"); + self thread mulekick_save_weapons(); + self thread mulekick_restore_weapons(); + self thread staminup(); + self setperk("specialty_unlimitedsprint"); + if( getdvar( "mapname" ) == "zm_highrise" ) + { + self thread removewhoswho(); + } + } +} + +staminup() +{ + level endon("end_game"); + self endon("disconnect"); + for (;;) + { + self waittill_any("perk_acquired", "perk_lost"); + + if (self hasperk("specialty_longersprint")) + { + self setperk("specialty_movefaster"); + self setperk("specialty_fallheight"); + self setperk("specialty_stalker"); + } + else + { + self unsetperk("specialty_movefaster"); + self unsetperk("specialty_fallheight"); + self unsetperk("specialty_stalker"); + } + } +} + +removewhoswho() +{ + level endon("end_game"); + self endon("disconnect"); + for (;;) + { + self waittill_any("perk_acquired", "perk_lost"); + + if (self hasperk("specialty_finalstand")) + { + self unsetperk("specialty_finalstand"); + } + } +} + +mulekick_save_weapons() +{ + level endon("end_game"); + self endon("disconnect"); + + for (;;) + { + if (getDvar("isBus") == "1") + { + return; + } + else if (getDvar("isBus") == "0") + { + break; + } + wait 0.5; + } + + for (;;) + { + if (!self hasPerk("specialty_additionalprimaryweapon")) + { + self waittill("perk_acquired"); + wait 0.05; + } + + if (self hasPerk("specialty_additionalprimaryweapon")) + { + primaries = self getweaponslistprimaries(); + if (primaries.size >= 3) + { + weapon = primaries[primaries.size - 1]; + self.a_saved_weapon = maps\mp\zombies\_zm_weapons::get_player_weapondata(self, weapon); + } + else + { + self.a_saved_weapon = undefined; + } + } + + wait 5; + } +} + +mulekick_restore_weapons() +{ + level endon("end_game"); + self endon("disconnect"); + + for (;;) + { + if (getDvar("isBus") == "1") + { + return; + } + else if (getDvar("isBus") == "0") + { + break; + } + wait 0.5; + } + for (;;) + { + self waittill("perk_acquired"); + + if (isDefined(self.a_saved_weapon) && self hasPerk("specialty_additionalprimaryweapon")) + { + pap_triggers = getentarray( "specialty_weapupgrade", "script_noteworthy" ); + + give_wep = 1; + if ( isDefined( self ) && self maps\mp\zombies\_zm_weapons::has_weapon_or_upgrade( self.a_saved_weapon["name"] ) ) + { + give_wep = 0; + } + else if ( !maps\mp\zombies\_zm_weapons::limited_weapon_below_quota( self.a_saved_weapon["name"], self, pap_triggers ) ) + { + give_wep = 0; + } + else if ( !self maps\mp\zombies\_zm_weapons::player_can_use_content( self.a_saved_weapon["name"] ) ) + { + give_wep = 0; + } + else if ( isDefined( level.custom_magic_box_selection_logic ) ) + { + if ( !( [[ level.custom_magic_box_selection_logic ]]( self.a_saved_weapon["name"], self, pap_triggers ) ) ) + { + give_wep = 0; + } + } + else if ( isDefined( self ) && isDefined( level.special_weapon_magicbox_check ) ) + { + give_wep = self [[ level.special_weapon_magicbox_check ]]( self.a_saved_weapon["name"] ); + } + + if (give_wep) + { + current_wep = self getCurrentWeapon(); + self maps\mp\zombies\_zm_weapons::weapondata_give(self.a_saved_weapon); + self switchToWeapon(current_wep); + } + + self.a_saved_weapon = undefined; + } + } +} \ No newline at end of file diff --git a/t6/scripts/stats.gsc b/t6/scripts/stats.gsc new file mode 100644 index 0000000..0b607a8 --- /dev/null +++ b/t6/scripts/stats.gsc @@ -0,0 +1,195 @@ +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_magicbox; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\zombies\_zm_power; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\_demo; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_chugabud; +#include maps\mp\_visionset_mgr; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm; + +main() +{ + replaceFunc(maps\mp\zombies\_zm_perks::perk_set_max_health_if_jugg, ::customJugg); +} +init() +{ + // level thread onPlayerConnect(); + level thread playerStats(); + setdvar("hp", ""); + setdvar("speed", ""); + setdvar("starthp", ""); + setdvar("0_hp", ""); + setdvar("1_hp", ""); + setdvar("2_hp", ""); + setdvar("3_hp", ""); + setdvar("4_hp", ""); + setdvar("5_hp", ""); + setdvar("6_hp", ""); + setdvar("7_hp", ""); + setdvar("0_speed", ""); + setdvar("1_speed", ""); + setdvar("2_speed", ""); + setdvar("3_speed", ""); + setdvar("4_speed", ""); + setdvar("5_speed", ""); + setdvar("6_speed", ""); + setdvar("7_speed", ""); + flag_wait( "initial_blackscreen_passed" ); + setdvar("restart", "1"); +} + +/*onPlayerConnect() +{ + while( 1 ) + { + level waittill( "connected", player ); + player thread onPlayerSpawned(); + } +} + +onPlayerSpawned() +{ + level endon("game_ended"); + self endon("disconnect"); + self waittill( "spawned_player" ); + flag_wait( "initial_blackscreen_passed" ); + wait 5; + for (;;) + { + cooldown_time = randomintrange(1, 10); + if (cooldown_time >= 7) + { + self SetMoveSpeedScale(2.2); + self iPrintLn("Your ^3weapon^7 feels ^2lighter ^7!"); + wait 5; + self iPrintLn("Your ^3weapon^7 feels ^2lighter ^7!"); + } + else + { + self SetMoveSpeedScale(0.6); + self iPrintLn("Your ^3weapon^7 feels ^1heavier^7..."); + wait 5; + self iPrintLn("Your ^3weapon^7 feels ^1heavier^7..."); + } + wait 0.5; + self waittill( "spawned_player" ); + } + + if (getDvar("starthp") != "") { + stats = strTok(getDvar("starthp"), ";"); + setDvar("starthp", ""); + self waittill( "spawned_player" ); + getPlayerByGuid(stats[0]).extrahealth = int(stats[1]); + baseHp = 100; + if (getPlayerByGuid(stats[0]) HasPerk("specialty_armorvest")) + baseHp += 150; + getPlayerByGuid(stats[0]).maxhealth = getPlayerByGuid(stats[0]).extrahealth + baseHp; + getPlayerByGuid(stats[0]).health = getPlayerByGuid(stats[0]).maxhealth; + getPlayerByGuid(stats[0]) iPrintLn("^3Custom^1 HP^3 set."); + } + // self SetMoveSpeedScale(1.9); +}*/ + +playerStats() { + for (;;) { + if (getDvar("hp") != "" && getDvar( "g_gametype" ) != "zgrief") + { + statsHp = strTok(getDvar("hp"), ";"); + setDvar("hp", ""); + target = getPlayerByGuid(statsHp[0]); + target.extrahealth = int(statsHp[1]); + baseHp = 100; + if (target HasPerk("specialty_armorvest")) + baseHp += 150; + target.maxhealth = target.extrahealth + baseHp; + target.health = target.maxhealth; + target iPrintLn("^1HP^3 set to ^2" + target.maxhealth + "^7"); + } + + if (getDvar("speed") != "") + { + statsSpeed = strTok(getDvar("speed"), ";"); + setDvar("speed", ""); + target = getPlayerByGuid(statsSpeed[0]); + if (target HasPerk("specialty_longersprint")) + { + target SetMoveSpeedScale(float(statsSpeed[1]) + 0.07); + target iPrintLn("^1Speed^3 set to ^2" + (float(statsSpeed[1]) + 0.07) + "^7"); + } + else + { + target SetMoveSpeedScale(float(statsSpeed[1])); + target iPrintLn("^1Speed^3 set to ^2" + statsSpeed[1] + "^7"); + } + } + wait 0.05; + } +} + +getPlayerByGuid(guid) { + for (i = 0; i < level.players.size; i++) { + if (isAlive(level.players[i]) && int(level.players[i] getGuid()) == int(guid)) { + return level.players[i]; + } + } + return false; +} + + +customJugg( perk, set_premaxhealth, clamp_health_to_max_health ) +{ + max_total_health = undefined; + + if ( perk == "specialty_armorvest" ) + { + if ( set_premaxhealth ) + self.premaxhealth = self.maxhealth; + + max_total_health = level.zombie_vars["zombie_perk_juggernaut_health"]; + } + else if ( perk == "specialty_armorvest_upgrade" ) + { + if ( set_premaxhealth ) + self.premaxhealth = self.maxhealth; + + max_total_health = level.zombie_vars["zombie_perk_juggernaut_health_upgrade"]; + } + else if ( perk == "jugg_upgrade" ) + { + if ( set_premaxhealth ) + self.premaxhealth = self.maxhealth; + + if ( self hasperk( "specialty_armorvest" ) ) + max_total_health = level.zombie_vars["zombie_perk_juggernaut_health"]; + else + max_total_health = 100; + } + else if ( perk == "health_reboot" ) + max_total_health = 100; + + if ( isdefined( max_total_health ) ) + { + // if ( self maps\mp\zombies\_zm_pers_upgrades_functions::pers_jugg_active() ) + // max_total_health += level.pers_jugg_upgrade_health_bonus; + + if (isdefined (self.extrahealth)) + self setmaxhealth( max_total_health + self.extrahealth); + else + self setmaxhealth( max_total_health); + + if ( isdefined( clamp_health_to_max_health ) && clamp_health_to_max_health == 1 ) + { + if ( self.health > self.maxhealth ) + self.health = self.maxhealth; + } + } +} + diff --git a/t6/scripts/time_slip.gsc b/t6/scripts/time_slip.gsc new file mode 100644 index 0000000..aae678d --- /dev/null +++ b/t6/scripts/time_slip.gsc @@ -0,0 +1,416 @@ +#include maps\mp\zombies\_zm_magicbox; + +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_magicbox_lock; +#include maps\mp\zombies\_zm_unitrigger; +#include maps\mp\zombies\_zm_audio_announcer; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\_demo; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zombies\_zm_perks; + +init() +{ + replacefunc(maps\mp\zombies\_zm_perks::perk_give_bottle_begin, ::perk_give_bottle_begin_custom); + replacefunc(maps\mp\zombies\_zm_magicbox::treasure_chest_weapon_spawn, ::treasure_chest_weapon_spawn_custom); + replacefunc(maps\mp\zombies\_zm_perks::third_person_weapon_upgrade, ::third_person_weapon_upgrade_custom); +} + +perk_give_bottle_begin_custom( perk ) +{ + + gun = self getcurrentweapon(); + if (isdefined(self.has_timeslip) && self.has_timeslip == 1) + { + self thread maps\mp\zombies\_zm_perks::wait_give_perk(perk, 0.1); + return gun; + } + + + self increment_is_drinking(); + self disable_player_move_states( 1 ); + + weapon = ""; + + switch ( perk ) + { + case "specialty_armorvest": + case " _upgrade": + weapon = level.machine_assets["juggernog"].weapon; + break; + case "specialty_quickrevive_upgrade": + case "specialty_quickrevive": + weapon = level.machine_assets["revive"].weapon; + break; + case "specialty_fastreload_upgrade": + case "specialty_fastreload": + weapon = level.machine_assets["speedcola"].weapon; + break; + case "specialty_rof_upgrade": + case "specialty_rof": + weapon = level.machine_assets["doubletap"].weapon; + break; + case "specialty_longersprint_upgrade": + case "specialty_longersprint": + weapon = level.machine_assets["marathon"].weapon; + break; + case "specialty_flakjacket_upgrade": + case "specialty_flakjacket": + weapon = level.machine_assets["divetonuke"].weapon; + break; + case "specialty_deadshot_upgrade": + case "specialty_deadshot": + weapon = level.machine_assets["deadshot"].weapon; + break; + case "specialty_additionalprimaryweapon_upgrade": + case "specialty_additionalprimaryweapon": + weapon = level.machine_assets["additionalprimaryweapon"].weapon; + break; + case "specialty_scavenger_upgrade": + case "specialty_scavenger": + weapon = level.machine_assets["tombstone"].weapon; + break; + case "specialty_finalstand_upgrade": + case "specialty_finalstand": + weapon = level.machine_assets["whoswho"].weapon; + break; + } + + if ( isdefined( level._custom_perks[perk] ) && isdefined( level._custom_perks[perk].perk_bottle ) ) + weapon = level._custom_perks[perk].perk_bottle; + + self giveweapon( weapon ); + self switchtoweapon( weapon ); + return gun; +} + +third_person_weapon_upgrade_custom( current_weapon, upgrade_weapon, packa_rollers, perk_machine, trigger ) +{ + level endon( "Pack_A_Punch_off" ); + trigger endon( "pap_player_disconnected" ); + rel_entity = trigger.perk_machine; + origin_offset = ( 0, 0, 0 ); + angles_offset = ( 0, 0, 0 ); + origin_base = self.origin; + angles_base = self.angles; + + if ( isdefined( rel_entity ) ) + { + if ( isdefined( level.pap_interaction_height ) ) + origin_offset = ( 0, 0, level.pap_interaction_height ); + else + origin_offset = vectorscale( ( 0, 0, 1 ), 35.0 ); + + angles_offset = vectorscale( ( 0, 1, 0 ), 90.0 ); + origin_base = rel_entity.origin; + angles_base = rel_entity.angles; + } + else + rel_entity = self; + + forward = anglestoforward( angles_base + angles_offset ); + interact_offset = origin_offset + forward * -25; + + if ( !isdefined( perk_machine.fx_ent ) ) + { + perk_machine.fx_ent = spawn( "script_model", origin_base + origin_offset + ( 0, 1, -34 ) ); + perk_machine.fx_ent.angles = angles_base + angles_offset; + perk_machine.fx_ent setmodel( "tag_origin" ); + perk_machine.fx_ent linkto( perk_machine ); + } + + if ( isdefined( level._effect["packapunch_fx"] ) ) + fx = playfxontag( level._effect["packapunch_fx"], perk_machine.fx_ent, "tag_origin" ); + + offsetdw = vectorscale( ( 1, 1, 1 ), 3.0 ); + weoptions = self maps\mp\zombies\_zm_weapons::get_pack_a_punch_weapon_options( current_weapon ); + trigger.worldgun = spawn_weapon_model( current_weapon, undefined, origin_base + interact_offset, self.angles, weoptions ); + worldgundw = undefined; + + if ( maps\mp\zombies\_zm_magicbox::weapon_is_dual_wield( current_weapon ) ) + worldgundw = spawn_weapon_model( current_weapon, maps\mp\zombies\_zm_magicbox::get_left_hand_weapon_model_name( current_weapon ), origin_base + interact_offset + offsetdw, self.angles, weoptions ); + + trigger.worldgun.worldgundw = worldgundw; + + if ( isdefined( level.custom_pap_move_in ) ) + perk_machine [[ level.custom_pap_move_in ]]( trigger, origin_offset, angles_offset, perk_machine ); + else + perk_machine pap_weapon_move_in( trigger, origin_offset, angles_offset ); + + self playsound( "zmb_perks_packa_upgrade" ); + + if ( isdefined( perk_machine.wait_flag ) ) + perk_machine.wait_flag rotateto( perk_machine.wait_flag.angles + vectorscale( ( 1, 0, 0 ), 179.0 ), 0.25, 0, 0 ); + + wait 0.35; + trigger.worldgun delete(); + + if ( isdefined( worldgundw ) ) + worldgundw delete(); + + if (!isdefined(self.has_timeslip) || self.has_timeslip == 0) + wait 3; + + if ( isdefined( self ) ) + self playsound( "zmb_perks_packa_ready" ); + else + return; + + upoptions = self maps\mp\zombies\_zm_weapons::get_pack_a_punch_weapon_options( upgrade_weapon ); + trigger.current_weapon = current_weapon; + trigger.upgrade_name = upgrade_weapon; + trigger.worldgun = spawn_weapon_model( upgrade_weapon, undefined, origin_base + origin_offset, angles_base + angles_offset + vectorscale( ( 0, 1, 0 ), 90.0 ), upoptions ); + worldgundw = undefined; + + if ( maps\mp\zombies\_zm_magicbox::weapon_is_dual_wield( upgrade_weapon ) ) + worldgundw = spawn_weapon_model( upgrade_weapon, maps\mp\zombies\_zm_magicbox::get_left_hand_weapon_model_name( upgrade_weapon ), origin_base + origin_offset + offsetdw, angles_base + angles_offset + vectorscale( ( 0, 1, 0 ), 90.0 ), upoptions ); + + trigger.worldgun.worldgundw = worldgundw; + + if ( isdefined( perk_machine.wait_flag ) ) + perk_machine.wait_flag rotateto( perk_machine.wait_flag.angles - vectorscale( ( 1, 0, 0 ), 179.0 ), 0.25, 0, 0 ); + + if ( isdefined( level.custom_pap_move_out ) ) + rel_entity thread [[ level.custom_pap_move_out ]]( trigger, origin_offset, interact_offset ); + else + rel_entity thread pap_weapon_move_out( trigger, origin_offset, interact_offset ); + + return trigger.worldgun; +} + +treasure_chest_weapon_spawn_custom( chest, player, respin ) +{ + if ( isdefined( level.using_locked_magicbox ) && level.using_locked_magicbox ) + { + self.owner endon( "box_locked" ); + self thread maps\mp\zombies\_zm_magicbox_lock::clean_up_locked_box(); + } + + self endon( "box_hacked_respin" ); + self thread clean_up_hacked_box(); + assert( isdefined( player ) ); + self.weapon_string = undefined; + modelname = undefined; + rand = undefined; + number_cycles = 40; + if (isdefined(player.has_timeslip) && player.has_timeslip == 1) + number_cycles = 19; + if ( isdefined( chest.zbarrier ) ) + { + if ( isdefined( level.custom_magic_box_do_weapon_rise ) ) + chest.zbarrier thread [[ level.custom_magic_box_do_weapon_rise ]](); + else + chest.zbarrier thread magic_box_do_weapon_rise(); + } + + for ( i = 0; i < number_cycles; i++ ) + { + if ( i < 20 ) + { + wait 0.05; + continue; + } + + if ( i < 30 ) + { + wait 0.1; + continue; + } + + if ( i < 35 ) + { + wait 0.2; + continue; + } + + if ( i < 38 ) + wait 0.3; + } + if (isdefined(player.has_timeslip) && player.has_timeslip == 1) + self setzbarrierpiecestate( 3, "open" ); + if ( isdefined( level.custom_magic_box_weapon_wait ) ) + [[ level.custom_magic_box_weapon_wait ]](); + + if ( isdefined( player.pers_upgrades_awarded["box_weapon"] ) && player.pers_upgrades_awarded["box_weapon"] ) + rand = maps\mp\zombies\_zm_pers_upgrades_functions::pers_treasure_chest_choosespecialweapon( player ); + else + rand = treasure_chest_chooseweightedrandomweapon( player ); + + self.weapon_string = rand; + wait 0.1; + + if ( isdefined( level.custom_magicbox_float_height ) ) + v_float = anglestoup( self.angles ) * level.custom_magicbox_float_height; + else + v_float = anglestoup( self.angles ) * 40; + + self.model_dw = undefined; + self.weapon_model = spawn_weapon_model( rand, undefined, self.origin + v_float, self.angles + vectorscale( ( 0, 1, 0 ), 180.0 ) ); + + if ( weapon_is_dual_wield( rand ) ) + self.weapon_model_dw = spawn_weapon_model( rand, get_left_hand_weapon_model_name( rand ), self.weapon_model.origin - vectorscale( ( 1, 1, 1 ), 3.0 ), self.weapon_model.angles ); + + if ( getdvar( "magic_chest_movable" ) == "1" && !( isdefined( chest._box_opened_by_fire_sale ) && chest._box_opened_by_fire_sale ) && !( isdefined( level.zombie_vars["zombie_powerup_fire_sale_on"] ) && level.zombie_vars["zombie_powerup_fire_sale_on"] && self [[ level._zombiemode_check_firesale_loc_valid_func ]]() ) ) + { + random = randomint( 100 ); + + if ( !isdefined( level.chest_min_move_usage ) ) + level.chest_min_move_usage = 4; + + if ( level.chest_accessed < level.chest_min_move_usage ) + chance_of_joker = -1; + else + { + chance_of_joker = level.chest_accessed + 20; + + if ( level.chest_moves == 0 && level.chest_accessed >= 8 ) + chance_of_joker = 100; + + if ( level.chest_accessed >= 4 && level.chest_accessed < 8 ) + { + if ( random < 15 ) + chance_of_joker = 100; + else + chance_of_joker = -1; + } + + if ( level.chest_moves > 0 ) + { + if ( level.chest_accessed >= 8 && level.chest_accessed < 13 ) + { + if ( random < 30 ) + chance_of_joker = 100; + else + chance_of_joker = -1; + } + + if ( level.chest_accessed >= 13 ) + { + if ( random < 50 ) + chance_of_joker = 100; + else + chance_of_joker = -1; + } + } + } + + if ( isdefined( chest.no_fly_away ) ) + chance_of_joker = -1; + + if ( isdefined( level._zombiemode_chest_joker_chance_override_func ) ) + chance_of_joker = [[ level._zombiemode_chest_joker_chance_override_func ]]( chance_of_joker ); + + if ( chance_of_joker > random ) + { + self.weapon_string = undefined; + self.weapon_model setmodel( level.chest_joker_model ); + self.weapon_model.angles = self.angles + vectorscale( ( 0, 1, 0 ), 90.0 ); + + if ( isdefined( self.weapon_model_dw ) ) + { + self.weapon_model_dw delete(); + self.weapon_model_dw = undefined; + } + + self.chest_moving = 1; + flag_set( "moving_chest_now" ); + level.chest_accessed = 0; + level.chest_moves++; + } + } + + self notify( "randomization_done" ); + + if ( flag( "moving_chest_now" ) && !( level.zombie_vars["zombie_powerup_fire_sale_on"] && self [[ level._zombiemode_check_firesale_loc_valid_func ]]() ) ) + { + if ( isdefined( level.chest_joker_custom_movement ) ) + self [[ level.chest_joker_custom_movement ]](); + else + { + wait 0.5; + level notify( "weapon_fly_away_start" ); + wait 2; + + if ( isdefined( self.weapon_model ) ) + { + v_fly_away = self.origin + anglestoup( self.angles ) * 500; + self.weapon_model moveto( v_fly_away, 4, 3 ); + } + + if ( isdefined( self.weapon_model_dw ) ) + { + v_fly_away = self.origin + anglestoup( self.angles ) * 500; + self.weapon_model_dw moveto( v_fly_away, 4, 3 ); + } + + self.weapon_model waittill( "movedone" ); + + self.weapon_model delete(); + + if ( isdefined( self.weapon_model_dw ) ) + { + self.weapon_model_dw delete(); + self.weapon_model_dw = undefined; + } + + self notify( "box_moving" ); + level notify( "weapon_fly_away_end" ); + } + } + else + { + acquire_weapon_toggle( rand, player ); + + if ( rand == "tesla_gun_zm" || rand == "ray_gun_zm" ) + { + if ( rand == "ray_gun_zm" ) + level.pulls_since_last_ray_gun = 0; + + if ( rand == "tesla_gun_zm" ) + { + level.pulls_since_last_tesla_gun = 0; + level.player_seen_tesla_gun = 1; + } + } + + if ( !isdefined( respin ) ) + { + if ( isdefined( chest.box_hacks["respin"] ) ) + self [[ chest.box_hacks["respin"] ]]( chest, player ); + } + else if ( isdefined( chest.box_hacks["respin_respin"] ) ) + self [[ chest.box_hacks["respin_respin"] ]]( chest, player ); + + if ( isdefined( level.custom_magic_box_timer_til_despawn ) ) + self.weapon_model thread [[ level.custom_magic_box_timer_til_despawn ]]( self ); + else + self.weapon_model thread timer_til_despawn( v_float ); + + if ( isdefined( self.weapon_model_dw ) ) + { + if ( isdefined( level.custom_magic_box_timer_til_despawn ) ) + self.weapon_model_dw thread [[ level.custom_magic_box_timer_til_despawn ]]( self ); + else + self.weapon_model_dw thread timer_til_despawn( v_float ); + } + + self waittill( "weapon_grabbed" ); + + if ( !chest.timedout ) + { + if ( isdefined( self.weapon_model ) ) + self.weapon_model delete(); + + if ( isdefined( self.weapon_model_dw ) ) + self.weapon_model_dw delete(); + } + } + + self.weapon_string = undefined; + self notify( "box_spin_done" ); +} \ No newline at end of file diff --git a/t6/scripts/upgrade.gsc b/t6/scripts/upgrade.gsc new file mode 100644 index 0000000..b9e76b1 --- /dev/null +++ b/t6/scripts/upgrade.gsc @@ -0,0 +1,66 @@ +init() +{ + level thread zcoins(); + setdvar("fire_rate", "0.75"); + setdvar("cost", "75"); + setdvar("upgrade", ""); + setdvar("perk_weapRateMultiplier", "0.75"); + level.rate = 0.75; + level.lock = 0; +} + +zcoins() +{ + for (;;) + { + if (getdvar("upgrade") != "") + { + level.rate = float(getdvar("upgrade")); + iprintln("rate = " + level.rate); +// if (level.rate <= 0.3) + // level.rate = 0.3; + setdvar("fire_rate", level.rate); + setdvar("upgrade", ""); + setdvar("perk_weapRateMultiplier", level.rate); + level thread joining_player_watcher(); + } + wait 0.1; + } +} + +joining_player_watcher() +{ + foreach(player in level.players) + { + if (player HasPerk("specialty_rof") == 0) + player thread maps\mp\zombies\_zm_perks::wait_give_perk("specialty_rof", 1); + if (level.rate != 0.3) + player iprintln("Fire rate ^3Upgraded^7 to " + level.rate + " !"); + } + if (level.rate <= 0.5 && level.lock == 0) + { + iprintln("Perma ^3Double Tap^7 ^2unlocked !"); + iprintln("Perma ^3Double Tap^7 ^2unlocked !"); + iprintln("Perma ^3Double Tap^7 ^2unlocked !"); + level thread firerate_upgrade(); + level.lock = 1; + } + +} + +firerate_upgrade() +{ + for (;;) + { + foreach(player in level.players) + { + if (player HasPerk("specialty_rof") == 0) + { + player thread maps\mp\zombies\_zm_perks::wait_give_perk("specialty_rof", 1); + } + + } + wait 1; + } + +} \ No newline at end of file diff --git a/t6/scripts/vipcommands.gsc b/t6/scripts/vipcommands.gsc new file mode 100644 index 0000000..8561636 --- /dev/null +++ b/t6/scripts/vipcommands.gsc @@ -0,0 +1,232 @@ + +#include maps\mp\_visionset_mgr; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\_demo; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_power; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\_utility; +#include common_scripts\utility; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\zombies\_zm_chugabud; +#include maps\mp\zombies\_zm_afterlife; +#include maps\mp\zombies\_zm_tombstone; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm_perk_vulture; +#include maps\mp\zombies\_zm_weap_time_bomb; +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\gametypes_zm\_gameobjects; +#include maps\mp\zombies\_zm_buildables; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm_clone; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_weap_cymbal_monkey; +#include maps\mp\zombies\_zm; + +init() +{ + setDvar("revive", ""); + setDvar("0_revivedRound", -10); + setDvar("1_revivedRound", -10); + setDvar("2_revivedRound", -10); + setDvar("3_revivedRound", -10); + setDvar("4_revivedRound", -10); + setDvar("5_revivedRound", -10); + setDvar("6_revivedRound", -10); + setDvar("7_revivedRound", -10); + setDvar("currentRound", 0); + level thread playerReviveCommand(); +} + +playerReviveCommand() +{ + level endon("game_ended"); + // if (level.script == "zm_prison") + // return; + flag_wait( "initial_blackscreen_passed" ); + level.rev_use = []; + level.revall_use = []; + rev = 0; + if (check_for_botb_port() == true || getdvar("net_port") == "30010" || getdvar("net_port") == "30011") + { + for (;;) + { + lock = 0; + if (getDvar("revive") != "") + { + content = strTok(getDvar("revive"), ";"); + setDvar("revive", ""); + reviver = getPlayerByGuid(content[0]); + if (content[1] == "all") + { + foreach(guid in level.revall_use) + { + if (guid == reviver getguid()) + { + reviver iprintln("You've ^1already used ^2.reviveall^7 this game."); + lock = 1; + break; + } + } + if (lock == 1) + continue; + revivePlayers(content); + iPrintLn(reviver.name + "^7 has ^3revived everyone ^7!"); + iPrintLn("^1Juggernog^7 granted to the fallens !"); + level.revall_use[level.revall_use.size] = reviver getguid(); + } + else if (content[1] == "guild") + { + tag = strTok(reviver.name, "]"); + + foreach(guid in level.rev_use) + { + if (guid == reviver getguid()) + { + lock++; + } + } + if ((lock >= 2 && (tag[1] == "^3[VIP" || tag[1] == "[^3VIP^7" )) || + (lock >= 3 && (tag[1] == "^6[VIP" || tag[1] == "[^6VIP^7" || tag[1] == "^1[VIP" || tag[1] == "[^1VIP^7" || tag[1] == "^2[VIP^7" || tag[1] == "[^2VIP^7"))) + { + reviver iprintln("You've ^1already used all your ^2.rev^7 this game."); + continue; + } + reviver reviveSelf(); + level.rev_use[level.rev_use.size] = reviver getguid(); + rev++; + } + else + { + tag = strTok(reviver.name, "]"); + + foreach(guid in level.rev_use) + { + if (guid == reviver getguid()) + { + lock++; + } + } + if ((lock >= 1 && (tag[1] == "^3[VIP" || tag[1] == "[^3VIP^7" )) || + (lock >= 2 && (tag[1] == "^6[VIP" || tag[1] == "[^6VIP^7" || tag[1] == "^1[VIP" || tag[1] == "[^1VIP^7" || tag[1] == "^2[VIP^7" || tag[1] == "[^2VIP^7"))) + { + reviver iprintln("You've ^1already used all your ^2.rev^7 this game."); + continue; + } + reviver reviveSelf(); + level.rev_use[level.rev_use.size] = reviver getguid(); + rev++; + + } + } + wait 0.5; + } + } + + for (;;) + { + if (int(getdvar("currentRound")) != level.round_number) + setdvar("currentRound", level.round_number); + if (getDvar("revive") != "") + { + content = strTok(getDvar("revive"), ";"); + setDvar("revive", ""); + reviver = getPlayerByGuid(content[0]); + tag = strTok(reviver.name, "]"); + revivePlayers(content); + iPrintLn(reviver.name + "^7 has ^3revived everyone ^7! ^2.rev^3"); + if (content[1] == "1") + iPrintLn("^1Juggernog^7 granted to the fallens !"); + } + wait 0.5; + } +} + +reviveSelf() +{ + if(self maps\mp\zombies\_zm_laststand::player_is_in_laststand()) + { + self thread maps\mp\zombies\_zm_laststand::auto_revive(self); + self thread PlayerTempInvulnerability(); + if (self HasPerk("specialty_armorvest") == 0) + self thread maps\mp\zombies\_zm_perks::wait_give_perk("specialty_armorvest", 1); + } + else if(self.sessionstate == "spectator") + { + self [[ level.spawnplayer ]](); + self thread PlayerTempInvulnerability(); + if (self HasPerk("specialty_armorvest") == 0) + self thread maps\mp\zombies\_zm_perks::wait_give_perk("specialty_armorvest", 1); + } + if (level.script != "zm_tomb" || level.script != "zm_prison" || !is_classic()) + { + thread maps\mp\zombies\_zm::refresh_player_navcard_hud(); + } +} + +revivePlayers(content) +{ + for (i = 0; i < level.players.size; i++) + { + if(level.players[i] maps\mp\zombies\_zm_laststand::player_is_in_laststand()) + { + level.players[i] thread maps\mp\zombies\_zm_laststand::auto_revive(level.players[i]); + level.players[i] thread PlayerTempInvulnerability(); + if (content[1] == "1" && level.players[i] HasPerk("specialty_armorvest") == 0) + level.players[i] thread maps\mp\zombies\_zm_perks::wait_give_perk("specialty_armorvest", 1); + } + else if(level.players[i].sessionstate == "spectator") + { + level.players[i] [[ level.spawnplayer ]](); + level.players[i] thread PlayerTempInvulnerability(); + if (content[1] == "1" && level.players[i] HasPerk("specialty_armorvest") == 0) + level.players[i] thread maps\mp\zombies\_zm_perks::wait_give_perk("specialty_armorvest", 1); + } + } + if (level.script != "zm_tomb" || level.script != "zm_prison" || !is_classic()) + { + thread maps\mp\zombies\_zm::refresh_player_navcard_hud(); + } +} + +PlayerTempInvulnerability() +{ + level endon("game_ended"); + self endon("player_disconnected"); + self EnableInvulnerability(); + self.ignoreme = true; + self iPrintln("Invincibility ^2ON^7 for ^35 seconds^7"); + wait 5; + self iPrintln("Invincibility ^1OFF^7"); + self DisableInvulnerability(); + self.ignoreme = false; + self Destroy(); +} + +getPlayerByGuid(guid) { + for (i = 0; i < level.players.size; i++) { + if (isAlive(level.players[i]) && int(level.players[i] getGuid()) == int(guid)) { + return level.players[i]; + } + } + return false; +} + +check_for_botb_port() +{ + found = 0; + if (isdefined(level.net_port_botb)) + { + foreach(port in level.net_port_botb) + { + if (getdvar("net_port") == port) + found = 1; + } + } + if (found == 0) + return false; + return true; +} \ No newline at end of file diff --git a/t6/scripts/vipperks.gsc b/t6/scripts/vipperks.gsc new file mode 100644 index 0000000..59ccc32 --- /dev/null +++ b/t6/scripts/vipperks.gsc @@ -0,0 +1,266 @@ +#include maps\mp\_visionset_mgr; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\_demo; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\zombies\_zm_power; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\_utility; +#include common_scripts\utility; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\zombies\_zm_chugabud; +#include maps\mp\zombies\_zm_afterlife; +#include maps\mp\zombies\_zm_tombstone; +#include maps\mp\zombies\_zm_perk_vulture; +#include maps\mp\zombies\_zm_weap_time_bomb; + +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\gametypes_zm\_gameobjects; +#include maps\mp\zombies\_zm_buildables; + + +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm_clone; +#include maps\mp\zombies\_zm_weap_cymbal_monkey; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm; + + +init() +{ + level.premium_pass_guid_list = []; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 3968479; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 3987957; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 1678458; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 1231669; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 2987958; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 1525072; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 45923; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 3208375; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 564391; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 3182080; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 46876; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 4065720; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 4084332; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 2986053; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 1672650; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 3647528; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 12404; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 69226; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 2495128; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 2431703; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 3896525; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 507816; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 3380572; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 3923832; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 207889; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 3069177; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 384664; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 3738486; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 711546; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 2322919; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 721994; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 544392; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 3793690; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 2119046; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 3718336; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 1409392; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 1325372; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 156188; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 813182; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 4207912; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 4034748; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 3651663; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 4274084; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 962346; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 4260233; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 4332223; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 185225; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 4209248; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 4152074; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 3562334; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 3749436; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 52224; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 3650683; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 1859204; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 3477011; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 4350989; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 1246281; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 638471; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 2701742; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 3658; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 4353146; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 2178072; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 211194; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 3758181; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 4033708; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 161608; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 93901565; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 3901565; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 4331907; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 3639908; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 3440389; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 2362298; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 4010056; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 1598430; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 4402645; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 4397760; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 2753396; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 2329450; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 2751401; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 4459498; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 3415461; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 4397609; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 4278924; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 4567245; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 4516531; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 1598430; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 4423522; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 4475944; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 294733; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 2395428; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 1680913; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 4429418; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 2012925; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 4105176; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 3531497; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 4438351; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 4583058; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 15686; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 4629606; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 3594591; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 4642679; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 250243; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 1814251; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 1431061; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 4403696; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 1937929; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 2953060; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 4295591; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 752582; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 3760007; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 1713786; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 3846726; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 4727280; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 3631325; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 3530081; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 4509605; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 4767238; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 390860; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 3361195; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 1027466; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 1789515; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 3069811; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 4838265; + level.premium_pass_guid_list[level.premium_pass_guid_list.size] = 831223; + + level.premium_pass_guid_list2 = []; + level.premium_pass_guid_list2[level.premium_pass_guid_list2.size] = 47780; + level.premium_pass_guid_list2[level.premium_pass_guid_list2.size] = 4289343; + level.premium_pass_guid_list2[level.premium_pass_guid_list2.size] = 4245614; + level.premium_pass_guid_list2[level.premium_pass_guid_list2.size] = 55406; + level.premium_pass_guid_list2[level.premium_pass_guid_list2.size] = 2157784; + level.premium_pass_guid_list2[level.premium_pass_guid_list2.size] = 2066354; + level.premium_pass_guid_list2[level.premium_pass_guid_list2.size] = 4296689; + level.premium_pass_guid_list2[level.premium_pass_guid_list2.size] = 4784168; + level.premium_pass_guid_list2[level.premium_pass_guid_list2.size] = 2239772; + level.premium_pass_guid_list2[level.premium_pass_guid_list2.size] = 2303783; + level.premium_pass_guid_list2[level.premium_pass_guid_list2.size] = 3961779; + level.premium_pass_guid_list2[level.premium_pass_guid_list2.size] = 2546035; + level.premium_pass_guid_list2[level.premium_pass_guid_list2.size] = 573910; + level.premium_pass_guid_list2[level.premium_pass_guid_list2.size] = 2768107; + level.premium_pass_guid_list2[level.premium_pass_guid_list2.size] = 2300756; + level.premium_pass_guid_list2[level.premium_pass_guid_list2.size] = 3303330; + level.premium_pass_guid_list2[level.premium_pass_guid_list2.size] = 1659566; + level.premium_pass_guid_list2[level.premium_pass_guid_list2.size] = 2611192; + level.premium_pass_guid_list2[level.premium_pass_guid_list2.size] = 5049898; + level.premium_pass_guid_list2[level.premium_pass_guid_list2.size] = 4511018; + level.premium_pass_guid_list2[level.premium_pass_guid_list2.size] = 4704248; + level.premium_pass_guid_list2[level.premium_pass_guid_list2.size] = 5074259; + level.premium_pass_guid_list2[level.premium_pass_guid_list2.size] = 1034509; + level.premium_pass_guid_list2[level.premium_pass_guid_list2.size] = 4952374; + level.premium_pass_guid_list2[level.premium_pass_guid_list2.size] = 4526906; + level.premium_pass_guid_list2[level.premium_pass_guid_list2.size] = 94746; + level.premium_pass_guid_list2[level.premium_pass_guid_list2.size] = 3745218; + level.premium_pass_guid_list2[level.premium_pass_guid_list2.size] = 508389; + level.premium_pass_guid_list2[level.premium_pass_guid_list2.size] = 3778421; + level.premium_pass_guid_list2[level.premium_pass_guid_list2.size] = 3308913; + level.premium_pass_guid_list2[level.premium_pass_guid_list2.size] = 5256290; + level.premium_pass_guid_list2[level.premium_pass_guid_list2.size] = 2872826; + level.premium_pass_guid_list2[level.premium_pass_guid_list2.size] = 3697647; +} + +onPlayerConnect(player) +{ + player thread onPlayerSpawned(); +} + +onPlayerSpawned() +{ + self endon( "disconnect" ); + level endon( "game_ended" ); + flag_wait( "initial_blackscreen_passed" ); + if(getDvar( "g_gametype" ) == "zgrief") + return; + for (;;) + { + tag = strTok(self.name, "]"); + if(tag[1] == "[^3VIP^7" || tag[1] == "^3[VIP" || tag[1] == "^6[VIP" || tag[1] == "[^6VIP" || tag[1] == "^1[VIP" || tag[1] == "[^1VIP^7" || tag[0] == "[^3SSS^7" + || tag[0] == "[^6 I ^7" || tag[0] == "[^6II^7" || tag[0] == "[^6III^7" + || tag[0] == "[^5IV^7" || tag[0] == "[^5V^7" || tag[0] == "[^5VI^7" || tag[0] == "[^5VII^7" + || tag[0] == "[^1IIX^7" || tag[0] == "[^1IX^7" || tag[0] == "[^1-X-^7" + ) + { + if(self.sessionstate != "spectator" && self HasPerk("specialty_armorvest") == 0 && self.afterlife != 1) + { + if (self player_is_in_laststand()) + { + } + else + { + self thread maps\mp\zombies\_zm_perks::wait_give_perk("specialty_armorvest", 1); + } + wait 2; + } + } + //speed cola + foreach(guid in level.premium_pass_guid_list) + { + if (self getguid() == guid) + { + if(self.sessionstate != "spectator" && self HasPerk("specialty_fastreload") == 0 && self.afterlife != 1) + { + if (self player_is_in_laststand()) + { + } + else + { + self thread maps\mp\zombies\_zm_perks::wait_give_perk("specialty_fastreload", 1); + } + wait 2; + } + } + } + foreach(guid in level.premium_pass_guid_list2) + { + if (self getguid() == guid) + { + if(self.sessionstate != "spectator" && self HasPerk("specialty_fastreload") == 0 && self.afterlife != 1) + { + if (self player_is_in_laststand()) + { + } + else + { + self thread maps\mp\zombies\_zm_perks::wait_give_perk("specialty_fastreload", 1); + } + wait 2; + } + } + } + wait 0.5; + } +} \ No newline at end of file diff --git a/t6/scripts/zm/.vs/VSWorkspaceState.json b/t6/scripts/zm/.vs/VSWorkspaceState.json new file mode 100644 index 0000000..31e1c68 --- /dev/null +++ b/t6/scripts/zm/.vs/VSWorkspaceState.json @@ -0,0 +1,8 @@ +{ + "ExpandedNodes": [ + "", + "\\zm_prison" + ], + "SelectedNode": "\\zm_prison\\brutuswave.gsc", + "PreviewInSolutionExplorer": false +} \ No newline at end of file diff --git a/t6/scripts/zm/.vs/slnx.sqlite b/t6/scripts/zm/.vs/slnx.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..e296fee75d2c6c4b11a1776f03107b267d928663 GIT binary patch literal 90112 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 literal 0 HcmV?d00001 diff --git a/t6/scripts/zm/.vs/zm/v17/.wsuo b/t6/scripts/zm/.vs/zm/v17/.wsuo new file mode 100644 index 0000000000000000000000000000000000000000..9194483f960bd9287b155553b3f87e3f460528b8 GIT binary patch literal 12288 zcmeHMUu;uV7(X4N;(tT|5oOMSICkf4*Y(eUWnH@}hRI|wOstZ-_I6xo*QWP&6V|CO z5Mwk^6BD0IG>XqWN{I1Ip8#V_j6R4DzWC&$FED?<`)9kWTj_2=HtE-W=l?n1x!?J| zbAIRS@}>1xK0CMNcTq)sVvV>qyH4EcD)+h4;vpd(M4n~WW@l$v#Wa#lT16T-C<^!) zqE!rv3B)CFl1o`PZ4_(g)_m=CdR^XkrTq8%zxdXnUH|=7<6%fFh~r`(q-T*D6mMK- zl!etBMa!Igs(oSY;<+G-VZJ6g@+r3{a+pC$sNfOkLIJCGyQQLb(c*J2_fqZL< z%k~KPZZQ4+0mKj6X?ER+G-K8^Y2|C+zx4mN&-~W(fB45r@_)xdIVbJ|j!!e@*?$+f z+W$A8jQ;QRb>c_uvZn7l8d>=<*Q%Pi?oJucYOX)?&i>CmpV*IQ2hRuY|Fj973$y{A z0h_>^!H2k{Tdhm;wb=)pPM+Xub z5ywmnW{9+jjC8Bnk|FWW8q^Y>)GL1n+H(IQ5%&@0m4Lkz;IJg-kwab=4l-0R6GOx? zE8=6-4CiOn>j8hZLGDFUx)2GB%P-B_BOftQU&SarO!*XJ0p_u{q#Hf zX1(7}U7g{E52}SfM}=R6L>S@Hv=j0-pxQYPmToy;BP03Oe74~fzuTdP2lFt1Bb%{@ z?hSWoM84bJhTsA8f^pLyx?uBV(AcPc{+V6UK_(%7kl z==UI>XB6j78WIP^VVs23-`nciiL923hdVsTmoU`F_Hebj3-r5r^?!Ua$Z0yms`@ zn0c?%Xn*Q~^2yn+PQ3MAC4c@+Ek021e7KHIf2&WizuvxV*XaC-jj8{IBOOMbvwA_s z0qy=tbGh0ncORy28gbtqf?ZiVyM_Kr@Ge@KgMftCi`QU!&2AAyI4xqp+(}@kF!F=I z2NHHgrn`~y3>+6xgh}%kN9!5U1)rL-QKuu9{$@Z9rIL1=;o<>t z3~iuY4vme;J<+J7`lG58%tkYkqGZETFc=I6L)mmT7z+EuH@-x#jNf!DkQ@vL2mR7O zIM^-u{Rvr$4fBBb3t9C9P=asZ)9U9W9nLy)cm)E0vA1 zKBY{mUE_MXQkjknbVmaCNuhuo;EeoIBodY}BUw&H!ad<=A~5r=_xbAu%uOpyl+>JJ zXp?GhqjQ0Qo6w&NqxCm6dm}ZQXsYwZsq=w_zUF)Frn>UxrTpqv$?a6sKv)Tl$&%U~ z?2&?jNJNT;GFhodRkGdDpsIFtOeV+^!NiBo1WvCB~5Bn7ju~VU$VCvJ3Yk9a8t8 zjfD&QfWC+WywEF`y!N!Dwd3Sn_=2O0RxxUxxPHu4#tB@Ds_z}vJ4Y5e7{^yzy0>m% zi;vRj0sr#ub=Ds40CapD2xJ_xs^3^fMPzZIuF^K(U*cYBv0nVkH*LqDvZT$ z!|G1`YZfkHizM;>G7Bd*8Bd@eE-{T zo)iC<_rFhU2X4OqJ3E>8*nLuXAH{pmM&uI*T>$1;tti}jXY;N*r)S5neU;4Kv-_NU zy)oa>iM=?F(+IcojcB-3$l}px`;B@Wn&ul2$$Si|3alDgo~g*4awVzcbk&?seL-{m zEj@W%f9|8s`oDwptz7?}o=|6CnI>@Fw|ael-4{Qe`}5Ndr8V}t^3!*J?Ar5D$IlnO vF28#EWZ$VDKDgS$m38lpOtZ{QV;5ii^21FnpL<<@_gJej-CY0Md;R|bl2<(H literal 0 HcmV?d00001 diff --git a/t6/scripts/zm/ranked.gsc b/t6/scripts/zm/ranked.gsc new file mode 100644 index 0000000..3616a34 --- /dev/null +++ b/t6/scripts/zm/ranked.gsc @@ -0,0 +1,531 @@ +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; + +main() +{ + if ( GetDvarInt( "scr_disablePlutoniumFixes" ) ) + { + return; + } + + if ( isDedicated() ) + { + // fix menuresponse exploits + replaceFunc( GetFunction( "maps/mp/gametypes_zm/_zm_gametype", "menu_onmenuresponse" ), ::menu_onmenuresponse_fix, -1 ); + + // fix player spawnpoints + replaceFunc( GetFunction( "maps/mp/zombies/_zm", "getfreespawnpoint" ), ::getFreeSpawnpoint_override, -1 ); + + // use coop revive + level.using_solo_revive = false; + replaceFunc( GetFunction( "maps/mp/zombies/_zm", "check_quickrevive_for_hotjoin" ), ::check_quickrevive_for_hotjoin_fix, -1 ); + + // add a timeout for all_players_connected and kill solo revive + replaceFunc( GetFunction( "maps/mp/zombies/_zm", "onallplayersready" ), ::onallplayersready_override, -1 ); + + // make sure game is coop mode + func = GetFunction( "maps/mp/zm_alcatraz_utility", "check_solo_status" ); + + if ( !isDefined( func ) ) + { + func = GetFunction( "maps/mp/zm_tomb_utility", "check_solo_status" ); + } + + if ( isDefined( func ) ) + { + replaceFunc( func, ::check_solo_status_override, -1 ); + } + + // fix inert zombies spawning + func = GetFunction( "maps/mp/zm_transit_classic", "spawn_inert_zombies" ); + + if ( isDefined( func ) ) + { + replaceFunc( func, ::spawn_inert_zombies_override, -1 ); + } + + // fix tombstone spawning + func = GetFunction( "maps/mp/zm_transit_utility", "solo_tombstone_removal" ); + + if ( isDefined( func ) ) + { + replaceFunc( func, ::noop, -1 ); + } + } + + // replaceFunc( GetFunction( "maps/mp/animscripts/zm_utility", "wait_network_frame" ), ::wait_network_frame_override, -1 ); + // replaceFunc( GetFunction( "maps/mp/zombies/_zm_utility", "wait_network_frame" ), ::wait_network_frame_override, -1 ); +} + +init() +{ + if ( GetDvarInt( "scr_disablePlutoniumFixes" ) ) + { + return; + } + + // enable 8 player zombie games + level.player_too_many_players_check = false; + + if ( isDedicated() ) + { + // fix ranking + level thread upload_stats_on_round_end(); + level thread upload_stats_on_game_end(); + level thread upload_stats_on_player_connect(); + + // fix teamchange exploit + level.allow_teamchange = getgametypesetting( "allowInGameTeamChange" ) + ""; + SetDvar( "ui_allow_teamchange", level.allow_teamchange ); + } + + level thread watch_all_zombies(); +} + +watch_all_zombies() +{ + can_mantle_over_zambies = ( level.script == "zm_transit" || level.script == "zm_transit_dr" || level.script == "zm_prison" || level.script == "zm_nuked" || level.script == "zm_highrise" ); + + for ( ;; ) + { + zombies = getaiarray( level.zombie_team ); + + foreach ( zombie in zombies ) + { + if ( isDefined( zombie.pluto_audit ) ) + { + continue; + } + + zombie.pluto_audit = true; + + // fix jumping over zombies + if ( isDedicated() && can_mantle_over_zambies ) + { + zombie thread fix_zombie_physparams(); + } + } + + wait 0.05; + } +} + +fix_zombie_physparams() +{ + self endon( "death" ); + + if ( !is_true( self.completed_emerging_into_playable_area ) ) + { + self waittill( "completed_emerging_into_playable_area" ); + } + + animname = self.animname; + + if ( !isDefined( animname ) ) + { + animname = self.targetname; + } + + if ( animname != "zombie" || !self.has_legs ) + { + return; + } + + self setphysparams( 15, 0, 60 ); +} + +upload_stats_on_round_end() +{ + level endon( "end_game" ); + + for ( ;; ) + { + level waittill( "end_of_round" ); + + uploadstats(); + } +} + +upload_stats_on_game_end() +{ + level waittill( "end_game" ); + + uploadstats(); +} + +upload_stats_on_player_connect() +{ + level endon( "end_game" ); + + for ( ;; ) + { + level waittill( "connected" ); + + level thread delay_uploadstats( 1 ); + } +} + +delay_uploadstats( delay ) +{ + level notify( "delay_uploadstats" ); + level endon( "delay_uploadstats" ); + + level endon( "end_game" ); + + wait delay; + uploadstats(); +} + +check_quickrevive_for_hotjoin_fix( disconnecting_player ) +{ + should_update = 0; + solo_mode = 0; + + if ( flag( "solo_game" ) ) + { + should_update = 1; + } + + flag_clear( "solo_game" ); + + level.using_solo_revive = solo_mode; + level.revive_machine_is_solo = solo_mode; + [[ GetFunction( "maps/mp/zombies/_zm", "set_default_laststand_pistol" ) ]]( solo_mode ); + + if ( should_update && isdefined( level.quick_revive_machine ) ) + { + [[ GetFunction( "maps/mp/zombies/_zm", "update_quick_revive" ) ]]( solo_mode ); + } +} + +menu_onmenuresponse_fix() +{ + self endon( "disconnect" ); + + for ( ;; ) + { + self waittill( "menuresponse", menu, response ); + + if ( response == "back" ) + { + self closemenu(); + self closeingamemenu(); + + if ( level.console ) + { + if ( menu == game["menu_changeclass"] || menu == game["menu_changeclass_offline"] || 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; + } + + 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; + } + + if ( response == "changeclass_opfor" ) + { + self closemenu(); + self closeingamemenu(); + self openmenu( game["menu_changeclass_axis"] ); + continue; + } + + if ( response == "changeclass_wager" ) + { + self closemenu(); + self closeingamemenu(); + self openmenu( game["menu_changeclass_wager"] ); + continue; + } + + if ( response == "changeclass_custom" ) + { + self closemenu(); + self closeingamemenu(); + self openmenu( game["menu_changeclass_custom"] ); + continue; + } + + if ( response == "changeclass_barebones" ) + { + self closemenu(); + self closeingamemenu(); + self openmenu( game["menu_changeclass_barebones"] ); + continue; + } + + if ( response == "changeclass_marines_splitscreen" ) + { + self openmenu( "changeclass_marines_splitscreen" ); + } + + if ( response == "changeclass_opfor_splitscreen" ) + { + self openmenu( "changeclass_opfor_splitscreen" ); + } + + 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; + } + + if ( menu == game["menu_changeclass"] || menu == game["menu_changeclass_offline"] || menu == game["menu_changeclass_wager"] || 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 ); + } + } +} + +check_solo_status_override() +{ + level.is_forever_solo_game = false; +} + +wait_network_frame_override() +{ + wait 0.05; +} + +noop() +{ +} + +getFreeSpawnpoint_override( spawnpoints, player ) +{ + if ( !isdefined( spawnpoints ) ) + { +/# + iprintlnbold( "ZM >> No free spawn points in map" ); +#/ + return undefined; + } + + if ( !isdefined( game["spawns_randomized"] ) ) + { + game["spawns_randomized"] = 1; + spawnpoints = array_randomize( spawnpoints ); + random_chance = randomint( 100 ); + + if ( random_chance > 50 ) + { + set_game_var( "side_selection", 1 ); + } + else + { + set_game_var( "side_selection", 2 ); + } + } + + side_selection = get_game_var( "side_selection" ); + + if ( get_game_var( "switchedsides" ) ) + { + if ( side_selection == 2 ) + { + side_selection = 1; + } + else if ( side_selection == 1 ) + { + side_selection = 2; + } + } + + if ( isdefined( player ) && isdefined( player.team ) ) + { + i = 0; + + while ( isdefined( spawnpoints ) && i < spawnpoints.size ) + { + if ( side_selection == 1 ) + { + if ( player.team != "allies" && ( isdefined( spawnpoints[i].script_int ) && spawnpoints[i].script_int == 1 ) ) + { + arrayremovevalue( spawnpoints, spawnpoints[i] ); + i = 0; + } + else if ( player.team == "allies" && ( isdefined( spawnpoints[i].script_int ) && spawnpoints[i].script_int == 2 ) ) + { + arrayremovevalue( spawnpoints, spawnpoints[i] ); + i = 0; + } + else + { + i++; + } + } + else if ( player.team == "allies" && ( isdefined( spawnpoints[i].script_int ) && spawnpoints[i].script_int == 1 ) ) + { + arrayremovevalue( spawnpoints, spawnpoints[i] ); + i = 0; + } + else if ( player.team != "allies" && ( isdefined( spawnpoints[i].script_int ) && spawnpoints[i].script_int == 2 ) ) + { + arrayremovevalue( spawnpoints, spawnpoints[i] ); + i = 0; + } + else + { + i++; + } + } + } + + max_clients = getdvarint( "sv_maxclients" ); + + if ( !isdefined( self.playernum ) ) + { + self.playernum = self getentitynumber(); + + assert( self.playernum < max_clients ); + } + + for ( j = 0; j < spawnpoints.size; j++ ) + { + if ( !isdefined( spawnpoints[j].en_num ) ) + { + for ( m = 0; m < spawnpoints.size; m++ ) + { + spawnpoints[m].en_num = m % max_clients; + } + } + + if ( spawnpoints[j].en_num == self.playernum ) + { + return spawnpoints[j]; + } + } + +/# + print( "getFreeSpawnpoint: no spawns found, use first spawn" ); +#/ + assert( spawnpoints.size > 0 ); + return spawnpoints[0]; +} + +onallplayersready_override() +{ +/# + println( "ZM >> player_count_expected=" + getnumexpectedplayers() ); +#/ + + player_count_actual = 0; + timeout_started = false; + timeout_point = 0; + + while ( getnumexpectedplayers() == 0 || getnumconnectedplayers() < getnumexpectedplayers() || player_count_actual != getnumexpectedplayers() ) + { + players = get_players(); + player_count_actual = 0; + + for ( i = 0; i < players.size; i++ ) + { + players[i] freezecontrols( 1 ); + + if ( players[i].sessionstate == "playing" ) + { + player_count_actual++; + } + } + + if ( player_count_actual > 0 ) + { + if ( !timeout_started ) + { + timeout_started = true; + timeout_point = ( getDvarFloat( "sv_connecttimeout" ) * 1000 ) + getTime(); + } + + if ( getTime() > timeout_point ) + { + break; + } + } + else + { + timeout_started = false; + } + +/# + println( "ZM >> Num Connected =" + getnumconnectedplayers() + " Expected : " + getnumexpectedplayers() ); +#/ + wait 0.1; + } + + setinitialplayersconnected(); + +/# + println( "ZM >> We have all players - START ZOMBIE LOGIC" ); +#/ + + flag_set( "initial_players_connected" ); + + while ( !aretexturesloaded() ) + { + wait 0.05; + } + + thread [[ GetFunction( "maps/mp/zombies/_zm", "start_zombie_logic_in_x_sec" ) ]]( 3.0 ); + + [[ GetFunction( "maps/mp/zombies/_zm", "fade_out_intro_screen_zm" ) ]]( 5.0, 1.5, 1 ); +} + +spawn_inert_zombies_override() +{ + flag_wait( "initial_players_connected" ); + + func = GetFunction( "maps/mp/zm_transit_classic", "spawn_inert_zombies" ); + disableDetourOnce( func ); + self [[func]](); +} diff --git a/t6/scripts/zm/zm_buried/buried_disable_trample.gsc b/t6/scripts/zm/zm_buried/buried_disable_trample.gsc new file mode 100644 index 0000000..9377e12 --- /dev/null +++ b/t6/scripts/zm/zm_buried/buried_disable_trample.gsc @@ -0,0 +1,267 @@ +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_buildables; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_magicbox; +#include maps\mp\zombies\_zm_sidequests; +#include maps\mp\zombies\_zm_buildables_pooled; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_melee_weapon; +#include maps\mp\zombies\_zm_weap_claymore; +#include maps\mp\zombies\_zm_unitrigger; + +#include maps\mp\zm_buried_buildables; + +main() +{ + replaceFunc(maps\mp\zm_buried_buildables::include_buildables, ::include_buildables_custom); +} + +include_buildables_custom( buildablesenabledlist ) +{ + turbine_fan = generate_zombie_buildable_piece( "turbine", "p6_zm_buildable_turbine_fan", 32, 64, 0, "zm_hud_icon_fan", ::onpickup_common, ::ondrop_common, undefined, "tag_part_03", undefined, 1 ); + turbine_panel = generate_zombie_buildable_piece( "turbine", "p6_zm_buildable_turbine_rudder", 32, 64, 0, "zm_hud_icon_rudder", ::onpickup_common, ::ondrop_common, undefined, "tag_part_04", undefined, 2 ); + turbine_body = generate_zombie_buildable_piece( "turbine", "p6_zm_buildable_turbine_mannequin", 32, 15, 0, "zm_hud_icon_mannequin", ::onpickup_common, ::ondrop_common, undefined, "tag_part_01", undefined, 3 ); + springpad_door = generate_zombie_buildable_piece( "springpad_zm", "p6_zm_buildable_tramplesteam_door", 32, 64, 0, "zom_hud_trample_steam_screen", ::onpickup_common, ::ondrop_common, undefined, "Tag_part_02", undefined, 4 ); + springpad_flag = generate_zombie_buildable_piece( "springpad_zm", "p6_zm_buildable_tramplesteam_bellows", 32, 15, 0, "zom_hud_trample_steam_bellow", ::onpickup_common, ::ondrop_common, undefined, "Tag_part_04", undefined, 5 ); + springpad_motor = generate_zombie_buildable_piece( "springpad_zm", "p6_zm_buildable_tramplesteam_compressor", 32, 15, 0, "zom_hud_trample_steam_compressor", ::onpickup_common, ::ondrop_common, undefined, "Tag_part_01", undefined, 6 ); + springpad_whistle = generate_zombie_buildable_piece( "springpad_zm", "p6_zm_buildable_tramplesteam_flag", 48, 15, 0, "zom_hud_trample_steam_whistle", ::onpickup_common, ::ondrop_common, undefined, "Tag_part_03", undefined, 7 ); + sq_common_electricbox = generate_zombie_buildable_piece( "sq_common", "p6_zm_buildable_sq_electric_box", 32, 64, 0, "zm_hud_icon_sq_powerbox", ::onpickup_common, ::ondrop_common, undefined, "tag_part_02", undefined, 1, 2 ); + sq_common_meteor = generate_zombie_buildable_piece( "sq_common", "p6_zm_buildable_sq_meteor", 32, 64, 0, "zm_hud_icon_sq_meteor", ::onpickup_common, ::ondrop_common, undefined, "tag_part_04", undefined, 2, 2 ); + sq_common_scaffolding = generate_zombie_buildable_piece( "sq_common", "p6_zm_buildable_sq_scaffolding", 64, 96, 0, "zm_hud_icon_sq_scafold", ::onpickup_common, ::ondrop_common, undefined, "tag_part_01", undefined, 3, 2 ); + sq_common_transceiver = generate_zombie_buildable_piece( "sq_common", "p6_zm_buildable_sq_transceiver", 64, 96, 0, "zm_hud_icon_sq_tranceiver", ::onpickup_common, ::ondrop_common, undefined, "tag_part_03", undefined, 4, 2 ); + sq_lamp_piece = generate_zombie_buildable_piece( "buried_sq_oillamp", "p6_zm_bu_lantern_silver_on", 32, 64, 0, "zm_hud_icon_jetgun_engine", ::onpickup_common, ::ondrop_common, undefined, undefined, undefined, 13, 2 ); + sq_m_tower_vacuum_tube = generate_zombie_buildable_piece( "buried_sq_bt_m_tower", "p6_zm_bu_sq_vaccume_tube", 32, 64, 0, "zm_hud_icon_sq_powerbox", ::onpickup_common, ::ondrop_common, undefined, "j_vaccume_01", undefined, 7, 2 ); + sq_m_tower_battery = generate_zombie_buildable_piece( "buried_sq_bt_m_tower", "p6_zm_bu_sq_buildable_battery", 32, 64, 0, "zm_hud_icon_battery", ::onpickup_common, ::ondrop_common, undefined, "j_battery", undefined, 8, 2 ); + sq_r_tower_crystal = generate_zombie_buildable_piece( "buried_sq_bt_r_tower", "p6_zm_bu_sq_crystal", 96, 64, 0, "zm_hud_icon_sq_powerbox", ::onpickup_common, ::ondrop_common, undefined, "j_crystal_01", undefined, 9, 2 ); + sq_r_tower_satellite = generate_zombie_buildable_piece( "buried_sq_bt_r_tower", "p6_zm_bu_sq_satellite_dish", 32, 64, 0, "zm_hud_icon_sq_powerbox", ::onpickup_common, ::ondrop_common, "j_satellite", undefined, undefined, 10, 2 ); + sq_s_tower_antenna = generate_zombie_buildable_piece( "buried_sq_bt_m_tower", "p6_zm_bu_sq_antenna", 32, 64, 0, "zm_hud_icon_sq_powerbox", ::onpickup_common, ::ondrop_common, undefined, "j_antenna", undefined, 11, 2 ); + sq_s_tower_wire = generate_zombie_buildable_piece( "buried_sq_bt_m_tower", "p6_zm_bu_sq_wire_spool", 32, 64, 0, "zm_hud_icon_sq_powerbox", ::onpickup_common, ::ondrop_common, undefined, "j_wire", undefined, 12, 2 ); + subwoofer_speaker = generate_zombie_buildable_piece( "subwoofer_zm", "t6_wpn_zmb_subwoofer_parts_speaker", 32, 64, 0, "zom_hud_icon_buildable_woof_speaker", ::onpickup_common, ::ondrop_common, undefined, "TAG_SPEAKER", undefined, 8 ); + subwoofer_motor = generate_zombie_buildable_piece( "subwoofer_zm", "t6_wpn_zmb_subwoofer_parts_motor", 48, 15, 0, "zom_hud_icon_buildable_woof_motor", ::onpickup_common, ::ondrop_common, undefined, "TAG_ENGINE", undefined, 9 ); + subwoofer_table = generate_zombie_buildable_piece( "subwoofer_zm", "t6_wpn_zmb_subwoofer_parts_table", 48, 15, 0, "zom_hud_icon_buildable_woof_frame", ::onpickup_common, ::ondrop_common, undefined, "TAG_SPIN", undefined, 11 ); + subwoofer_mount = generate_zombie_buildable_piece( "subwoofer_zm", "t6_wpn_zmb_subwoofer_parts_mount", 32, 15, 0, "zom_hud_icon_buildable_woof_chains", ::onpickup_common, ::ondrop_common, undefined, "TAG_MOUNT", undefined, 10 ); + headchopper_blade = generate_zombie_buildable_piece( "headchopper_zm", "t6_wpn_zmb_chopper_part_blade", 32, 64, 0, "zom_hud_icon_buildable_chop_a", ::onpickup_common, ::ondrop_common, undefined, "TAG_SAW", undefined, 12 ); + headchopper_crank = generate_zombie_buildable_piece( "headchopper_zm", "t6_wpn_zmb_chopper_part_crank", 32, 15, 0, "zom_hud_icon_buildable_chop_b", ::onpickup_common, ::ondrop_common, undefined, "TAG_CRANK", undefined, 13 ); + headchopper_hinge = generate_zombie_buildable_piece( "headchopper_zm", "t6_wpn_zmb_chopper_part_hinge", 32, 15, 0, "zom_hud_icon_buildable_chop_c", ::onpickup_common, ::ondrop_common, undefined, "TAG_GEARS", undefined, 14 ); + headchopper_mount = generate_zombie_buildable_piece( "headchopper_zm", "t6_wpn_zmb_chopper_part_mount", 32, 15, 0, "zom_hud_icon_buildable_chop_d", ::onpickup_common, ::ondrop_common, undefined, "TAG_MOUNT", undefined, 15 ); + bottle = generate_zombie_buildable_piece( "booze", "p6_zm_bu_booze", 32, 64, 2.4, "zom_hud_icon_buildable_sloth_booze", ::onpickup_booze, ::ondrop_booze, undefined, undefined, 0, 1, 1 ); + cane = generate_zombie_buildable_piece( "candy", "p6_zm_bu_sloth_candy_bowl", 32, 64, 2.4, "zom_hud_icon_buildable_sloth_candy", ::onpickup_candy, ::ondrop_candy, undefined, undefined, 0, 2, 1 ); + pencil = generate_zombie_buildable_piece( "chalk", "p6_zm_bu_chalk", 32, 64, 2.4, "zom_hud_icon_buildable_weap_chalk", ::onpickup_common, ::ondrop_chalk, undefined, undefined, 0, 4, 1 ); + key_chain = generate_zombie_buildable_piece( "keys_zm", "p6_zm_bu_sloth_key", 32, 64, 9, "zom_hud_icon_buildable_sloth_key", ::onpickup_keys, ::ondrop_keys, undefined, undefined, 0, 3, 1 ); + + if ( isinarray( buildablesenabledlist, "turbine" ) ) + { + turbine = spawnstruct(); + turbine.name = "turbine"; + turbine add_buildable_piece( turbine_fan ); + turbine add_buildable_piece( turbine_panel ); + turbine add_buildable_piece( turbine_body ); + turbine.onuseplantobject = ::onuseplantobject_turbine; + turbine.triggerthink = ::turbinebuildable; + include_buildable( turbine ); + maps\mp\zombies\_zm_buildables::hide_buildable_table_model( "turbine_buildable_trigger" ); + } + + if ( isinarray( buildablesenabledlist, "springpad_zm" ) ) + { + springpad = spawnstruct(); + springpad.name = "springpad_zm"; + springpad add_buildable_piece( springpad_door ); + springpad add_buildable_piece( springpad_flag ); + springpad add_buildable_piece( springpad_motor ); + springpad add_buildable_piece( springpad_whistle ); + springpad.triggerthink = ::springpadbuildable; + // include_buildable( springpad ); + } + + if ( isinarray( buildablesenabledlist, "sq_common" ) ) + { + if ( is_sidequest_allowed( "zclassic" ) ) + { + sqcommon = spawnstruct(); + sqcommon.name = "sq_common"; + sqcommon add_buildable_piece( sq_common_electricbox ); + sqcommon add_buildable_piece( sq_common_meteor ); + sqcommon add_buildable_piece( sq_common_scaffolding ); + sqcommon add_buildable_piece( sq_common_transceiver ); + sqcommon.triggerthink = ::sqcommonbuildable; + include_buildable( sqcommon ); + maps\mp\zombies\_zm_buildables::hide_buildable_table_model( "sq_common_buildable_trigger" ); + } + } + + if ( isinarray( buildablesenabledlist, "buried_sq_oillamp" ) ) + { + if ( is_sidequest_allowed( "zclassic" ) ) + { + sq_oillamp = spawnstruct(); + sq_oillamp.name = "buried_sq_oillamp"; + sq_oillamp add_buildable_piece( sq_lamp_piece ); + sq_oillamp.triggerthink = ::sqoillampbuildable; + include_buildable( sq_oillamp ); + } + } + + if ( isinarray( buildablesenabledlist, "buried_sq_bt_m_tower" ) ) + { + if ( is_sidequest_allowed( "zclassic" ) ) + { + sq_m_tower = spawnstruct(); + sq_m_tower.name = "buried_sq_bt_m_tower"; + sq_m_tower add_buildable_piece( sq_m_tower_vacuum_tube ); + sq_m_tower add_buildable_piece( sq_m_tower_battery ); + sq_m_tower add_buildable_piece( sq_s_tower_antenna, undefined, 1 ); + sq_m_tower add_buildable_piece( sq_s_tower_wire, undefined, 1 ); + sq_m_tower.triggerthink = ::sqmtowerbuildable; + sq_m_tower.onuseplantobject = ::onuseplantobject_mtower; + include_buildable( sq_m_tower ); + } + else + remove_maxis_tower(); + } + + if ( isinarray( buildablesenabledlist, "buried_sq_bt_r_tower" ) ) + { + if ( is_sidequest_allowed( "zclassic" ) ) + { + sq_r_tower = spawnstruct(); + sq_r_tower.name = "buried_sq_bt_r_tower"; + sq_r_tower add_buildable_piece( sq_r_tower_crystal ); + sq_r_tower add_buildable_piece( sq_r_tower_satellite ); + sq_r_tower add_buildable_piece( sq_s_tower_antenna, undefined, 1 ); + sq_r_tower add_buildable_piece( sq_s_tower_wire, undefined, 1 ); + sq_r_tower.triggerthink = ::sqrtowerbuildable; + sq_r_tower.onuseplantobject = ::onuseplantobject_rtower; + include_buildable( sq_r_tower ); + } + else + remove_ricky_tower(); + } + + if ( isinarray( buildablesenabledlist, "subwoofer_zm" ) ) + { + subwoofer = spawnstruct(); + subwoofer.name = "subwoofer_zm"; + subwoofer add_buildable_piece( subwoofer_speaker ); + subwoofer add_buildable_piece( subwoofer_motor ); + subwoofer add_buildable_piece( subwoofer_table ); + subwoofer add_buildable_piece( subwoofer_mount ); + subwoofer.triggerthink = ::subwooferbuildable; + include_buildable( subwoofer ); + } + + if ( isinarray( buildablesenabledlist, "headchopper_zm" ) ) + { + ent = getent( "buildable_headchopper", "targetname" ); + ent setmodel( "t6_wpn_zmb_chopper" ); + headchopper = spawnstruct(); + headchopper.name = "headchopper_zm"; + headchopper add_buildable_piece( headchopper_blade ); + headchopper add_buildable_piece( headchopper_crank ); + headchopper add_buildable_piece( headchopper_hinge ); + headchopper add_buildable_piece( headchopper_mount ); + headchopper.triggerthink = ::headchopperbuildable; + include_buildable( headchopper ); + } + + if ( isinarray( buildablesenabledlist, "booze" ) ) + { + level.booze_model = "p6_zm_bu_sloth_booze_jug"; + precachemodel( level.booze_model ); + bottle.hint_grab = &"ZM_BURIED_BOOZE_G"; + bottle.hint_swap = &"ZM_BURIED_BOOZE_G"; + bottle manage_multiple_pieces( 2 ); + bottle.onspawn = ::piece_spawn_booze; + bottle.onunspawn = ::piece_unspawn_booze; + bottle.ondestroy = ::piece_destroy_booze; + level.booze_piece = bottle; + booze = spawnstruct(); + booze.name = "booze"; + booze.hint_more = &"ZM_BURIED_I_NEED_BOOZE"; + booze.hint_wrong = &"ZM_BURIED_I_SAID_BOOZE"; + booze add_buildable_piece( bottle ); + booze.triggerthink = ::boozebuildable; + booze.onuseplantobject = ::onuseplantobject_booze_and_candy; + include_buildable( booze ); + } + + if ( isinarray( buildablesenabledlist, "candy" ) ) + { + level.candy_model = "p6_zm_bu_sloth_candy_bowl"; + precachemodel( level.candy_model ); + cane.hint_grab = &"ZM_BURIED_CANDY_G"; + cane.hint_swap = &"ZM_BURIED_CANDY_G"; + cane manage_multiple_pieces( 1 ); + cane.onspawn = ::piece_spawn_candy; + cane.onunspawn = ::piece_unspawn_candy; + cane.ondestroy = ::piece_destroy_candy; + level.candy_piece = cane; + candy = spawnstruct(); + candy.name = "candy"; + candy.hint_more = &"ZM_BURIED_I_WANT_CANDY"; + candy.hint_wrong = &"ZM_BURIED_THATS_NOT_CANDY"; + candy add_buildable_piece( cane ); + candy.triggerthink = ::candybuildable; + candy.onuseplantobject = ::onuseplantobject_booze_and_candy; + include_buildable( candy ); + } + + if ( isinarray( buildablesenabledlist, "sloth" ) ) + { + sloth_buildable = spawnstruct(); + sloth_buildable.name = "sloth"; + sloth_buildable.hint_more = &"NULL_EMPTY"; + sloth_buildable.hint_wrong = &"NULL_EMPTY"; + sloth_buildable add_buildable_piece( bottle ); + sloth_buildable add_buildable_piece( cane ); + sloth_buildable.triggerthink = ::slothbuildable; + sloth_buildable.onuseplantobject = ::onuseplantobject_sloth; + sloth_buildable.snd_build_add_vo_override = ::empty; + include_buildable( sloth_buildable ); + } + + if ( isinarray( buildablesenabledlist, "chalk" ) ) + { + pencil.hint_grab = level.str_buildables_grab_part; + pencil.hint_swap = level.str_buildables_swap_part; + pencil.onspawn = ::piece_spawn_chalk; + pencil.ondestroy = ::piece_destroy_chalk; + pencil manage_multiple_pieces( 6, 6 ); + chalk = spawnstruct(); + chalk.name = "chalk"; + chalk.hint_more = &"NULL_EMPTY"; + chalk.hint_wrong = &"NULL_EMPTY"; + chalk add_buildable_piece( pencil ); + chalk.triggerthink = ::chalkbuildable; + chalk.onuseplantobject = ::onuseplantobject_chalk; + + if ( isdefined( level.buy_random_wallbuys ) && level.buy_random_wallbuys ) + chalk.oncantuse = ::oncantuse_chalk; + + chalk.onbeginuse = ::onbeginuse_chalk; + chalk.onenduse = ::onenduse_chalk; + include_buildable( chalk ); + } + + if ( isinarray( buildablesenabledlist, "keys_zm" ) ) + { + key_chain.onspawn = ::onspawn_keys; + key_chain manage_multiple_pieces( 2 ); + key_chain.hint_grab = &"ZM_BURIED_KEY_G"; + key_chain.hint_swap = &"ZM_BURIED_KEY_G"; + key = spawnstruct(); + key.name = "keys_zm"; + key add_buildable_piece( key_chain ); + key.triggerthink = ::keysbuildable; + key.onuseplantobject = ::onuseplantobject_key; + key.hint_wrong = &"NULL_EMPTY"; + include_buildable( key ); + } + + generate_piece_makers(); + level thread maps\mp\zombies\_zm_buildables_pooled::randomize_pooled_buildables( "buried" ); +} \ No newline at end of file diff --git a/t6/scripts/zm/zm_buried/buried_ee_fix.gsc b/t6/scripts/zm/zm_buried/buried_ee_fix.gsc new file mode 100644 index 0000000..642420c --- /dev/null +++ b/t6/scripts/zm/zm_buried/buried_ee_fix.gsc @@ -0,0 +1,46 @@ +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_sidequests; +#include maps\mp\_visionset_mgr; +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\zombies\_zm_buildables; +#include maps\mp\zombies\_zm; +#include maps\mp\zm_buried_sq; +#include maps\mp\zombies\_zm_weap_time_bomb; +#include maps\mp\zombies\_zm_unitrigger; +#include maps\mp\zm_buried_buildables; + + +main() +{ + replaceFunc(maps\mp\zombies\_zm_sidequests::is_sidequest_allowed, ::is_sidequest_allowed_custom); + replaceFunc(maps\mp\zm_buried_sq_tpo::_are_all_players_in_time_bomb_volume, ::_are_all_players_in_time_bomb_volume_custom); +} + +_are_all_players_in_time_bomb_volume_custom( e_volume ) +{ + return 4; +} + +is_sidequest_allowed_custom( a_gametypes ) +{ + + if ( isdefined( level.gamedifficulty ) && level.gamedifficulty == 0 ) + return 0; + + + return 1; + b_is_gametype_active = 0; + + if ( !isarray( a_gametypes ) ) + a_gametypes = array( a_gametypes ); + + for ( i = 0; i < a_gametypes.size; i++ ) + { + if ( getdvar( "g_gametype" ) == a_gametypes[i] ) + b_is_gametype_active = 1; + } + + return b_is_gametype_active; +} \ No newline at end of file diff --git a/t6/scripts/zm/zm_buried/buried_remove_spawn_slide.gsc b/t6/scripts/zm/zm_buried/buried_remove_spawn_slide.gsc new file mode 100644 index 0000000..34ec154 --- /dev/null +++ b/t6/scripts/zm/zm_buried/buried_remove_spawn_slide.gsc @@ -0,0 +1,26 @@ +#include common_scripts\utility; + +init() +{ + level thread check_first_room_height(); +} + +check_first_room_height() +{ + flag_wait("initial_blackscreen_passed"); + + for (;;) + { + foreach (player in level.players) + { + if (isdefined(level.is_first_room) && player.sessionstate != "spectator" && player.origin[2] < 1250) + { + setdvar( "player_lastStandBleedoutTime", "0" ); + player DoDamage(999, player.origin); + wait 0.1; + setdvar( "player_lastStandBleedoutTime", "45" ); + } + } + wait 0.1; + } +} \ No newline at end of file diff --git a/t6/scripts/zm/zm_buried/remove_limited_weapon_buried.gsc b/t6/scripts/zm/zm_buried/remove_limited_weapon_buried.gsc new file mode 100644 index 0000000..311d934 --- /dev/null +++ b/t6/scripts/zm/zm_buried/remove_limited_weapon_buried.gsc @@ -0,0 +1,147 @@ +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zm_buried_gamemodes; +#include maps\mp\zombies\_zm_banking; +#include maps\mp\zm_buried_sq; +#include maps\mp\zombies\_zm_weapon_locker; +#include maps\mp\zm_buried_distance_tracking; +#include maps\mp\zm_buried_fx; +#include maps\mp\zm_buried_ffotd; +#include maps\mp\zm_buried_buildables; +#include maps\mp\zombies\_zm; +#include maps\mp\animscripts\zm_death; +#include maps\mp\zm_buried_amb; +#include maps\mp\zombies\_zm_ai_ghost; +#include maps\mp\zombies\_zm_ai_sloth; +#include maps\mp\zombies\_load; +#include maps\mp\teams\_teamset_cdc; +#include maps\mp\gametypes_zm\_spawning; +#include maps\mp\zombies\_zm_perk_divetonuke; +#include maps\mp\zombies\_zm_perk_vulture; +#include maps\mp\zm_buried_jail; +#include maps\mp\zombies\_zm_weap_bowie; +#include maps\mp\zombies\_zm_weap_cymbal_monkey; +#include maps\mp\zombies\_zm_weap_claymore; +#include maps\mp\zombies\_zm_weap_ballistic_knife; +#include maps\mp\zombies\_zm_weap_slowgun; +#include maps\mp\zombies\_zm_weap_tazer_knuckles; +#include maps\mp\zombies\_zm_weap_time_bomb; +#include maps\mp\zm_buried_achievement; +#include maps\mp\zm_buried_maze; +#include maps\mp\zombies\_zm_zonemgr; +#include maps\mp\zm_buried_classic; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\zombies\_zm_devgui; +#include maps\mp\zombies\_zm_buildables; +#include character\c_transit_player_farmgirl; +#include character\c_transit_player_oldman; +#include character\c_transit_player_engineer; +#include character\c_buried_player_reporter_dam; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\zombies\_zm_ai_faller; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zombies\_zm_equip_headchopper; +#include maps\mp\zm_buried; + +main () +{ + replaceFunc(maps\mp\zm_buried::include_weapons, ::include_weapons_buried_custom); +} + +include_weapons_buried_custom() +{ + gametype = getdvar( "ui_gametype" ); + include_weapon( "knife_zm", 0 ); + include_weapon( "frag_grenade_zm", 0 ); + include_weapon( "claymore_zm", 0 ); + include_weapon( "m1911_zm", 0 ); + include_weapon( "m1911_upgraded_zm", 1 ); + include_weapon( "rnma_zm" ); + include_weapon( "rnma_upgraded_zm", 0 ); + include_weapon( "judge_zm" ); + include_weapon( "judge_upgraded_zm", 0 ); + include_weapon( "kard_zm" ); + include_weapon( "kard_upgraded_zm", 0 ); + include_weapon( "fiveseven_zm" ); + include_weapon( "fiveseven_upgraded_zm", 0 ); + include_weapon( "beretta93r_zm", 0 ); + include_weapon( "beretta93r_upgraded_zm", 0 ); + include_weapon( "fivesevendw_zm" ); + include_weapon( "fivesevendw_upgraded_zm", 0 ); + include_weapon( "ak74u_zm", 0 ); + include_weapon( "ak74u_upgraded_zm", 0 ); + include_weapon( "mp5k_zm", 0 ); + include_weapon( "mp5k_upgraded_zm", 0 ); + + if ( gametype == "zcleansed" ) + include_weapon( "qcw05_zm" ); + + include_weapon( "870mcs_zm", 0 ); + include_weapon( "870mcs_upgraded_zm", 0 ); + include_weapon( "rottweil72_zm", 0 ); + include_weapon( "rottweil72_upgraded_zm", 0 ); + include_weapon( "saiga12_zm" ); + include_weapon( "saiga12_upgraded_zm", 0 ); + include_weapon( "srm1216_zm" ); + include_weapon( "srm1216_upgraded_zm", 0 ); + include_weapon( "m14_zm", 0 ); + include_weapon( "m14_upgraded_zm", 0 ); + include_weapon( "saritch_zm" ); + include_weapon( "saritch_upgraded_zm", 0 ); + include_weapon( "m16_zm", 0 ); + include_weapon( "m16_gl_upgraded_zm", 0 ); + include_weapon( "tar21_zm" ); + include_weapon( "tar21_upgraded_zm", 0 ); + include_weapon( "galil_zm" ); + include_weapon( "galil_upgraded_zm", 0 ); + include_weapon( "fnfal_zm" ); + include_weapon( "fnfal_upgraded_zm", 0 ); + include_weapon( "dsr50_zm" ); + include_weapon( "dsr50_upgraded_zm", 0 ); + include_weapon( "barretm82_zm" ); + include_weapon( "barretm82_upgraded_zm", 0 ); + include_weapon( "svu_zm", 0 ); + include_weapon( "svu_upgraded_zm", 0 ); + include_weapon( "lsat_zm", 1 ); + include_weapon( "lsat_upgraded_zm", 0 ); + include_weapon( "hamr_zm" ); + include_weapon( "hamr_upgraded_zm", 0 ); + include_weapon( "pdw57_zm", 0 ); + include_weapon( "pdw57_upgraded_zm", 0 ); + include_weapon( "usrpg_zm" ); + include_weapon( "usrpg_upgraded_zm", 0 ); + include_weapon( "m32_zm" ); + include_weapon( "m32_upgraded_zm", 0 ); + include_weapon( "an94_zm", 0 ); + include_weapon( "an94_upgraded_zm", 0 ); + include_weapon( "cymbal_monkey_zm" ); + include_weapon( "ray_gun_zm" ); + include_weapon( "ray_gun_upgraded_zm", 0 ); + include_weapon( "raygun_mark2_zm", 1 ); + include_weapon( "raygun_mark2_upgraded_zm", 0 ); + include_weapon( "slowgun_zm", 1 ); + include_weapon( "slowgun_upgraded_zm", 0 ); + include_weapon( "tazer_knuckles_zm", 0 ); + include_weapon( "knife_ballistic_no_melee_zm", 0 ); + include_weapon( "knife_ballistic_no_melee_upgraded_zm", 0 ); + include_weapon( "knife_ballistic_zm" ); + include_weapon( "knife_ballistic_upgraded_zm", 0 ); + include_weapon( "knife_ballistic_bowie_zm", 0 ); + include_weapon( "knife_ballistic_bowie_upgraded_zm", 0 ); + level._uses_retrievable_ballisitic_knives = 1; + add_weapon_to_content( "raygun_mark2_zm", "dlc3" ); + add_weapon_locker_mapping( "python_zm", "rnma_zm" ); + add_weapon_locker_mapping( "qcw05_zm", "pdw57_zm" ); + add_weapon_locker_mapping( "xm8_zm", "tar21_zm" ); + add_weapon_locker_mapping( "type95_zm", "tar21_zm" ); + add_weapon_locker_mapping( "rpd_zm", "galil_zm" ); + add_weapon_locker_mapping( "python_upgraded_zm", "rnma_upgraded_zm" ); + add_weapon_locker_mapping( "qcw05_upgraded_zm", "pdw57_upgraded_zm" ); + add_weapon_locker_mapping( "xm8_upgraded_zm", "tar21_upgraded_zm" ); + add_weapon_locker_mapping( "type95_upgraded_zm", "tar21_upgraded_zm" ); + add_weapon_locker_mapping( "rpd_upgraded_zm", "galil_upgraded_zm" ); +} \ No newline at end of file diff --git a/t6/scripts/zm/zm_buried/witchspeed.gsc b/t6/scripts/zm/zm_buried/witchspeed.gsc new file mode 100644 index 0000000..f903ac3 --- /dev/null +++ b/t6/scripts/zm/zm_buried/witchspeed.gsc @@ -0,0 +1,8 @@ +main() +{ + replaceFunc(maps\mp\zombies\_zm_ai_ghost::set_player_moving_speed_scale, ::customWitchSpeedScale); +} + +customWitchSpeedScale( player, move_speed_scale ) +{ +} \ No newline at end of file diff --git a/t6/scripts/zm/zm_highrise/no_spawn_elevator.gsc b/t6/scripts/zm/zm_highrise/no_spawn_elevator.gsc new file mode 100644 index 0000000..9cd8ac9 --- /dev/null +++ b/t6/scripts/zm/zm_highrise/no_spawn_elevator.gsc @@ -0,0 +1,46 @@ +main() +{ + replacefunc(maps\mp\zm_highrise_classic::escape_pod_are_all_alive_players_ready, ::escape_pod_are_all_alive_players_ready_custom); +} + +init() +{ + level thread disable_spawn_elevator(); +} + +escape_pod_are_all_alive_players_ready_custom() +{ + players = level.players; + players_in_escape_pod = 0; + players_alive = 0; + + foreach ( player in players ) + { + if ( player.sessionstate != "spectator" ) + { + players_alive++; + + if ( player istouching( self ) && !(isdefined(level.is_first_room))) + players_in_escape_pod++; + } + } + if (players_alive == players_in_escape_pod) + { + level.is_spawn_elevator_used = 1; + } + return players_alive == players_in_escape_pod; +} + +disable_spawn_elevator() +{ + for (;;) + { + escape_pod = getent( "elevator_bldg1a_body", "targetname" ); +/* escape_pod setmovingplatformenabled( 1 ); + escape_pod escapeelevatoruseanimtree(); + escape_pod_trigger = getent( "escape_pod_trigger", "targetname" );*/ + escape_pod.is_elevator = 0; + wait 0.1; + } + +} \ No newline at end of file diff --git a/t6/scripts/zm/zm_highrise/remove_limited_weapon_highrise.gsc b/t6/scripts/zm/zm_highrise/remove_limited_weapon_highrise.gsc new file mode 100644 index 0000000..752371c --- /dev/null +++ b/t6/scripts/zm/zm_highrise/remove_limited_weapon_highrise.gsc @@ -0,0 +1,143 @@ +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_weapon_locker; +#include maps\mp\zm_highrise_gamemodes; +#include maps\mp\zm_highrise_sq; +#include maps\mp\zombies\_zm_banking; +#include maps\mp\zm_highrise_fx; +#include maps\mp\zm_highrise_ffotd; +#include maps\mp\zm_highrise_utility; +#include maps\mp\zombies\_zm; +#include maps\mp\animscripts\zm_death; +#include maps\mp\zm_highrise_amb; +#include maps\mp\zm_highrise_elevators; +#include maps\mp\zombies\_load; +#include maps\mp\gametypes_zm\_spawning; +#include maps\mp\zm_highrise_classic; +#include maps\mp\zombies\_zm_ai_leaper; +#include maps\mp\zm_highrise; +#include maps\mp\_sticky_grenade; +#include maps\mp\zombies\_zm_weap_bowie; +#include maps\mp\zombies\_zm_weap_cymbal_monkey; +#include maps\mp\zombies\_zm_weap_claymore; +#include maps\mp\zombies\_zm_weap_ballistic_knife; +#include maps\mp\zombies\_zm_weap_slipgun; +#include maps\mp\zombies\_zm_weap_tazer_knuckles; +#include maps\mp\zm_highrise_achievement; +#include maps\mp\zombies\_zm_zonemgr; +#include maps\mp\zm_highrise_distance_tracking; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\gametypes_zm\_zm_gametype; +#include maps\mp\zombies\_zm_devgui; +#include maps\mp\zombies\_zm_buildables; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_perks; +#include character\c_highrise_player_farmgirl; +#include character\c_highrise_player_oldman; +#include character\c_highrise_player_engineer; +#include character\c_highrise_player_reporter; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm_unitrigger; +#include maps\mp\zombies\_zm_chugabud; + +main () +{ + replaceFunc(maps\mp\zm_highrise::include_weapons, ::include_weapons_highrise_custom); +} + +include_weapons_highrise_custom() +{ + include_weapon( "knife_zm", 0 ); + include_weapon( "frag_grenade_zm", 0 ); + include_weapon( "claymore_zm", 0 ); + include_weapon( "sticky_grenade_zm", 0 ); + include_weapon( "m1911_zm", 0 ); + include_weapon( "m1911_upgraded_zm", 1 ); + include_weapon( "python_zm" ); + include_weapon( "python_upgraded_zm", 0 ); + include_weapon( "judge_zm" ); + include_weapon( "judge_upgraded_zm", 0 ); + include_weapon( "kard_zm" ); + include_weapon( "kard_upgraded_zm", 0 ); + include_weapon( "fiveseven_zm" ); + include_weapon( "fiveseven_upgraded_zm", 0 ); + include_weapon( "beretta93r_zm", 0 ); + include_weapon( "beretta93r_upgraded_zm", 0 ); + include_weapon( "fivesevendw_zm" ); + include_weapon( "fivesevendw_upgraded_zm", 0 ); + include_weapon( "ak74u_zm", 0 ); + include_weapon( "ak74u_upgraded_zm", 0 ); + include_weapon( "mp5k_zm", 0 ); + include_weapon( "mp5k_upgraded_zm", 0 ); + include_weapon( "qcw05_zm" ); + include_weapon( "qcw05_upgraded_zm", 0 ); + include_weapon( "870mcs_zm", 0 ); + include_weapon( "870mcs_upgraded_zm", 0 ); + include_weapon( "rottweil72_zm", 0 ); + include_weapon( "rottweil72_upgraded_zm", 0 ); + include_weapon( "saiga12_zm" ); + include_weapon( "saiga12_upgraded_zm", 0 ); + include_weapon( "srm1216_zm" ); + include_weapon( "srm1216_upgraded_zm", 0 ); + include_weapon( "m14_zm", 0 ); + include_weapon( "m14_upgraded_zm", 0 ); + include_weapon( "saritch_zm" ); + include_weapon( "saritch_upgraded_zm", 0 ); + include_weapon( "m16_zm", 0 ); + include_weapon( "m16_gl_upgraded_zm", 0 ); + include_weapon( "xm8_zm" ); + include_weapon( "xm8_upgraded_zm", 0 ); + include_weapon( "type95_zm" ); + include_weapon( "type95_upgraded_zm", 0 ); + include_weapon( "tar21_zm" ); + include_weapon( "tar21_upgraded_zm", 0 ); + include_weapon( "galil_zm" ); + include_weapon( "galil_upgraded_zm", 0 ); + include_weapon( "fnfal_zm" ); + include_weapon( "fnfal_upgraded_zm", 0 ); + include_weapon( "dsr50_zm" ); + include_weapon( "dsr50_upgraded_zm", 0 ); + include_weapon( "barretm82_zm" ); + include_weapon( "barretm82_upgraded_zm", 0 ); + include_weapon( "svu_zm", 0 ); + include_weapon( "svu_upgraded_zm", 0 ); + include_weapon( "rpd_zm" ); + include_weapon( "rpd_upgraded_zm", 0 ); + include_weapon( "hamr_zm" ); + include_weapon( "hamr_upgraded_zm", 0 ); + include_weapon( "pdw57_zm", 0 ); + include_weapon( "pdw57_upgraded_zm", 0 ); + include_weapon( "usrpg_zm" ); + include_weapon( "usrpg_upgraded_zm", 0 ); + include_weapon( "m32_zm" ); + include_weapon( "m32_upgraded_zm", 0 ); + include_weapon( "an94_zm", 1 ); + include_weapon( "cymbal_monkey_zm" ); + include_weapon( "ray_gun_zm" ); + include_weapon( "ray_gun_upgraded_zm", 0 ); + include_weapon( "slipgun_zm", 1 ); + include_weapon( "slipgun_upgraded_zm", 0 ); + include_weapon( "tazer_knuckles_zm", 0 ); + include_weapon( "knife_ballistic_no_melee_zm", 0 ); + include_weapon( "knife_ballistic_no_melee_upgraded_zm", 0 ); + include_weapon( "knife_ballistic_zm" ); + include_weapon( "knife_ballistic_upgraded_zm", 0 ); + include_weapon( "knife_ballistic_bowie_zm", 0 ); + include_weapon( "knife_ballistic_bowie_upgraded_zm", 0 ); + level._uses_retrievable_ballisitic_knives = 1; + add_weapon_locker_mapping( "lsat_zm", "hamr_zm" ); + add_weapon_locker_mapping( "lsat_upgraded_zm", "hamr_upgraded_zm" ); + add_weapon_locker_mapping( "rnma_zm", "python_zm" ); + add_weapon_locker_mapping( "rnma_upgraded_zm", "python_upgraded_zm" ); + + if ( isdefined( level.raygun2_included ) && level.raygun2_included ) + { + include_weapon( "raygun_mark2_zm" ); + include_weapon( "raygun_mark2_upgraded_zm", 0 ); + add_weapon_to_content( "raygun_mark2_zm", "dlc3" ); + add_limited_weapon( "raygun_mark2_zm", 1 ); + add_limited_weapon( "raygun_mark2_upgraded_zm", 1 ); + } +} \ No newline at end of file diff --git a/t6/scripts/zm/zm_highrise/sliquifier.gsc b/t6/scripts/zm/zm_highrise/sliquifier.gsc new file mode 100644 index 0000000..311cc85 --- /dev/null +++ b/t6/scripts/zm/zm_highrise/sliquifier.gsc @@ -0,0 +1,99 @@ +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\gametypes_zm\_weaponobjects; +#include maps\mp\zombies\_zm_spawner; +#include maps\mp\zombies\_zm; +#include maps\mp\animscripts\zm_utility; +#include maps\mp\animscripts\zm_shared; +#include maps\mp\zombies\_zm_ai_basic; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\zombies\_zm_audio; + +main() +{ + replacefunc(maps\mp\zombies\_zm_weap_slipgun::explode_to_near_zombies, ::customSliquifier); + // replacefunc(maps\mp\zombies\_zm_weap_slipgun::add_slippery_spot, ::no_slippery_spot); +} + +customSliquifier( 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 = []; + + if ( isdefined( enemies ) && enemies.size ) + { + index = 0; + for ( enemy = enemies[index]; distancesquared( enemy.origin, origin ) < rsquared; enemy = enemies[index] ) + { + if ( isalive( enemy ) && !is_true( enemy.guts_explosion ) && !is_true( enemy.nuked ) && !isdefined( enemy.slipgun_sizzle ) ) + { + trace = bullettrace( origin + vectorscale( ( 0, 0, 1 ), 50.0 ), enemy.origin + vectorscale( ( 0, 0, 1 ), 50.0 ), 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; + } + } + + if ( isdefined( marked_zombies ) && marked_zombies.size ) + { + foreach ( enemy in marked_zombies ) + { + 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 maps\mp\zombies\_zm_weap_slipgun::add_slippery_spot( enemy.origin, duration, startpos ); + } + } + } + } + } + } + } +} + +no_slippery_spot( origin, duration, startpos ) +{ + return; +} \ No newline at end of file diff --git a/t6/scripts/zm/zm_nuked/remove_limited_weapon_nuked.gsc b/t6/scripts/zm/zm_nuked/remove_limited_weapon_nuked.gsc new file mode 100644 index 0000000..1d6999a --- /dev/null +++ b/t6/scripts/zm/zm_nuked/remove_limited_weapon_nuked.gsc @@ -0,0 +1,120 @@ +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zm_nuked_gamemodes; +#include maps\mp\zm_nuked_ffotd; +#include maps\mp\zm_nuked_fx; +#include maps\mp\zombies\_zm; +#include maps\mp\animscripts\zm_death; +#include maps\mp\zombies\_load; +#include maps\mp\teams\_teamset_cdc; +#include maps\mp\gametypes_zm\_spawning; +#include maps\mp\zm_nuked_perks; +#include maps\mp\_sticky_grenade; +#include maps\mp\zombies\_zm_weap_tazer_knuckles; +#include maps\mp\zombies\_zm_weap_bowie; +#include maps\mp\zombies\_zm_weap_cymbal_monkey; +#include maps\mp\zombies\_zm_weap_claymore; +#include maps\mp\zombies\_zm_weap_ballistic_knife; +#include maps\mp\zombies\_zm_zonemgr; +#include maps\mp\zombies\_zm_net; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\animscripts\zm_run; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_blockers; +#include maps\mp\zombies\_zm_sidequests; +#include maps\mp\_compass; + +main () +{ + replaceFunc(maps\mp\zm_nuked::include_weapons, ::include_weapons_nuked_custom); +} + +include_weapons_nuked_custom() +{ + include_weapon( "knife_zm", 0 ); + include_weapon( "frag_grenade_zm", 0 ); + include_weapon( "claymore_zm", 0 ); + include_weapon( "sticky_grenade_zm", 0 ); + include_weapon( "m1911_zm", 0 ); + include_weapon( "m1911_upgraded_zm", 1 ); + include_weapon( "python_zm" ); + include_weapon( "python_upgraded_zm", 0 ); + include_weapon( "judge_zm" ); + include_weapon( "judge_upgraded_zm", 0 ); + include_weapon( "kard_zm" ); + include_weapon( "kard_upgraded_zm", 0 ); + include_weapon( "fiveseven_zm" ); + include_weapon( "fiveseven_upgraded_zm", 0 ); + include_weapon( "beretta93r_zm", 0 ); + include_weapon( "beretta93r_upgraded_zm", 0 ); + include_weapon( "fivesevendw_zm" ); + include_weapon( "fivesevendw_upgraded_zm", 0 ); + include_weapon( "ak74u_zm", 1 ); + include_weapon( "ak74u_upgraded_zm", 0 ); + include_weapon( "mp5k_zm", 0 ); + include_weapon( "mp5k_upgraded_zm", 0 ); + include_weapon( "qcw05_zm" ); + include_weapon( "qcw05_upgraded_zm", 0 ); + include_weapon( "870mcs_zm", 0 ); + include_weapon( "870mcs_upgraded_zm", 0 ); + include_weapon( "rottweil72_zm", 0 ); + include_weapon( "rottweil72_upgraded_zm", 0 ); + include_weapon( "saiga12_zm" ); + include_weapon( "saiga12_upgraded_zm", 0 ); + include_weapon( "srm1216_zm" ); + include_weapon( "srm1216_upgraded_zm", 0 ); + include_weapon( "m14_zm", 0 ); + include_weapon( "m14_upgraded_zm", 0 ); + include_weapon( "saritch_zm" ); + include_weapon( "saritch_upgraded_zm", 0 ); + include_weapon( "m16_zm", 1 ); + include_weapon( "m16_gl_upgraded_zm", 0 ); + include_weapon( "xm8_zm" ); + include_weapon( "xm8_upgraded_zm", 0 ); + include_weapon( "type95_zm" ); + include_weapon( "type95_upgraded_zm", 0 ); + include_weapon( "tar21_zm" ); + include_weapon( "tar21_upgraded_zm", 0 ); + include_weapon( "galil_zm" ); + include_weapon( "galil_upgraded_zm", 0 ); + include_weapon( "fnfal_zm" ); + include_weapon( "fnfal_upgraded_zm", 0 ); + include_weapon( "dsr50_zm" ); + include_weapon( "dsr50_upgraded_zm", 0 ); + include_weapon( "barretm82_zm" ); + include_weapon( "barretm82_upgraded_zm", 0 ); + include_weapon( "rpd_zm" ); + include_weapon( "rpd_upgraded_zm", 0 ); + include_weapon( "hamr_zm" ); + include_weapon( "hamr_upgraded_zm", 0 ); + include_weapon( "usrpg_zm" ); + include_weapon( "usrpg_upgraded_zm", 0 ); + include_weapon( "m32_zm" ); + include_weapon( "m32_upgraded_zm", 0 ); + include_weapon( "hk416_zm" ); + include_weapon( "hk416_upgraded_zm", 0 ); + include_weapon( "lsat_zm" ); + include_weapon( "lsat_upgraded_zm", 0 ); + include_weapon( "cymbal_monkey_zm" ); + include_weapon( "ray_gun_zm" ); + include_weapon( "ray_gun_upgraded_zm", 0 ); + include_weapon( "tazer_knuckles_zm", 0 ); + include_weapon( "knife_ballistic_no_melee_zm", 0 ); + include_weapon( "knife_ballistic_no_melee_upgraded_zm", 0 ); + include_weapon( "knife_ballistic_zm" ); + include_weapon( "knife_ballistic_upgraded_zm", 0 ); + include_weapon( "knife_ballistic_bowie_zm", 0 ); + include_weapon( "knife_ballistic_bowie_upgraded_zm", 0 ); + level._uses_retrievable_ballisitic_knives = 1; + + if ( isdefined( level.raygun2_included ) && level.raygun2_included ) + { + include_weapon( "raygun_mark2_zm" ); + include_weapon( "raygun_mark2_upgraded_zm", 0 ); + add_weapon_to_content( "raygun_mark2_zm", "dlc3" ); + } +} \ No newline at end of file diff --git a/t6/scripts/zm/zm_prison/afterlife_fix.gsc b/t6/scripts/zm/zm_prison/afterlife_fix.gsc new file mode 100644 index 0000000..70486ba --- /dev/null +++ b/t6/scripts/zm/zm_prison/afterlife_fix.gsc @@ -0,0 +1,29 @@ +#include common_scripts\utility; + +init() +{ + level thread on_player_connect(); +} + +on_player_connect() +{ + for(;;) + { + level waittill("connected", player); + player thread afterlife_ignoreme(); + } +} + +afterlife_ignoreme() +{ + flag_wait("initial_blackscreen_passed"); + + for (;;) + { + if (self.afterlife) + self.ignoreme = 1; + else + self.ignoreme = 0; + wait 0.1; + } +} \ No newline at end of file diff --git a/t6/scripts/zm/zm_prison/brutuswave.gsc b/t6/scripts/zm/zm_prison/brutuswave.gsc new file mode 100644 index 0000000..72006ad --- /dev/null +++ b/t6/scripts/zm/zm_prison/brutuswave.gsc @@ -0,0 +1,3888 @@ +#include maps\mp\zombies\_zm_magicbox; +#include maps\mp\zombies\_zm_zonemgr; +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\animscripts\zm_utility; +#include maps\mp\zombies\_zm_ai_brutus; +#include maps\mp\zombies\_zm_spawner; +#include maps\mp\animscripts\zm_shared; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zm_alcatraz_utility; +#include maps\mp\zombies\_zm_ai_basic; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\animscripts\shared; +#include maps\mp\zombies\_zm_unitrigger; +#include maps\mp\zombies\_zm_weap_riostshield_prison; +#include maps\mp\animscripts\zm_death; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm_craftables; +#include maps\mp\zm_alcatraz_sq; +#include maps\mp\gametypes_zm\_zm_gametype; + +#include maps\mp\_ambientpackage; +#include maps\mp\zombies\_zm_sidequests; + +#include maps\_utility; +#include maps\_vehicle; +#include maps\mp\zombies\_zm_afterlife; +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\gametypes_zm\_hud; + +#include maps\mp\zombies\_zm_pers_upgrades_system; +#include maps\mp\zombies\_zm_pers_upgrades; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include scripts\AATs_Perks; +#include maps\mp\_visionset_mgr; +#include character\c_zom_cellbreaker; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_melee_weapon; +#include maps\mp\zombies\_zm_weap_tomahawk; + + +main() +{ + replaceFunc(maps\mp\zombies\_zm_ai_brutus::brutus_spawn, ::brutus_spawn_custom); + replaceFunc(maps\mp\zombies\_zm_ai_brutus::brutus_stuck_teleport, ::brutus_stuck_teleport_custom); + + replaceFunc(maps\mp\zombies\_zm_ffotd::main_start, ::modified_main_start); + replaceFunc(maps\mp\zombies\_zm_pers_upgrades::is_pers_system_active, ::always_pers_system_active); + replaceFunc(maps\mp\zombies\_zm_pers_upgrades::is_pers_system_disabled, ::never_pers_system_disabled); + replaceFunc(maps\mp\zombies\_zm_ai_brutus::brutus_fire_teargas_when_possible, ::brutus_fire_teargas_when_possible_custom); + replaceFunc(maps\mp\zombies\_zm_spawner::zombie_damage, ::zombie_damage_custom); + replaceFunc(maps\mp\zombies\_zm_ai_brutus::brutus_damage_override, ::brutus_damage_override_custom); + replaceFunc(maps\mp\zombies\_zm_weap_tomahawk::tomahawk_return_player, ::tomahawk_return_player_custom); + replaceFunc(maps\mp\zombies\_zm_weap_tomahawk::tomahawk_thrown, ::tomahawk_thrown_custom); + replaceFunc(maps\mp\zombies\_zm_weap_tomahawk::watch_for_tomahawk_throw, ::watch_for_tomahawk_throw_custom); + replaceFunc(maps\mp\zombies\_zm_weap_tomahawk::tomahawk_attack_zombies, ::tomahawk_attack_zombies_custom); + replaceFunc(maps\mp\zombies\_zm_weap_tomahawk::tomahawk_hit_zombie, ::tomahawk_hit_zombie_custom); + replaceFunc(maps\mp\zombies\_zm_weap_tomahawk::play_charge_fx, ::play_charge_fx_custom); + replaceFunc(maps\mp\zombies\_zm_weap_tomahawk::calculate_tomahawk_damage, ::calculate_tomahawk_damage_custom); +} + +calculate_tomahawk_damage_custom( n_target_zombie, n_tomahawk_power, tomahawk ) +{ + if(isdefined(n_target_zombie.is_boss)) + return 20000; + + if ( n_tomahawk_power > 2 ) + { + if (n_target_zombie.fakeHat) + n_target_zombie.fakeHat delete(); + if (n_target_zombie.fakeBrutus) + n_target_zombie.fakeBrutus delete(); + n_target_zombie dodamage(n_target_zombie.health + 666, n_target_zombie.origin); + return n_target_zombie.health + 1; + } + + else if ( level.round_number >= 10 && level.round_number < 13 && tomahawk.low_level_instant_kill_charge <= 3 ) + { + tomahawk.low_level_instant_kill_charge += 1; + return n_target_zombie.health + 1; + } + else if ( level.round_number >= 13 && level.round_number < 15 && tomahawk.low_level_instant_kill_charge <= 2 ) + { + tomahawk.low_level_instant_kill_charge += 1; + return n_target_zombie.health + 1; + } + else + return 1000 * n_tomahawk_power; +} + +play_charge_fx_custom() +{ + self endon( "death" ); + self endon( "disconnect" ); + self endon( "grenade_fire" ); + waittillframeend; + time_to_pulse = 1000; + + if (check_for_botb_port() == true) + self.n_tomahawk_cooking_time -= 900; + while ( true ) + { + time = gettime() - self.n_tomahawk_cooking_time; + self.current_tactical_grenade = self get_player_tactical_grenade(); + + if ( time >= time_to_pulse ) + { + if ( self.current_tactical_grenade == "upgraded_tomahawk_zm" ) + playfxontag( level._effect["tomahawk_charge_up_ug"], self, "tag_origin" ); + else + playfxontag( level._effect["tomahawk_charge_up"], self, "tag_origin" ); + + time_to_pulse += 1000; + self playrumbleonentity( "reload_small" ); + self.n_tomahawk_cooking_time -= 900; + } + + if ( time_to_pulse > 2400 && self.current_tactical_grenade != "upgraded_tomahawk_zm" ) + break; + + if ( time_to_pulse >= 3400 ) + break; + + wait 0.05; + } +} + + +tomahawk_hit_zombie_custom( ai_zombie, grenade ) +{ + self endon( "disconnect" ); + + if ( isdefined( ai_zombie ) && isalive( ai_zombie ) ) + { + tag = "J_Head"; + + if ( ai_zombie.isdog ) + tag = "J_Spine1"; + + v_target = ai_zombie gettagorigin( tag ); + if (check_for_botb_port() == true) + grenade moveto( v_target, 0.3 * self.hawk_cd ); + else + grenade moveto( v_target, 0.3 ); + + grenade waittill( "movedone" ); + + if ( isdefined( ai_zombie ) && isalive( ai_zombie ) ) + { + if ( self.current_tactical_grenade == "upgraded_tomahawk_zm" ) + playfxontag( level._effect["tomahawk_impact_ug"], ai_zombie, tag ); + else + playfxontag( level._effect["tomahawk_impact"], ai_zombie, tag ); + + ai_zombie setclientfield( "play_tomahawk_hit_sound", 1 ); + n_tomahawk_damage = calculate_tomahawk_damage( ai_zombie, grenade.n_grenade_charge_power, grenade ); + if (n_tomahawk_damage > ai_zombie.health) + { + self add_to_player_score( 50 ); + self.kills++; + self.pers["kills"] = self.kills; + } + ai_zombie dodamage( n_tomahawk_damage, grenade.origin, self, grenade, "none", "MOD_GRENADE", 0, "bouncing_tomahawk_zm" ); + ai_zombie.hit_by_tomahawk = 1; + self maps\mp\zombies\_zm_score::add_to_player_score( 10 ); + } + } +} + +tomahawk_attack_zombies_custom( m_tomahawk, a_zombies ) +{ + self endon( "disconnect" ); + + if ( !isdefined( a_zombies ) ) + { + self thread tomahawk_return_player( m_tomahawk, 0 ); + return; + } + + if ( a_zombies.size <= 4 ) + n_attack_limit = a_zombies.size; + else + n_attack_limit = 4; + + for ( i = 0; i < n_attack_limit; i++ ) + { + if ( isdefined( a_zombies[i] ) && isalive( a_zombies[i] ) ) + { + tag = "J_Head"; + + if ( a_zombies[i].isdog ) + tag = "J_Spine1"; + + if ( isdefined( a_zombies[i].hit_by_tomahawk ) && !a_zombies[i].hit_by_tomahawk ) + { + v_target = a_zombies[i] gettagorigin( tag ); + if (check_for_botb_port() == true) + m_tomahawk moveto( v_target, 0.3 * self.hawk_cd); + else + m_tomahawk moveto( v_target, 0.3 ); + + m_tomahawk waittill( "movedone" ); + + if ( isdefined( a_zombies[i] ) && isalive( a_zombies[i] ) ) + { + if ( self.current_tactical_grenade == "upgraded_tomahawk_zm" ) + playfxontag( level._effect["tomahawk_impact_ug"], a_zombies[i], tag ); + else + playfxontag( level._effect["tomahawk_impact"], a_zombies[i], tag ); + + playfxontag( level._effect["tomahawk_fire_dot"], a_zombies[i], "j_spineupper" ); + a_zombies[i] setclientfield( "play_tomahawk_hit_sound", 1 ); + n_tomahawk_damage = calculate_tomahawk_damage( a_zombies[i], m_tomahawk.n_grenade_charge_power, m_tomahawk ); + if (n_tomahawk_damage > a_zombies[i].health) + { + self add_to_player_score( 50 ); + self.kills++; + self.pers["kills"] = self.kills; + } + a_zombies[i] dodamage( n_tomahawk_damage, m_tomahawk.origin, self, m_tomahawk, "none", "MOD_GRENADE", 0, "bouncing_tomahawk_zm" ); + a_zombies[i].hit_by_tomahawk = 1; + self maps\mp\zombies\_zm_score::add_to_player_score( 10 ); + } + } + } + + wait 0.2; + } + + self thread tomahawk_return_player( m_tomahawk, n_attack_limit ); +} + +watch_for_tomahawk_throw_custom() +{ + self endon( "disconnect" ); + + while ( true ) + { + self waittill( "grenade_fire", grenade, weapname ); + + if ( !issubstr( weapname, "tomahawk_zm" ) ) + continue; + + grenade.use_grenade_special_bookmark = 1; + grenade.grenade_multiattack_bookmark_count = 1; + grenade.low_level_instant_kill_charge = 1; + grenade.owner = self; + self notify( "throwing_tomahawk" ); + + if ( isdefined( self.n_tomahawk_cooking_time ) ) + grenade.n_cookedtime = grenade.birthtime - self.n_tomahawk_cooking_time; + else + grenade.n_cookedtime = 0; + + self thread check_for_time_out( grenade ); + self thread tomahawk_thrown( grenade ); + } +} + +tomahawk_thrown_custom( grenade ) +{ + self endon( "disconnect" ); + grenade endon( "in_hellhole" ); + grenade_owner = undefined; + + if ( isdefined( grenade.owner ) ) + grenade_owner = grenade.owner; + + playfxontag( level._effect["tomahawk_charged_trail"], grenade, "tag_origin" ); + self setclientfieldtoplayer( "tomahawk_in_use", 2 ); + grenade waittill_either( "death", "time_out" ); + grenade_origin = grenade.origin; + a_zombies = getaispeciesarray( "axis", "all" ); + n_grenade_charge_power = grenade get_grenade_charge_power( self ); + a_zombies = get_array_of_closest( grenade_origin, a_zombies, undefined, undefined, 200 ); + a_powerups = get_array_of_closest( grenade_origin, level.active_powerups, undefined, undefined, 200 ); + + if ( isdefined( level.a_tomahawk_pickup_funcs ) ) + { + foreach ( tomahawk_func in level.a_tomahawk_pickup_funcs ) + { + if ( [[ tomahawk_func ]]( grenade, n_grenade_charge_power ) ) + return; + } + } + + if ( isdefined( a_powerups ) && a_powerups.size > 0 ) + { + m_tomahawk = tomahawk_spawn( grenade_origin, n_grenade_charge_power ); + m_tomahawk.n_grenade_charge_power = n_grenade_charge_power; + + foreach ( powerup in a_powerups ) + { + powerup.origin = grenade_origin; + powerup linkto( m_tomahawk ); + m_tomahawk.a_has_powerup = a_powerups; + } + + self thread tomahawk_return_player( m_tomahawk, 0 ); + return; + } + + if ( !isdefined( a_zombies ) ) + { + m_tomahawk = tomahawk_spawn( grenade_origin, n_grenade_charge_power ); + m_tomahawk.n_grenade_charge_power = n_grenade_charge_power; + self thread tomahawk_return_player( m_tomahawk, 0 ); + return; + } + else + { + foreach ( ai_zombie in a_zombies ) + ai_zombie.hit_by_tomahawk = 0; + } + + if ( isdefined( a_zombies[0] ) && isalive( a_zombies[0] ) ) + { + v_zombiepos = a_zombies[0].origin; + + if ( distancesquared( grenade_origin, v_zombiepos ) <= 4900 ) + { + a_zombies[0] setclientfield( "play_tomahawk_hit_sound", 1 ); + n_tomahawk_damage = calculate_tomahawk_damage( a_zombies[0], n_grenade_charge_power, grenade ); + a_zombies[0] dodamage( n_tomahawk_damage, grenade_origin, self, grenade, "none", "MOD_GRENADE", 0, "bouncing_tomahawk_zm" ); + a_zombies[0].hit_by_tomahawk = 1; + self maps\mp\zombies\_zm_score::add_to_player_score( 10 ); + self thread tomahawk_ricochet_attack( grenade_origin, n_grenade_charge_power ); + } + else + { + m_tomahawk = tomahawk_spawn( grenade_origin, n_grenade_charge_power ); + m_tomahawk.n_grenade_charge_power = n_grenade_charge_power; + self thread tomahawk_return_player( m_tomahawk, 0 ); + } + } + else + { + m_tomahawk = tomahawk_spawn( grenade_origin, n_grenade_charge_power ); + m_tomahawk.n_grenade_charge_power = n_grenade_charge_power; + + if ( isdefined( grenade ) ) + grenade delete(); + + self thread tomahawk_return_player( m_tomahawk, 0 ); + } +} + + +tomahawk_return_player_custom( m_tomahawk, num_zombie_hit ) +{ + self endon( "disconnect" ); + n_dist = distance2dsquared( m_tomahawk.origin, self.origin ); + + if ( !isdefined( num_zombie_hit ) ) + num_zombie_hit = 5; + + while ( n_dist > 4096 ) + { + if (check_for_botb_port() == true) + m_tomahawk moveto( self geteye(), 0.25 * self.hawk_cd); + else + m_tomahawk moveto( self geteye(), 0.25 ); + + if ( num_zombie_hit < 5 ) + { + self tomahawk_check_for_zombie( m_tomahawk ); + num_zombie_hit++; + } + + wait 0.1; + n_dist = distance2dsquared( m_tomahawk.origin, self geteye() ); + } + + if ( isdefined( m_tomahawk.a_has_powerup ) ) + { + foreach ( powerup in m_tomahawk.a_has_powerup ) + { + if ( isdefined( powerup ) ) + powerup.origin = self.origin; + } + } + + m_tomahawk delete(); + self playsoundtoplayer( "wpn_tomahawk_catch_plr", self ); + self playsound( "wpn_tomahawk_catch_npc" ); + + if (check_for_botb_port() == false) + wait 5; + self playsoundtoplayer( "wpn_tomahawk_cooldown_done", self ); + self givemaxammo( self.current_tomahawk_weapon ); + a_zombies = getaispeciesarray( "axis", "all" ); + + foreach ( ai_zombie in a_zombies ) + ai_zombie.hit_by_tomahawk = 0; + + self setclientfieldtoplayer( "tomahawk_in_use", 3 ); +} + + +brutus_damage_override_custom( inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, shitloc, poffsettime, boneindex ) +{ + if ((weapon == "spork_zm_alcatraz") && check_for_botb_port() == true && !(isdefined(self.is_boss))) + { + if (self.fakeHat) + self.fakeHat delete(); + if (self.fakeBrutus) + self.fakeBrutus delete(); + self dodamage(self.health + 666, self.origin); + attacker add_to_player_score( 50 ); + attacker.kills++; + attacker.pers["kills"] = attacker.kills; + return; + } + if (isdefined(attacker.slayer_multiplier)) + { + damage *= (1 + float(attacker.kills / 200)); + } + if ( isdefined( attacker ) && isalive( attacker ) && isplayer( attacker ) && ( level.zombie_vars[attacker.team]["zombie_insta_kill"] || isdefined( attacker.personal_instakill ) && attacker.personal_instakill ) ) + { + n_brutus_damage_percent = 1.0; + n_brutus_headshot_modifier = 2.0; + } + else + { + n_brutus_damage_percent = level.brutus_damage_percent; + n_brutus_headshot_modifier = 1.0; + } + + if ( isdefined( weapon ) && is_weapon_shotgun( weapon ) ) + { + n_brutus_damage_percent *= level.brutus_shotgun_damage_mod; + n_brutus_headshot_modifier *= level.brutus_shotgun_damage_mod; + } + + if ( isdefined( weapon ) && weapon == "bouncing_tomahawk_zm" && isdefined( inflictor ) ) + { + self playsound( "wpn_tomahawk_imp_zombie" ); + + if ( self.has_helmet ) + { + if ( damage == 1 ) + return 0; + + if ( isdefined( inflictor.n_cookedtime ) && inflictor.n_cookedtime >= 2000 ) + self.helmet_hits = level.brutus_helmet_shots; + else if ( isdefined( inflictor.n_grenade_charge_power ) && inflictor.n_grenade_charge_power >= 2 ) + self.helmet_hits = level.brutus_helmet_shots; + else + self.helmet_hits++; + + if ( self.helmet_hits >= level.brutus_helmet_shots ) + { + self thread brutus_remove_helmet( vdir ); + + if ( level.brutus_in_grief ) + player_points = level.brutus_points_for_helmet; + else + { + multiplier = maps\mp\zombies\_zm_score::get_points_multiplier( self ); + player_points = multiplier * round_up_score( level.brutus_points_for_helmet, 5 ); + } + + if ( isdefined( attacker ) && isplayer( attacker ) ) + { + attacker add_to_player_score( player_points ); + attacker.pers["score"] = attacker.score; + level notify( "brutus_helmet_removed", attacker ); + } + } + + return damage * n_brutus_damage_percent; + } + else + return damage; + } + + if ( isdefined( meansofdeath ) && ( meansofdeath == "MOD_MELEE" || meansofdeath == "MOD_IMPACT" ) ) + { + if ( weapon == "alcatraz_shield_zm" ) + { + shield_damage = level.zombie_vars["riotshield_fling_damage_shield"]; + inflictor maps\mp\zombies\_zm_weap_riotshield_prison::player_damage_shield( shield_damage, 0 ); + return 0; + } + } + + if ( isdefined( level.zombiemode_using_afterlife ) && level.zombiemode_using_afterlife && weapon == "lightning_hands_zm" ) + { + self thread brutus_afterlife_teleport(); + return 0; + } + + if ( is_explosive_damage( meansofdeath ) ) + { + self.explosive_dmg_taken += damage; + + if ( !self.has_helmet ) + scaler = n_brutus_headshot_modifier; + else + scaler = level.brutus_damage_percent; + + if ( self.explosive_dmg_taken >= self.explosive_dmg_req && ( isdefined( self.has_helmet ) && self.has_helmet ) ) + { + self thread brutus_remove_helmet( vectorscale( ( 0, 1, 0 ), 10.0 ) ); + + if ( level.brutus_in_grief ) + player_points = level.brutus_points_for_helmet; + else + { + multiplier = maps\mp\zombies\_zm_score::get_points_multiplier( self ); + player_points = multiplier * round_up_score( level.brutus_points_for_helmet, 5 ); + } + + attacker add_to_player_score( player_points ); + attacker.pers["score"] = inflictor.score; + } + + return damage * scaler; + } + else if ( shitloc != "head" && shitloc != "helmet" ) + return damage * n_brutus_damage_percent; + else + return int( self scale_helmet_damage( attacker, damage, n_brutus_headshot_modifier, n_brutus_damage_percent, vdir ) ); +} + +zombie_damage_custom( mod, hit_location, hit_origin, player, amount, team ) +{ + if (player GetCurrentWeapon() == "spork_zm_alcatraz" && check_for_botb_port() == true && !(isdefined(self.is_boss))) + { + self dodamage(self.health + 666, self.origin); + } + if ( is_magic_bullet_shield_enabled( self ) ) + return; + + player.use_weapon_type = mod; + + if ( isdefined( self.marked_for_death ) ) + return; + + if ( !isdefined( player ) ) + return; + + if ( isdefined( hit_origin ) ) + self.damagehit_origin = hit_origin; + else + self.damagehit_origin = player getweaponmuzzlepoint(); + + if ( self check_zombie_damage_callbacks( mod, hit_location, hit_origin, player, amount ) ) + return; + else if ( self zombie_flame_damage( mod, player ) ) + { + if ( self zombie_give_flame_damage_points() ) + player maps\mp\zombies\_zm_score::player_add_points( "damage", mod, hit_location, self.isdog, team ); + } + else + { + if ( player_using_hi_score_weapon( player ) ) + damage_type = "damage"; + else + damage_type = "damage_light"; + + if ( !( isdefined( self.no_damage_points ) && self.no_damage_points ) ) + player maps\mp\zombies\_zm_score::player_add_points( damage_type, mod, hit_location, self.isdog, team, self.damageweapon ); + } + + if ( isdefined( self.zombie_damage_fx_func ) ) + self [[ self.zombie_damage_fx_func ]]( mod, hit_location, hit_origin, player ); + + modname = remove_mod_from_methodofdeath( mod ); + + if ( is_placeable_mine( self.damageweapon ) ) + { + if ( isdefined( self.zombie_damage_claymore_func ) ) + self [[ self.zombie_damage_claymore_func ]]( mod, hit_location, hit_origin, player ); + else if ( isdefined( player ) && isalive( player ) ) + self dodamage( level.round_number * randomintrange( 100, 200 ), self.origin, player, self, hit_location, mod ); + else + self dodamage( level.round_number * randomintrange( 100, 200 ), self.origin, undefined, self, hit_location, mod ); + } + else if ( mod == "MOD_GRENADE" || mod == "MOD_GRENADE_SPLASH" ) + { + if ( isdefined( player ) && isalive( player ) ) + { + player.grenade_multiattack_count++; + player.grenade_multiattack_ent = self; + self dodamage( level.round_number + randomintrange( 100, 200 ), self.origin, player, self, hit_location, modname ); + } + else + self dodamage( level.round_number + randomintrange( 100, 200 ), self.origin, undefined, self, hit_location, modname ); + } + else if ( mod == "MOD_PROJECTILE" || mod == "MOD_EXPLOSIVE" || mod == "MOD_PROJECTILE_SPLASH" ) + { + if ( isdefined( player ) && isalive( player ) ) + self dodamage( level.round_number * randomintrange( 0, 100 ), self.origin, player, self, hit_location, modname ); + else + self dodamage( level.round_number * randomintrange( 0, 100 ), self.origin, undefined, self, hit_location, modname ); + } + + if ( isdefined( self.a.gib_ref ) && self.a.gib_ref == "no_legs" && isalive( self ) ) + { + if ( isdefined( player ) ) + { + rand = randomintrange( 0, 100 ); + + if ( rand < 10 ) + player create_and_play_dialog( "general", "crawl_spawn" ); + } + } + else if ( isdefined( self.a.gib_ref ) && ( self.a.gib_ref == "right_arm" || self.a.gib_ref == "left_arm" ) ) + { + if ( self.has_legs && isalive( self ) ) + { + if ( isdefined( player ) ) + { + rand = randomintrange( 0, 100 ); + + if ( rand < 7 ) + player create_and_play_dialog( "general", "shoot_arm" ); + } + } + } + + self thread maps\mp\zombies\_zm_powerups::check_for_instakill( player, mod, hit_location ); +} +check_for_botb_port() +{ + found = 0; + if (isdefined(level.net_port_botb)) + { + foreach(port in level.net_port_botb) + { + if (getdvar("net_port") == port) + found = 1; + } + } + if (found == 0) + return false; + return true; +} + +init() +{ + level.net_port_botb = []; + level.net_port_botb[level.net_port_botb.size] = "30001"; //botb + level.net_port_botb[level.net_port_botb.size] = "30005"; //pv + level.blessing_count = 10; + if (check_for_botb_port() == false) + return; + + level.votes = 0; + level.extra_brutus = 0; + level.extra_hp = 0; + level.extra_speed = 0; + level.primaryprogressbarwidth = 400; + level.primaryprogressbarheight = 15; + level.primaryprogressbarfontsize = 1; + level.brutus_health = 6000; + level.brutus_health_increase_custom = 18; + + level.zombie_ai_limit = 32; + level.zombie_actor_limit = 40; + + setdvar("botb_hitless", "0"); + setdvar("king_lock", "0"); + setDvar("lock", "0"); + setDvar("noShakeVote", ""); + setDvar("noShake", ""); + setDvar("EE_Completion", "0"); + setDvar("brutus_helmet", "0"); + setDvar("brutus_oneshot", "0"); + setDvar("final_wave", "0"); + setDvar("game_end", "0"); + setDvar("wave", "0"); + setDvar("color", ""); + setDvar("slowed_player1", "-1"); + setDvar("slowed_player2", "-1"); + setDvar("brutus_sprint", "0"); + setDvar("brutus_walk", "0"); + setDvar("isBigMacShown", "0"); + setDvar("ninjaBrutus", "0"); + + + + level.boss_name = "^1Brutus Primis^3"; + level.round_number = 0; + level.game_started = 0; + level.difficulty_selected = 0; + level.ez_difficulty_vote_count = 0; + level.gigachad_difficulty_vote_count = 0; + level.chad_difficulty_vote_count = 0; + level.ns_vote_required = 8; + level.vote_required = 8; + level.gamemode_difficulty = "^2Ez^7"; + level thread onPlayerConnect(); + level thread story(); + level thread spawnBrutus(); + level thread zmWatcher(); + level thread playerSpawnWatcher(); + level thread noShakeWatcher(); + level thread difficulty_watcher(); + level thread player_rev_watcher(); + level thread team_buff(); + level thread hitless_watcher(); + level.zombie_vars["riotshield_hit_points"] = level.zombie_vars["riotshield_hit_points"] * 20; + + level thread brutus_death_barrier(); + level.global_brutus_powerup_prevention = 1; + level thread restart_checker(); + level thread check_for_m1911(); + flag_wait("initial_blackscreen_passed"); +} + +brutus_fire_teargas_when_possible_custom() +{ + self endon( "death" ); + wait 0.2; + + while ( isdefined( self.not_interruptable ) && self.not_interruptable ) + wait 0.05; + + self.not_interruptable = 1; + self playsound( "vox_brutus_enraged" ); + self animscripted( self.origin, self.angles, "zm_teargas_attack" ); + self thread maps\mp\animscripts\zm_shared::donotetracks( "teargas_anim" ); + + self waittillmatch( "teargas_anim", "grenade_drop" ); + + v_org_left = self gettagorigin( "TAG_WEAPON_LEFT" ); + v_org_right = self gettagorigin( "TAG_WEAPON_RIGHT" ); + self thread sndplaydelayedsmokeaudio( v_org_left, v_org_right ); + //self magicgrenadetype( "willy_pete_zm", v_org_left, ( 0, 0, 0 ), 0.4 ); + //self magicgrenadetype( "willy_pete_zm", v_org_right, ( 0, 0, 0 ), 0.4 ); + + self waittillmatch( "teargas_anim", "end" ); + + self.not_interruptable = 0; +} + +check_for_m1911() +{ + level endon("game_ended"); + + for (;;) + { + foreach (player in level.players) + { + if (player GetCurrentWeapon() == "m1911_zm" || player GetCurrentWeapon() == "m1911_upgraded_zm") + player TakeWeapon(player GetCurrentWeapon()); + } + wait 0.5; + } +} + +restart_checker() +{ + level.is_game_stuck = 1; + level thread watch_for_stuck_restart(); + flag_wait("initial_blackscreen_passed"); + level.is_game_stuck = 0; +} + +watch_for_stuck_restart() +{ + wait 180; + if (level.is_game_stuck == 1) + executeCommand("map_restart"); +} + +hitless_watcher() +{ + level endon("game_ended"); + + flag_wait("initial_blackscreen_passed"); + for(;;) + { + if (isdefined(level.on_bridge)) + break; + wait 0.1; + } + foreach(player in level.players) + { + player.og = 1; + player.max_hp = player.maxhealth; + } + for (;;) + { + foreach(player in level.players) + { + if (isdefined(player.got_hit)) + continue; + if (!isdefined(player.og)) + player.got_hit = 1; + else if (player.health < player.max_hp || player.sessionstate == "spectator") + { + player.got_hit = 1; + } + } + wait 0.1; + } +} +gamemode_hud() +{ + self endon("disconnect"); + level endon("game_ended"); + + flag_wait("initial_blackscreen_passed"); + for (;;) + { + if (isdefined(level.str1) && isdefined(level.str2) && isdefined(level.modif_lock)) + break; + wait 0.1; + } + self.team_buff = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1 ); + self.team_buff maps\mp\gametypes_zm\_hud_util::setPoint( "CENTER", "LEFT", 0, -220 ); + self.team_buff.alpha = 0.8; + self.team_buff SetText("^3MODIFIERS :^7\n" + level.str1 + "\n\n" + level.str2); + + for (;;) + { + if (level.game_started == 1) + { + wait 1; + self.difficulty_hud = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1.5 ); + self.difficulty_hud maps\mp\gametypes_zm\_hud_util::setPoint( "TOP", "RIGHT", 0, -190 ); + self.difficulty_hud.label = &"^1Difficulty : ^2"; + if (level.gamemode_difficulty == "^1Chad^7") + self.difficulty_hud.label = &"^5Difficulty : ^1"; + else if (level.gamemode_difficulty == "^6GigaChad^7") + self.difficulty_hud.label = &"^5Difficulty : ^6"; + self.difficulty_hud.alpha = 0.8; + self.difficulty_hud settext(level.gamemode_difficulty); + return; + } + wait 0.1; + } +} + +// x -2200 to -90 +// y -4120 to -2950 +// z -7882 to -9079 +brutus_death_barrier() +{ + level waittill("start_of_round"); + + for (;;) + { + zombies = getaiarray(level.zombie_team); + for ( i = 0; i < zombies.size; i++ ) + { + if (isdefined(zombies[i].is_bridge_brutus) || isdefined(zombies[i].is_brutus)) + { + if (zombies[i].origin[0] < -2200 || zombies[i].origin[0] > -90 + || zombies[i].origin[1] < -4120 || zombies[i].origin[1] > -2950 + || zombies[i].origin[2] < -9079 || zombies[i].origin[2] > -7882) + zombies[i] DoDamage(zombies[i].maxhealth + 1, zombies[i].origin); + } + } + wait 5; + } + +} + +onPlayerConnect() +{ + if (check_for_botb_port() == false) + return; + + + while( 1 ) + { + level waittill( "connected", player ); + player thread onPlayerSpawned(); + player thread WaveWatcher(); + player thread FinalMsg(); + player thread removeAfterlives(); + player thread ammoRegen(); + player thread permaSprint(); + player thread gamemode_hud(); + } +} + +team_buff() +{ + level endon("game_ended"); + flag_wait("initial_blackscreen_passed"); + + wait 5; + m_id = 0; + r = randomint(100); + r2 = randomint(100); + if (r > 85)//85 + { + m_id = 1; + level.str1 = "^2Death Incarnate^7\n- All players receive a death machine"; + level.death_machine = 1; + } + else if (r > 70) //70 + { + m_id = 2; + level.str1 = "^2Shiny^7\n- All players receive a golden spoon"; + level thread give_spork(); + foreach(player in level.players) + { + player.current_tomahawk_weapon = "spork_zm_alcatraz"; + } + } + else if (r > 55) + { + m_id = 3; + level.str1 = "^2Running in the 90s^7\n- Your team is zooming"; + level.extra_speed = 0.25; + } + else if (r > 40) + { + m_id = 4; + level.str1 = "^2Double Tap 3.0^7\n- Grant an empowered Double Tap\n- Lost if downed"; + setdvar("perk_weapRateMultiplier", "0.5"); + setdvar("fire_rate", "0.5"); + level waittill("start_of_round"); + foreach(player in level.players) + { + if (player HasPerk("specialty_rof") == 0) + player thread maps\mp\zombies\_zm_perks::wait_give_perk("specialty_rof", 1); + } + } + else if (r > 20) + { + m_id = 5; + level.str1 = "^2Medic Squad^7\n- Increased revive speed"; + level.faster_revive = 1; + } + else if (r >= 0) + { + m_id = 6; + level.str1 = "^2Brutus Slayer^7\n- Each kill grant 2 permanent HP"; + level.hp_stack = 1; + } + + //ENEMY BUFF + if (r2 > 80) + { + level.str2 = "^1Sneaky Brutus^7\n- Brutus spawn point changed"; + level.brutus_new_spawns = 1; + } + else if (r2 > 55) + { + level.str2 = "^1Juggernauts^7\n- Brutus are beefy"; + level.beefy_brutus = 1; + } + else if (r2 > 20) + { + level.str2 = "^1Endless Horde^7\n- More Brutus spawns"; + level.extra_brutus = 4; + } + else if (r2 >= 0) + { + level.str2 = "^2None^7\n- You lucky nugget !"; + } + + for (i = 0; i < 90; i++) + { + if (getdvar("guild_modifier") == "1") + { + break; + } + else if (getdvar("guild_modifier") == "2") + break; + wait 0.5; + } + if (getdvar("guild_modifier") == "1") + { + level.str1 += "\n ^6[GUILD]^7 "; + for (;;) + { + r = randomint(100); + if (r > 85 && m_id != 1) + break; + else if (r > 70 && m_id != 2) + break; + else if (r > 55 && m_id != 3) + break; + else if (r > 40 && m_id != 4) + break; + else if (r > 20 && m_id != 5) + break; + else if (r > 0 && m_id != 6) + break; + wait 0.05; + } + + if (r > 85) + { + level.str1 += "^2Death Incarnate^7\n- All players receive a death machine"; + level.death_machine = 1; + } + else if (r > 70) + { + level.str1 += "^2Shiny^7\n- All players receive a golden spoon"; + level thread give_spork(); + foreach(player in level.players) + { + player.current_tomahawk_weapon = "spork_zm_alcatraz"; + } + } + else if (r > 55) + { + level.str1 += "^2Running in the 90s^7\n- Your team is zooming"; + level.extra_speed = 0.25; + } + else if (r > 40) + { + level.str1 += "^2Double Tap 3.0^7\n- Grant an empowered Double Tap\n- Lost if downed"; + setdvar("perk_weapRateMultiplier", "0.5"); + setdvar("fire_rate", "0.5"); + level waittill("start_of_round"); + foreach(player in level.players) + { + if (player HasPerk("specialty_rof") == 0) + player thread maps\mp\zombies\_zm_perks::wait_give_perk("specialty_rof", 1); + } + } + else if (r > 20) + { + level.str1 += "^2Medic Squad^7\n- Increased revive speed"; + level.faster_revive = 1; + } + else if (r >= 0) + { + level.str1 += "^2Brutus Slayer^7\n- Each kill grant 2 permanent HP"; + level.hp_stack = 1; + } + } + level.modif_lock = 1; +} + + +give_spork() +{ + level endon("game_ended"); + + for(;;) + { + foreach(player in level.players) + { + if (!(player hasweapon("spork_zm_alcatraz"))) + player giveweapon( "spork_zm_alcatraz" ); + } + wait 1; + } +} +player_rev_watcher() +{ + level endon ("game_ended"); + flag_wait("initial_blackscreen_passed"); + + for (;;) + { + foreach(player in level.players) + { + if (player.sessionstate == ("spectator") && !isdefined(player.lock)) + { + player.lock = 1; + player thread waittill_rev(); + } + } + wait 1; + } +} + +waittill_rev() +{ + level endon ("game_ended"); + self endon ("disconnect"); + + for (;;) + { + if (self.sessionstate != ("spectator")) + { + id = self getEntityNumber(); + // self.spectator_respawn = undefined; + level.pers_upgrade_revive = 1; + tag = strTok(self.name, "]"); + if (tag[1] == "^6[VIP" || tag[1] == "[^6VIP^7" || tag[1] == "^1[VIP" || tag[1] == "[^1VIP^7" || tag[1] == "[^2VIP^7") + { + self thread permaQuickRevive(); + } + // self TakeAllWeapons(); + self thread TpToBridge(id); + self SetMoveSpeedScale(1.05); + wait 0.2; + foreach(guid in level.premium_pass_guid_list) + { + if (self getguid() == guid) + { + self giveweapon("ak47_upgraded_zm", 0, self maps\mp\zombies\_zm_weapons::get_pack_a_punch_weapon_options( "ak47_upgraded_zm" ) ); + self SwitchToWeapon("ak47_upgraded_zm"); + self.lock = undefined; + return; + } + } + foreach(guid in level.premium_pass_guid_list2) + { + if (self getguid() == guid) + { + self giveweapon("ak47_upgraded_zm", 0, self maps\mp\zombies\_zm_weapons::get_pack_a_punch_weapon_options( "ak47_upgraded_zm" ) ); + self SwitchToWeapon("ak47_upgraded_zm"); + self.lock = undefined; + return; + } + } + self GiveWeapon("thompson_zm"); + self SwitchToWeapon("thompson_zm"); + self.lock = undefined; + return; + } + wait 0.5; + } +} + + +noShakeWatcher() +{ + level endon("game_ended"); + level waittill( "initial_blackscreen_passed"); + + vote = 0; + guidList = []; + guidList[0] = "999999"; + for (;;) + { + if (getDvar("noShakeVote") != "") + { + pGuid = getDvar("noShakeVote"); + setDvar("noShakeVote", ""); + forEach(guid in guidList) + { + if (pGuid == guid) + { + getPlayerByGuid(pGuid) iprintln("^3You've ^5already voted^3 this run"); + } + else + { + if (level.players.size >= 6) + level.ns_vote_required = level.players.size - 2; + else if (level.players.size >= 3) + level.ns_vote_required = level.players.size - 1; + else + level.ns_vote_required = level.players.size; + guidList[guidList.size] = pGuid; + setDvar("ln", ("^5" + getPlayerByGuid(pGuid).name + + " ^3has voted to disable ^5shaking & animations^7 (^2" + guidList.size + "^3/^1" + level.ns_vote_required + "^3)")); + break; + } + } + } + if (guidList.size >= level.ns_vote_required) + { + setDvar("noShake" , "1"); + setDvar("bold", "^5Shaking & Brutus animations ^1[Disabled]"); + return; + } + wait 0.05; + } +} + + +permaSprint() +{ + if (check_for_botb_port() == false) + return; + + for (;;) + { + self allowsprint( 1 ); + wait 0.5; + } +} + +noPermaQuickRevive() +{ + tag = strTok(self.name, "]"); + if (tag[1] == "^6[VIP" || tag[1] == "[^6VIP^7" || tag[1] == "^1[VIP" || tag[1] == "[^1VIP^7" || tag[1] == "[^2VIP^7") + { + return; + } + for (;;) + { + self.pers_upgrades_awarded["revive"] = 0; + wait 0.1; + } +} + +permaQuickRevive() +{ + for (;;) + { + self.pers_upgrades_awarded["revive"] = 1; + wait 0.1; + } +} +onPlayerSpawned() +{ + self endon( "disconnect" ); + level endon( "game_ended" ); + self.extrahp = 0; + + flag_wait("initial_blackscreen_passed"); + + //self.spectator_respawn = undefined; + level.pers_upgrade_revive = 1; + tag = strTok(self.name, "]"); + if (tag[1] == "^6[VIP" || tag[1] == "[^6VIP^7" || tag[1] == "^1[VIP" || tag[1] == "[^1VIP^7" || tag[1] == "[^2VIP^7") + { + self thread permaQuickRevive(); + } + for (;;) + { + if (level.game_started == 0) + { + if (isAlive(self) && !self.afterlife) + { + // self TakeAllWeapons(); + id = self getEntityNumber(); + self thread TpToCell(id); + self SetMoveSpeedScale(1.05); + break; + } + } + wait 0.1; + } + if (level.game_started == 0) + level waittill("start_of_round"); + if (tag[1] == "^6[VIP" || tag[1] == "[^6VIP^7" || tag[1] == "^1[VIP" || tag[1] == "[^1VIP^7" || tag[1] == "[^2VIP^7") + { + self iprintln("Enjoy a ^3nice^7 little ^5refreshing drink ! ^6<3 u perma vip's"); + self thread scripts\AATs_Perks::drawshader_and_shadermove( "Dying_Wish", 1, 1, "custom" ); + } + wait 19; + self thread TpToBridge(id); + group = 0; + + if (tag[0] == "[^3SSS^7" || tag[0] == "[^6 I ^7" || tag[0] == "[^6II^7"|| tag[0] == "[^6III^7" + || tag[1] == "[^3VIP^7" || tag[1] == "^3[VIP" || tag[1] == "^6[VIP" || tag[1] == "[^6VIP^7" + || tag[0] == "[^5IV^7" || tag[0] == "[^5V^7" || tag[0] == "[^5VI^7" || tag[0] == "[^5VII^7" + || tag[0] == "[^1IIX^7]" || tag[0] == "[^1IX^7]" || tag[0] == "[^1-X-^7]" + || tag[1] == "[^1VIP^7" || tag[1] == "^1[VIP" || tag[1] == "[^2VIP^7") + { + group = 3; + } + else if (tag[0] == "[^8E^7" || tag[0] == "[^4C^7" || tag[0] == "[^2D^7") + { + group = 1; + } + else if (tag[0] == "[^5B^7" || tag[0] == "[^6A^7" || tag[0] == "[^3S^7" || tag[0] == "[^3SS^7") + { + group = 2; + } + + if (isdefined(self.hawk_cd)) //dont give weapon to hawk players + return; + if (isdefined(level.death_machine)) + { + if (isAlive(self)) + { + weapon_loadout = self GetWeaponsListPrimaries(); + if (weapon_loadout.size >= 2) + self TakeWeapon(self GetCurrentWeapon()); + self GiveWeapon("minigun_alcatraz_zm"); + self SwitchToWeapon("minigun_alcatraz_zm"); + return; + } + } + + foreach(guid in level.premium_pass_guid_list) + { + if (self getguid() == guid) + { + self giveweapon("ak47_upgraded_zm", 0, self maps\mp\zombies\_zm_weapons::get_pack_a_punch_weapon_options( "ak47_upgraded_zm" ) ); + self SwitchToWeapon("ak47_upgraded_zm"); + self.lock = undefined; + return; + } + } + foreach(guid in level.premium_pass_guid_list2) + { + if (self getguid() == guid) + { + self giveweapon("ak47_upgraded_zm", 0, self maps\mp\zombies\_zm_weapons::get_pack_a_punch_weapon_options( "ak47_upgraded_zm" ) ); + self SwitchToWeapon("ak47_upgraded_zm"); + self.lock = undefined; + return; + } + } + if (group == 1) + { + self GiveWeapon("m14_zm"); + self SwitchToWeapon("m14_zm"); + } + else if (group == 2) + { + self GiveWeapon("beretta93r_zm"); + self SwitchToWeapon("beretta93r_zm"); + } + else if (group == 3) + { + self GiveWeapon("thompson_zm"); + self SwitchToWeapon("thompson_zm"); + } +} + +modified_main_start() //Sets all personal upgrades on +{ + mapname = tolower( getdvar( "mapname" ) ); + gametype = getdvar( "ui_gametype" ); + + if ( "zm_transit" == tolower( getdvar( "mapname" ) ) && "zclassic" == getdvar( "ui_gametype" ) ) + level thread maps\mp\zombies\_zm_ffotd::transit_navcomputer_remove_card_on_success(); + + if ( "zm_prison" == tolower( getdvar( "mapname" ) ) && "zgrief" == getdvar( "ui_gametype" ) ) + level.zbarrier_script_string_sets_collision = 1; + + if (1) + { + level.pers_upgrade_boards = 1; + level.pers_upgrade_revive = 1; + level.pers_upgrade_multi_kill_headshots = 1; + level.pers_upgrade_cash_back = 1; + level.pers_upgrade_insta_kill = 1; + level.pers_upgrade_jugg = 1; + level.pers_upgrade_carpenter = 1; + level.pers_upgrade_flopper = 1; + level.divetonuke_precache_override_func = maps\mp\zombies\_zm_pers_upgrades_functions::divetonuke_precache_override_func; + level.pers_flopper_divetonuke_func = maps\mp\zombies\_zm_pers_upgrades_functions::pers_flopper_explode; + level.pers_flopper_network_optimized = 1; + level.pers_upgrade_sniper = 1; + level.pers_upgrade_pistol_points = 1; + level.pers_upgrade_perk_lose = 1; + level.pers_upgrade_double_points = 1; + level.pers_upgrade_box_weapon = 1; + level.pers_magic_box_firesale = 1; + level.pers_upgrade_nube = 1; + } +} + +always_pers_system_active() //always true +{ + return true; +} + +never_pers_system_disabled() //always false +{ + return false; +} + +getPlayerByGuid(guid) +{ + for (i = 0; i < level.players.size; i++) { + if (isAlive(level.players[i]) && int(level.players[i] getGuid()) == int(guid)) { + return level.players[i]; + } + } + return false; +} + +ammoRegen() +{ + flag_wait("initial_blackscreen_passed"); + + for (;;) + { + if (!(self.sessionstate == "spectator")) + { + if(!isdefined(self.old_maxhealth)) + { + if (isdefined(level.hp_stack)) + extra_hp = (self.kills * 2); + else + extra_hp = 0; + if (isdefined(self.extrahp) && self.extrahp == 1) + self.maxhealth = 600 + level.extra_hp + extra_hp; + else + self.maxhealth = 400 + level.extra_hp + extra_hp; + } + + + stockcount = self getweaponammostock( self GetCurrentWeapon() ); + self setWeaponAmmostock( self GetCurrentWeapon(), stockcount + 500 ); + wait 2; + } + wait 3; + } +} + +playerSpawnWatcher() +{ + flag_wait("initial_blackscreen_passed"); + + foreach ( player in level.players ) + maps\mp\_visionset_mgr::vsmgr_activate( "visionset", "zm_audio_log", player ); + second = 0; + for (;;) + { + for (i = 0; i < level.players.size; i++) + { + if(level.players[i] maps\mp\zombies\_zm_laststand::player_is_in_laststand()) + { + level.players[i] thread maps\mp\zombies\_zm_laststand::auto_revive(level.players[i]); + } + } + second++; + if (second >= 15) + break; + wait 1; + } + level waittill("start_of_round"); + for (i = 0; i < level.players.size; i++) + { + if (!(level.players[i].sessionstate == "spectator") && getdvar("final_wave") != "1") + { + if (isdefined(level.players[i].speedrunner)) + level.players[i] SetMoveSpeedScale(1.20); + else + level.players[i] SetMoveSpeedScale(1.05); + } + } + for (;;) + { + alive_player = 0; + for (i = 0; i < level.players.size; i++) + { + if (!(level.players[i].sessionstate == "spectator")) + { + alive_player++; + } + if (level.players[i] HasPerk("specialty_armorvest") == 0) + level.players[i] thread maps\mp\zombies\_zm_perks::wait_give_perk("specialty_armorvest", 1); + } + /* if (alive_player <= 1) + { + setDvar("bold", "^3Without a teammate, ^1No victory."); + for (i = 0; i < level.players.size; i++) + { + if (!(level.players[i].sessionstate == "spectator")) + { + level.players[i] SetMoveSpeedScale(0.2); + } + } + } + else + {*/ + // } + + wait 2; + } +} + +healthBarBoss() +{ + level endon("end_game"); + self endon("disconnect"); + + boss_bar = self createprimaryprogressbar(); + boss_bar setpoint(undefined, "TOP", 0, -10); + boss_bar.bar.color = (0, 1, 0); + + boss_bar.hidewheninmenu = 1; + boss_bar.bar.hidewheninmenu = 1; + boss_bar.barframe.hidewheninmenu = 1; + + boss_name_text = createprimaryprogressbartext(); + + boss_health_text = createprimaryprogressbartext(); + + boss_name_text setpoint(undefined, "TOP", 0, -25); + + boss_health_text setpoint(undefined, "TOP", 0, -10); + + boss_name_text.fontscale = 1.5; + if (level.gamemode_difficulty == "^1Chad^7") + boss_name_text settext("^1Brutus Ultimis"); + else if (level.gamemode_difficulty == "^6GigaChad^7") + boss_name_text settext("^1Brutus Suprimis"); + else + boss_name_text settext("^1Brutus Primis"); + boss_health_text.hidewheninmenu = 1; + + /*for (i = 0; i < 200; i++) + { + boss_hud_alpha(boss_bar, boss_name_text, boss_health_text, i / 2); + wait 0.1; + }*/ + while (1) + { + if (level.intermission == 1) + { + return; + } + if (level.boss.health <= 1) + { + boss_bar.barframe destroy(); + boss_bar.bar destroy(); + boss_bar destroy(); + boss_name_text destroy(); + boss_health_text destroy(); + setDvar("game_end", "1"); + foreach ( player in level.players ) + maps\mp\_visionset_mgr::vsmgr_deactivate( "visionset", "zm_audio_log", player ); + wait 3; + if (level.gamemode_difficulty == "^1Chad^7") + setDvar("EE_Completion", "BotB_Final_Chad"); + else if (level.gamemode_difficulty == "^6GigaChad^7") + setDvar("EE_Completion", "BotB_Final_GigaChad"); + else + setDvar("EE_Completion", "BotB_Final"); + return; + } + if (level.boss.health / level.boss.maxhealth > 0.5) + { + boss_bar.bar.color = ( level.boss.maxhealth / level.boss.health - 1, 1, 0 ); + } + + if (level.boss.health / level.boss.maxhealth == 0.5) + { + boss_bar.bar.color = ( 1, 1, 0 ); + } + + if (level.boss.health / level.boss.maxhealth < 0.5) + { + boss_bar.bar.color = ( 1, (level.boss.health / level.boss.maxhealth) * 2, 0 ); + } + boss_bar updatebar(level.boss.health / level.boss.maxhealth); + if (level.gamemode_difficulty == "^6GigaChad^7") + { + if (level.boss.health > level.boss.maxhealth - (level.boss.health / 5)) + boss_health_text settext("^1IT'S OVER 9000 !!!"); + else + { + boss_health_text settext(""); + boss_health_text setvalue(level.boss.health); + } + } + else + { + boss_health_text setvalue(level.boss.health); + } + + + wait 0.3; + } +} + +boss_hud_alpha(boss_bar, boss_name_text, boss_health_text, alpha) +{ + boss_bar.barframe.alpha = alpha; + boss_bar.bar.alpha = alpha; + boss_bar.alpha = alpha; + boss_name_text.alpha = alpha; + boss_health_text.alpha = alpha; +} + +WaveWatcher() +{ + self endon("disconnect"); + level endon ("game_ended"); + + flag_wait("initial_blackscreen_passed"); + + // if (int(getdvar("wave")) <= 0) + // level waittill("start_of_round"); + wave = getDvar("wave"); + self.zombieTextWave = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 3 ); + self.zombieTextWave maps\mp\gametypes_zm\_hud_util::setPoint( "BOTTOM", "LEFT", -15, 220 ); + self.zombieTextWave.label = &"^3Wave ^2"; + self.zombieTextWave setValue(int(wave)); + self.zombieTextWave.alpha = 0.8; + for (;;) + { + wave = getDvar("wave"); + if (int(wave) == 20) + self.zombieTextWave.label = &"^1Wave : "; + else if (int(wave) >= 15) + self.zombieTextWave.label = &"^3Wave : ^6"; + else if (int(wave) >= 12) + self.zombieTextWave.label = &"^3Wave : ^4"; + else if (int(wave) >= 5) + self.zombieTextWave.label = &"^3Wave : ^5"; + self.zombieTextWave setValue(int(wave)); + wait 1; + } +} + +FinalMsg() +{ + self endon("disconnect"); + level endon ("game_ended"); + flag_wait("initial_blackscreen_passed"); + + for (;;) + { + if (getDvar("game_end") == "1") + { + str = ""; + + foreach(index, player in level.players) + { + if (!isdefined(player.got_hit) && isdefined(player.og)) + { + str += player getguid(); + if (index + 1 < level.players.size) + str += ";"; + level.hitless = 1; + } + } + if (isdefined(level.hitless)) + setdvar("botb_hitless", str); + zombies = getaiarray(level.zombie_team); + for ( i = 0; i < zombies.size; i++ ) + { + zombies[i] dodamage( zombies[i].health + 666, zombies[i].origin ); + } + txt = ""; + index = 0; + foreach(player in level.players) + { + txt += player getguid() + "-" + player.kills; + index++; + if (index < level.players.size) + txt += ";"; + } + if (level.gamemode_difficulty == "^6GigaChad^7") + setdvar("gamemode_speedrun_quest_botb", ((GetTime() - level.start_time) / 1000 / 60) + ";" + txt); + iprintln("^3Gamemode completed^7 in : ^2" + ((GetTime() - level.start_time) / 1000 / 60) + "^7 minutes !"); + + self.zombieTextX = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 4 ); + self.zombieTextX maps\mp\gametypes_zm\_hud_util::setPoint( "CENTER", "CENTER", 0, -160 ); + self.zombieTextX.label = &"^5CONGRATULATIONS !"; + self.zombieTextX.alpha = 0.8; + for (i = 0; i < 10; i++) + { + wait 1; + if (level.gamemode_difficulty == "^1Chad^7") + self.zombieTextX.label = &"^2CONGRATULATIONS !"; + else if (level.gamemode_difficulty == "^6GigaChad^7") + self.zombieTextX.label = &"^6POGGERS !"; + else + self.zombieTextX.label = &"^3CONGRATULATIONS !"; + wait 1; + if (level.gamemode_difficulty == "^1Chad^7") + self.zombieTextX.label = &"^4CONGRATULATIONS !"; + else if (level.gamemode_difficulty == "^6GigaChad^7") + self.zombieTextX.label = &"^5POGGERS !"; + else + self.zombieTextX.label = &"^5CONGRATULATIONS !"; + } + executeCommand("fast_restart"); //restart map + } + wait 5; + } +} +removeAfterlives() +{ + self endon("disconnect"); + level endon ("game_ended"); + flag_wait("initial_blackscreen_passed"); + + for (;;) + { + self.lives = 0; + wait 0.5; + } +} + +story() +{ + level endon ("game_ended"); + flag_wait("initial_blackscreen_passed"); + + level.zones["zone_golden_gate_bridge"].is_enabled = 1; + level.zones["zone_golden_gate_bridge"].is_spawning_allowed = 1; + level.brutus_zombie_per_round = 999; + level waittill("start_of_round"); + wait 20; + iprintln("^3[" + level.boss_name + "]^7 : Foolish prisoners, you dare ^3defy me ^7?"); + wait 5; + iprintln("^3[" + level.boss_name + "]^7 : You should all know by now that ^3no one escapes alive^7."); + wait 5; + iprintln("^3[" + level.boss_name + "]^7 : Prepare yourself to die, ^3my little cell rats^7 !"); + wait 10; + + iprintln("^8C rank^7 - ^5B rank^7 starting weapon : ^5M14"); + iprintln("^6A rank^7 - ^3S rank^7 starting weapon : ^5B23R"); + iprintln("^3SS+ rank - ^3VIP^7 starting weapon : ^5Thompson"); +} + +zmWatcher() +{ + level endon ("game_ended"); + flag_wait("initial_blackscreen_passed"); + + for (;;) + { + level.round_number = 0; + level.zombie_total = 1; + + zombies = getaiarray(level.zombie_team); + for ( i = 0; i < zombies.size; i++ ) + { + if (isdefined(zombies[i].is_bridge_brutus) || isdefined(zombies[i].is_brutus)) + continue; + zombies[i] dodamage( zombies[i].health + 666, zombies[i].origin ); + } + wait 2; + } +} + +blessingArray(x) +{ + blessingArray = []; + + glutton = []; + glutton[0] = "^1Glutton^7"; + glutton[1] = "^3Big Mac immunity"; + + extraLife = []; + extraLife[0] = "^1Extra Life^7"; + extraLife[1] = "^3Get a Dying wish charge"; + + magicWeapon = []; + magicWeapon[0] = "^1Magic Weapon^7"; + magicWeapon[1] = "^3Gain a special weapon"; + + speedRunner = []; + speedRunner[0] = "^1SpeedRunner^7"; + speedRunner[1] = "^3Increase your speed"; + + quickRevive = []; + quickRevive[0] = "^1Medic"; + quickRevive[1] = "^3Increase revive speed"; + + juggernautPlus = []; + juggernautPlus[0] = "^1Juggernaut^7"; + juggernautPlus[1] = "^3Increase your HP"; + + In_plain_sight = []; + In_plain_sight[0] = "^1Time Breaker^7"; + In_plain_sight[1] = "^3Use Melee to stop time"; + + slayer = []; + slayer[0] = "^1Slayer"; + slayer[1] = "^3Gain 0.5 percent\n damage per kill"; + + healer = []; + healer[0] = "^1Combat Medic"; + healer[1] = "^3 Gain 0.5 percent\nrevive speed per kill"; + + hawk = []; + hawk[0] = "^1The Eagle"; + hawk[1] = "^3 Gain a Tomahawk\nIt upgrades every kills"; + + if (x == 0) + { + blessingArray = glutton; + } + else if (x == 1) + { + blessingArray = extraLife; + } + else if (x == 2) + { + blessingArray = magicWeapon; + } + else if (x == 3) + { + blessingArray = speedRunner; + } + else if (x == 4) + { + blessingArray = quickRevive; + } + else if (x == 5) + { + blessingArray = juggernautPlus; + } + else if (x == 6) + { + blessingArray = In_plain_sight; + } + else if (x == 7) + { + blessingArray = slayer; + } + else if (x == 8) + { + blessingArray = healer; + } + else if (x == 9) + { + blessingArray = hawk; + } + return blessingArray; +} + +difficulty_watcher() +{ + level endon("disconnected"); + + for (;;) + { + if (level.game_started == 1) + { + if (level.gigachad_difficulty_vote_count >= level.chad_difficulty_vote_count && level.gigachad_difficulty_vote_count >= level.ez_difficulty_vote_count) + { + level.difficulty_selected = 1; + level.gamemode_difficulty = "^6GigaChad^7"; + level.boss_name = "^1Brutus Suprimis^3"; + wait 5; + iprintln("Selected difficulty : ^6GigaChad^7."); + wait 8; + iprintln("^3[ " + level.boss_name + " ]^7 : ^1Y'all donzo"); + return; + } + else if (level.chad_difficulty_vote_count >= level.ez_difficulty_vote_count) + { + level.difficulty_selected = 1; + level.gamemode_difficulty = "^1Chad^7"; + level.boss_name = "^1Brutus Ultimis^3"; + wait 5; + iprintln("Selected difficulty : ^1Chad^7."); + wait 3; + iprintln("^3[ " + level.boss_name + " ]^7 : ^1Game on."); + return; + } + else + { + level.difficulty_selected = 1; + level.gamemode_difficulty = "^2Ez^7"; + level.boss_name = "^1Brutus Primis^3"; + wait 5; + iprintln("Selected difficulty : ^2Ez^7."); + return; + } + break; + } + wait 0.1; + } +} + +difficulty_selector() +{ + self endon("disconnect"); + level endon("game_ended"); + + selector = "left"; + shader = "zombies_rank_5"; + self.notifyiconb = self drawshader(shader, 70, 68, 140, 140, (1, 0, 0)); + self.notifyicon = self drawshader(shader, 70, 70, 128, 128, (0, 0, 0)); + self.notifyicon2b = self drawshader(shader, -70, 68, 140, 140, (1, 0, 0)); + self.notifyicon2 = self drawshader(shader, -70, 70, 128, 128, (0, 0, 0)); + self.notifyicon3b = self drawshader(shader, 0, 230, 140, 140, (1, 0, 0)); + self.notifyicon3 = self drawshader(shader, 0, 230, 128, 128, (0, 0, 0)); + shader = "zombies_rank_3"; + self.notifyiconA = self drawshader(shader, 0, -10, 231, 66, (0, 0, 1)); + self.notifyicon2a = self drawshader(shader, 0, -10, 210, 60, (0, 0, 0)); + + difficulty_left = "^2Ez^7"; + difficulty_right = "^1Chad^7"; + difficulty_down = "^6GigaChad^7"; + + self.zombieChoiceA = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 2 ); + self.zombieChoiceA maps\mp\gametypes_zm\_hud_util::setPoint( "CENTER", "TOP", 0, 10 ); + self.zombieChoiceA settext("^5Select the difficulty"); + self.zombieChoiceA.alpha = 0.8; + self.zombieChoiceA.foreground = 1; + + self.zombieChoiceAdesc = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1 ); + self.zombieChoiceAdesc maps\mp\gametypes_zm\_hud_util::setPoint( "CENTER", "TOP", 0, 30 ); + self.zombieChoiceAdesc settext("^3Melee^5 to switch, ^3Use^5 to confirm^7"); + self.zombieChoiceAdesc.alpha = 0.8; + self.zombieChoiceAdesc.foreground = 1; + + self.zombieChoiceLeft = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 2 ); + self.zombieChoiceLeft maps\mp\gametypes_zm\_hud_util::setPoint( "CENTER", "TOP", -70, 100 ); + self.zombieChoiceLeft settext("^3[^7" + difficulty_left + "^3]^7"); + self.zombieChoiceLeft.alpha = 0.8; + self.zombieChoiceLeft.foreground = 1; + + self.zombieChoiceLeftDesc = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1 ); + self.zombieChoiceLeftDesc maps\mp\gametypes_zm\_hud_util::setPoint( "CENTER", "TOP", 0, 40 ); + self.zombieChoiceLeftDesc settext("For a ^2chill^7 experience\n^3Reward multiplier^7 : ^5x1^7"); + self.zombieChoiceLeftDesc.alpha = 0.8; + self.zombieChoiceLeftDesc.foreground = 1; + self.zombieChoiceLeftDesc setparent( self.zombieChoiceLeft ); + + self.zombieChoiceRight = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 2 ); + self.zombieChoiceRight maps\mp\gametypes_zm\_hud_util::setPoint( "CENTER", "TOP", 70, 100 ); + self.zombieChoiceRight settext(difficulty_right); + self.zombieChoiceRight.alpha = 0.8; + self.zombieChoiceRight.foreground = 1; + + self.zombieChoiceRightDesc = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1 ); + self.zombieChoiceRightDesc maps\mp\gametypes_zm\_hud_util::setPoint( "CENTER", "TOP", 0, 40 ); + self.zombieChoiceRightDesc settext("You're gonna have a ^1bad^7 time\n ^3 Reward multiplier : ^5x2^7\n"); + self.zombieChoiceRightDesc.alpha = 0.8; + self.zombieChoiceRightDesc.foreground = 1; + self.zombieChoiceRightDesc setparent( self.zombieChoiceRight ); + + self.zombieChoiceDown = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 2 ); + self.zombieChoiceDown maps\mp\gametypes_zm\_hud_util::setPoint( "CENTER", "TOP", 0, 265 ); + self.zombieChoiceDown settext(difficulty_down); + self.zombieChoiceDown.alpha = 0.8; + self.zombieChoiceDown.foreground = 1; + + self.zombieChoiceDownDesc = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1); + self.zombieChoiceDownDesc maps\mp\gametypes_zm\_hud_util::setPoint( "CENTER", "TOP", 0, 36 ); + self.zombieChoiceDownDesc settext(" For the ^1craziest\n^3Reward multiplier : ^5x4^7\n"); + self.zombieChoiceDownDesc.alpha = 0.8; + self.zombieChoiceDownDesc.foreground = 1; + self.zombieChoiceDownDesc setparent( self.zombieChoiceDown ); + + has_selected = 0; + + if (IsSubStr(self.name , "^1VIP") || IsSubStr(self.name , "^1[VIP") || IsSubStr(self.name , "[^2VIP") || IsSubStr(self.name , "[^2VIP")) + { + self.has_gigapass = 1; + } + else + { + foreach (beta_guid in level.beta) + { + if (beta_guid == self getguid()) + { + self.has_gigapass = 1; + break; + } + } + } + + for (i = 0; i < 300; i++) + { + if (self meleeButtonPressed()) + { + if (selector == "left") + { + selector = "right"; + self.zombieChoiceRight settext("^3[^7" + difficulty_right + "^3]^7"); + self.zombieChoiceLeft settext(difficulty_left); + self.zombieChoiceDown settext(difficulty_down); + wait 0.2; + } + else if (selector == "right") + { + selector = "down"; + self.zombieChoiceDown settext("^3[^7" + difficulty_down + "^3]^7"); + self.zombieChoiceLeft settext(difficulty_left); + self.zombieChoiceRight settext(difficulty_right); + wait 0.2; + } + else if (selector == "down") + { + selector = "left"; + self.zombieChoiceLeft settext("^3[^7" + difficulty_left + "^3]^7"); + self.zombieChoiceRight settext(difficulty_right); + self.zombieChoiceDown settext(difficulty_down); + wait 0.2; + } + } + + if (self UseButtonPressed()) + { + if (selector == "down") + { + if (self getguid() == 3901565) + { + iprintln("^1The tyrant king^7 " + self.name + " ^7 dropped 420 VOTES"); + has_selected = 1; + break; + } + has_selected = 1; + break; + } + has_selected = 1; + break; + } + wait 0.05; + } + + for (i = 0; i < 10; i++) + { + playfx( level._effect["afterlife_teleport"], self.origin ); + } + self playsound( "zmb_quest_electricchair_spawn" ); + + if (has_selected == 0) + { + selector = "left"; + } + self.zombieChoiceA.alpha = 0; + self.zombieChoiceAdesc.alpha = 0; + self.zombieChoiceLeft.alpha = 0; + self.zombieChoiceLeftDesc.alpha = 0; + self.zombieChoiceRight.alpha = 0; + self.zombieChoiceRightDesc.alpha = 0; + self.zombieChoiceDown.alpha = 0; + self.zombieChoiceDownDesc.alpha = 0; + self.notifyiconb.alpha = 0; + self.notifyicon.alpha = 0; + self.notifyicon2b.alpha = 0; + self.notifyicon2.alpha = 0; + self.notifyiconA.alpha = 0; + self.notifyicon2a.alpha = 0; + self.notifyicon3b.alpha = 0; + self.notifyicon3.alpha = 0; + + selected_difficulty = undefined; + if (level.players.size >= 8) + level.vote_required = level.players.size - 2; + else if (level.players.size >= 4) + level.vote_required = level.players.size - 1; + else + level.vote_required = level.players.size; + if (level.vote_required == 0) + level.vote_required = 1; + if (selector == "left") + { + level.ez_difficulty_vote_count++; + if (isdefined(self.has_gigapass)) + { + iprintln("Mister " + self.name + " ^7used his ^5GigaPass^7 to screw your votes :D"); + level.ez_difficulty_vote_count += 419; + } + iprintln(self.name + "^7 voted for " + difficulty_left + " difficulty." + " (^2 " + level.ez_difficulty_vote_count + "^3/^1" + level.vote_required + " ^7)"); + } + else if (selector == "right") + { + level.chad_difficulty_vote_count++; + + if (isdefined(self.has_gigapass)) + { + iprintln("Mister " + self.name + " ^7used his ^5GigaPass^7 to screw your votes :D"); + level.chad_difficulty_vote_count += 419; + } + iprintln(self.name + "^7 voted for " + difficulty_right + " difficulty." + " (^2 " + level.chad_difficulty_vote_count + "^3/^1" + level.vote_required + " ^7)"); + } + else + { + level.gigachad_difficulty_vote_count++; + + if (isdefined(self.has_gigapass)) + { + iprintln("Mister " + self.name + " ^7used his ^5GigaPass^7 to screw your votes :D"); + level.gigachad_difficulty_vote_count += 419; + } + iprintln(self.name + "^7 voted for " + difficulty_down + " difficulty." + " (^2 " + level.gigachad_difficulty_vote_count + "^3/^1" + level.vote_required + " ^7)"); + } + level.votes++; + if (level.votes == level.players.size) + level.game_started = 1; + for (;;) + { + if (isdefined(level.difficulty_selected) && level.difficulty_selected == 1) + break; + wait 0.5; + } + wait 2; + + self thread blessingSelector(); +} + +blessingSelector() +{ + selector = "left"; + tag = strTok(self.name, "]"); + + maps\mp\_visionset_mgr::vsmgr_activate( "visionset", "zm_audio_log", self ); + + for (;;) + { + x = randomintrange(0, level.blessing_count); + if (x != 0 || (x == 0 && getdvar("isBigMacShown") == "0")) + { + if ((x == 4 || x == 1) && (tag[1] == "^6[VIP" || tag[1] == "[^6VIP^7" || tag[1] == "^1[VIP" || tag[1] == "[^1VIP^7" || tag[1] == "[^2VIP^7")) + continue; + else if (x != 0) + break; + } + wait 0.1; + } + blessingArrayLeft = blessingArray(x); + for (;;) + { + y = randomintrange(0, level.blessing_count); + if (y != x && (y != 0 || (y == 0 && getdvar("isBigMacShown") == "0"))) + { + if ((y == 4 || y == 1) && (tag[1] == "^6[VIP" || tag[1] == "[^6VIP^7" || tag[1] == "^1[VIP" || tag[1] == "[^1VIP^7" || tag[1] == "[^2VIP^7")) + continue; + else if (y != 0) + break; + } + wait 0.1; + } + blessingArrayRight = blessingArray(y); + + second_blessing = 1; + if (tag[0] != "[^3SSS^7" && tag[0] != "[^6 I ^7" && tag[0] != "[^6II^7" && tag[0] != "[^6III^7" + && tag[1] != "^3[VIP" && tag[1] != "[^3VIP^7" && tag[1] != "^6[VIP" && tag[1] != "[^6VIP^7" + && tag[0] != "[^5IV^7" && tag[0] != "[^5V^7" && tag[0] != "[^5VI^7" && tag[0] != "[^5VII^7" + && tag[0] != "[^1IIX^7]" && tag[0] != "[^1IX^7]" && tag[0] != "[^1-X-^7]" + && tag[1] != "[^1VIP^7" && tag[1] != "^1[VIP" + && tag[1] != "[^2VIP^7") + { + second_blessing = 0; + blessingArrayRight[0] = "^1 LOCKED ^7"; + blessingArrayRight[1] = "Additionnal ^5blessing^7\n is reserved for\n ^3VIP & SSS ONLY^7"; + } + + self.zombieChoiceA.alpha = 1; + self.zombieChoiceAdesc.alpha = 1; + self.zombieChoiceLeft.alpha = 1; + self.zombieChoiceLeftDesc.alpha = 1; + self.zombieChoiceRight.alpha = 1; + self.zombieChoiceRightDesc.alpha = 1; + self.notifyiconb.alpha = 1; + self.notifyicon.alpha = 1; + self.notifyicon2b.alpha = 1; + self.notifyicon2.alpha = 1; + self.notifyiconA.alpha = 1; + self.notifyicon2a .alpha = 1; + + self.zombieChoiceA settext("^5Select your Blessing"); + self.zombieChoiceAdesc settext("^3Melee^5 to switch, ^3Use^5 to confirm^7\n ^3Jump^5 to reroll"); + self.zombieChoiceLeft settext("^3[^7" + blessingArrayLeft[0] + "^3]^7"); + self.zombieChoiceLeftDesc settext(blessingArrayLeft[1]); + self.zombieChoiceRight settext(blessingArrayRight[0]); + self.zombieChoiceRightDesc settext(blessingArrayRight[1]); + + cost = 20; + iteration = 0; + for (i = 0; i < 600; i++) // i < 600 + { + if (self meleeButtonPressed()) + { + if (selector == "left") + { + selector = "right"; + self.zombieChoiceRight settext("^3[^7" + blessingArrayRight[0] + "^3]^7"); + self.zombieChoiceLeft settext(blessingArrayLeft[0]); + wait 0.2; + } + else if (selector == "right") + { + selector = "left"; + self.zombieChoiceLeft settext("^3[^7" + blessingArrayLeft[0] + "^3]^7"); + self.zombieChoiceRight settext(blessingArrayRight[0]); + wait 0.2; + } + } + + if (self UseButtonPressed()) + { + if (selector == "left") + { + self thread applyBlessing(x); + for (i = 0; i < 10; i++) + { + playfx( level._effect["afterlife_teleport"], self.origin ); + } + self playsound( "zmb_quest_electricchair_spawn" ); + break; + } + else if (selector == "right" && second_blessing == 1) + { + self thread applyBlessing(y); + for (i = 0; i < 10; i++) + { + playfx( level._effect["afterlife_teleport"], self.origin ); + } + self playsound( "zmb_quest_electricchair_spawn" ); + break; + } + + } + if (self JumpButtonPressed()) + { + foreach(guid in level.premium_pass_guid_list) + { + if (self getguid() == guid) + { + if (iteration < 2) + cost = 0; + else if (iteration == 2) + cost = 10; + } + } + foreach(guid in level.premium_pass_guid_list2) + { + if (self getguid() == guid) + { + if (iteration < 2) + cost = 0; + else if (iteration == 2) + cost = 10; + } + } + iteration++; + + playerzcoin = int(getDvar("zcoins_" + self getGuid())); + if (playerzcoin - cost < 0) + { + self playsound("zmb_no_cha_ching"); + self iprintln("Out of ^5Z-Coins^7 !"); + wait 0.2; + continue; + } + self playsound("zmb_cha_ching"); + res = playerzcoin - cost; + setDvar("zcoins_" + self getGuid(), res); + if (cost == 0) + self iprintln("Used ^3Premium Pass^7 free reroll !"); + else + self iprintln("^5" + cost + " Z-Coins^3 used. Remaining ^5Z-Coins : " + getDvar("zcoins_" + self getGuid()) + "^7"); + cost = int(cost * 1.3); + wait 0.1; + + old_x = x; + old_y = y; + for (;;) + { + x = randomintrange(0, level.blessing_count); + if (x != 0 || (x == 0 && getdvar("isBigMacShown") == "0")) + { + if ((x == 4 || x == 1) && (tag[1] == "^6[VIP" || tag[1] == "[^6VIP^7" || tag[1] == "^1[VIP" || tag[1] == "[^1VIP^7" || tag[1] == "[^2VIP^7" || tag[1] == "^2[VIP^7")) + continue; + // if (x == old_x || x == old_y) + // continue; + else if (x != 0) + break; + } + wait 0.05; + } + blessingArrayLeft = blessingArray(x); + for (;;) + { + y = randomintrange(0, level.blessing_count); + if (y != x && (y != 0 || (y == 0 && getdvar("isBigMacShown") == "0"))) + { + if ((y == 4 || y == 1) && (tag[1] == "^6[VIP" || tag[1] == "[^6VIP^7" || tag[1] == "^1[VIP" || tag[1] == "[^1VIP^7" || tag[1] == "[^2VIP^7" || tag[1] == "^2[VIP^7")) + continue; + // if (y == old_x || y == old_y) + // continue; + else if (y != 0) + break; + } + wait 0.05; + } + blessingArrayRight = blessingArray(y); + selector = "left"; + self.zombieChoiceLeft settext("^3[^7" + blessingArrayLeft[0] + "^3]^7"); + self.zombieChoiceLeftDesc settext(blessingArrayLeft[1]); + self.zombieChoiceRight settext(blessingArrayRight[0]); + self.zombieChoiceRightDesc settext(blessingArrayRight[1]); + wait 0.2; + } + wait 0.05; + } + self.zombieChoiceLeft destroy(); + self.zombieChoiceRight destroy(); + self.zombieChoiceRightDesc destroy(); + self.zombieChoiceLeftDesc destroy(); + self.zombieChoiceAdesc destroy(); + self.zombieChoiceA destroy(); + self.zombieChoiceDown destroy(); + self.zombieChoiceDownDesc destroy(); + self.notifyicon destroy(); + self.notifyiconb destroy(); + self.notifyicon2 destroy(); + self.notifyicon2b destroy(); + self.notifyiconA destroy(); + self.notifyicon2a destroy(); + self.notifyicon3b destroy(); + self.notifyicon3 destroy(); + self.hasBlessing = 1; + maps\mp\_visionset_mgr::vsmgr_deactivate( "visionset", "zm_audio_log", self); +} + +applyBlessing(blessingNumber) +{ + if (blessingNumber == 0) + { + iprintln(self.name + " ^7picked ^3Glutton"); + self.noslow = 1; + self iPrintln("^3You can hear your ^5stomach growling^7!"); + } + else if (blessingNumber == 1) + { + iprintln(self.name + " ^7picked ^3Extra Life"); + self thread scripts\AATs_Perks::drawshader_and_shadermove( "Dying_Wish", 1, 1, "custom" ); + self iPrintln("^3It feels like ^5a guardian angel^3 is watching you^7 !"); + } + else if (blessingNumber == 2) + { + iprintln(self.name + " ^7picked ^3Magic weapon"); + weapon_loadout = self GetWeaponsListPrimaries(); + if (weapon_loadout.size >= 2) + self TakeWeapon(self GetCurrentWeapon()); + weapon_name = ""; + i = randomintrange(0, 100); + if (i >= 95) + weapon_name = "blundergat_zm"; + else if (i >= 90) + weapon_name = "raygun_mark2_zm"; + else if (i >= 60) + weapon_name = "lsat_zm"; + else if (i >= 30) + { + weapon_name = "blundergat_zm"; + if (level.gamemode_difficulty == "^1Chad^7" || level.gamemode_difficulty == "^6GigaChad^7") + weapon_name = "lsat_zm"; + } + else if (i >= 0) + weapon_name = "galil_zm"; + self GiveWeapon(weapon_name); + self SwitchToWeapon(weapon_name); + self iPrintln("^3A ^2magic weapon ^5suddenly materialized^3 in your hand!"); + } + else if (blessingNumber == 3) + { + iprintln(self.name + " ^7picked ^3Speedrunner"); + self.speedrunner = 1; + self SetMoveSpeedScale(1.15); + self iPrintln("^3You feel as ^5light as a feather!^7"); + } + else if (blessingNumber == 4) + { + iprintln(self.name + " ^7picked ^3Medic"); + self thread permaQuickRevive(); + self.perma_quick = 1; + self iPrintln("^3No team survives without a ^5Medic"); + } + else if (blessingNumber == 5) + { + iprintln(self.name + " ^7picked ^3Juggernaut"); + self iPrintln("^3You feel ^1bulkier"); + self.extrahp = 1; + } + else if (blessingNumber == 6) + { + iprintln(self.name + " ^7picked ^3Time Breaker"); + self thread in_plain_sight(); + } + else if (blessingNumber == 7) + { + iprintln(self.name + " ^7picked ^3Slayer"); + self.slayer_multiplier = 1; + } + else if (blessingNumber == 8) + { + iprintln(self.name + " ^7picked ^3Combat Medic"); + self.healer_multiplier = 1; + } + else if (blessingNumber == 9) + { + self.hawk_cd = 0.5; + self.loadout.hastomahawk = 1; + self giveweapon( "zombie_tomahawk_flourish" ); + self switchtoweapon( "zombie_tomahawk_flourish" ); + + self giveweapon( "bouncing_tomahawk_zm" ); + self set_player_tactical_grenade( "bouncing_tomahawk_zm" ); + self setclientfieldtoplayer( "tomahawk_in_use", 1 ); + + self thread watch_hawk_kill_count(); + self thread tomahawk_clear_guns(); + self thread tomahawk_watcher(); + } + if (blessingNumber != 4) + self thread noPermaQuickRevive(); +} + +tomahawk_watcher() +{ + self endon("disconnect"); + + for(;;) + { + if (self maps\mp\zombies\_zm_laststand::player_is_in_laststand()) + { + for(;;) + { + if (!(self maps\mp\zombies\_zm_laststand::player_is_in_laststand()) && (self.sessionstate != "spectator")) + { + if (self.kills > 15) + { + self takeweapon( "bouncing_tomahawk_zm" ); + self takeweapon( "upgraded_tomahawk_zm" ); + self.current_tomahawk_weapon = "upgraded_tomahawk_zm"; + self giveweapon( "upgraded_tomahawk_zm" ); + self set_player_tactical_grenade( "upgraded_tomahawk_zm" ); + self setclientfieldtoplayer( "upgraded_tomahawk_in_use", 1 ); + break; + } + else + { + self takeweapon( "bouncing_tomahawk_zm" ); + self takeweapon( "upgraded_tomahawk_zm" ); + self giveweapon( "bouncing_tomahawk_zm" ); + self set_player_tactical_grenade( "bouncing_tomahawk_zm" ); + self setclientfieldtoplayer( "tomahawk_in_use", 1 ); + break; + } + } + wait 0.1; + } + } + wait 0.1; + } +} + +watch_hawk_kill_count() +{ + self endon("disconnect"); + + lock = 0; + for(;;) + { + if (self.kills > 5 && lock == 0) + { + self.hawk_cd = 0.3; + self playsound( "zmb_easteregg_scream"); + for (i = 0; i < 10; i++) + { + playfx( level._effect["afterlife_teleport"], self.origin ); + } + lock = 1; + } + if (self.kills > 15 && lock == 1) + { + self.hawk_cd = 0.15; + self takeweapon( "bouncing_tomahawk_zm" ); + self set_player_tactical_grenade( "none" ); + maps\mp\_visionset_mgr::vsmgr_activate( "visionset", "zm_afterlife", self ); + self playsound( "zmb_easteregg_scream"); + for (i = 0; i < 10; i++) + { + playfx( level._effect["afterlife_teleport"], self.origin ); + } + + self.current_tomahawk_weapon = "upgraded_tomahawk_zm"; + self giveweapon( "upgraded_tomahawk_zm" ); + self set_player_tactical_grenade( "upgraded_tomahawk_zm" ); + self setclientfieldtoplayer( "upgraded_tomahawk_in_use", 1 ); + wait 0.2; + maps\mp\_visionset_mgr::vsmgr_deactivate( "visionset", "zm_afterlife", self ); + lock = 2; + } + if (self.kills > 70 && lock == 2) + { + self.hawk_cd = 0.01; + self playsound( "zmb_easteregg_scream"); + for (i = 0; i < 10; i++) + { + playfx( level._effect["afterlife_teleport"], self.origin ); + } + lock = 3; + } + wait 0.1; + } +} + +tomahawk_clear_guns() +{ + self endon("disconnect"); + + for(;;) + { + if (self GetCurrentWeapon() != "zombie_tomahawk_flourish" && self GetCurrentWeapon() != "spork_zm_alcatraz") + { + self giveweapon( "zombie_tomahawk_flourish" ); + self switchtoweapon( "zombie_tomahawk_flourish" ); + } + + wait 0.1; + } +} + +in_plain_sight() +{ + self endon("disconnect"); + cooldown = 60; + for (;;) + { + if (self MeleeButtonPressed()) + { + self EnableInvulnerability(); + self.ignoreme = 1; + maps\mp\_visionset_mgr::vsmgr_activate( "visionset", "zm_audio_log", self ); + self setclientthirdperson( 1 ); + for (i = 0; i < 10; i++) + { + playfx( level._effect["afterlife_teleport"], self.origin ); + } + self playsound( "zmb_quest_electricchair_spawn" ); + wait 5; + for (i = 0; i < 10; i++) + { + playfx( level._effect["afterlife_teleport"], self.origin ); + } + maps\mp\_visionset_mgr::vsmgr_deactivate( "visionset", "zm_audio_log", self); + self setclientthirdperson( 0 ); + self.ignoreme = 0; + self DisableInvulnerability(); + wait cooldown; + self iprintln("^3Time Breaker^7 - ^2READY"); + self iprintln("^3Time Breaker^7 - ^2READY"); + self iprintln("^3Time Breaker^7 - ^2READY"); + } + wait .05; + } +} + +drawshader( shader, x, y, width, height, color, alpha) +{ + level endon("end_game"); + self endon("disconnect"); + hud = newclienthudelem( self ); + hud.elemtype = "icon"; + hud.color = color; + hud.alpha = alpha; + hud.sort = 0; + hud.children = []; + hud.hidewheninmenu = 1; + hud setparent(level.uiparent); + hud setshader( shader, width, height ); + hud.x = x; + hud.y = y; + hud.foreground = 0; + return hud; +} + +spawn_brutus_cluster_side_shaped(amount) +{ + + /* + -455, -3907 -1333 / 10 + -1788, -3907 670 / 10 + -1788, -3237 +718 / 5 + -1070, -3237 +670 / 5 + -455, -3422 + + */ + if (getdvar("final_wave" == "1")) + wait 3; + setDvar("brutus_walk", "1"); + level.brutus_cluster = 1; + x_offset = 0; + y_offset = 0; + x = -455; + y = -3907; + lock = 0; + for (i = 0; i < amount; i++) + { + if (i == 6 || i == 8) + { + x_offset += -133.3; + continue; + } + level.brutus_last_spawn_round = -1; + ai = spawn_zombie( level.brutus_spawners[0] ); + ai.pos = (x + x_offset, y + y_offset, -8447.88); + ai thread brutus_spawn_custom(); + if (i < 10) + { + x_offset += -133.3; + } + else if (i < 20) + { + y_offset += 67; + x_offset = -1333; + } + else if (i < 25) + { + x_offset += 143.6; + y_offset = 670; + } + else + { + x = -455; + y = -3422; + x_offset = 0; + if (lock == 0) + { + lock = 1; + y_offset = 0; + + continue; + } + y_offset -= 134; + } + // wait .05; + } + level.brutus_cluster = 0; + setDvar("brutus_walk", "0"); + wait 3; + + if (getDvar("final_wave") != "1") + { + zombies = getaispeciesarray( "axis", "all" ); + foreach(zombie in zombies) + { + zombie set_zombie_run_cycle( "sprint" ); + } + } + +} + +spawn_brutus_cluster_cross_shaped() +{ +/* + -465 -3597 -1390 / 21 +-1855 -3597 + +-1073 -3252 -656 / 9 +-1073 -3908 +*/ + setDvar("brutus_walk", "1"); + level.brutus_cluster = 1; + x_offset = 0; + y_offset = 0; + x = -465; + y = -3597; + for (i = 0; i < 29; i++) + { + if (i == 4 || i == 5) + { + x_offset += -66.19; + continue; + } + level.brutus_last_spawn_round = -1; + ai = spawn_zombie( level.brutus_spawners[0] ); + ai.pos = (x + x_offset, y + y_offset, -8447.88); + ai thread brutus_spawn_custom(); + if (i < 21) + { + x = -465; + y = -3597; + x_offset += -66.19; + } + else + { + x = -1073; + y = -3252; + x_offset = 0; + y_offset += -72.888; + } + // wait .05; + } + level.brutus_cluster = 0; + setDvar("brutus_walk", "0"); + wait 3; + + zombies = getaispeciesarray( "axis", "all" ); + foreach(zombie in zombies) + { + zombie set_zombie_run_cycle( "sprint" ); + } +} + +spawn_brutus_cluster_u_shaped(x, y, x_inc, y_inc, x_cap, y_cap, type) +{ + level.brutus_cluster = 1; + x_offset = 0; + y_offset = 0; +/* + U shaped Spawn + -1211 -3330 + 47.7 to 334 + -32.9 to -527 +*/ + +/* + U shaped Spawn Chair + -1351 -3814 + -1780 -3814 x_cap = -429 / 7 + -1780 -3234 y_cap = -580 / 16 + -1351 -3234 x_cap = +429 / 7 + -61.3 to -429 + -36.25 to -580 +*/ + +/* + U shaped Spawn Dock + -979 -3416 x_cap = 510 / 7 + -469 -3416 y_cap = -499 / 16 + -469 -3915 + -979 -3915 + 72.85 to 510 + -31.18 to -499 +*/ + + for (i = 0; i < 29; i++) + { + level.brutus_last_spawn_round = -1; + ai = spawn_zombie( level.brutus_spawners[0] ); + ai.pos = (x + x_offset, y + y_offset, -8447.88); + ai thread brutus_spawn_custom(); + if (i < 7)// 7 side + x_offset += x_inc; + else if (i < 23) // 16 main + { + x_offset = x_cap; + y_offset -= y_inc; + } + else // 7 side + { + x_offset -= x_inc; + if (type == 1) + { + y_cap = -y_cap; + type = 0; + } + y_offset = y_cap; + } + // wait .05; + } + level.brutus_cluster = 0; + zombies = getaispeciesarray( "axis", "all" ); + foreach(zombie in zombies) + { + zombie set_zombie_run_cycle( "sprint" ); + } +} + +spawnBrutus() +{ + level endon ("game_ended"); + level waittill("start_of_round"); + + wait 25; + wave = 0; + delay = 2; + lock = 0; + checkpoint = 0; + wlock = 0; + level thread PlayEESong("mus_zmb_secret_song"); + for (;;) + { + if (wave >= 15) + setdvar("king_lock", "1"); + if (wave >= 4) + { + for (i = 0; i < level.players.size; i++) + { + if (level.players[i] HasPerk("specialty_fastreload") == 0) + { + level.players[i] iprintln("^3[ ^2Nikolai^3 ] ^7: Take a drink my friend. ^3Vodka^7 makes hands ^2faster!"); + level.players[i] thread maps\mp\zombies\_zm_perks::wait_give_perk("specialty_fastreload", 1); + } + } + } + if (wave >= 16) + { + for (i = 0; i < level.players.size; i++) + { + if (level.players[i] HasPerk("specialty_rof") == 0) + { + level.players[i] iprintln("^3[ ^2Dempsey^3 ] ^7: A ^5true Marine^7 knows his weapon by heart, ^3this^7 will pump up yours."); + level.players[i] thread maps\mp\zombies\_zm_perks::wait_give_perk("specialty_rof", 1); + } + } + } + zombies = getaispeciesarray( "axis", "all" ); + brutus_count = 0; + foreach (zombie in zombies) + { + if (zombie.animname == "brutus_zombie" && zombie.is_brutus == 1) + { + brutus_count++; + } + } + if (brutus_count <= 0) + { + wave++; + // if (wave >= 8) + // level thread SlowRandomPlayers(0.5); + setDvar("wave", wave); + delay -= 0.2; + //-------------------------------------------------------------------CHECKPOINTS + if (wave >= 10 && checkpoint == 0) + { + if (level.gamemode_difficulty == "^6GigaChad^7") + setDvar("EE_Completion", "BotB_Middle_GigaChad"); + else + setDvar("EE_Completion", "8"); + for (i = 0; i < level.players.size; i++) + { + if(level.players[i].sessionstate == "spectator") + { + level.players[i] thread Checkpoint(i); + } + } + checkpoint = 1; + setDvar("bold", "Checkpoint ^2reached!"); + wait 60; + } + if (wave >= 15 && checkpoint == 1) + { + for (i = 0; i < level.players.size; i++) + { + if(level.players[i].sessionstate == "spectator") + { + level.players[i] thread Checkpoint(i); + } + } + checkpoint = 2; + setDvar("bold", "Checkpoint ^2reached!"); + wait 60; + } + //-------------------------------------------------------------------WEAPONS + if (wave >= 5 && wlock == 0) + { + setdvar("bold", "^1[!]^7 New weapon : ^5" + weapon); + wait 5; + for (i = 0; i < level.players.size; i++) + { + r = RandomInt(3); + if (r == 1) + weapon = "dsr50_zm"; + else if (r == 2) + weapon = "tar21_zm"; + else + weapon = "mp5k_zm"; + + if (isAlive(level.players[i]) && !(isdefined(level.players[i].hawk_cd))) + { + weapon_loadout = level.players[i] GetWeaponsListPrimaries(); + if (weapon_loadout.size >= 2) + level.players[i] TakeWeapon(level.players[i] GetCurrentWeapon()); + level.players[i] GiveWeapon(weapon); + level.players[i] SwitchToWeapon(weapon); + } + } + wlock = 1; + } + if (wave >= 9 && wlock == 1) + { + r = RandomInt(4); + if (r == 1) + weapon = "uzi_zm"; + else if (r == 2) + weapon = "pdw57_zm"; + else if (r == 3) + weapon = "thompson_zm"; + else + weapon = "saiga12_zm"; + + setdvar("bold", "^1[!]^7 New weapon : ^5" + weapon); + wait 5; + for (i = 0; i < level.players.size; i++) + { + if (isAlive(level.players[i]) && !(isdefined(level.players[i].hawk_cd))) + { + weapon_loadout = level.players[i] GetWeaponsListPrimaries(); + if (weapon_loadout.size >= 2) + level.players[i] TakeWeapon(level.players[i] GetCurrentWeapon()); + level.players[i] GiveWeapon(weapon); + level.players[i] SwitchToWeapon(weapon); + } + } + wlock = 2; + } + if (wave >= 12 && wlock == 2) + { + r = RandomInt(3); + if (r == 1) + weapon = "lsat_zm"; + else if (r == 2) + weapon = "galil_zm"; + else + weapon = "ak47_zm"; + + level thread PlayEESong("mus_zmb_secret_song"); + setdvar("bold", "^1[!]^7 New weapon : ^5" + weapon); + wait 5; + for (i = 0; i < level.players.size; i++) + { + if (isAlive(level.players[i]) && !(isdefined(level.players[i].hawk_cd))) + { + weapon_loadout = level.players[i] GetWeaponsListPrimaries(); + if (weapon_loadout.size >= 2) + level.players[i] TakeWeapon(level.players[i] GetCurrentWeapon()); + level.players[i] GiveWeapon(weapon); + level.players[i] SwitchToWeapon(weapon); + } + } + wlock = 3; + } + if (wave >= 16 && wlock == 3) + { + r = RandomInt(100); + if (r > 95) + weapon = "blundergat_zm"; + else + weapon = "minigun_alcatraz_zm"; + setdvar("bold", "^1[!]^7 New weapon : ^5" + weapon); + wait 5; + level thread PlayEESong( "mus_zmb_secret_song_2"); + + for (i = 0; i < level.players.size; i++) + { + if (isAlive(level.players[i]) && !(isdefined(level.players[i].hawk_cd))) + { + weapon_loadout = level.players[i] GetWeaponsListPrimaries(); + if (weapon_loadout.size >= 2) + level.players[i] TakeWeapon(level.players[i] GetCurrentWeapon()); + level.players[i] GiveWeapon(weapon); + level.players[i] SwitchToWeapon(weapon); + } + } + wlock = 4; + } + /* if (wave == 19 && wlock == 4) + { + for (i = 0; i < level.players.size; i++) + { + if (isAlive(level.players[i])) + { + weapon_loadout = level.players[i] GetWeaponsListPrimaries(); + if (weapon_loadout.size >= 2) + level.players[i] TakeWeapon(level.players[i] GetCurrentWeapon()); + level.players[i] GiveWeapon("blundergat_zm"); + level.players[i] SwitchToWeapon("blundergat_zm"); + } + } + wlock = 5; + }*/ + if (wave <= 2) + { + setDvar("brutus_walk", "1"); + } + else + { + setDvar("brutus_walk", "0"); + } + if (wave >= 3 && lock == 0) + { + setDvar("ln", "^3[ " + level.boss_name + " ]^7 : ^3You thought it was going to be that easy ? ^1Make them dance"); + lock = 1; + } + if (wave >= 5 && lock == 1) + { + setDvar("ln", "^3[ " + level.boss_name + " ]^7 : Do you think you stand a chance ? Boys, ^3helmets on^7 !!"); + setDvar("brutus_helmet", "1"); + lock = 2; + } + if (wave >= 10 && wave <= 11 && lock == 2) + { + setDvar("ln", "^3[ " + level.boss_name + " ]^7 : ^5Ninja Brutus^7,^3 Your numbers are on!"); + setDvar("ninjaBrutus", "1"); + lock = 3; + } + if (wave != 10 && wave != 11) + setDvar("ninjaBrutus", "0"); + if (wave >= 12 && lock == 3) + { + setDvar("ln", "^3[ " + level.boss_name + " ]^7 : Let's ^2speed^7 things up"); + setDvar("brutus_sprint", "1"); + lock = 4; + } + if (wave >= 14 && lock == 4) + { + setDvar("ln", "^3[ " + level.boss_name + " ]^7 : Spread up ^3boys !"); + lock = 5; + } + if (wave >= 15 && lock == 5) + { + if (level.gamemode_difficulty == "^1Chad^7") + { + setDvar("brutus_oneshot", "1"); + setDvar("ln", "^3[ " + level.boss_name + " ]^7 : Get closer to us again^7, ^1see what happens ^7!"); + level thread PlayEESong( "mus_zmb_secret_song_2"); + } + wait 20; + lock = 6; + } + if (wave == 20 && lock == 6) + { + level.final_wave = 1; + lock = 7; + color = "^6"; + setDvar("color", color); + setDvar("ln", "^3[ " + level.boss_name + " ]^7 : I see you managed to defeat my ^3minions^7, however your ^5hopes^7 ends ^1now^7."); + wait 11; + setDvar("ln", "^3[ " + level.boss_name + " ]^7 : Bring it on, ^3I'll take all of you on^7 by ^1myself"); + wait 14; + + foreach ( player in level.players ) + maps\mp\_visionset_mgr::vsmgr_activate( "visionset", "zm_audio_log", player ); + + level thread RespawnWatcher(); + level thread LoopEESong(); + /* if(level.gamemodedifficulty == "^1Chad^7") + level thread SpawnSmoke(15); + else + level thread SpawnSmoke(3);*/ + level thread SlowPlayers(0.4); + setDvar("final_wave", "1"); + setDvar("brutus_oneshot", "1"); + wait 2; + level notify( "spawn_brutus", 1 ); + wait 3; + if (level.gamemode_difficulty == "^6GigaChad^7") + level thread boss_phase(); + for (;;) + { + zombies = getaispeciesarray( "axis", "all" ); + for (i = 0; i < zombies.size; i++) + { + if (isdefined(zombies[i].is_brutus)) + { + level.boss = zombies[i]; + zombies[i].is_boss = 1; + foreach(player in level.players) + { + player thread healthbarboss(); + } + level.boss thread player_too_close_watcher(); + return; + } + } + wait 0.1; + } + } + + level.brutus_last_spawn_round = -1; + + if (level.gamemode_difficulty == "^6GigaChad^7") + { + if (wave > 14 && wave % 2 == 0 && wave != 20) + setDvar("ninjaBrutus", "1"); + else + setDvar("ninjaBrutus", "0"); + if (wave == 1 || wave == 6 || wave == 11 || wave == 16) + level thread spawn_brutus_cluster_u_shaped(-1211, -3330, 47.7, 32.9, 334, -527, 0); + if (wave == 2 || wave == 7 || wave == 12 || wave == 17) + level thread spawn_brutus_cluster_u_shaped(-1351, -3814, -61.3, -36.25, -429, -580, 1); + if (wave == 3 || wave == 8 || wave == 13 || wave == 18) + level thread spawn_brutus_cluster_u_shaped(-979, -3416, 72.85, 31.18, 510, -499, 0); + if (wave == 4 || wave == 9 || wave == 14 || wave == 18) + level thread spawn_brutus_cluster_cross_shaped(); + if (wave == 5 || wave == 10 || wave == 15 || wave == 19) + level thread spawn_brutus_cluster_side_shaped(29); + for (;;) + { + brutus_count = 0; + zombies = getaispeciesarray( "axis", "all" ); + foreach (zombie in zombies) + { + if (isdefined(zombie.is_brutus) && zombie.is_brutus == 1) + { + brutus_count++; + } + } + if (brutus_count <= 0) + break; + wait 3; + } + + } + for (i = 0; i < (wave * 2) + level.extra_brutus; i++) + { + for (;;) + { + zombies = getaispeciesarray( "axis", "all" ); + if (zombies.size < 18) + break; + wait 1; + } + if (delay < 0.4) + delay = 0.4; + x = randomintrange(0, 15); + if (x == 9 && wave >= 14) + { + setDvar("brutus_walk", "1"); + ai = spawn_zombie( level.brutus_spawners[0] ); + ai thread brutus_spawn_custom(); + // level notify( "spawn_brutus", 1 ); + wait 0.1; + setDvar("brutus_walk", "0"); + } + else if ((x == 8 || x == 7) && wave >= 14) + { + setDvar("ninjaBrutus", "1"); + setDvar("brutus_walk", "1"); + ai = spawn_zombie( level.brutus_spawners[0] ); + ai thread brutus_spawn_custom(); + // level notify( "spawn_brutus", 1 ); + wait 0.1; + setDvar("ninjaBrutus", "0"); + setDvar("brutus_walk", "0"); + } + else + { + ai = spawn_zombie( level.brutus_spawners[0] ); + ai thread brutus_spawn_custom(); + // level notify( "spawn_brutus", 1 ); + } + wait delay; + } + + } + wait 3; + } +} + +boss_phase() +{ + level endon("game_ended"); + + wait 5; + boss_stage = 0; + for (;;) + { + if (level.intermission == 1) + { + return; + } + if (boss_stage == 0 && level.boss.health < (level.boss.maxhealth - (level.boss.maxhealth / 3))) + { + iprintln("^3[" + level.boss_name + "]^7 : Brutes, ^1COVER ME !^7"); + level.is_adds = 1; + level thread spawn_brutus_cluster_side_shaped(10); + level.is_adds = 0; + boss_stage = 1; + } + if (boss_stage == 1 && level.boss.health < level.boss.maxhealth / 3) + { + iprintln("^3[" + level.boss_name + "]^7 : Brutes, ^1COVER ME !^7"); + level.is_adds = 1; + level thread spawn_brutus_cluster_side_shaped(20); + level.is_adds = 0; + boss_stage = 2; + } + wait 0.1; + } +} + +player_too_close_watcher() +{ + for (;;) + { + foreach(player in level.players) + { + if (distance(player.origin, self.origin) < 120) + { + foreach(index, ignored_player in self.ignoreplayer) + { + if (ignored_player == player) + { + self.ignoreplayer[index] = undefined; + wait 3; + self.ignoreplayer[index] = player; + } + } + + } + } + wait 0.1; + } +} + +LoopEESong() +{ + level endon ("game_ended"); + for (;;) + { + level thread PlayEESong( "mus_zmb_secret_song_2"); + wait 140; + } +} + +RespawnWatcher() +{ + level endon ("game_ended"); + setdvar( "player_lastStandBleedoutTime", "0" ); +} + +SpawnSmoke(seconds) +{ + level endon( "game_ended" ); + + for (;;) + { + if (isdefined(level.jammer)) + return; + if (getDvar("game_end") == "1") + return; + alive_player = 0; + for (i = 0; i < level.players.size; i++) + { + v_org_left = level.players[i] gettagorigin( "TAG_WEAPON_LEFT" ); + v_org_right = level.players[i] gettagorigin( "TAG_WEAPON_RIGHT" ); + level.players[i] thread sndplaydelayedsmokeaudio( v_org_left, v_org_right ); + level.players[i] magicgrenadetype( "willy_pete_zm", v_org_left, ( 0, 0, 0 ), 0.4 ); + level.players[i] magicgrenadetype( "willy_pete_zm", v_org_right, ( 0, 0, 0 ), 0.4 ); + + if (!(level.players[i].sessionstate == "spectator")) + { + alive_player++; + } + } + wait seconds; + } +} + +SlowRandomPlayers(ms) +{ + level endon( "game_ended" ); + + alive_player = 0; + for (i = 0; i < level.players.size; i++) + { + if (!(level.players[i].sessionstate == "spectator")) + { + alive_player++; + } + } + + for (i = 0; i < level.players.size; i++) + { + if (alive_player > 1 && !(level.players[i].sessionstate == "spectator") && getdvar("final_wave") != "1") + { + if (isdefined(level.players[i].speedrunner)) + level.players[i] SetMoveSpeedScale(1.20 + level.extra_speed); + else + level.players[i] SetMoveSpeedScale(1.05 + level.extra_speed); + } + } + + slowed_players = 0; + if (alive_player <= 3) + { + slowed_players = 1; + setDvar("slowed_player2", "-1"); + } + else if (alive_player > 3) + slowed_players = 2; + slowed_player1 = int(getdvar("slowed_player1")); + slowed_player2 = int(getdvar("slowed_player2")); + + for (i = 0; i < slowed_players; i++) + { + for (f = 0; f < 1000; f++) + { + x = randomintrange(0, alive_player); + if (x != slowed_player1 && x != slowed_player2) + { + break; + } + } + /* if (alive_player <= 1) + { + for (j = 0; j < level.players.size; j++) + { + if (!(level.players[j].sessionstate == "spectator")) + { + level.players[j] SetMoveSpeedScale(0.2); + } + } + } + else + { */ + w = 0; + for (k = 0; k < level.players.size; k++) + { + if (!(level.players[k].sessionstate == "spectator")) + { + if (w == x) + { + if (i == 0) + { + slowed_player1 = k; + setdvar("slowed_player1", k); + } + if (i == 1) + { + slowed_player2 = k; + setdvar("slowed_player2", k); + } + if (level.players[k].noslow && level.players[k].noslow == 1) + { + level.players[k] iPrintln("^3You ate ^1A LOT of ^3BigMacs^3 but it ^2barely filled up your belly :)"); + break; + } + else + { + if (isdefined(level.players[k].speedrunner)) + { + level.players[k] SetMoveSpeedScale(ms + 0.2); + level.players[k] iPrintln("^1You ate too many ^3Big Macs ^2 but you are still speedy!"); + } + else + { + level.players[k] SetMoveSpeedScale(ms); + level.players[k] iPrintln("^1You ate too many ^3Big Macs"); + } + break; + } + } + w++; + } + } + //} + } +} + +SlowPlayers(ms) +{ + level endon( "game_ended" ); + + for (;;) + { + for (i = 0; i < level.players.size; i++) + { + if (isdefined(level.players[i].speedrunner)) + level.players[i] SetMoveSpeedScale(ms + 0.1); + else + level.players[i] SetMoveSpeedScale(ms); + } + wait 0.5; + if (getdvar("game_end") == "1") + break; + } +} + +PlayEESong(song) +{ + level endon ("game_ended"); + level.music_override = 1; + playsoundatposition( song, ( 0, 0, 0 ) ); + wait 140; + level.music_override = 0; +} + +CheckPoint(i) +{ + self endon ("disconnect"); + self.origin = (10000, 10000, 10000 + 100 * i); + // self.spectator_respawn = 1; + self [[ level.spawnplayer ]](); + wait 0.1; + // self.spectator_respawn = undefined; + self thread TpToCell(i); + //self TakeAllWeapons(); + wait 10; + self iprintln("^3[ ^2Kiels^3 ]^7 : It is ^3too soon^7 for you to die, ^5get ready soldier"); + wait 6; + self thread TpToBridge(i); + + foreach(guid in level.premium_pass_guid_list) + { + if (self getguid() == guid && !(isdefined(self.hawk_cd))) + { + self giveweapon("ak47_upgraded_zm", 0, self maps\mp\zombies\_zm_weapons::get_pack_a_punch_weapon_options( "ak47_upgraded_zm" ) ); + self SwitchToWeapon("ak47_upgraded_zm"); + return; + } + } + foreach(guid in level.premium_pass_guid_list2) + { + if (self getguid() == guid && !(isdefined(self.hawk_cd))) + { + self giveweapon("ak47_upgraded_zm", 0, self maps\mp\zombies\_zm_weapons::get_pack_a_punch_weapon_options( "ak47_upgraded_zm" ) ); + self SwitchToWeapon("ak47_upgraded_zm"); + return; + } + } + group = 0; + tag = strTok(self, "]"); + if (tag[0] == "[^3SSS^7" || tag[0] == "[^6 I ^7" || tag[0] == "[^6II^7"|| tag[0] == "[^6III^7" + || tag[1] == "[^3VIP^7" || tag[1] == "^3[VIP" || tag[1] == "^6[VIP" || tag[1] == "[^6VIP^7" + || tag[0] == "[^5IV^7" || tag[0] == "[^5V^7" || tag[0] == "[^5VI^7" || tag[0] == "[^5VII^7" + || tag[0] == "[^1IIX^7]" || tag[0] == "[^1IX^7]" || tag[0] == "[^1-X-^7]") + { + group = 3; + } + else if (tag[0] == "[^9F^7" || tag[0] == "[^8E^7" || tag[0] == "[^4C^7" || tag[0] == "[^2D^7" || tag[0] == "[^5B^7" ) + { + group = 1; + } + else if (tag[0] == "[^6A^7" || tag[0] == "[^3S^7" ) + { + group = 2; + } + + if (group == 1) + { + self GiveWeapon("m14_zm"); + self SwitchToWeapon("m14_zm"); + } + else if (group == 2) + { + self GiveWeapon("beretta93r_zm"); + self SwitchToWeapon("beretta93r_zm"); + } + else if (group == 3) + { + self GiveWeapon("thompson_zm"); + self SwitchToWeapon("thompson_zm"); + } +} + +TpToBridge(id) +{ + level endon ("game_ended"); + self endon("disconnect"); + + level.on_bridge = 1; + if (id == 0) + { + origin = (-1061.06, -3448.74, -8447.88); + angle = (1.59851, 267.896, 0); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 1) + { + origin = (-1072, -3686.39, -8447.88); + angle = (8.255, 84.9902, 0); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 2) + { + origin = (-973.846, -3553.86, -8444.87); + angle = (0.961304, 179.572, 0); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 3) + { + origin = (-1156.97, -3543.47, -8447.88); + angle = (358.588, 357.303, 0); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 4) + { + origin = (-1125.43, -3483.31, -8447.88); + angle = (7.206, 306.392, 0); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 5) + { + origin = (-1009.49, -3635.56, -8447.88); + angle = (19.3018, 128.09, 0); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 6) + { + origin = (-1007.36, -3489.46, -8440.38); + angle = (11.3104, 222.435, 0); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 7) + { + origin = (-1149.47, -3608.69, -8447.88); + angle = (359.517, 34.8706, 0); + self setOrigin(origin); + self SetPlayerAngles(angle); + } +} + +TpToCell(id) +{ + level endon ("game_ended"); + self endon("disconnect"); + + maps\mp\_visionset_mgr::vsmgr_deactivate( "visionset", "zm_audio_log", self); + angle = (6.66, 89.65, 0); + if (id == 0) + { + origin = (1004.46, 10372.1, 1440.13); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 1) + { + origin = (1726.43, 10392.3, 1336.13); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 2) + { + origin = (832.784, 10391.3, 1440.13); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 3) + { + origin = (1650.3, 10375.5, 1455.13); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 4) + { + origin = (1724.79, 10372.2, 1440.13); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 5) + { + origin = (1155.6, 10380.4, 1544.13); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 6) + { + origin = (1390.07, 10355.8, 1544.13); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 7) + { + origin = (1316.04, 10346.8, 1440.13); + self setOrigin(origin); + angle = (8.22876, 85.7813, 0); + self SetPlayerAngles(angle); + } + + wait 2; + if (level.game_started == 0) + { + self thread difficulty_selector(); + } + +} + +brutus_stuck_teleport_custom() +{ + self endon( "death" ); + + if (check_for_botb_port() == true) + return; + + + align_struct = spawn( "script_model", self.origin ); + align_struct.angles = self.angles; + align_struct setmodel( "tag_origin" ); + + if ( !level.brutus_in_grief && ( self istouching( level.e_gondola.t_ride ) || isdefined( self.force_gondola_teleport ) && self.force_gondola_teleport ) ) + { + self.force_gondola_teleport = 0; + align_struct linkto( level.e_gondola ); + self linkto( align_struct ); + } + + self.not_interruptable = 1; + playfxontag( level._effect["brutus_spawn"], align_struct, "tag_origin" ); + self animscripted( self.origin, self.angles, "zm_taunt" ); + self maps\mp\animscripts\zm_shared::donotetracks( "taunt_anim" ); + self.not_interruptable = 0; + self ghost(); + self notify( "brutus_cleanup" ); + self notify( "brutus_teleporting" ); + + if ( isdefined( align_struct ) ) + align_struct delete(); + + if ( isdefined( self.sndbrutusmusicent ) ) + { + self.sndbrutusmusicent delete(); + self.sndbrutusmusicent = undefined; + } + + if ( isdefined( level.brutus_respawn_after_despawn ) && level.brutus_respawn_after_despawn ) + { + b_no_current_valid_targets = are_all_targets_invalid(); + level thread maps\mp\zombies\_zm_ai_brutus::respawn_brutus( self.health, self.has_helmet, self.helmet_hits, self.explosive_dmg_taken, self.force_zone, b_no_current_valid_targets ); + } + + level.brutus_count--; + self delete(); +} + +brutus_spawn_custom( starting_health, has_helmet, helmet_hits, explosive_dmg_taken, zone_name ) +{ + level.num_pulls_since_brutus_spawn = 0; + self set_zombie_run_cycle( "run" ); + if (getdvar("ninjaBrutus") == "1") + self ghost(); + if (getDvar("brutus_walk") == "1") + { + self set_zombie_run_cycle( "walk" ); + self.is_walking = 1; + } + + else if (getDvar("brutus_sprint") == "1") + self set_zombie_run_cycle( "sprint" ); + self.has_helmet = 0; + if (getDvar("brutus_helmet") == "1") + { + r = randomint(100); + //if (r > 80) + self.has_helmet = 1; + } + + self.helmet_hits = 5; + self.explosive_dmg_taken = 0; + self.meleedamage = 340; + if (getDvar("brutus_oneshot") == "1") + { + self.meleedamage = 450; + } + if (isdefined(level.gamemode_difficulty) && level.gamemode_difficulty == "^6GigaChad^7") + self.meleedamage = 450; + + if (check_for_botb_port() == false) + self brutus_health_increases(); + if (level.gamemode_difficulty == "^6GigaChad^7") + level.brutus_health += level.brutus_health_increase_custom; + else + self brutus_health_increases_customized(); + self.maxhealth = level.brutus_health; + self.health = level.brutus_health; + if (isdefined(level.beefy_brutus)) + { + self.maxhealth *= 1.2; + self.health *= 1.2; + } + + if (isdefined(level.is_adds) && level.is_adds == 1) + { + self.maxhealth = self.maxhealth * 1.25; + self.health = self.maxhealth; + self.meleedamage = 9999; + } + + self.custom_item_dmg = 1000; + if (getDvar("final_wave") == "1" && getDvar("lock") == "0") + { + setDvar("lock", "1"); + self.is_boss = 1; + self.maxhealth = 250000; + self.health = self.maxhealth; + self.meleedamage = 999; + if (isdefined(level.gamemode_difficulty) && level.gamemode_difficulty == "^1Chad^7") + { + self.meleedamage = 999999; + self.maxhealth = 550000; + self.health = self.maxhealth; + self.custom_item_dmg = 1000000; + } + if (isdefined(level.gamemode_difficulty) && level.gamemode_difficulty == "^6GigaChad^7") + { + self.meleedamage = 999999; + self.maxhealth = 1100000; + self.health = self.maxhealth; + self.custom_item_dmg = 1000000; + } + } + self.explosive_dmg_req = level.brutus_expl_dmg_req; + self.no_damage_points = 1; + self endon( "death" ); + level endon( "intermission" ); + self.animname = "brutus_zombie"; + self.audio_type = "brutus"; + self.has_legs = 1; + self.ignore_all_poi = 1; + self.is_brutus = 1; + self.ignore_enemy_count = 1; + self.instakill_func = ::brutus_instakill_override; + self.nuke_damage_func = ::brutus_nuke_override; + self.melee_anim_func = ::melee_anim_func; + self.brutus_lockdown_state = 0; + recalc_zombie_array(); + self setphysparams( 20, 0, 60 ); + self.zombie_init_done = 1; + self notify( "zombie_init_done" ); + self.allowpain = 0; + self animmode( "normal" ); + self orientmode( "face enemy" ); + self maps\mp\zombies\_zm_spawner::zombie_setup_attack_properties(); + self setfreecameralockonallowed( 0 ); + level thread maps\mp\zombies\_zm_spawner::zombie_death_event( self ); + self thread maps\mp\zombies\_zm_spawner::enemy_death_detection(); + + if (getDvar("noShake") == "1" && getdvar("ninjaBrutus") != "1" && getDvar("final_wave") != "1" && isdefined(level.gamemode_difficulty) && level.gamemode_difficulty == "^6GigaChad^7") + self ghost(); + else if (getDvar("noShake") == "1" && getdvar("ninjaBrutus") != "1" && getDvar("final_wave") != "1") + self thread addBrutusModel(); + + zone_name = "zone_golden_gate_bridge"; + spawn_pos = get_random_brutus_spawn_pos( zone_name ); + + if (isdefined(level.brutus_cluster) && level.brutus_cluster == 1) + { + spawn_pos.origin = self.pos; + } + else if (check_for_botb_port() == true) + { + x = randomintrange(0, 3); + if (isdefined(level.brutus_new_spawns)) + { + if (x == 0) + spawn_pos.origin = (-1213, -3267, -8447.88); + if (x == 1) + spawn_pos.origin = (-926, -3798, -8447.88); + if (x == 2) + spawn_pos.origin = (-1684, -3801, -8447.88); + + + + } + else + { + if (x == 0) + spawn_pos.origin = (-494.192, -3600.21, -8447.88); + if (x == 1) + spawn_pos.origin = (-1745.74, -3587.59, -8447.88); + if (x == 2) + spawn_pos.origin = (-980.373, -3590.95, -8447.88); + } + + } + + if ( !isdefined( spawn_pos ) ) + { + self delete(); + return; + } + + if ( !isdefined( spawn_pos.angles ) ) + spawn_pos.angles = ( 0, 0, 0 ); + + // if ( isdefined( level.brutus_do_prologue ) && level.brutus_do_prologue ) + // self brutus_spawn_prologue( spawn_pos ); + + if ( !self.has_helmet ) + self detach( "c_zom_cellbreaker_helmet" ); + + level.brutus_count++; + self maps\mp\zombies\_zm_spawner::zombie_complete_emerging_into_playable_area(); + self thread snddelayedmusic(); + self thread brutus_death(); + self thread brutus_check_zone(); + self thread brutus_watch_enemy(); + self forceteleport( spawn_pos.origin, spawn_pos.angles ); + self.cant_melee = 1; + self.not_interruptable = 1; + self.actor_damage_func = ::brutus_damage_override; + self.non_attacker_func = ::brutus_non_attacker_damage_override; + //self thread brutus_lockdown_client_effects( 999999999 ); + playfx( level._effect["brutus_spawn"], self.origin ); + playsoundatposition( "zmb_ai_brutus_spawn", self.origin ); + if (isdefined(level.gamemode_difficulty) && level.gamemode_difficulty != "^6GigaChad^7") + { + self animscripted( spawn_pos.origin, spawn_pos.angles, "zm_spawn" ); + self thread maps\mp\animscripts\zm_shared::donotetracks( "spawn_anim" ); + + self waittillmatch( "spawn_anim", "spawn_complete" ); + } + + self.not_interruptable = 0; + self.cant_melee = 0; + self thread brutus_chest_flashlight(); + self thread brutus_find_flesh(); + self thread maps\mp\zombies\_zm_spawner::delayed_zombie_eye_glow(); + level notify( "brutus_spawned", self ); + if (getDvar("final_wave") == "1" && isdefined(self.is_boss) && isdefined(level.gamemode_difficulty) && (level.gamemode_difficulty == "^1Chad^7" || level.gamemode_difficulty == "^6GigaChad^7")) + { + self thread target_selector(); + } +} + +brutus_health_increases_customized() +{ + if ( level.round_number > level.brutus_last_spawn_round ) + { + a_players = getplayers(); + n_player_modifier = 1; + + if (a_players.size >= 6) + n_player_modifier = 6 * 0.75; + else if ( a_players.size > 1 ) + n_player_modifier = a_players.size * 0.75; + + level.brutus_round_count++; + level.brutus_health = int( level.brutus_health_increase * n_player_modifier * level.brutus_round_count ); + level.brutus_expl_dmg_req = int( level.brutus_explosive_damage_increase * n_player_modifier * level.brutus_round_count ); + + if ( level.brutus_health >= 7000 * n_player_modifier ) + level.brutus_health = int( 7000 * n_player_modifier ); + + if ( level.brutus_expl_dmg_req >= 4500 * n_player_modifier ) + level.brutus_expl_dmg_req = int( 4500 * n_player_modifier ); + + level.brutus_last_spawn_round = level.round_number; + } +} + +target_selector() +{ + wait 2; + + rand = 0; + for (;;) + { + for (;;) + { + rand = randomintrange(0, level.players.size); + if (level.players[rand].sessionstate != "spectator") + { + self.favoriteenemy = level.players[rand]; + tag = strtok(level.players[rand].name, "]"); + if (isdefined(tag[3])) + player_name = tag[3]; + else if (isdefined(tag[2])) + player_name = tag[2]; + else if (isdefined(tag[1])) + player_name = tag[1]; + else if (isdefined(tag[0])) + player_name = tag[0]; + rand2 = randomintrange (0, 3); + if (rand2 == 0) + iprintln("^3[ " + level.boss_name + " ]^7 : " + player_name + "^7, I'm coming for ^1you^7"); + if (rand2 == 1) + iprintln("^3[ " + level.boss_name + " ]^7 : " + "You're ^1next^7 " + player_name); + if (rand2 == 2) + iprintln("^3[ " + level.boss_name + " ]^7 : " + "Do you think you're ^1safe^7 " + player_name + " ^7?"); + self.ignore_player = []; + for(i = 0; i < level.players.size; i++) + { + if (i == rand) + continue; + self.ignore_player[self.ignore_player.size] = level.players[i]; + } + break; + } + wait 0.1; + } + for (i = 0 ; i < 7 ; i++) + { + if (level.players[rand].sessionstate == "spectator") + { + break; + } + self.favoriteenemy = level.players[rand]; + wait 3; + } + wait 1; + } +} + +// the part where i prove mr elmaasarawy12 that i'm lucky this time :) +addBrutusModel() +{ + self ghost(); + self.fakeBrutus = spawn( "script_model", self.origin ); + self.fakeBrutus setmodel( "c_zom_cellbreaker_fb" ); + self.fakeBrutus linkto( self, "J_SpineLower", (-48.7, 4, 0), (180, -90, -90)); + + if (self.has_helmet) + { + self.fakeHat = spawn( "script_model", self.origin ); + self.fakeHat setmodel( "c_zom_cellbreaker_fb" ); + self.fakeHat linkto( self, "J_SpineLower", (-48.7, 4, 0), (180, -90, -90)); + self.fakeHat attach( "c_zom_cellbreaker_helmet" ); + for (;;) + { + if (self && self.has_helmet == 0) + { + if (self && self.fakeHat) + self.fakeHat delete(); + break; + } + wait 0.1; + } + } + self waittill( "brutus_cleanup" ); + if (self && self.fakeBrutus) + self.fakeBrutus delete(); +} \ No newline at end of file diff --git a/t6/scripts/zm/zm_prison/item_watcher.gsc b/t6/scripts/zm/zm_prison/item_watcher.gsc new file mode 100644 index 0000000..9e5d7bb --- /dev/null +++ b/t6/scripts/zm/zm_prison/item_watcher.gsc @@ -0,0 +1,53 @@ +init() +{ + wait 1; + if (check_for_botb_port() == true || getdvar("net_port") == "30011" || getdvar("net_port") == "30001") + return; + level thread check_for_equipment(); + setdvar("upgraded_tomahawk", "0"); + setdvar("golden_spork", "0"); +} + +check_for_equipment() +{ + level waittill("start_of_round"); + for(;;) + { + foreach(player in level.players) + { + if (player hasweapon("spork_zm_alcatraz") && !isdefined(player.has_spork)) + { + setdvar("golden_spork", player getguid()); + player iprintln("^3Golden Spoon^7 challenge ^2completed^7 !"); + player iprintln("^3Golden Spoon^7 challenge ^2completed^7 !"); + player iprintln("^3Golden Spoon^7 challenge ^2completed^7 !"); + player.has_spork = 1; + } + if (player hasweapon( "upgraded_tomahawk_zm") && !isdefined(player.has_hawk)) + { + setdvar("upgraded_tomahawk", player getguid()); + player iprintln("^5Upgraded Tomahawk^7 challenge ^2completed^7 !"); + player iprintln("^5Upgraded Tomahawk^7 challenge ^2completed^7 !"); + player iprintln("^5Upgraded Tomahawk^7 challenge ^2completed^7 !"); + player.has_hawk = 1; + } + } + wait 1; + } +} + +check_for_botb_port() +{ + found = 0; + if (isdefined(level.net_port_botb)) + { + foreach(port in level.net_port_botb) + { + if (getdvar("net_port") == port) + found = 1; + } + } + if (found == 0) + return false; + return true; +} \ No newline at end of file diff --git a/t6/scripts/zm/zm_prison/motd_perk_back.gsc b/t6/scripts/zm/zm_prison/motd_perk_back.gsc new file mode 100644 index 0000000..d8d8fb2 --- /dev/null +++ b/t6/scripts/zm/zm_prison/motd_perk_back.gsc @@ -0,0 +1,672 @@ +#include maps\mp\_utility; +#include common_scripts\utility; +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\gametypes_zm\_spawnlogic; +#include maps\mp\animscripts\traverse\shared; +#include maps\mp\animscripts\utility; +#include maps\mp\zombies\_load; +#include maps\mp\_createfx; +#include maps\mp\_music; +#include maps\mp\_busing; +#include maps\mp\_script_gen; +#include maps\mp\gametypes_zm\_globallogic_audio; +#include maps\mp\gametypes_zm\_tweakables; +#include maps\mp\_challenges; +#include maps\mp\gametypes_zm\_weapons; +#include maps\mp\_demo; +#include maps\mp\gametypes_zm\_hud_message; +#include maps\mp\gametypes_zm\_spawning; +#include maps\mp\gametypes_zm\_globallogic_utils; +#include maps\mp\gametypes_zm\_spectating; +#include maps\mp\gametypes_zm\_globallogic_spawn; +#include maps\mp\gametypes_zm\_globallogic_ui; +#include maps\mp\gametypes_zm\_hostmigration; +#include maps\mp\gametypes_zm\_globallogic_score; +#include maps\mp\gametypes_zm\_globallogic; +#include maps\mp\zombies\_zm; +#include maps\mp\zombies\_zm_ai_faller; +#include maps\mp\zombies\_zm_spawner; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\zombies\_zm_pers_upgrades; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\animscripts\zm_run; +#include maps\mp\animscripts\zm_death; +#include maps\mp\zombies\_zm_blockers; +#include maps\mp\animscripts\zm_shared; +#include maps\mp\animscripts\zm_utility; +#include maps\mp\zombies\_zm_ai_basic; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\zombies\_zm_net; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\gametypes_zm\_zm_gametype; +#include maps\mp\_visionset_mgr; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm_power; +#include maps\mp\zombies\_zm_server_throttle; +#include maps\mp\gametypes\_hud_util; +#include maps\mp\zombies\_zm_unitrigger; +#include maps\mp\zombies\_zm_zonemgr; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm_melee_weapon; +#include maps\mp\zombies\_zm_audio_announcer; +#include maps\mp\zombies\_zm_magicbox; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_ai_dogs; +#include maps\mp\zombies\_zm_game_module; +#include maps\mp\zombies\_zm_buildables; +#include codescripts\character; +#include maps\mp\zombies\_zm_weap_riotshield; +#include maps\mp\zombies\_zm_weap_riotshield_tomb; +#include maps\mp\zombies\_zm_weap_riotshield_prison; +#include maps\mp\zm_transit_bus; +#include maps\mp\zm_transit_utility; +#include maps\mp\zombies\_zm_equip_turret; +#include maps\mp\zombies\_zm_mgturret; +#include maps\mp\zombies\_zm_weap_jetgun; + +#include maps\mp\zombies\_zm_ai_sloth; +#include maps\mp\zombies\_zm_ai_sloth_ffotd; +#include maps\mp\zombies\_zm_ai_sloth_utility; +#include maps\mp\zombies\_zm_ai_sloth_magicbox; +#include maps\mp\zombies\_zm_ai_sloth_crawler; +#include maps\mp\zombies\_zm_ai_sloth_buildables; + +#include maps\mp\zombies\_zm_tombstone; +#include maps\mp\zombies\_zm_chugabud; + +#include maps\mp\zm_nuked_perks; + +#include maps\mp\zm_tomb_utility; +#include maps\mp\zm_tomb_gamemodes; +#include maps\mp\zm_tomb_fx; +#include maps\mp\zm_tomb_ffotd; +#include maps\mp\zm_tomb_tank; +#include maps\mp\zm_tomb_quest_fire; +#include maps\mp\zm_tomb_capture_zones; +#include maps\mp\zm_tomb_teleporter; +#include maps\mp\zm_tomb_giant_robot; +#include maps\mp\zm_tomb_amb; +#include maps\mp\zombies\_zm_ai_mechz; +#include maps\mp\zombies\_zm_ai_quadrotor; +#include maps\mp\zm_tomb_vo; +#include maps\mp\zombies\_zm_perk_divetonuke; +#include maps\mp\zombies\_zm_perk_electric_cherry; +#include maps\mp\zombies\_zm_weap_one_inch_punch; +#include maps\mp\zombies\_zm_weap_staff_fire; +#include maps\mp\zombies\_zm_weap_staff_water; +#include maps\mp\zombies\_zm_weap_staff_lightning; +#include maps\mp\zombies\_zm_weap_staff_air; +#include maps\mp\zm_tomb; +#include maps\mp\zm_tomb_achievement; +#include maps\mp\zm_tomb_distance_tracking; +#include maps\mp\zombies\_zm_magicbox_tomb; +#include maps\mp\zm_tomb_challenges; +#include maps\mp\zombies\_zm_perk_random; +#include maps\mp\_sticky_grenade; +#include maps\mp\zombies\_zm_weap_beacon; +#include maps\mp\zombies\_zm_weap_claymore; +#include maps\mp\zombies\_zm_weap_staff_revive; +#include maps\mp\zombies\_zm_weap_cymbal_monkey; +#include maps\mp\zm_tomb_ambient_scripts; +#include maps\mp\zm_tomb_dig; +#include maps\mp\zm_tomb_main_quest; +#include maps\mp\zm_tomb_ee_main; +#include maps\mp\zm_tomb_ee_side; +#include maps\mp\zm_tomb_chamber; +#include character\c_usa_dempsey_dlc4; +#include character\c_rus_nikolai_dlc4; +#include character\c_ger_richtofen_dlc4; +#include character\c_jap_takeo_dlc4; +#include maps\mp\zombies\_zm_powerup_zombie_blood; +#include maps\mp\zombies\_zm_devgui; +#include maps\mp\zombies\_zm_challenges; +#include scripts\AATs_Perks; +#include maps\mp\zm_prison_sq_final; +#include maps\mp\zm_alcatraz_sq_vo; +#include maps\mp\zm_alcatraz_sq_nixie; +#include maps\mp\zombies\_zm_ai_brutus; +#include maps\mp\animscripts\shared; +#include maps\mp\zombies\_zm_clone; +#include maps\mp\zombies\_zm_craftables; +#include maps\mp\zm_alcatraz_utility; +#include maps\mp\zm_alcatraz_weap_quest; +#include maps\mp\zombies\_zm_afterlife; + +#include maps\mp\zm_alcatraz_travel; + +main() +{ + replaceFunc(maps\mp\zm_alcatraz_sq::track_quest_status_thread, ::track_quest_status_thread_custom); + replaceFunc(maps\mp\zm_alcatraz_utility::disable_powerup_if_player_on_bridge, ::disable_powerup_if_player_on_bridge_custom); + replaceFunc(maps\mp\zm_alcatraz_utility::enable_powerup_if_no_player_on_bridge, ::enable_powerup_if_no_player_on_bridge_custom); + replaceFunc(maps\mp\zombies\_zm_afterlife::afterlife_fake_death, ::afterlife_fake_death_custom); + replaceFunc(maps\mp\zm_alcatraz_utility::wait_for_player_to_take, ::wait_for_player_to_take_custom); + replaceFunc(maps\mp\zm_alcatraz_craftables::include_craftables, ::include_craftables_custom); + maps\mp\zombies\_zm::register_player_damage_callback( ::playerDamageLastCheckMOTD ); +} +init() +{ + + level.is_forever_solo_game = 1; + level thread onPlayerConnect(); +} + +include_craftables_custom() +{ + level.zombie_include_craftables["open_table"].custom_craftablestub_update_prompt = ::prison_open_craftablestub_update_prompt; + craftable_name = "alcatraz_shield_zm"; + riotshield_dolly = generate_zombie_craftable_piece( craftable_name, "dolly", "t6_wpn_zmb_shield_dlc2_dolly", 32, 64, 0, undefined, ::onpickup_common, ::ondrop_common, undefined, undefined, undefined, undefined, "piece_riotshield_dolly", 1, "build_zs" ); + riotshield_door = generate_zombie_craftable_piece( craftable_name, "door", "t6_wpn_zmb_shield_dlc2_door", 48, 15, 25, undefined, ::onpickup_common, ::ondrop_common, undefined, undefined, undefined, undefined, "piece_riotshield_door", 1, "build_zs" ); + riotshield_clamp = generate_zombie_craftable_piece( craftable_name, "clamp", "t6_wpn_zmb_shield_dlc2_shackles", 32, 15, 0, undefined, ::onpickup_common, ::ondrop_common, undefined, undefined, undefined, undefined, "piece_riotshield_clamp", 1, "build_zs" ); + riotshield = spawnstruct(); + riotshield.name = craftable_name; + riotshield add_craftable_piece( riotshield_dolly ); + riotshield add_craftable_piece( riotshield_door ); + riotshield add_craftable_piece( riotshield_clamp ); + riotshield.onbuyweapon = maps\mp\zm_alcatraz_craftables::onbuyweapon_riotshield; + riotshield.triggerthink = maps\mp\zm_alcatraz_craftables::riotshieldcraftable; + maps\mp\zm_alcatraz_utility::include_craftable( riotshield ); + craftable_name = "packasplat"; + packasplat_case = generate_zombie_craftable_piece( craftable_name, "case", "p6_zm_al_packasplat_suitcase", 48, 36, 0, undefined, ::onpickup_common, ::ondrop_common, undefined, undefined, undefined, undefined, "piece_packasplat_case", 1, "build_bsm" ); + packasplat_fuse = generate_zombie_craftable_piece( craftable_name, "fuse", "p6_zm_al_packasplat_engine", 32, 36, 0, undefined, ::onpickup_common, ::ondrop_common, undefined, undefined, undefined, undefined, "piece_packasplat_fuse", 1, "build_bsm" ); + packasplat_blood = generate_zombie_craftable_piece( craftable_name, "blood", "p6_zm_al_packasplat_iv", 32, 15, 0, undefined, ::onpickup_common, ::ondrop_common, undefined, undefined, undefined, undefined, "piece_packasplat_blood", 1, "build_bsm" ); + packasplat = spawnstruct(); + packasplat.name = craftable_name; + packasplat add_craftable_piece( packasplat_case ); + packasplat add_craftable_piece( packasplat_fuse ); + packasplat add_craftable_piece( packasplat_blood ); + packasplat.triggerthink = maps\mp\zm_alcatraz_craftables::packasplatcraftable; + maps\mp\zm_alcatraz_utility::include_craftable( packasplat ); + maps\mp\zm_alcatraz_craftables::include_key_craftable( "quest_key1", "p6_zm_al_key" ); + craftable_name = "plane"; + plane_cloth = generate_zombie_craftable_piece( craftable_name, "cloth", "p6_zm_al_clothes_pile_lrg", 48, 15, 0, undefined, ::onpickup_plane, ::ondrop_plane, ::oncrafted_plane, undefined, "tag_origin", undefined, 1 ); + plane_fueltanks = generate_zombie_craftable_piece( craftable_name, "fueltanks", "veh_t6_dlc_zombie_part_fuel", 32, 15, 0, undefined, ::onpickup_plane, ::ondrop_plane, ::oncrafted_plane, undefined, "tag_feul_tanks", undefined, 2 ); + plane_engine = generate_zombie_craftable_piece( craftable_name, "engine", "veh_t6_dlc_zombie_part_engine", 32, 62, 0, undefined, ::onpickup_plane, ::ondrop_plane, ::oncrafted_plane, undefined, "tag_origin", undefined, 3 ); + plane_steering = generate_zombie_craftable_piece( craftable_name, "steering", "veh_t6_dlc_zombie_part_control", 32, 15, 0, undefined, ::onpickup_plane, ::ondrop_plane, ::oncrafted_plane, undefined, "tag_control_mechanism", undefined, 4 ); + plane_rigging = generate_zombie_craftable_piece( craftable_name, "rigging", "veh_t6_dlc_zombie_part_rigging", 32, 15, 0, undefined, ::onpickup_plane, ::ondrop_plane, ::oncrafted_plane, undefined, "tag_origin", undefined, 5 ); + + // if ( level.is_forever_solo_game ) + // { + plane_cloth.is_shared = 1; + plane_fueltanks.is_shared = 1; + plane_engine.is_shared = 1; + plane_steering.is_shared = 1; + plane_rigging.is_shared = 1; + plane_cloth.client_field_state = undefined; + plane_fueltanks.client_field_state = undefined; + plane_engine.client_field_state = undefined; + plane_steering.client_field_state = undefined; + plane_rigging.client_field_state = undefined; + // } + + plane_cloth.pickup_alias = "sidequest_sheets"; + plane_fueltanks.pickup_alias = "sidequest_oxygen"; + plane_engine.pickup_alias = "sidequest_engine"; + plane_steering.pickup_alias = "sidequest_valves"; + plane_rigging.pickup_alias = "sidequest_rigging"; + plane = spawnstruct(); + plane.name = craftable_name; + plane add_craftable_piece( plane_cloth ); + plane add_craftable_piece( plane_engine ); + plane add_craftable_piece( plane_fueltanks ); + plane add_craftable_piece( plane_steering ); + plane add_craftable_piece( plane_rigging ); + plane.triggerthink = maps\mp\zm_alcatraz_craftables::planecraftable; + plane.custom_craftablestub_update_prompt = maps\mp\zm_alcatraz_craftables::prison_plane_update_prompt; + maps\mp\zm_alcatraz_utility::include_craftable( plane ); + craftable_name = "refuelable_plane"; + refuelable_plane_gas1 = generate_zombie_craftable_piece( craftable_name, "fuel1", "accessories_gas_canister_1", 32, 15, 0, undefined, ::onpickup_fuel, ::ondrop_fuel, ::oncrafted_fuel, undefined, undefined, undefined, 6 ); + refuelable_plane_gas2 = generate_zombie_craftable_piece( craftable_name, "fuel2", "accessories_gas_canister_1", 32, 15, 0, undefined, ::onpickup_fuel, ::ondrop_fuel, ::oncrafted_fuel, undefined, undefined, undefined, 7 ); + refuelable_plane_gas3 = generate_zombie_craftable_piece( craftable_name, "fuel3", "accessories_gas_canister_1", 32, 15, 0, undefined, ::onpickup_fuel, ::ondrop_fuel, ::oncrafted_fuel, undefined, undefined, undefined, 8 ); + refuelable_plane_gas4 = generate_zombie_craftable_piece( craftable_name, "fuel4", "accessories_gas_canister_1", 32, 15, 0, undefined, ::onpickup_fuel, ::ondrop_fuel, ::oncrafted_fuel, undefined, undefined, undefined, 9 ); + refuelable_plane_gas5 = generate_zombie_craftable_piece( craftable_name, "fuel5", "accessories_gas_canister_1", 32, 15, 0, undefined, ::onpickup_fuel, ::ondrop_fuel, ::oncrafted_fuel, undefined, undefined, undefined, 10 ); + +// if ( level.is_forever_solo_game ) + // { + refuelable_plane_gas1.is_shared = 1; + refuelable_plane_gas2.is_shared = 1; + refuelable_plane_gas3.is_shared = 1; + refuelable_plane_gas4.is_shared = 1; + refuelable_plane_gas5.is_shared = 1; + refuelable_plane_gas1.client_field_state = undefined; + refuelable_plane_gas2.client_field_state = undefined; + refuelable_plane_gas3.client_field_state = undefined; + refuelable_plane_gas4.client_field_state = undefined; + refuelable_plane_gas5.client_field_state = undefined; + // } + + refuelable_plane = spawnstruct(); + refuelable_plane.name = craftable_name; + refuelable_plane add_craftable_piece( refuelable_plane_gas1 ); + refuelable_plane add_craftable_piece( refuelable_plane_gas2 ); + refuelable_plane add_craftable_piece( refuelable_plane_gas3 ); + refuelable_plane add_craftable_piece( refuelable_plane_gas4 ); + refuelable_plane add_craftable_piece( refuelable_plane_gas5 ); + refuelable_plane.triggerthink = maps\mp\zm_alcatraz_craftables::planefuelable; + plane.custom_craftablestub_update_prompt = maps\mp\zm_alcatraz_craftables::prison_plane_update_prompt; + maps\mp\zm_alcatraz_utility::include_craftable( refuelable_plane ); +} + +checkPlayerAfterlife() +{ + self endon("game_ended"); + self endon ("disconnect"); + for (;;) + { + if(!self.afterlife) + { + self iprintln("Adding you ^2$1M^7 in ^19 seconds, use ^2.d all^7"); + wait 1; + self iprintln("Adding you ^2$1M^7 in ^18 seconds, use ^2.d all^7"); + wait 1; + self iprintln("Adding you ^2$1M^7 in ^17 seconds, use ^2.d all^7"); + wait 1; + self iprintln("Adding you ^2$1M^7 in ^16 seconds, use ^2.d all^7"); + wait 1; + self iprintln("Adding you ^2$1M^7 in ^15 seconds, use ^2.d all^7"); + wait 1; + self iprintln("Adding you ^2$1M^7 in ^14 seconds, use ^2.d all^7"); + wait 1; + self iprintln("Adding you ^2$1M^7 in ^13 seconds, use ^2.d all^7"); + wait 1; + self iprintln("Adding you ^2$1M^7 in ^12 seconds, use ^2.d all^7"); + wait 1; + self iprintln("Adding you ^2$1M^7 in ^11 second, use ^2.d all^7"); + wait 1; + self.score += 1000000; + wait 3; + self iprintln("Congratulations! Make sure to use ^2.d all^7"); + self iprintln("Congratulations! Make sure to use ^2.d all^7"); + self iprintln("Congratulations! Make sure to use ^2.d all^7"); + return; + } + wait 0.5; + } +} +onPlayerConnect() +{ + while( 1 ) + { + level waittill( "connected", player ); + player thread onPlayerSpawned(); + } +} + +onPlayerSpawned() +{ + self endon( "disconnect" ); + level endon( "game_ended" ); + self waittill( "spawned_player" ); + self.shouldkeepperk = 1; + /* lock = 0; + bridge = (-1205.55, -3389.17, -8447.88); + spawn = (1963, 10493, 1343.38); + wait 10; + for (;;) + { + + if (self is_jumping() && lock == 0) + { + + self setOrigin(bridge); + lock = 1; + wait 3; + } + if (self is_jumping() && lock == 1) + { + self setOrigin(spawn); + lock = 0; + wait 3; + } + wait 0.1; + }*/ +} + +wait_for_player_to_take_custom( player, str_valid_weapon ) +{ + self endon( "acid_timeout" ); + player endon( "disconnect" ); + + while ( true ) + { + self waittill( "trigger", trigger_player ); + + if ( isdefined( level.custom_craftable_validation ) ) + { + valid = self [[ level.custom_craftable_validation ]]( player ); + + if ( !valid ) + continue; + } + + if ( trigger_player == player ) + { + current_weapon = player getcurrentweapon(); + + if ( is_player_valid( player ) && !( player.is_drinking > 0 ) && !is_placeable_mine( current_weapon ) && !is_equipment( current_weapon ) && level.revive_tool != current_weapon && "none" != current_weapon && !player hacker_active() ) + { + self notify( "acid_taken" ); + player notify( "acid_taken" ); + + weapon_limit = 2; + if (player scripts\AATs_Perks::hascustomperk("MULE")) + weapon_limit = 3; + primaries = player getweaponslistprimaries(); + + if ( isdefined( primaries ) && primaries.size >= weapon_limit ) + player takeweapon( current_weapon ); + + str_new_weapon = undefined; + + if ( str_valid_weapon == "blundergat_zm" ) + str_new_weapon = "blundersplat_zm"; + else + str_new_weapon = "blundersplat_upgraded_zm"; + + if ( player hasweapon( "blundersplat_zm" ) ) + player givemaxammo( "blundersplat_zm" ); + else if ( player hasweapon( "blundersplat_upgraded_zm" ) ) + player givemaxammo( "blundersplat_upgraded_zm" ); + else + { + player giveweapon( str_new_weapon ); + player switchtoweapon( str_new_weapon ); + } + + player thread do_player_general_vox( "general", "player_recieves_blundersplat" ); + player notify( "player_obtained_acidgat" ); + player thread maps\mp\zm_alcatraz_utility::player_lost_blundersplat_watcher(); + return; + } + } + } +} + +afterlife_fake_death_custom() +{ + level notify( "fake_death" ); + self notify( "fake_death" ); + + self.savedaat = self.aat; + if (self scripts\AATs_Perks::hascustomperk("MULE")) + { + weapons = self GetWeaponsListPrimaries(); + if (weapons && weapons[2]) + self.muleweap = weapons[2]; + self.muleweapstockcount = self getweaponammostock( weapons[2] ); + self.muleweapclipcount = self getweaponammoclip( weapons[2] ); + } + self thread giveAATback(); + self takeallweapons(); + self allowstand( 0 ); + self allowcrouch( 0 ); + self allowprone( 1 ); + self setstance( "prone" ); + + if ( self is_jumping() ) + { + while ( self is_jumping() ) + wait 0.05; + } + playfx( level._effect["afterlife_enter"], self.origin ); + self.ignoreme = 1; + self enableinvulnerability(); + self freezecontrols( 1 ); +} + +disable_powerup_if_player_on_bridge_custom() +{ + self endon( "disconnect" ); + return; + /* flag_wait( "afterlife_start_over" ); + + while ( true ) + { + if ( self maps\mp\zombies\_zm_zonemgr::is_player_in_zone( "zone_golden_gate_bridge" ) ) + { + if ( flag( "zombie_drop_powerups" ) ) + flag_clear( "zombie_drop_powerups" ); + } + + wait 1; + }*/ +} + +enable_powerup_if_no_player_on_bridge_custom() +{ + // flag_wait( "afterlife_start_over" ); + + while ( true ) + { + // n_player_total = 0; + // n_player_total += get_players_in_zone( "zone_golden_gate_bridge" ); + + // if ( n_player_total == 0 && !flag( "zombie_drop_powerups" ) ) + flag_set( "zombie_drop_powerups" ); + + wait 1; + } +} + +track_quest_status_thread_custom() +{ + while ( true ) + { + + /* while ( level.characters_in_nml.size == 0 ) + wait 1; + + while ( level.characters_in_nml.size > 0 ) + wait 1;*/ + flag_wait("plane_crashed"); + wait 26; + // if ( flag( "plane_trip_to_nml_successful" ) ) + // { + maps\mp\zm_alcatraz_sq::bestow_quest_rewards(); + flag_clear( "plane_trip_to_nml_successful" ); + // } + + level notify( "bridge_empty" ); + + // level waittill( "start_of_round" ); + + if ( level.n_quest_iteration_count == 2 ) + maps\mp\zm_alcatraz_sq_vo::vo_play_four_part_conversation( level.four_part_convos["alcatraz_return_alt" + randomintrange( 0, 2 )] ); + + maps\mp\zm_alcatraz_sq::prep_for_new_quest(); + maps\mp\zombies\_zm_craftables::waittill_crafted( "refuelable_plane" ); + maps\mp\zombies\_zm_ai_brutus::transfer_plane_trigger( "fuel", "fly" ); + t_plane_fly = getent( "plane_fly_trigger", "targetname" ); + t_plane_fly trigger_on(); + } +} + +playerDamageLastCheckMOTD(einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime) +{ + players = get_players(); + for(i=0;i 0) + { + self PlaySound("zmb_elec_jib_zombie"); + self setweaponammoclip(grenades, (grenade_count - 1)); + zombie thread scripts\AATs_Perks::ww_points( self ); + } + } + } + } + if(self scripts\AATs_Perks::hascustomperk("PHD_FLOPPER")) + { + if( smeansofdeath == "MOD_FALLING" ) + { + if(isDefined( self.divetoprone ) && self.divetoprone == 1 ) + { + radiusdamage( self.origin, 300, 5000, 1000, self, "MOD_GRENADE_SPLASH" ); + playfx(loadfx("explosions/fx_default_explosion"), self.origin, anglestoforward( ( 0, 45, 55 ) ) ); + self playsound( "zmb_phdflop_explo" ); + } + return 0; + } + if( smeansofdeath == "MOD_PROJECTILE" || smeansofdeath == "MOD_PROJECTILE_SPLASH" || smeansofdeath == "MOD_GRENADE" || smeansofdeath == "MOD_GRENADE_SPLASH" && eattacker == self) + { + return 0; + } + } + if(idamage > self.health && !self.dying_wish_on_cooldown && self scripts\AATs_Perks::hascustomperk("Dying_Wish") ) + { + self notify("dying_wish_charge"); + self thread scripts\AATs_Perks::dying_wish_effect(); + return 0; + } + + + + if ( isdefined( eattacker ) ) + { + if ( isdefined( eattacker.is_zombie ) && eattacker.is_zombie ) + { + if ( isdefined( eattacker.custom_damage_func ) ) + idamage = eattacker [[ eattacker.custom_damage_func ]]( self ); + else if ( isdefined( eattacker.meleedamage ) && smeansofdeath != "MOD_GRENADE_SPLASH" ) + idamage = eattacker.meleedamage; + + if ( isdefined( self.afterlife ) && self.afterlife ) + { + self maps\mp\zombies\_zm_afterlife::afterlife_reduce_mana( 10 ); + self clientnotify( "al_d" ); + return 0; + } + } + } + + if ( isdefined( self.afterlife ) && self.afterlife ) + return 0; + + if ( isdefined( eattacker ) && ( isdefined( eattacker.is_zombie ) && eattacker.is_zombie || isplayer( eattacker ) ) ) + { + if ( isdefined( self.hasriotshield ) && self.hasriotshield && isdefined( vdir ) ) + { + item_dmg = 100; + + if ( isdefined( eattacker.custom_item_dmg ) ) + item_dmg = eattacker.custom_item_dmg; + + if ( isdefined( self.hasriotshieldequipped ) && self.hasriotshieldequipped ) + { + if ( self player_shield_facing_attacker( vdir, 0.2 ) && isdefined( self.player_shield_apply_damage ) ) + { + self [[ self.player_shield_apply_damage ]]( item_dmg, 0 ); + return 0; + } + } + else if ( !isdefined( self.riotshieldentity ) ) + { + if ( !self player_shield_facing_attacker( vdir, -0.2 ) && isdefined( self.player_shield_apply_damage ) ) + { + self [[ self.player_shield_apply_damage ]]( item_dmg, 0 ); + return 0; + } + } + } + } + + if ( sweapon == "tower_trap_zm" || sweapon == "tower_trap_upgraded_zm" || sweapon == "none" && shitloc == "riotshield" && !( isdefined( eattacker.is_zombie ) && eattacker.is_zombie ) ) + { + self.use_adjusted_grenade_damage = 1; + return 0; + } + + if ( smeansofdeath == "MOD_PROJECTILE" || smeansofdeath == "MOD_PROJECTILE_SPLASH" || smeansofdeath == "MOD_GRENADE" || smeansofdeath == "MOD_GRENADE_SPLASH" ) + { + if ( sweapon == "blundersplat_explosive_dart_zm" ) + { + if ( self hasperk( "specialty_flakjacket" ) ) + { + self.use_adjusted_grenade_damage = 1; + idamage = 0; + } + + if ( isalive( self ) && !( isdefined( self.is_zombie ) && self.is_zombie ) ) + { + self.use_adjusted_grenade_damage = 1; + idamage = 10; + } + } + else + { + if ( self hasperk( "specialty_flakjacket" ) ) + return 0; + + if ( self.health > 75 && !( isdefined( self.is_zombie ) && self.is_zombie ) ) + idamage = 75; + } + } + + if ( idamage >= self.health && ( isdefined( level.intermission ) && !level.intermission ) ) + { + self.savedaat = self.aat; + self thread giveAATback(); + self.shouldkeepperk = 0; + if ( self.lives > 0 && ( isdefined( self.afterlife ) && !self.afterlife ) ) + { + self playsoundtoplayer( "zmb_afterlife_death", self ); + self maps\mp\zombies\_zm_afterlife::afterlife_remove(); + self.afterlife = 1; + self thread maps\mp\zombies\_zm_afterlife::afterlife_laststand(); + + if ( self.health <= 1 ) + return 0; + else + idamage = self.health - 1; + } + else + self thread last_stand_conscience_vo(); + } + return idamage; +} + +giveAATback() +{ + wait 2; + for (;;) + { + if (!self.afterlife) + { + /* if (self scripts\AATs_Perks::hascustomperk("MULE")) + { + if (self.muleweap) + { + weapon = self.muleweap; + self giveweapon( weapon, 2, self maps\mp\zombies\_zm_weapons::get_pack_a_punch_weapon_options( weapon ) ); + self setweaponammostock( weapon, self.muleweapstockcount ); + self setweaponammoclip( weapon, self.muleweapclipcount ); + } + }*/ + self.aat = self.savedaat; + weapon = self getCurrentWeapon(); + name = self.aat[weapon]; + self scripts\AATs_Perks::aat_hud(name); + return; + } + wait 0.5; + } +} \ No newline at end of file diff --git a/t6/scripts/zm/zm_prison/no_lightning.gsc b/t6/scripts/zm/zm_prison/no_lightning.gsc new file mode 100644 index 0000000..4944a5a --- /dev/null +++ b/t6/scripts/zm/zm_prison/no_lightning.gsc @@ -0,0 +1,14 @@ +#include maps\mp\_utility; + + +init() +{ + if (getDvar("mapname") == "zm_prison") + level._callbacks[ "on_player_connect" ][ 16 ] = ::player_lightning_manager_override; +} + + +player_lightning_manager_override() +{ + self setclientfieldtoplayer( "toggle_lightning", 0 ); +} \ No newline at end of file diff --git a/t6/scripts/zm/zm_prison/zm_spin.gsc b/t6/scripts/zm/zm_prison/zm_spin.gsc new file mode 100644 index 0000000..65ac057 --- /dev/null +++ b/t6/scripts/zm/zm_prison/zm_spin.gsc @@ -0,0 +1,48 @@ +#include common_scripts\utility; + +init() +{ + setdvar("spin", "0"); + level thread init_spin(); +} + +init_spin() +{ + level endon ("game_ended"); + + for(;;) + { + if (getdvar("spin") == "1") + { + zombies = getaispeciesarray( "axis", "all" ); + foreach(zombie in zombies) + { + if (!isdefined(zombie.is_spinning)) + { + zombie.is_spinning = 1; + zombie thread spin(); + } + } + } + wait 2; + } +} + +spin() +{ + self endon("death"); + + spin = randomintrange(25, 75); + i = 0; + for (;;) + { + if (getdvar("spin") == "1") + { + if (i > 36000) + i = 0; + self.angles = (0, i, 0); + i += spin; + } + wait .1; + } +} \ No newline at end of file diff --git a/t6/scripts/zm/zm_tomb/M/M_zm_ai_mechz.gsc b/t6/scripts/zm/zm_tomb/M/M_zm_ai_mechz.gsc new file mode 100644 index 0000000..79396de --- /dev/null +++ b/t6/scripts/zm/zm_tomb/M/M_zm_ai_mechz.gsc @@ -0,0 +1,1989 @@ +// T6 GSC SOURCE +// Generated by https://github.com/xensik/gsc-tool +#include maps\mp\zombies\_zm_zonemgr; +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_net; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\animscripts\zm_utility; +#include maps\mp\zm_tomb_tank; +#include maps\mp\zombies\_zm_ai_mechz_dev; +#include maps\mp\zombies\_zm_ai_mechz_claw; +#include maps\mp\zombies\_zm_ai_mechz_ft; +#include maps\mp\zombies\_zm_ai_mechz_booster; +#include maps\mp\zombies\_zm_ai_mechz_ffotd; +#include maps\mp\zombies\_zm_ai_mechz; +#include maps\mp\zombies\_zm_spawner; +#include maps\mp\animscripts\zm_shared; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\zm_tomb_chamber; +#include maps\mp\zombies\_zm_ai_basic; + +precache() +{ + level thread mechz_setup_armor_pieces(); + precachemodel( "c_zom_mech_claw" ); + precachemodel( "c_zom_mech_faceplate" ); + precachemodel( "c_zom_mech_powersupply_cap" ); + level._effect["mech_dmg_sparks"] = loadfx( "maps/zombie_tomb/fx_tomb_mech_dmg_sparks" ); + level._effect["mech_dmg_steam"] = loadfx( "maps/zombie_tomb/fx_tomb_mech_dmg_steam" ); + level._effect["mech_booster"] = loadfx( "maps/zombie_tomb/fx_tomb_mech_jump_booster" ); + level._effect["mech_wpn_source"] = loadfx( "maps/zombie_tomb/fx_tomb_mech_wpn_source" ); + level._effect["mech_wpn_flamethrower"] = loadfx( "maps/zombie_tomb/fx_tomb_mech_wpn_flamethrower" ); + level._effect["mech_booster_landing"] = loadfx( "maps/zombie_tomb/fx_tomb_mech_jump_landing" ); + level._effect["mech_faceplate_dmg"] = loadfx( "maps/zombie_tomb/fx_tomb_mech_dmg_armor_face" ); + level._effect["mech_armor_dmg"] = loadfx( "maps/zombie_tomb/fx_tomb_mech_dmg_armor" ); + level._effect["mech_exhaust"] = loadfx( "maps/zombie_tomb/fx_tomb_mech_exhaust_smoke" ); + level._effect["mech_booster_feet"] = loadfx( "maps/zombie_tomb/fx_tomb_mech_jump_booster_sm" ); + level._effect["mech_headlamp"] = loadfx( "maps/zombie_tomb/fx_tomb_mech_head_light" ); + level._effect["mech_footstep_steam"] = loadfx( "maps/zombie_tomb/fx_tomb_mech_foot_step_steam" ); + setdvar( "zombie_double_wide_checks", 1 ); + precacherumble( "mechz_footsteps" ); + precacheshellshock( "lava_small" ); +} + +#using_animtree("mechz_claw"); + +init() +{ + maps\mp\zombies\_zm_ai_mechz_ffotd::mechz_init_start(); + level.mechz_spawners = getentarray( "mechz_spawner", "script_noteworthy" ); + + if ( level.mechz_spawners.size == 0 ) + return; + + for ( i = 0; i < level.mechz_spawners.size; i++ ) + { + level.mechz_spawners[i].is_enabled = 1; + level.mechz_spawners[i].script_forcespawn = 1; + } + + level.mechz_base_health = 5000; + level.mechz_health = level.mechz_base_health; + level.mechz_health_increase = 1000; + level.mechz_round_count = 0; + level.mechz_damage_percent = 0.1; + level.mechz_remove_helmet_head_dmg_base = 500; + level.mechz_remove_helmet_head_dmg = level.mechz_remove_helmet_head_dmg_base; + level.mechz_remove_helmet_head_dmg_increase = 250; + level.mechz_explosive_dmg_head_scaler = 0.25; + level.mechz_helmet_health_percentage = 0.1; + level.mechz_powerplant_expose_dmg_base = 300; + level.mechz_powerplant_expose_dmg = level.mechz_powerplant_expose_base_dmg; + level.mechz_powerplant_expose_dmg_increase = 100; + level.mechz_powerplant_destroy_dmg_base = 500; + level.mechz_powerplant_destroy_dmg = level.mechz_powerplant_destroy_dmg_base; + level.mechz_powerplant_destroy_dmg_increase = 150; + level.mechz_powerplant_expose_health_percentage = 0.05; + level.mechz_powerplant_destroyed_health_percentage = 0.025; + level.mechz_explosive_dmg_to_cancel_claw_percentage = 0.1; + level.mechz_min_round_fq = 3; + level.mechz_max_round_fq = 4; + level.mechz_min_round_fq_solo = 4; + level.mechz_max_round_fq_solo = 6; + level.mechz_reset_dist_sq = 65536; + level.mechz_sticky_dist_sq = 1048576; + level.mechz_aggro_dist_sq = 16384; + level.mechz_zombie_per_round = 1; + level.mechz_left_to_spawn = 0; + level.mechz_players_in_zone_spawn_point_cap = 120; + level.mechz_shotgun_damage_mod = 1.5; + level.mechz_failed_paths_to_jump = 3; + level.mechz_jump_dist_threshold = 4410000; + level.mechz_jump_delay = 3; + level.mechz_player_flame_dmg = 10; + level.mechz_half_front_arc = cos( 45 ); + level.mechz_ft_sweep_chance = 10; + level.mechz_aim_max_pitch = 60; + level.mechz_aim_max_yaw = 45; + level.mechz_custom_goalradius = 48; + level.mechz_custom_goalradius_sq = level.mechz_custom_goalradius * level.mechz_custom_goalradius; + level.mechz_tank_knockdown_time = 5; + level.mechz_robot_knockdown_time = 10; + level.mechz_dist_for_sprint = 129600; + level.mechz_dist_for_stop_sprint = 57600; + level.mechz_claw_cooldown_time = 7000; + level.mechz_flamethrower_cooldown_time = 5000; + level.mechz_min_extra_spawn = 8; + level.mechz_max_extra_spawn = 11; + level.mechz_points_for_killer = 250; + level.mechz_points_for_team = 500; + level.mechz_points_for_helmet = 100; + level.mechz_points_for_powerplant = 100; + level.mechz_flogger_stun_time = 3; + level.mechz_powerplant_stun_time = 4; + flag_init( "mechz_launching_claw" ); + flag_init( "mechz_claw_move_complete" ); + registerclientfield( "actor", "mechz_fx", 14000, 12, "int" ); + registerclientfield( "toplayer", "mechz_grab", 14000, 1, "int" ); + level thread init_flamethrower_triggers(); + + if ( isdefined( level.mechz_spawning_logic_override_func ) ) + level thread [[ level.mechz_spawning_logic_override_func ]](); + else + level thread mechz_spawning_logic(); + + scriptmodelsuseanimtree( #animtree ); +/# + setup_devgui(); +#/ + maps\mp\zombies\_zm_ai_mechz_ffotd::mechz_init_end(); +} + +mechz_setup_armor_pieces() +{ + level.mechz_armor_info = []; + level.mechz_armor_info[0] = spawnstruct(); + level.mechz_armor_info[0].model = "c_zom_mech_armor_knee_left"; + level.mechz_armor_info[0].tag = "J_Knee_Attach_LE"; + level.mechz_armor_info[1] = spawnstruct(); + level.mechz_armor_info[1].model = "c_zom_mech_armor_knee_right"; + level.mechz_armor_info[1].tag = "J_Knee_attach_RI"; + level.mechz_armor_info[2] = spawnstruct(); + level.mechz_armor_info[2].model = "c_zom_mech_armor_shoulder_left"; + level.mechz_armor_info[2].tag = "J_ShoulderArmor_LE"; + level.mechz_armor_info[3] = spawnstruct(); + level.mechz_armor_info[3].model = "c_zom_mech_armor_shoulder_right"; + level.mechz_armor_info[3].tag = "J_ShoulderArmor_RI"; + level.mechz_armor_info[4] = spawnstruct(); + level.mechz_armor_info[4].tag = "J_Root_Attach_LE"; + level.mechz_armor_info[5] = spawnstruct(); + level.mechz_armor_info[5].tag = "J_Root_Attach_RI"; + + for ( i = 0; i < level.mechz_armor_info.size; i++ ) + { + if ( isdefined( level.mechz_armor_info[i].model ) ) + precachemodel( level.mechz_armor_info[i].model ); + } +} + +mechz_setup_fx() +{ + self.fx_field = 0; + self thread booster_fx_watcher(); + self thread flamethrower_fx_watcher(); +} + +clear_one_off_fx( fx_id ) +{ + self endon( "death" ); + wait 10; + self.fx_field = self.fx_field & ~fx_id; + self setclientfield( "mechz_fx", self.fx_field ); +} + +traversal_booster_fx_watcher() +{ + self endon( "death" ); + + while ( true ) + { + self waittill( "traverse_anim", notetrack ); + + if ( notetrack == "booster_on" ) + { + self.fx_field = self.fx_field | 128; + self.sndloopent playsound( "zmb_ai_mechz_rocket_start" ); + self.sndloopent playloopsound( "zmb_ai_mechz_rocket_loop", 0.75 ); + } + else if ( notetrack == "booster_off" ) + { + self.fx_field = self.fx_field & ~128; + self.sndloopent playsound( "zmb_ai_mechz_rocket_stop" ); + self.sndloopent stoploopsound( 1 ); + } + + self setclientfield( "mechz_fx", self.fx_field ); + } +} + +booster_fx_watcher() +{ + self endon( "death" ); + self thread traversal_booster_fx_watcher(); + + while ( true ) + { + self waittill( "jump_anim", notetrack ); + + if ( isdefined( self.mechz_hidden ) && self.mechz_hidden ) + continue; + + if ( notetrack == "booster_on" ) + { + self.fx_field = self.fx_field | 128; + self.sndloopent playsound( "zmb_ai_mechz_rocket_start" ); + self.sndloopent playloopsound( "zmb_ai_mechz_rocket_loop", 0.75 ); + } + else if ( notetrack == "booster_off" ) + { + self.fx_field = self.fx_field & ~128; + self.sndloopent playsound( "zmb_ai_mechz_rocket_stop" ); + self.sndloopent stoploopsound( 1 ); + } + else if ( notetrack == "impact" ) + { + self.fx_field = self.fx_field | 512; + + if ( isdefined( self.has_helmet ) && self.has_helmet ) + self.fx_field = self.fx_field | 2048; + + self thread clear_one_off_fx( 512 ); + } + + self setclientfield( "mechz_fx", self.fx_field ); + } +} + +flamethrower_fx_watcher() +{ + self endon( "death" ); + + while ( true ) + { + self waittill( "flamethrower_anim", notetrack ); + + if ( notetrack == "start_ft" ) + self.fx_field = self.fx_field | 64; + else if ( notetrack == "stop_ft" ) + self.fx_field = self.fx_field & ~64; + + self setclientfield( "mechz_fx", self.fx_field ); + } +} + +fx_cleanup() +{ + self.fx_field = 0; + self setclientfield( "mechz_fx", self.fx_field ); + wait_network_frame(); +} + +mechz_setup_snd() +{ + self.audio_type = "mechz"; + + if ( !isdefined( self.sndloopent ) ) + { + self.sndloopent = spawn( "script_origin", self.origin ); + self.sndloopent linkto( self, "tag_origin" ); + self thread snddeleteentondeath( self.sndloopent ); + } + + self thread play_ambient_mechz_vocals(); +} + +snddeleteentondeath( ent ) +{ + self waittill( "death" ); + ent delete(); +} + +play_ambient_mechz_vocals() +{ + self endon( "death" ); + wait( randomintrange( 2, 4 ) ); + + while ( true ) + { + if ( isdefined( self ) ) + { + if ( isdefined( self.favoriteenemy ) && distance( self.origin, self.favoriteenemy.origin ) <= 150 ) + { + + } + else + self playsound( "zmb_ai_mechz_vox_ambient" ); + } + + wait( randomfloatrange( 3, 6 ) ); + } +} + +enable_mechz_rounds() +{ +/# + if ( getdvarint( #"zombie_cheat" ) >= 2 ) + return; +#/ + level.mechz_rounds_enabled = 1; + flag_init( "mechz_round" ); + level thread mechz_round_tracker(); +} + +mechz_round_tracker() +{ + maps\mp\zombies\_zm_ai_mechz_ffotd::mechz_round_tracker_start(); + level.num_mechz_spawned = 0; + old_spawn_func = level.round_spawn_func; + old_wait_func = level.round_wait_func; + + while ( !isdefined( level.zombie_mechz_locations ) ) + wait 0.05; + + flag_wait( "activate_zone_nml" ); + mech_start_round_num = 8; + + if ( isdefined( level.is_forever_solo_game ) && level.is_forever_solo_game ) + mech_start_round_num = 8; + + while ( level.round_number < mech_start_round_num ) + level waittill( "between_round_over" ); + + level.next_mechz_round = level.round_number; + level thread debug_print_mechz_round(); + + while ( true ) + { + maps\mp\zombies\_zm_ai_mechz_ffotd::mechz_round_tracker_loop_start(); + + if ( level.num_mechz_spawned > 0 ) + level.mechz_should_drop_powerup = 1; + + if ( level.next_mechz_round <= level.round_number ) + { + a_zombies = getaispeciesarray( level.zombie_team, "all" ); + + foreach ( zombie in a_zombies ) + { + if ( isdefined( zombie.is_mechz ) && zombie.is_mechz && isalive( zombie ) ) + { + level.next_mechz_round++; + break; + } + } + } + + if ( level.mechz_left_to_spawn == 0 && level.next_mechz_round <= level.round_number ) + { + mechz_health_increases(); + + if ( isdefined( level.is_forever_solo_game ) && level.is_forever_solo_game ) + level.mechz_zombie_per_round = 1; + else if ( level.mechz_round_count < 2 ) + level.mechz_zombie_per_round = 1; + else if ( level.mechz_round_count < 5 ) + level.mechz_zombie_per_round = 2; + else + level.mechz_zombie_per_round = 3; + + level.mechz_left_to_spawn = level.mechz_zombie_per_round; + mechz_spawning = level.mechz_left_to_spawn; + wait( randomfloatrange( 10.0, 15.0 ) ); + level notify( "spawn_mechz" ); + + if ( isdefined( level.is_forever_solo_game ) && level.is_forever_solo_game ) + n_round_gap = randomintrange( level.mechz_min_round_fq_solo, level.mechz_max_round_fq_solo ); + else + n_round_gap = randomintrange( level.mechz_min_round_fq, level.mechz_max_round_fq ); + + level.next_mechz_round = level.round_number + n_round_gap; + level.mechz_round_count++; + level thread debug_print_mechz_round(); + level.num_mechz_spawned = level.num_mechz_spawned + mechz_spawning; + } + + maps\mp\zombies\_zm_ai_mechz_ffotd::mechz_round_tracker_loop_end(); + level waittill( "between_round_over" ); + mechz_clear_spawns(); + } +} + +debug_print_mechz_round() +{ + flag_wait( "start_zombie_round_logic" ); +/# + iprintln( "Next mechz Round = " + level.next_mechz_round ); +#/ +} + +mechz_spawning_logic() +{ + level thread enable_mechz_rounds(); + + while ( true ) + { + level waittill( "spawn_mechz" ); + + while ( level.mechz_left_to_spawn ) + { + while ( level.zombie_mechz_locations.size < 1 ) + wait( randomfloatrange( 5.0, 10.0 ) ); + + ai = spawn_zombie( level.mechz_spawners[0] ); + ai thread mechz_spawn(); + level.mechz_left_to_spawn--; + + if ( level.mechz_left_to_spawn == 0 ) + level thread response_to_air_raid_siren_vo(); + + ai thread mechz_hint_vo(); + wait( randomfloatrange( 3.0, 6.0 ) ); + } + } +} + +mechz_prespawn() +{ + +} + +mechz_attach_objects() +{ + self detachall(); + self.armor_state = []; + + for ( i = 0; i < level.mechz_armor_info.size; i++ ) + { + self.armor_state[i] = spawnstruct(); + self.armor_state[i].index = i; + self.armor_state[i].tag = level.mechz_armor_info[i].tag; + + if ( isdefined( level.mechz_armor_info[i].model ) ) + { + self attach( level.mechz_armor_info[i].model, level.mechz_armor_info[i].tag, 1 ); + self.armor_state[i].model = level.mechz_armor_info[i].model; + } + } + + if ( isdefined( self.m_claw ) ) + { + self.m_claw delete(); + self.m_claw = undefined; + } + + org = self gettagorigin( "tag_claw" ); + ang = self gettagangles( "tag_claw" ); + self.m_claw = spawn( "script_model", org ); + self.m_claw setmodel( "c_zom_mech_claw" ); + self.m_claw.angles = ang; + self.m_claw linkto( self, "tag_claw" ); + self.m_claw useanimtree( #animtree ); + + if ( isdefined( self.m_claw_damage_trigger ) ) + { + self.m_claw_damage_trigger unlink(); + self.m_claw_damage_trigger delete(); + self.m_claw_damage_trigger = undefined; + } + + trigger_spawnflags = 0; + trigger_radius = 3; + trigger_height = 15; + self.m_claw_damage_trigger = spawn( "trigger_damage", org, trigger_spawnflags, trigger_radius, trigger_height ); + self.m_claw_damage_trigger.angles = ang; + self.m_claw_damage_trigger enablelinkto(); + self.m_claw_damage_trigger linkto( self, "tag_claw" ); + self thread mechz_claw_damage_trigger_thread(); + self attach( "c_zom_mech_faceplate", "J_Helmet", 0 ); + self.has_helmet = 1; + self attach( "c_zom_mech_powersupply_cap", "tag_powersupply", 0 ); + self.has_powerplant = 1; + self.powerplant_covered = 1; + self.armor_state = array_randomize( self.armor_state ); +} + +mechz_set_starting_health() +{ + self.maxhealth = level.mechz_health; + self.helmet_dmg = 0; + self.helmet_dmg_for_removal = self.maxhealth * level.mechz_helmet_health_percentage; + self.powerplant_cover_dmg = 0; + self.powerplant_cover_dmg_for_removal = self.maxhealth * level.mechz_powerplant_expose_health_percentage; + self.powerplant_dmg = 0; + self.powerplant_dmg_for_destroy = self.maxhealth * level.mechz_powerplant_destroyed_health_percentage; + level.mechz_explosive_dmg_to_cancel_claw = self.maxhealth * level.mechz_explosive_dmg_to_cancel_claw_percentage; +/# + if ( getdvarint( #"_id_E7121222" ) > 0 ) + { + println( "\\nMZ: MechZ Starting Health: " + self.maxhealth ); + println( "\\nMZ: MechZ Required Helmet Dmg: " + self.helmet_dmg_for_removal ); + println( "\\nMZ: MechZ Required Powerplant Cover Dmg: " + self.powerplant_cover_dmg_for_removal ); + println( "\\nMZ: MechZ Required Powerplant Dmg: " + self.powerplant_dmg_for_destroy ); + } +#/ + self.health = level.mechz_health; + self.non_attacker_func = ::mechz_non_attacker_damage_override; + self.non_attack_func_takes_attacker = 1; + self.actor_damage_func = ::mechz_damage_override; + self.instakill_func = ::mechz_instakill_override; + self.nuke_damage_func = ::mechz_nuke_override; +} + +mechz_spawn() +{ + fire = (9463, -8560, -398); + ice = (11211, -7058.7, -345.875); + wind = (11253, -8655, -408); + lightning = (9623.4, -7016.2, -345.875); + crazy = (10341.6, -7907.17, -411.875); + self maps\mp\zombies\_zm_ai_mechz_ffotd::spawn_start(); + self endon( "death" ); + level endon( "intermission" ); + self mechz_attach_objects(); + self mechz_set_starting_health(); + self mechz_setup_fx(); + self mechz_setup_snd(); + level notify( "sam_clue_mechz", self ); + //self.closest_player_override = maps\mp\zombies\_zm_ai_mechz::get_favorite_enemy; + self.closest_player_override = scripts\zm\zm_tomb\boss_ivo1::get_favorite_enemy_custom; + self.animname = "mechz_zombie"; + self.has_legs = 1; + self.no_gib = 1; + self.ignore_all_poi = 1; + self.is_mechz = 1; + self.ignore_enemy_count = 1; + self.no_damage_points = 1; + self.melee_anim_func = ::melee_anim_func; + self.meleedamage = 1000; + self.custom_item_dmg = 2000; + recalc_zombie_array(); + self setphysparams( 20, 0, 80 ); + self setcandamage( 0 ); + self.zombie_init_done = 1; + self notify( "zombie_init_done" ); + self.allowpain = 0; + self animmode( "normal" ); + self orientmode( "face enemy" ); + self maps\mp\zombies\_zm_spawner::zombie_setup_attack_properties(); + self.completed_emerging_into_playable_area = 1; + self notify( "completed_emerging_into_playable_area" ); + self.no_powerups = 0; + self setfreecameralockonallowed( 0 ); + //self notsolid(); + self thread maps\mp\zombies\_zm_spawner::zombie_eye_glow(); + level thread maps\mp\zombies\_zm_spawner::zombie_death_event( self ); + self thread maps\mp\zombies\_zm_spawner::enemy_death_detection(); + + if ( level.zombie_mechz_locations.size ) + spawn_pos = self get_best_mechz_spawn_pos(); + + if ( !isdefined( spawn_pos ) ) + { +/# + println( "ERROR: Tried to spawn mechz with no mechz spawn_positions!\\n" ); + iprintln( "ERROR: Tried to spawn mechz with no mechz spawn_positions!" ); +#/ + //iPrintLnBold("INCOMING PANZER!"); + //places = array( ice, fire, lightning, wind, crazy); + random = level.places[randomint(level.places.size)]; + self animscripted( random , (0, 0, 0), "zm_spawn" ); + //self delete(); + //return; + } + + if ( isdefined( level.mechz_force_spawn_pos ) ) + { + spawn_pos = level.mechz_force_spawn_pos; + level.mechz_force_spawn_pos = undefined; + } + + if ( !isdefined( spawn_pos.angles ) ) + spawn_pos.angles = ( 0, 0, 0 ); + + self thread mechz_death(); + self forceteleport( crazy, (0, 0, 0) ); + /* foreach( player in level.players) + { + player shellshock( "lava_small", 3 ); + }*/ + self playsound( "zmb_ai_mechz_incoming_alarm" ); + + if ( !isdefined( spawn_pos.angles ) ) + spawn_pos.angles = ( 0, 0, 0 ); + + //self animscripted( (10314.5, -7889.91, -411.875), (0, 0, 0), "zm_spawn" ); + self animscripted( spawn_pos.origin, spawn_pos.angles, "zm_spawn" ); + self maps\mp\animscripts\zm_shared::donotetracks( "jump_anim" ); + self setfreecameralockonallowed( 1 ); + //self solid(); + self set_zombie_run_cycle( "walk" ); + if ( isdefined( level.mechz_find_flesh_override_func ) ) + level thread [[ level.mechz_find_flesh_override_func ]](); + + + else + self thread mechz_find_flesh(); + + self thread mechz_jump_think( spawn_pos ); + self setcandamage( 1 ); + self init_anim_rate(); + self maps\mp\zombies\_zm_ai_mechz_ffotd::spawn_end(); + self setcandamage( 0 ); + wait 5; + self setcandamage( 1 ); +} + +get_closest_mechz_spawn_pos( org ) +{ + best_dist = -1; + best_pos = undefined; + players = get_players(); + + for ( i = 0; i < level.zombie_mechz_locations.size; i++ ) + { + dist = distancesquared( org, level.zombie_mechz_locations[i].origin ); + + if ( dist < best_dist || best_dist < 0 ) + { + best_dist = dist; + best_pos = level.zombie_mechz_locations[i]; + } + } + +/# + if ( !isdefined( best_pos ) ) + println( "Error: Mechz could not find a valid jump pos from position ( " + self.origin[0] + ", " + self.origin[1] + ", " + self.origin[2] + " )" ); +#/ + return best_pos; +} + +get_best_mechz_spawn_pos( ignore_used_positions ) +{ + if ( !isdefined( ignore_used_positions ) ) + ignore_used_positions = 0; + + best_dist = -1; + best_pos = undefined; + players = get_players(); + + for ( i = 0; i < level.zombie_mechz_locations.size; i++ ) + { + if ( !ignore_used_positions && ( isdefined( level.zombie_mechz_locations[i].has_been_used ) && level.zombie_mechz_locations[i].has_been_used ) ) + continue; + + if ( ignore_used_positions == 1 && ( isdefined( level.zombie_mechz_locations[i].used_cooldown ) && level.zombie_mechz_locations[i].used_cooldown ) ) + continue; + + for ( j = 0; j < players.size; j++ ) + { + if ( is_player_valid( players[j], 1, 1 ) ) + { + dist = distancesquared( level.zombie_mechz_locations[i].origin, players[j].origin ); + + if ( dist < best_dist || best_dist < 0 ) + { + best_dist = dist; + best_pos = level.zombie_mechz_locations[i]; + } + } + } + } + + if ( ignore_used_positions && isdefined( best_pos ) ) + best_pos thread jump_pos_used_cooldown(); + + if ( isdefined( best_pos ) ) + best_pos.has_been_used = 1; + else if ( level.zombie_mechz_locations.size > 0 ) + return level.zombie_mechz_locations[randomint( level.zombie_mechz_locations.size )]; + + return best_pos; +} + +mechz_clear_spawns() +{ + for ( i = 0; i < level.zombie_mechz_locations.size; i++ ) + level.zombie_mechz_locations[i].has_been_used = 0; +} + +jump_pos_used_cooldown() +{ + self.used_cooldown = 1; + wait 5.0; + self.used_cooldown = 0; +} + +mechz_health_increases() +{ + if ( !isdefined( level.mechz_last_spawn_round ) || level.round_number > level.mechz_last_spawn_round ) + { + a_players = getplayers(); + n_player_modifier = 1; + + if ( a_players.size > 1 ) + n_player_modifier = a_players.size * 0.75; + + level.mechz_health = int( n_player_modifier * ( level.mechz_base_health + level.mechz_health_increase * level.mechz_round_count ) ); + + if ( level.mechz_health >= 22500 * n_player_modifier ) + level.mechz_health = int( 22500 * n_player_modifier ); + + level.mechz_last_spawn_round = level.round_number; + } +} + +mechz_death() +{ + self endon( "mechz_cleanup" ); + thread mechz_cleanup(); + self waittill( "death" ); + death_origin = self.origin; + + if ( isdefined( self.robot_stomped ) && self.robot_stomped ) + death_origin = death_origin + vectorscale( ( 0, 0, 1 ), 90.0 ); + + self mechz_claw_detach(); + self release_flamethrower_trigger(); + self.fx_field = 0; + self setclientfield( "mechz_fx", self.fx_field ); + self thread maps\mp\zombies\_zm_spawner::zombie_eye_glow_stop(); + self mechz_interrupt(); + + if ( isdefined( self.favoriteenemy ) ) + { + if ( isdefined( self.favoriteenemy.hunted_by ) ) + self.favoriteenemy.hunted_by--; + } + + self thread mechz_explode( "tag_powersupply", death_origin ); + + if ( get_current_zombie_count() == 0 && level.zombie_total == 0 ) + { + level.last_mechz_origin = self.origin; + level notify( "last_mechz_down" ); + } + + if ( isplayer( self.attacker ) ) + { + event = "death"; + + if ( issubstr( self.damageweapon, "knife_ballistic_" ) ) + event = "ballistic_knife_death"; + + self.attacker delay_thread( 4.0, maps\mp\zombies\_zm_audio::create_and_play_dialog, "general", "mech_defeated" ); + self.attacker maps\mp\zombies\_zm_score::player_add_points( event, self.damagemod, self.damagelocation, 1 ); + self.attacker maps\mp\zombies\_zm_stats::increment_client_stat( "tomb_mechz_killed", 0 ); + self.attacker maps\mp\zombies\_zm_stats::increment_player_stat( "tomb_mechz_killed" ); + + if ( isdefined( level.mechz_should_drop_powerup ) && level.mechz_should_drop_powerup ) + { + wait_network_frame(); + wait_network_frame(); + level.mechz_should_drop_powerup = 0; + + if ( level.powerup_drop_count >= level.zombie_vars["zombie_powerup_drop_max_per_round"] ) + level.powerup_drop_count = level.zombie_vars["zombie_powerup_drop_max_per_round"] - 1; + + level.zombie_vars["zombie_drop_item"] = 1; + level thread maps\mp\zombies\_zm_powerups::powerup_drop( self.origin ); + } + } +} + +mechz_explode( str_tag, death_origin ) +{ + wait 2.0; + v_origin = self gettagorigin( str_tag ); + level notify( "mechz_exploded", v_origin ); + playsoundatposition( "zmb_ai_mechz_death_explode", v_origin ); + playfx( level._effect["mechz_death"], v_origin ); + radiusdamage( v_origin, 128, 100, 25, undefined, "MOD_GRENADE_SPLASH" ); + earthquake( 0.5, 1.0, v_origin, 256 ); + playrumbleonposition( "grenade_rumble", v_origin ); + level notify( "mechz_killed", death_origin ); +} + +mechz_cleanup() +{ + self waittill( "mechz_cleanup" ); + self mechz_interrupt(); + level.sndmechzistalking = 0; + + if ( isdefined( self.sndmechzmusicent ) ) + { + self.sndmechzmusicent delete(); + self.sndmechzmusicent = undefined; + } + + if ( isdefined( self.favoriteenemy ) ) + { + if ( isdefined( self.favoriteenemy.hunted_by ) ) + self.favoriteenemy.hunted_by--; + } +} + +mechz_interrupt() +{ + self notify( "kill_claw" ); + self notify( "kill_ft" ); + self notify( "kill_jump" ); +} + +mechz_stun( time ) +{ + self endon( "death" ); + + if ( !isalive( self ) || isdefined( self.not_interruptable ) && self.not_interruptable || isdefined( self.is_traversing ) && self.is_traversing ) + return; + + curr_time = 0; + anim_time = self getanimlengthfromasd( "zm_stun", 0 ); + self mechz_interrupt(); + self mechz_claw_detach(); + wait 0.05; + self.not_interruptable = 1; +/# + if ( getdvarint( #"_id_E7121222" ) > 1 ) + println( "\\nMZ: Stun setting not interruptable\\n" ); +#/ + + while ( curr_time < time ) + { + self animscripted( self.origin, self.angles, "zm_stun" ); + self maps\mp\animscripts\zm_shared::donotetracks( "stun_anim" ); + self clearanim( %root, 0 ); + curr_time = curr_time + anim_time; + } + + self.not_interruptable = 0; +/# + if ( getdvarint( #"_id_E7121222" ) > 1 ) + println( "\\nMZ: Stun clearing not interruptable\\n" ); +#/ +} + +mechz_tank_hit_callback() +{ + self endon( "death" ); + + if ( isdefined( self.mechz_hit_by_tank ) && self.mechz_hit_by_tank ) + return; + +/# + if ( getdvarint( #"_id_E7121222" ) > 1 ) + println( "\\nMZ: Tank damage setting not interruptable\\n" ); +#/ + self.not_interruptable = 1; + self.mechz_hit_by_tank = 1; + self mechz_interrupt(); + v_trace_start = self.origin + vectorscale( ( 0, 0, 1 ), 100.0 ); + v_trace_end = self.origin - vectorscale( ( 0, 0, 1 ), 500.0 ); + v_trace = physicstrace( self.origin, v_trace_end, ( -15, -15, -5 ), ( 15, 15, 5 ), self ); + self.origin = v_trace["position"]; + timer = 0; + self animscripted( self.origin, self.angles, "zm_tank_hit_in" ); + self maps\mp\animscripts\zm_shared::donotetracks( "pain_anim" ); + anim_length = self getanimlengthfromasd( "zm_tank_hit_loop", 0 ); + + while ( timer < level.mechz_tank_knockdown_time ) + { + timer = timer + anim_length; + self animscripted( self.origin, self.angles, "zm_tank_hit_loop" ); + self maps\mp\animscripts\zm_shared::donotetracks( "pain_anim" ); + } + + self animscripted( self.origin, self.angles, "zm_tank_hit_out" ); + self maps\mp\animscripts\zm_shared::donotetracks( "pain_anim" ); +/# + if ( getdvarint( #"_id_E7121222" ) > 1 ) + println( "\\nMZ: Tank damage clearing not interruptable\\n" ); +#/ + self.not_interruptable = 0; + self.mechz_hit_by_tank = 0; + + if ( !level.vh_tank ent_flag( "tank_moving" ) && self istouching( level.vh_tank ) ) + { + self notsolid(); + self ghost(); + self.mechz_hidden = 1; + + if ( isdefined( self.m_claw ) ) + self.m_claw ghost(); + + self.fx_field_old = self.fx_field; + self thread maps\mp\zombies\_zm_spawner::zombie_eye_glow_stop(); + self fx_cleanup(); + self mechz_do_jump(); + self solid(); + self.mechz_hidden = 0; + } +} + +mechz_robot_stomp_callback() +{ + self endon( "death" ); + + if ( isdefined( self.robot_stomped ) && self.robot_stomped ) + return; + + self.not_interruptable = 1; + self.robot_stomped = 1; + self mechz_interrupt(); +/# + if ( getdvarint( #"_id_E7121222" ) > 1 ) + println( "\\nMZ: Robot stomp setting not interruptable\\n" ); +#/ + self thread mechz_stomped_by_giant_robot_vo(); + v_trace_start = self.origin + vectorscale( ( 0, 0, 1 ), 100.0 ); + v_trace_end = self.origin - vectorscale( ( 0, 0, 1 ), 500.0 ); + v_trace = physicstrace( self.origin, v_trace_end, ( -15, -15, -5 ), ( 15, 15, 5 ), self ); + self.origin = v_trace["position"]; + timer = 0; + self animscripted( self.origin, self.angles, "zm_robot_hit_in" ); + self maps\mp\animscripts\zm_shared::donotetracks( "pain_anim" ); + anim_length = self getanimlengthfromasd( "zm_robot_hit_loop", 0 ); + + while ( timer < level.mechz_robot_knockdown_time ) + { + timer = timer + anim_length; + self animscripted( self.origin, self.angles, "zm_robot_hit_loop" ); + self maps\mp\animscripts\zm_shared::donotetracks( "pain_anim" ); + } + + self animscripted( self.origin, self.angles, "zm_robot_hit_out" ); + self maps\mp\animscripts\zm_shared::donotetracks( "jump_anim" ); +/# + if ( getdvarint( #"_id_E7121222" ) > 1 ) + println( "\\nMZ: Robot stomp clearing not interruptable\\n" ); +#/ + self.not_interruptable = 0; + self.robot_stomped = 0; +} + +mechz_delayed_item_delete() +{ + wait 30; + self delete(); +} + +mechz_get_closest_valid_player() +{ + players = get_players(); + + if ( isdefined( self.ignore_player ) ) + { + for ( i = 0; i < self.ignore_player.size; i++ ) + arrayremovevalue( players, self.ignore_player[i] ); + } + + for ( i = 0; i < players.size; i++ ) + { + if ( isdefined( level._zombie_using_humangun ) && level._zombie_using_humangun && isai( players[i] ) ) + return players[i]; + + if ( !is_player_valid( players[i], 1, 1 ) ) + { + arrayremovevalue( players, players[i] ); + i--; + } + } + + switch ( players.size ) + { + case 0: + return undefined; + case 1: + return players[0]; + default: + if ( isdefined( level.closest_player_override ) ) + player = [[ level.closest_player_override ]]( self.origin, players ); + else if ( isdefined( level.calc_closest_player_using_paths ) && level.calc_closest_player_using_paths ) + player = get_closest_player_using_paths( self.origin, players ); + else + player = getclosest( self.origin, players ); + + return player; + } +} + +get_favorite_enemy( origin, players ) +{ + mechz_targets = getplayers(); + least_hunted = undefined; + best_hunted_val = -1; + best_dist = -1; + distances = []; + + if ( isdefined( self.favoriteenemy ) && is_player_valid( self.favoriteenemy, 1, 1 ) && !isdefined( self.favoriteenemy.in_giant_robot_head ) && !self.favoriteenemy maps\mp\zm_tomb_chamber::is_player_in_chamber() ) + { + assert( isdefined( self.favoriteenemy.hunted_by ) ); + self.favoriteenemy.hunted_by--; + least_hunted = self.favoriteenemy; + } + + for ( i = 0; i < mechz_targets.size; i++ ) + { + if ( !isdefined( mechz_targets[i].hunted_by ) || mechz_targets[i].hunted_by < 0 ) + mechz_targets[i].hunted_by = 0; + + if ( !is_player_valid( mechz_targets[i], 1, 1 ) ) + { + distances[i] = undefined; + continue; + } + + distances[i] = distancesquared( self.origin, mechz_targets[i].origin ); + } + + found_weapon_target = 0; + + for ( i = 0; i < mechz_targets.size; i++ ) + { + if ( abs( mechz_targets[i].origin[2] - self.origin[2] ) > 60 ) + continue; + + dist = distances[i]; + + if ( !isdefined( dist ) ) + continue; + + if ( dist < 50000 && ( dist < best_dist || best_dist < 0 ) ) + { + found_weapon_target = 1; + least_hunted = mechz_targets[i]; + best_dist = dist; + } + } + + if ( found_weapon_target ) + { + least_hunted.hunted_by++; + return least_hunted; + } + + if ( isdefined( self.favoriteenemy ) && is_player_valid( self.favoriteenemy, 1, 1 ) ) + { + if ( distancesquared( self.origin, self.favoriteenemy.origin ) <= level.mechz_sticky_dist_sq ) + { + self.favoriteenemy.hunted_by++; + return self.favoriteenemy; + } + } + + for ( i = 0; i < mechz_targets.size; i++ ) + { + if ( isdefined( mechz_targets[i].in_giant_robot_head ) ) + continue; + + if ( mechz_targets[i] maps\mp\zm_tomb_chamber::is_player_in_chamber() ) + continue; + + if ( isdefined( distances[i] ) ) + dist = distances[i]; + else + continue; + + hunted = mechz_targets[i].hunted_by; + + if ( !isdefined( least_hunted ) || hunted <= least_hunted.hunted_by ) + { + if ( dist < best_dist || best_dist < 0 ) + { + least_hunted = mechz_targets[i]; + best_dist = dist; + } + } + } + + if ( isdefined( least_hunted ) ) + least_hunted.hunted_by++; + + return least_hunted; +} + +mechz_check_in_arc( right_offset ) +{ + origin = self.origin; + + if ( isdefined( right_offset ) ) + { + right_angle = anglestoright( self.angles ); + origin = origin + right_angle * right_offset; + } + + facing_vec = anglestoforward( self.angles ); + enemy_vec = self.favoriteenemy.origin - origin; + enemy_yaw_vec = ( enemy_vec[0], enemy_vec[1], 0 ); + facing_yaw_vec = ( facing_vec[0], facing_vec[1], 0 ); + enemy_yaw_vec = vectornormalize( enemy_yaw_vec ); + facing_yaw_vec = vectornormalize( facing_yaw_vec ); + enemy_dot = vectordot( facing_yaw_vec, enemy_yaw_vec ); + + if ( enemy_dot < cos( level.mechz_aim_max_yaw ) ) + return false; + + enemy_angles = vectortoangles( enemy_vec ); + + if ( abs( angleclamp180( enemy_angles[0] ) ) > level.mechz_aim_max_pitch ) + return false; + + return true; +} + +mechz_get_aim_anim( anim_prefix, target_pos, right_offset ) +{ + in_arc = self mechz_check_in_arc( right_offset ); + + if ( !in_arc ) + return undefined; + + origin = self.origin; + + if ( isdefined( right_offset ) ) + { + right_angle = anglestoright( self.angles ); + origin = origin + right_angle * right_offset; + } + + aiming_vec = vectortoangles( target_pos - origin ); + pitch = angleclamp180( aiming_vec[0] ); + yaw = angleclamp180( self.angles[1] - aiming_vec[1] ); + centered_ud = abs( pitch ) < level.mechz_aim_max_pitch / 2; + centered_lr = abs( yaw ) < level.mechz_aim_max_yaw / 2; + right_anim = angleclamp180( self.angles[1] - aiming_vec[1] ) > 0; + up_anim = pitch < 0; + + if ( centered_ud && centered_lr ) + return anim_prefix + "_aim_5"; + else if ( centered_ud && right_anim ) + return anim_prefix + "_aim_6"; + else if ( centered_ud ) + return anim_prefix + "_aim_4"; + else if ( centered_lr && up_anim ) + return anim_prefix + "_aim_8"; + else if ( centered_lr ) + return anim_prefix + "_aim_2"; + else if ( right_anim && up_anim ) + return anim_prefix + "_aim_9"; + else if ( right_anim ) + return anim_prefix + "_aim_3"; + else if ( up_anim ) + return anim_prefix + "_aim_7"; + else + return anim_prefix + "_aim_1"; +} + +mechz_start_basic_find_flesh() +{ + self.goalradius = level.mechz_custom_goalradius; + self.custom_goalradius_override = level.mechz_custom_goalradius; + + if ( !isdefined( self.ai_state ) || self.ai_state != "find_flesh" ) + { + self.ai_state = "find_flesh"; + self thread maps\mp\zombies\_zm_ai_basic::find_flesh(); + } +} + +mechz_stop_basic_find_flesh() +{ + if ( isdefined( self.ai_state ) && self.ai_state == "find_flesh" ) + { + self.ai_state = undefined; + self notify( "stop_find_flesh" ); + self notify( "zombie_acquire_enemy" ); + } +} + +watch_for_player_dist() +{ + self endon( "death" ); + + while ( true ) + { + player = mechz_get_closest_valid_player(); + + if ( isdefined( player ) && ( isdefined( player.is_player_slowed ) && player.is_player_slowed ) ) + reset_dist = level.mechz_reset_dist_sq / 2; + else + reset_dist = level.mechz_reset_dist_sq; + + if ( !isdefined( player ) || distancesquared( player.origin, self.origin ) > reset_dist ) + self.disable_complex_behaviors = 0; + + wait 0.5; + } +} + +mechz_find_flesh() +{ + self endon( "death" ); + level endon( "intermission" ); + + if ( level.intermission ) + return; + + self.helitarget = 1; + self.ignoreme = 0; + self.nododgemove = 1; + self.ignore_player = []; + self.goalradius = 32; + self.ai_state = "spawning"; + self thread watch_for_player_dist(); + + while ( true ) + { +/# + if ( isdefined( self.force_behavior ) && self.force_behavior ) + { + wait 0.05; + continue; + } +#/ + + if ( isdefined( self.not_interruptable ) && self.not_interruptable ) + { +/# + if ( getdvarint( #"_id_E7121222" ) > 1 ) + println( "\\nMZ: Not thinking since a behavior has set not_interruptable\\n" ); +#/ + wait 0.05; + continue; + } + + if ( isdefined( self.is_traversing ) && self.is_traversing ) + { +/# + if ( getdvarint( #"_id_E7121222" ) > 1 ) + println( "\\nMZ: Not thinking since mech is traversing\\n" ); +#/ + wait 0.05; + continue; + } + + player = [[ self.closest_player_override ]](); + self mechz_set_locomotion_speed(); +/# + if ( getdvarint( #"_id_E7121222" ) > 1 ) + println( "\\nMZ: Doing think\\n" ); +#/ + self.favoriteenemy = player; + + if ( !isdefined( player ) ) + { +/# + if ( getdvarint( #"_id_E7121222" ) > 1 ) + println( "\\n\\tMZ: No Enemy, idling\\n" ); +#/ + self.goal_pos = self.origin; + self setgoalpos( self.goal_pos ); + self.ai_state = "idle"; + self setanimstatefromasd( "zm_idle" ); + wait 0.5; + continue; + } + + if ( player entity_on_tank() ) + { + if ( level.vh_tank ent_flag( "tank_moving" ) ) + { + if ( isdefined( self.jump_pos ) && self mechz_in_range_for_jump() ) + { +/# + if ( getdvarint( #"_id_E7121222" ) > 1 ) + println( "\\n\\tMZ: Enemy on moving tank, do jump out and jump in when tank is stationary\\n" ); +#/ + self mechz_do_jump( 1 ); + } + else + { +/# + if ( getdvarint( #"_id_E7121222" ) > 1 ) + println( "\\n\\tMZ: Enemy on moving tank, Jump Requested, going to jump pos\\n" ); +#/ + + if ( !isdefined( self.jump_pos ) ) + self.jump_pos = get_closest_mechz_spawn_pos( self.origin ); + + if ( isdefined( self.jump_pos ) ) + { + self.goal_pos = self.jump_pos.origin; + self setgoalpos( self.goal_pos ); + } + + wait 0.5; + continue; + } + } + else + { +/# + if ( getdvarint( #"_id_E7121222" ) > 1 ) + println( "\\n\\tMZ: Enemy on tank, targetting a tank pos\\n" ); +#/ + self.disable_complex_behaviors = 0; + self mechz_stop_basic_find_flesh(); + self.ai_state = "tracking_tank"; + self.goalradius = level.mechz_custom_goalradius; + self.custom_goalradius_override = level.mechz_custom_goalradius; + closest_tank_tag = level.vh_tank get_closest_mechz_tag_on_tank( self, self.origin ); + + if ( !isdefined( closest_tank_tag ) ) + { +/# + if ( getdvarint( #"_id_E7121222" ) > 1 ) + println( "\\n\\tMZ: Enemy on tank, no closest tank pos found, continuing\\n" ); +#/ + wait 0.5; + continue; + } + + closest_tank_tag_pos = level.vh_tank gettagorigin( closest_tank_tag ); + + if ( abs( self.origin[2] - closest_tank_tag_pos[2] ) >= level.mechz_custom_goalradius || distance2dsquared( self.origin, closest_tank_tag_pos ) >= level.mechz_custom_goalradius_sq ) + { +/# + if ( getdvarint( #"_id_E7121222" ) > 1 ) + println( "\\n\\tMZ: Enemy on tank, setting tank pos as goal\\n" ); +#/ + self.goal_pos = closest_tank_tag_pos; + self setgoalpos( self.goal_pos ); + self waittill_any_or_timeout( 0.5, "goal", "bad_path" ); + + if ( !player entity_on_tank() ) + { +/# + if ( getdvarint( #"_id_E7121222" ) > 1 ) + println( "\\n\\tMZ: Enemy got off tank by the time we reached our goal, continuing\\n" ); +#/ + continue; + } + } + + if ( abs( self.origin[2] - closest_tank_tag_pos[2] ) < level.mechz_custom_goalradius && distance2dsquared( self.origin, closest_tank_tag_pos ) < level.mechz_custom_goalradius_sq ) + { +/# + if ( getdvarint( #"_id_E7121222" ) > 1 ) + println( "\\n\\tMZ: Enemy on tank, reached tank pos, doing flamethrower sweep\\n" ); +#/ + self.angles = vectortoangles( level.vh_tank.origin - self.origin ); + self mechz_do_flamethrower_attack( 1 ); + self notify( "tank_flamethrower_attack_complete" ); + } + } + + continue; + } + else if ( isdefined( self.jump_requested ) && self.jump_requested || isdefined( self.force_jump ) && self.force_jump ) + { + if ( self mechz_in_range_for_jump() ) + self mechz_do_jump(); + else + { +/# + if ( getdvarint( #"_id_E7121222" ) > 1 ) + println( "\\n\\tMZ: Jump Requested, going to jump pos\\n" ); +#/ + self.goal_pos = self.jump_pos.origin; + self setgoalpos( self.goal_pos ); + wait 0.5; + continue; + } + } + else if ( self.zombie_move_speed == "sprint" && isdefined( player ) ) + { +/# + if ( getdvarint( #"_id_E7121222" ) > 1 ) + println( "\\n\\tMZ: Sprinting\\n" ); +#/ + self.goal_pos = player.origin; + self setgoalpos( self.goal_pos ); + wait 0.5; + continue; + } + else if ( distancesquared( self.origin, player.origin ) < level.mechz_aggro_dist_sq ) + { +/# + if ( getdvarint( #"_id_E7121222" ) > 1 ) + println( "\\n\\tMZ: Player very close, switching to melee only\\n" ); +#/ + self.disable_complex_behaviors = 1; + } + else if ( self should_do_claw_attack() ) + { + self mechz_do_claw_grab(); + continue; + } + else if ( self should_do_flamethrower_attack() ) + { + self mechz_do_flamethrower_attack(); + continue; + } + +/# + if ( getdvarint( #"_id_E7121222" ) > 1 ) + println( "\\n\\tMZ: No special behavior valid, heading after player\\n" ); +#/ + self.goal_pos = player.origin; + + if ( isdefined( level.damage_prone_players_override_func ) ) + level thread [[ level.damage_prone_players_override_func ]](); + else + self thread damage_prone_players(); + + mechz_start_basic_find_flesh(); + wait 0.5; + } +} + +damage_prone_players() +{ + self endon( "death" ); + a_players = getplayers(); + + foreach ( player in a_players ) + { + if ( isdefined( self.favoriteenemy ) && self.favoriteenemy == player ) + { + n_dist = distance2dsquared( player.origin, self.origin ); + + if ( n_dist < 2025 ) + { + player_z = player.origin[2]; + mechz_z = self.origin[2]; + + if ( player_z < mechz_z && mechz_z - player_z <= 75 ) + { + if ( isdefined( self.meleedamage ) ) + idamage = self.meleedamage; + else + idamage = 50; + + player dodamage( idamage, self.origin, self, self, "none", "MOD_MELEE" ); + } + } + } + } +} + +melee_anim_func() +{ + self.next_leap_time = gettime() + 1500; +} + +mechz_launch_armor_piece() +{ + if ( !isdefined( self.next_armor_piece ) ) + self.next_armor_piece = 0; + + if ( !isdefined( self.armor_state ) || self.next_armor_piece >= self.armor_state.size ) + { +/# + println( "Trying to launch armor piece after all pieces have already been launched!" ); +#/ + return; + } + + if ( isdefined( self.armor_state[self.next_armor_piece].model ) ) + self detach( self.armor_state[self.next_armor_piece].model, self.armor_state[self.next_armor_piece].tag ); + + self.fx_field = self.fx_field | 1 << self.armor_state[self.next_armor_piece].index; + self setclientfield( "mechz_fx", self.fx_field ); + + if ( sndmechzisnetworksafe( "destruction" ) ) + self playsound( "zmb_ai_mechz_destruction" ); + + self.next_armor_piece++; +} + +mechz_damage_override( inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, shitloc, poffsettime, boneindex ) +{ + num_tiers = level.mechz_armor_info.size + 1; + old_health_tier = int( num_tiers * self.health / self.maxhealth ); + bonename = getpartname( "c_zom_mech_body", boneindex ); + + if ( isdefined( attacker ) && isalive( attacker ) && isplayer( attacker ) && ( level.zombie_vars[attacker.team]["zombie_insta_kill"] || isdefined( attacker.personal_instakill ) && attacker.personal_instakill ) ) + { + n_mechz_damage_percent = 1.0; + n_mechz_headshot_modifier = 2.0; + } + else + { + n_mechz_damage_percent = level.mechz_damage_percent; + n_mechz_headshot_modifier = 1.0; + } + + if ( isdefined( weapon ) && is_weapon_shotgun( weapon ) ) + { + n_mechz_damage_percent = n_mechz_damage_percent * level.mechz_shotgun_damage_mod; + n_mechz_headshot_modifier = n_mechz_headshot_modifier * level.mechz_shotgun_damage_mod; + } + + if ( damage <= 10 ) + n_mechz_damage_percent = 1.0; + + if ( is_explosive_damage( meansofdeath ) || issubstr( weapon, "staff" ) ) + { + if ( n_mechz_damage_percent < 0.5 ) + n_mechz_damage_percent = 0.5; + + if ( !( isdefined( self.has_helmet ) && self.has_helmet ) && issubstr( weapon, "staff" ) && n_mechz_damage_percent < 1.0 ) + n_mechz_damage_percent = 1.0; + + final_damage = damage * n_mechz_damage_percent; + + if ( !isdefined( self.explosive_dmg_taken ) ) + self.explosive_dmg_taken = 0; + + self.explosive_dmg_taken = self.explosive_dmg_taken + final_damage; + self.helmet_dmg = self.helmet_dmg + final_damage; + + if ( isdefined( self.explosive_dmg_taken_on_grab_start ) ) + { + if ( isdefined( self.e_grabbed ) && self.explosive_dmg_taken - self.explosive_dmg_taken_on_grab_start > level.mechz_explosive_dmg_to_cancel_claw ) + { + if ( isdefined( self.has_helmet ) && self.has_helmet && self.helmet_dmg < self.helmet_dmg_for_removal || !( isdefined( self.has_helmet ) && self.has_helmet ) ) + self thread mechz_claw_shot_pain_reaction(); + + self thread ent_released_from_claw_grab_achievement( attacker, self.e_grabbed ); + self thread mechz_claw_release(); + } + } + } + else if ( shitloc != "head" && shitloc != "helmet" ) + { + if ( bonename == "tag_powersupply" ) + { + final_damage = damage * n_mechz_damage_percent; + + if ( !( isdefined( self.powerplant_covered ) && self.powerplant_covered ) ) + self.powerplant_dmg = self.powerplant_dmg + final_damage; + else + self.powerplant_cover_dmg = self.powerplant_cover_dmg + final_damage; + } + + if ( isdefined( self.e_grabbed ) && ( shitloc == "left_hand" || shitloc == "left_arm_lower" || shitloc == "left_arm_upper" ) ) + { + if ( isdefined( self.e_grabbed ) ) + self thread mechz_claw_shot_pain_reaction(); + + self thread ent_released_from_claw_grab_achievement( attacker, self.e_grabbed ); + self thread mechz_claw_release( 1 ); + } + + final_damage = damage * n_mechz_damage_percent; + } + else if ( !( isdefined( self.has_helmet ) && self.has_helmet ) ) + final_damage = damage * n_mechz_headshot_modifier; + else + { + final_damage = damage * n_mechz_damage_percent; + self.helmet_dmg = self.helmet_dmg + final_damage; + } + + if ( !isdefined( weapon ) || weapon == "none" ) + { + if ( !isplayer( attacker ) ) + final_damage = 0; + } + + new_health_tier = int( num_tiers * ( self.health - final_damage ) / self.maxhealth ); + + if ( old_health_tier > new_health_tier ) + { + while ( old_health_tier > new_health_tier ) + { +/# + if ( getdvarint( #"_id_E7121222" ) > 0 ) + println( "\\nMZ: Old tier: " + old_health_tier + " New Health Tier: " + new_health_tier + " Launching armor piece" ); +#/ + + if ( old_health_tier < num_tiers ) + self mechz_launch_armor_piece(); + + old_health_tier--; + } + } + + if ( isdefined( self.has_helmet ) && self.has_helmet && self.helmet_dmg >= self.helmet_dmg_for_removal ) + { + self.has_helmet = 0; + self detach( "c_zom_mech_faceplate", "J_Helmet" ); + + if ( sndmechzisnetworksafe( "destruction" ) ) + self playsound( "zmb_ai_mechz_destruction" ); + + if ( sndmechzisnetworksafe( "angry" ) ) + self playsound( "zmb_ai_mechz_vox_angry" ); + + self.fx_field = self.fx_field | 1024; + self.fx_field = self.fx_field & ~2048; + self setclientfield( "mechz_fx", self.fx_field ); + + if ( !( isdefined( self.not_interruptable ) && self.not_interruptable ) && !( isdefined( self.is_traversing ) && self.is_traversing ) ) + { + self mechz_interrupt(); + self animscripted( self.origin, self.angles, "zm_pain_faceplate" ); + self maps\mp\animscripts\zm_shared::donotetracks( "pain_anim_faceplate" ); + } + + self thread shoot_mechz_head_vo(); + } + + if ( isdefined( self.powerplant_covered ) && self.powerplant_covered && self.powerplant_cover_dmg >= self.powerplant_cover_dmg_for_removal ) + { + self.powerplant_covered = 0; + self detach( "c_zom_mech_powersupply_cap", "tag_powersupply" ); + cap_model = spawn( "script_model", self gettagorigin( "tag_powersupply" ) ); + cap_model.angles = self gettagangles( "tag_powersupply" ); + cap_model setmodel( "c_zom_mech_powersupply_cap" ); + cap_model physicslaunch( cap_model.origin, anglestoforward( cap_model.angles ) ); + cap_model thread mechz_delayed_item_delete(); + + if ( sndmechzisnetworksafe( "destruction" ) ) + self playsound( "zmb_ai_mechz_destruction" ); + + if ( !( isdefined( self.not_interruptable ) && self.not_interruptable ) && !( isdefined( self.is_traversing ) && self.is_traversing ) ) + { + self mechz_interrupt(); + self animscripted( self.origin, self.angles, "zm_pain_powercore" ); + self maps\mp\animscripts\zm_shared::donotetracks( "pain_anim_powercore" ); + } + } + else if ( !( isdefined( self.powerplant_covered ) && self.powerplant_covered ) && ( isdefined( self.has_powerplant ) && self.has_powerplant ) && self.powerplant_dmg >= self.powerplant_dmg_for_destroy ) + { + self.has_powerplant = 0; + self thread mechz_stun( level.mechz_powerplant_stun_time ); + + if ( sndmechzisnetworksafe( "destruction" ) ) + self playsound( "zmb_ai_mechz_destruction" ); + } + +/# + if ( getdvarint( #"_id_E7121222" ) > 0 ) + { + println( "\\nMZ: Doing " + final_damage + " damage to mechz, Health Remaining: " + self.health ); + + if ( self.helmet_dmg < self.helmet_dmg_for_removal ) + println( "\\nMZ: Current helmet dmg: " + self.helmet_dmg + " Required helmet dmg: " + self.helmet_dmg_for_removal ); + } +#/ + return final_damage; +} + +mechz_non_attacker_damage_override( damage, weapon, attacker ) +{ + if ( attacker == level.vh_tank ) + self thread mechz_tank_hit_callback(); + + return false; +} + +mechz_instakill_override() +{ + +} + +mechz_nuke_override() +{ + self endon( "death" ); + wait( randomfloatrange( 0.1, 0.7 ) ); + self playsound( "evt_nuked" ); + self dodamage( self.health * 0.25, self.origin ); +} + +mechz_set_locomotion_speed() +{ + self endon( "death" ); + self.prev_move_speed = self.zombie_move_speed; + + if ( !isdefined( self.favoriteenemy ) ) + self.zombie_move_speed = "walk"; + else if ( isdefined( self.force_run ) && self.force_run ) + self.zombie_move_speed = "run"; + else if ( isdefined( self.force_sprint ) && self.force_sprint ) + self.zombie_move_speed = "sprint"; + else if ( isdefined( self.favoriteenemy ) && self.favoriteenemy entity_on_tank() && isdefined( level.vh_tank ) && level.vh_tank ent_flag( "tank_activated" ) ) + self.zombie_move_speed = "run"; + else if ( isdefined( self.favoriteenemy ) && distancesquared( self.origin, self.favoriteenemy.origin ) > level.mechz_dist_for_sprint ) + self.zombie_move_speed = "run"; + else if ( !( isdefined( self.has_powerplant ) && self.has_powerplant ) ) + self.zombie_move_speed = "walk"; + else + self.zombie_move_speed = "walk"; + + if ( self.zombie_move_speed == "sprint" && self.prev_move_speed != "sprint" ) + { + self mechz_interrupt(); + self animscripted( self.origin, self.angles, "zm_sprint_intro" ); + self maps\mp\animscripts\zm_shared::donotetracks( "jump_anim" ); + } + else if ( self.zombie_move_speed != "sprint" && self.prev_move_speed == "sprint" ) + { + self animscripted( self.origin, self.angles, "zm_sprint_outro" ); + self maps\mp\animscripts\zm_shared::donotetracks( "jump_anim" ); + } + + self set_zombie_run_cycle( self.zombie_move_speed ); +} + +response_to_air_raid_siren_vo() +{ + wait 3.0; + a_players = getplayers(); + + if ( a_players.size == 0 ) + return; + + a_players = array_randomize( a_players ); + + foreach ( player in a_players ) + { + if ( is_player_valid( player ) ) + { + if ( !( isdefined( player.dontspeak ) && player.dontspeak ) ) + { + if ( !isdefined( level.air_raid_siren_count ) ) + { + player maps\mp\zombies\_zm_audio::create_and_play_dialog( "general", "siren_1st_time" ); + level.air_raid_siren_count = 1; + + while ( isdefined( player ) && ( isdefined( player.isspeaking ) && player.isspeaking ) ) + wait 0.1; + + level thread start_see_mech_zombie_vo(); + break; + } + else if ( level.mechz_zombie_per_round == 1 ) + { + player maps\mp\zombies\_zm_audio::create_and_play_dialog( "general", "siren_generic" ); + break; + } + else + { + player maps\mp\zombies\_zm_audio::create_and_play_dialog( "general", "multiple_mechs" ); + break; + } + } + } + } +} + +start_see_mech_zombie_vo() +{ + wait 1.0; + a_zombies = getaispeciesarray( level.zombie_team, "all" ); + + foreach ( zombie in a_zombies ) + { + if ( isdefined( zombie.is_mechz ) && zombie.is_mechz ) + ai_mechz = zombie; + } + + a_players = getplayers(); + + if ( a_players.size == 0 ) + return; + + if ( isalive( ai_mechz ) ) + { + foreach ( player in a_players ) + player thread player_looking_at_mechz_watcher( ai_mechz ); + } +} + +player_looking_at_mechz_watcher( ai_mechz ) +{ + self endon( "disconnect" ); + ai_mechz endon( "death" ); + level endon( "first_mech_zombie_seen" ); + + while ( true ) + { + if ( distancesquared( self.origin, ai_mechz.origin ) < 1000000 ) + { + if ( self is_player_looking_at( ai_mechz.origin + vectorscale( ( 0, 0, 1 ), 60.0 ), 0.75 ) ) + { + if ( !( isdefined( self.dontspeak ) && self.dontspeak ) ) + { + self maps\mp\zombies\_zm_audio::create_and_play_dialog( "general", "discover_mech" ); + level notify( "first_mech_zombie_seen" ); + break; + } + } + } + + wait 0.1; + } +} + +mechz_grabbed_played_vo( ai_mechz ) +{ + self endon( "disconnect" ); + self maps\mp\zombies\_zm_audio::create_and_play_dialog( "general", "mech_grab" ); + + while ( isdefined( self ) && ( isdefined( self.isspeaking ) && self.isspeaking ) ) + wait 0.1; + + wait 1.0; + + if ( isalive( ai_mechz ) && isdefined( ai_mechz.e_grabbed ) ) + ai_mechz thread play_shoot_arm_hint_vo(); +} + +play_shoot_arm_hint_vo() +{ + self endon( "death" ); + + while ( true ) + { + if ( !isdefined( self.e_grabbed ) ) + return; + + a_players = getplayers(); + + foreach ( player in a_players ) + { + if ( player == self.e_grabbed ) + continue; + + if ( distancesquared( self.origin, player.origin ) < 1000000 ) + { + if ( player is_player_looking_at( self.origin + vectorscale( ( 0, 0, 1 ), 60.0 ), 0.75 ) ) + { + if ( !( isdefined( player.dontspeak ) && player.dontspeak ) ) + { + player maps\mp\zombies\_zm_audio::create_and_play_dialog( "general", "shoot_mech_arm" ); + return; + } + } + } + } + + wait 0.1; + } +} + +mechz_hint_vo() +{ + self endon( "death" ); + wait 30.0; + + while ( true ) + { + if ( self.health > self.maxhealth * 0.5 ) + { + wait 1.0; + continue; + } + + if ( !( isdefined( self.powerplant_covered ) && self.powerplant_covered ) ) + { + wait 1.0; + continue; + } + + a_players = getplayers(); + + foreach ( player in a_players ) + { + if ( isdefined( self.e_grabbed ) && self.e_grabbed == player ) + continue; + + if ( distancesquared( self.origin, player.origin ) < 1000000 ) + { + if ( player is_player_looking_at( self.origin + vectorscale( ( 0, 0, 1 ), 60.0 ), 0.75 ) ) + { + if ( !( isdefined( player.dontspeak ) && player.dontspeak ) ) + { + player maps\mp\zombies\_zm_audio::create_and_play_dialog( "general", "shoot_mech_power" ); + return; + } + } + } + } + + wait 0.1; + } +} + +shoot_mechz_head_vo() +{ + self endon( "death" ); + a_players = getplayers(); + + foreach ( player in a_players ) + { + if ( isdefined( self.e_grabbed ) && self.e_grabbed == player ) + continue; + + if ( distancesquared( self.origin, player.origin ) < 1000000 ) + { + if ( player is_player_looking_at( self.origin + vectorscale( ( 0, 0, 1 ), 60.0 ), 0.75 ) ) + { + if ( !( isdefined( player.dontspeak ) && player.dontspeak ) ) + { + player maps\mp\zombies\_zm_audio::create_and_play_dialog( "general", "shoot_mech_head" ); + return; + } + } + } + } +} + +mechz_jump_vo() +{ + a_players = getplayers(); + + foreach ( player in a_players ) + { + if ( distancesquared( self.origin, player.origin ) < 1000000 ) + { + if ( player is_player_looking_at( self.origin + vectorscale( ( 0, 0, 1 ), 60.0 ), 0.5 ) ) + { + if ( !( isdefined( player.dontspeak ) && player.dontspeak ) ) + { + player delay_thread( 3.0, maps\mp\zombies\_zm_audio::create_and_play_dialog, "general", "rspnd_mech_jump" ); + return; + } + } + } + } +} + +mechz_stomped_by_giant_robot_vo() +{ + self endon( "death" ); + wait 5.0; + a_players = getplayers(); + + foreach ( player in a_players ) + { + if ( distancesquared( self.origin, player.origin ) < 1000000 ) + { + if ( player is_player_looking_at( self.origin + vectorscale( ( 0, 0, 1 ), 60.0 ), 0.75 ) ) + { + if ( !( isdefined( player.dontspeak ) && player.dontspeak ) ) + { + player thread maps\mp\zombies\_zm_audio::create_and_play_dialog( "general", "robot_crush_mech" ); + return; + } + } + } + } +} + +init_anim_rate() +{ + self setclientfield( "anim_rate", 1 ); + n_rate = self getclientfield( "anim_rate" ); + self setentityanimrate( n_rate ); +} + +sndmechzisnetworksafe( type ) +{ + if ( !isdefined( level.sndmechz ) ) + level.sndmechz = []; + + if ( !isdefined( level.sndmechz[type] ) ) + level thread sndmechznetworkchoke( type ); + + if ( level.sndmechz[type] > 1 ) + return false; + + level.sndmechz[type]++; + return true; +} + +sndmechznetworkchoke( type ) +{ + while ( true ) + { + level.sndmechz[type] = 0; + wait_network_frame(); + } +} diff --git a/t6/scripts/zm/zm_tomb/M/M_zm_ai_mechz_claw.gsc b/t6/scripts/zm/zm_tomb/M/M_zm_ai_mechz_claw.gsc new file mode 100644 index 0000000..6c4bbc3 --- /dev/null +++ b/t6/scripts/zm/zm_tomb/M/M_zm_ai_mechz_claw.gsc @@ -0,0 +1,606 @@ +// T6 GSC SOURCE +// Generated by https://github.com/xensik/gsc-tool +#include maps\mp\zombies\_zm_zonemgr; +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_net; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zm_tomb_utility; +#include maps\mp\animscripts\zm_utility; +#include maps\mp\zm_tomb_tank; +#include maps\mp\zombies\_zm_ai_mechz_dev; +#include maps\mp\zombies\_zm_ai_mechz; +#include maps\mp\zombies\_zm_ai_mechz_ft; +#include maps\mp\animscripts\zm_shared; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\zombies\_zm_weap_riotshield_tomb; + +#using_animtree("mechz_claw"); + +mechz_claw_detach() +{ + if ( isdefined( self.m_claw ) ) + { + self.m_claw setanim( %ai_zombie_mech_grapple_arm_open_idle, 1, 0.2, 1 ); + + if ( isdefined( self.m_claw.fx_ent ) ) + self.m_claw.fx_ent delete(); + + self.m_claw unlink(); + self.m_claw physicslaunch( self.m_claw.origin, ( 0, 0, -1 ) ); + self.m_claw thread mechz_delayed_item_delete(); + self.m_claw = undefined; + } + + if ( isdefined( self.m_claw_damage_trigger ) ) + { + self.m_claw_damage_trigger unlink(); + self.m_claw_damage_trigger delete(); + self.m_claw_damage_trigger = undefined; + } +} + +mechz_claw_release( bopenclaw ) +{ + self.explosive_dmg_taken_on_grab_start = undefined; + + if ( isdefined( self.e_grabbed ) ) + { + if ( isplayer( self.e_grabbed ) ) + { + self.e_grabbed setclientfieldtoplayer( "mechz_grab", 0 ); + //self.e_grabbed allowcrouch( 1 ); + //self.e_grabbed allowprone( 1 ); + } + + if ( !isdefined( self.e_grabbed._fall_down_anchor ) ) + { + trace_start = self.e_grabbed.origin + vectorscale( ( 0, 0, 1 ), 70.0 ); + trace_end = self.e_grabbed.origin + vectorscale( ( 0, 0, -1 ), 500.0 ); + drop_trace = playerphysicstrace( trace_start, trace_end ) + vectorscale( ( 0, 0, 1 ), 24.0 ); + self.e_grabbed unlink(); + self.e_grabbed setorigin( drop_trace ); + } + + self.e_grabbed = undefined; + + if ( isdefined( bopenclaw ) && bopenclaw ) + self.m_claw setanim( %ai_zombie_mech_grapple_arm_open_idle, 1, 0.2, 1 ); + } + self setcandamage( 1 ); +} + +mechz_claw_shot_pain_reaction() +{ + self mechz_interrupt(); + self animscripted( self.origin, self.angles, "zm_head_pain" ); + self maps\mp\animscripts\zm_shared::donotetracks( "head_pain_anim" ); +} + +ent_released_from_claw_grab_achievement( e_releaser, e_held_by_mechz ) +{ + if ( isdefined( e_releaser ) && isdefined( e_held_by_mechz ) && isplayer( e_releaser ) && isplayer( e_held_by_mechz ) ) + { + if ( e_releaser == e_held_by_mechz ) + e_releaser notify( "mechz_grab_released_self" ); + else + e_releaser notify( "mechz_grab_released_friendly" ); + } +} + +mechz_claw_notetracks() +{ + self endon( "death" ); + self endon( "kill_claw" ); + self waittillmatch( "grapple_anim", "muzzleflash" ); + self waittillmatch( "grapple_anim", "end" ); +} + +mechz_claw_aim( target_pos ) +{ + self endon( "death" ); + self endon( "kill_claw" ); + self endon( "claw_complete" ); + aim_anim = mechz_get_aim_anim( "zm_grapple", target_pos ); + self animscripted( self.origin, self.angles, "zm_grapple_aim_start" ); + self thread mechz_claw_notetracks(); + self maps\mp\animscripts\zm_shared::donotetracks( "grapple_anim" ); + + while ( flag( "mechz_launching_claw" ) ) + { + self animscripted( self.origin, self.angles, aim_anim ); + self maps\mp\animscripts\zm_shared::donotetracks( "grapple_anim" ); + self clearanim( %root, 0.0 ); + } +} + +player_can_be_grabbed() +{ + if ( self getstance() == "prone" && ( isdefined( self.is_dtp ) && self.is_dtp ) ) + return false; + + if ( !is_player_valid( self, 1, 1 ) ) + return false; + + return true; +} + +mechz_claw_explosive_watcher() +{ + if ( !isdefined( self.explosive_dmg_taken ) ) + self.explosive_dmg_taken = 0; + + self.explosive_dmg_taken_on_grab_start = self.explosive_dmg_taken; +} + +mechz_unlink_on_laststand( mechz ) +{ + self endon( "death" ); + self endon( "disconnect" ); + mechz endon( "death" ); + mechz endon( "claw_complete" ); + mechz endon( "kill_claw" ); + + while ( true ) + { + if ( isdefined( self ) && self maps\mp\zombies\_zm_laststand::player_is_in_laststand() ) + { + mechz thread mechz_claw_release(); + return; + } + + wait 0.05; + } +} + +claw_grapple() +{ + self endon( "death" ); + self endon( "kill_claw" ); + + if ( !isdefined( self.favoriteenemy ) ) + return; + + v_claw_origin = self gettagorigin( "tag_claw" ); + v_claw_angles = vectortoangles( self.origin - self.favoriteenemy.origin ); + self.fx_field = self.fx_field | 256; + self setclientfield( "mechz_fx", self.fx_field ); + self.m_claw setanim( %ai_zombie_mech_grapple_arm_open_idle, 1, 0, 1 ); + self.m_claw unlink(); + self.m_claw.fx_ent = spawn( "script_model", self.m_claw gettagorigin( "tag_claw" ) ); + self.m_claw.fx_ent.angles = self.m_claw gettagangles( "tag_claw" ); + self.m_claw.fx_ent setmodel( "tag_origin" ); + self.m_claw.fx_ent linkto( self.m_claw, "tag_claw" ); + network_safe_play_fx_on_tag( "mech_claw", 1, level._effect["mechz_claw"], self.m_claw.fx_ent, "tag_origin" ); + v_enemy_origin = self.favoriteenemy.origin + vectorscale( ( 0, 0, 1 ), 36.0 ); + n_dist = distance( v_claw_origin, v_enemy_origin ); + n_time = n_dist / 1800;//Hook Launch speed + self playsound( "zmb_ai_mechz_claw_fire" ); + self.m_claw moveto( v_enemy_origin, n_time ); + self.m_claw thread check_for_claw_move_complete(); + self.m_claw playloopsound( "zmb_ai_mechz_claw_loop_out", 0.1 ); + self.e_grabbed = undefined; + + do + { + a_players = getplayers(); + self setcandamage( 0 ); + foreach ( player in a_players ) + { + if ( !is_player_valid( player, 1, 1 ) || !player player_can_be_grabbed() ) + continue; + + n_dist_sq = distancesquared( player.origin + vectorscale( ( 0, 0, 1 ), 36.0 ), self.m_claw.origin ); + + if ( n_dist_sq < 2304 ) + { + if ( isdefined( player.hasriotshield ) && player.hasriotshield && player getcurrentweapon() == level.riotshield_name ) + { + shield_dmg = level.zombie_vars["riotshield_hit_points"]; + player maps\mp\zombies\_zm_weap_riotshield_tomb::player_damage_shield( shield_dmg - 1, 1 ); + wait 1; + player maps\mp\zombies\_zm_weap_riotshield_tomb::player_damage_shield( 1, 1 ); + } + else + { + self.e_grabbed = player;self setcandamage( 0 ); + self.e_grabbed setclientfieldtoplayer( "mechz_grab", 1 ); + self.e_grabbed playerlinktodelta( self.m_claw, "tag_attach_player" ); + //self.e_grabbed setplayerangles( vectortoangles( self.origin - self.e_grabbed.origin ) ); + self.e_grabbed playsound( "zmb_ai_mechz_claw_grab" ); + self.e_grabbed setstance( "stand" ); + //self.e_grabbed allowcrouch( 0 ); + //self.e_grabbed allowprone( 0 ); + self.e_grabbed thread mechz_grabbed_played_vo( self ); + + if ( !flag( "mechz_claw_move_complete" ) ) + self.m_claw moveto( self.m_claw.origin, 0.05 ); + } + + break; + } + } + + wait 0.05; + } + while (!flag( "mechz_claw_move_complete" ) && !isdefined( self.e_grabbed ) ); + + if ( !isdefined( self.e_grabbed ) ) + { + a_ai_zombies = get_round_enemy_array(); + + foreach ( ai_zombie in a_ai_zombies ) + { + if ( !isalive( ai_zombie ) || isdefined( ai_zombie.is_giant_robot ) && ai_zombie.is_giant_robot || isdefined( ai_zombie.is_mechz ) && ai_zombie.is_mechz ) + continue; + + n_dist_sq = distancesquared( ai_zombie.origin + vectorscale( ( 0, 0, 1 ), 36.0 ), self.m_claw.origin ); + + if ( n_dist_sq < 2304 ) + { + self.e_grabbed = ai_zombie; + self.e_grabbed linkto( self.m_claw, "tag_attach_player", ( 0, 0, 0 ) ); + self.e_grabbed.mechz_grabbed_by = self; + self.e_grabbed animcustom( ::zombie_grabbed_by_mechz_claw ); + break; + } + } + } + + self.m_claw clearanim( %root, 0.2 ); + self.m_claw setanim( %ai_zombie_mech_grapple_arm_closed_idle, 1, 0.2, 1 ); + wait 0.5;//after grab idle time and wait time for hook before pulling + + if ( isdefined( self.e_grabbed ) ) + n_time = n_dist / 100000;//pull player time + else + n_time = n_dist / 100000;//pull empty time + + self mechz_claw_explosive_watcher(); + v_claw_origin = self gettagorigin( "tag_claw" ); + v_claw_angles = self gettagangles( "tag_claw" ); + self.m_claw moveto( v_claw_origin, max( 0.05, n_time ) ); + self.m_claw playloopsound( "zmb_ai_mechz_claw_loop_in", 0.1 ); + self.m_claw waittill( "movedone" ); + v_claw_origin = self gettagorigin( "tag_claw" ); + v_claw_angles = self gettagangles( "tag_claw" ); + self.m_claw playsound( "zmb_ai_mechz_claw_back" ); + self.m_claw stoploopsound( 1 ); + + if ( maps\mp\zombies\_zm_ai_mechz::sndmechzisnetworksafe( "angry" ) ) + self playsound( "zmb_ai_mechz_vox_angry" ); + + self.m_claw.origin = v_claw_origin; + self.m_claw.angles = v_claw_angles; + self.m_claw clearanim( %root, 0.2 ); + self.m_claw linkto( self, "tag_claw", ( 0, 0, 0 ) ); + self.m_claw setanim( %ai_zombie_mech_grapple_arm_closed_idle, 1, 0.2, 1 ); + self.m_claw.fx_ent delete(); + self.m_claw.fx_ent = undefined; + self.fx_field = self.fx_field & ~256; + //self.fx_field = self.fx_field & ~300; + self setclientfield( "mechz_fx", self.fx_field ); + flag_clear( "mechz_launching_claw" ); + + if ( isdefined( self.e_grabbed ) ) + { + if ( !isdefined( self.flamethrower_trigger ) ) + self mechz_flamethrower_initial_setup(); + + if ( isplayer( self.e_grabbed ) && is_player_valid( self.e_grabbed ) ) + self.e_grabbed thread mechz_unlink_on_laststand( self ); + else if ( isai( self.e_grabbed ) ) + { + self mechz_interrupt(); + self animscripted( self.origin, self.angles, "zm_head_pain" ); + self maps\mp\animscripts\zm_shared::donotetracks( "head_pain_anim" ); + } + + self thread check_for_claw_damaged( self.e_grabbed ); + self animscripted( self.origin, self.angles, "zm_flamethrower_claw_victim" ); + self maps\mp\animscripts\zm_shared::donotetracks( "flamethrower_anim" ); + } + + flag_clear( "mechz_claw_move_complete" ); +} + +zombie_grabbed_by_mechz_claw() +{ + self endon( "death" ); + self setanimstatefromasd( "zm_grabbed_by_mech" ); + self.mechz_grabbed_by waittill_any( "death", "claw_complete", "kill_claw" ); +} + +check_for_claw_damaged( player ) +{ + player endon( "death" ); + player endon( "disconnect" ); + self endon( "death" ); + self endon( "claw_complete" ); + self endon( "kill_claw" ); + self thread claw_damaged_mechz_endon_watcher( player ); + player thread claw_damaged_player_endon_watcher( self ); + self.m_claw setcandamage( 1 ); + + while ( isdefined( self.e_grabbed ) ) + { + self.m_claw waittill( "damage", amount, inflictor, direction, point, type, tagname, modelname, partname, weaponname, idflags ); + + if ( is_player_valid( inflictor ) ) + { + self dodamage( 1, inflictor.origin, inflictor, inflictor, "left_hand", type ); + self.m_claw setcandamage( 0 ); + self notify( "claw_damaged" ); + break; + } + } +} + +claw_damaged_mechz_endon_watcher( player ) +{ + self endon( "claw_damaged" ); + player endon( "death" ); + player endon( "disconnect" ); + self waittill_any( "death", "claw_complete", "kill_claw" ); + + if ( isdefined( self ) && isdefined( self.m_claw ) ) + self.m_claw setcandamage( 0 ); +} + +claw_damaged_player_endon_watcher( mechz ) +{ + mechz endon( "claw_damaged" ); + mechz endon( "death" ); + mechz endon( "claw_complete" ); + mechz endon( "kill_claw" ); + self waittill_any( "death", "disconnect" ); + + if ( isdefined( mechz ) && isdefined( mechz.m_claw ) ) + mechz.m_claw setcandamage( 0 ); +} + +check_for_players_mid_grapple() +{ + self endon( "movedone" ); + + while ( true ) + { + a_players = getplayers(); + + foreach ( player in a_players ) + { + if ( !is_player_valid( player, 1, 1 ) || !player player_can_be_grabbed() ) + continue; + + n_dist_sq = distancesquared( player.origin + vectorscale( ( 0, 0, 1 ), 36.0 ), self.origin ); + + if ( n_dist_sq < 2304 ) + { + self moveto( self.origin, 0.05 ); + self notify( "movedone" ); + return; + } + } + + wait 0.05; + } +} + +check_for_claw_move_complete() +{ + self waittill( "movedone" ); + wait 0.05; + flag_set( "mechz_claw_move_complete" ); +} + +mechz_zombie_flamethrower_gib( mechz ) +{ + mechz waittillmatch( "flamethrower_anim", "start_ft" ); + + if ( isalive( self ) ) + { + self thread zombie_gib_all(); + self dodamage( self.health, self.origin, self ); + } +} + +should_do_claw_attack() +{ + assert( isdefined( self.favoriteenemy ) ); +/# + if ( getdvarint( #"_id_E7121222" ) > 1 ) + println( "\\n\\tMZ: Checking should claw\\n" ); +#/ + + if ( !( isdefined( self.has_powerplant ) && self.has_powerplant ) ) + { +/# + if ( getdvarint( #"_id_E7121222" ) > 1 ) + println( "\\n\\t\\tMZ: Not doing claw because powerplant has been destroyed\\n" ); +#/ + return false; + } + + if ( isdefined( self.disable_complex_behaviors ) && self.disable_complex_behaviors ) + { +/# + if ( getdvarint( #"_id_E7121222" ) > 1 ) + println( "\\n\\t\\tMZ: Not doing claw because doing force aggro\\n" ); +#/ + return false; + } + + if ( isdefined( self.not_interruptable ) && self.not_interruptable ) + { +/# + if ( getdvarint( #"_id_E7121222" ) > 1 ) + println( "\\n\\t\\tMZ: Not doing claw because another behavior has set not_interruptable\\n" ); +#/ + return false; + } + + if ( isdefined( self.last_claw_time ) && gettime() - self.last_claw_time < level.mechz_claw_cooldown_time ) + { +/# + if ( getdvarint( #"_id_E7121222" ) > 1 ) + println( "\\n\\t\\tMZ: Not doing claw because claw is on cooldown\\n" ); +#/ + return false; + } + + if ( !self mechz_check_in_arc() ) + { +/# + if ( getdvarint( #"_id_E7121222" ) > 1 ) + println( "\\n\\t\\tMZ: Not doing claw because target is not in front arc\\n" ); +#/ + return false; + } + + n_dist_sq = distancesquared( self.origin, self.favoriteenemy.origin ); + + if ( n_dist_sq < 60000 || n_dist_sq > 2000000 ) + { +/# + if ( getdvarint( #"_id_E7121222" ) > 1 ) + println( "\\n\\t\\tMZ: Not doing claw because target is not in range\\n" ); +#/ + return false; + } + + if ( !self.favoriteenemy player_can_be_grabbed() ) + { +/# + if ( getdvarint( #"_id_E7121222" ) > 1 ) + println( "\\n\\t\\tMZ: Not doing claw because player is prone or dtp\\n" ); +#/ + return false; + } + + curr_zone = get_zone_from_position( self.origin + vectorscale( ( 0, 0, 1 ), 36.0 ) ); + + if ( isdefined( curr_zone ) && "ug_bottom_zone" == curr_zone ) + { +/# + if ( getdvarint( #"_id_E7121222" ) > 1 ) + println( "\\n\\t\\tMZ: Not doing claw because mech is in main chamber\\n" ); +#/ + return false; + } + + clip_mask = level.physicstracemaskclip | level.physicstracemaskphysics; + claw_origin = self.origin + vectorscale( ( 0, 0, 1 ), 65.0 ); + trace = physicstrace( claw_origin, self.favoriteenemy.origin + vectorscale( ( 0, 0, 1 ), 30.0 ), ( -15, -15, -20 ), ( 15, 15, 40 ), self, clip_mask ); + b_cansee = trace["fraction"] == 1.0 || isdefined( trace["entity"] ) && trace["entity"] == self.favoriteenemy; + + if ( !b_cansee ) + { +/# + if ( getdvarint( #"_id_E7121222" ) > 1 ) + println( "\\n\\t\\tMZ: Not doing claw because capsule trace failed\\n" ); +#/ + return false; + } + + return true; +} + +mechz_do_claw_grab() +{ + self endon( "death" ); + self endon( "kill_claw" ); +/# + if ( getdvarint( #"_id_E7121222" ) > 0 ) + println( "\\n\\tMZ: Doing Claw Attack\\n" ); +#/ + assert( isdefined( self.favoriteenemy ) ); + self thread mechz_kill_claw_watcher(); + self.last_claw_time = gettime(); + target_pos = self.favoriteenemy.origin + vectorscale( ( 0, 0, 1 ), 30.0 ); + self thread mechz_stop_basic_find_flesh(); + self.ai_state = "grapple_attempt"; + flag_set( "mechz_launching_claw" ); + self thread mechz_claw_aim( target_pos ); + self orientmode( "face enemy" ); + self waittillmatch( "grapple_anim", "muzzleflash" ); + self claw_grapple(); + self mechz_claw_cleanup(); +} + +mechz_kill_claw_watcher() +{ + self endon( "claw_complete" ); + self waittill_either( "death", "kill_claw" ); + self mechz_claw_cleanup(); +} + +mechz_claw_cleanup() +{ + self.fx_field = self.fx_field & ~256; + self.fx_field = self.fx_field & ~64; + self setclientfield( "mechz_fx", self.fx_field ); + self mechz_claw_release(); + + if ( isdefined( self.m_claw ) ) + { + self.m_claw clearanim( %root, 0.2 ); + + if ( isdefined( self.m_claw.fx_ent ) ) + { + self.m_claw.fx_ent delete(); + self.m_claw.fx_ent = undefined; + } + + if ( !( isdefined( self.has_powerplant ) && self.has_powerplant ) ) + { + self mechz_claw_detach(); + flag_clear( "mechz_launching_claw" ); + } + else + { + if ( !self.m_claw islinkedto( self ) ) + { + v_claw_origin = self gettagorigin( "tag_claw" ); + v_claw_angles = self gettagangles( "tag_claw" ); + n_dist = distance( self.m_claw.origin, v_claw_origin ); + n_time = n_dist / 10; + self.m_claw moveto( v_claw_origin, max( 0.05, n_time ) ); + self.m_claw playloopsound( "zmb_ai_mechz_claw_loop_in", 0.1 ); + self.m_claw waittill( "movedone" ); + v_claw_origin = self gettagorigin( "tag_claw" ); + v_claw_angles = self gettagangles( "tag_claw" ); + self.m_claw playsound( "zmb_ai_mechz_claw_back" ); + self.m_claw stoploopsound( 1 ); + self.m_claw.origin = v_claw_origin; + self.m_claw.angles = v_claw_angles; + self.m_claw clearanim( %root, 0.2 ); + self.m_claw linkto( self, "tag_claw", ( 0, 0, 0 ) ); + } + + self.m_claw setanim( %ai_zombie_mech_grapple_arm_closed_idle, 1, 0.2, 1 ); + } + } + + self notify( "claw_complete" ); +} + +mechz_claw_damage_trigger_thread() +{ + self endon( "death" ); + self.m_claw_damage_trigger endon( "death" ); + + while ( true ) + { + self.m_claw_damage_trigger waittill( "damage", amount, inflictor, direction, point, type, tagname, modelname, partname, weaponname, idflags ); + + if ( self.m_claw islinkedto( self ) ) + continue; + + if ( is_player_valid( inflictor ) ) + { + self dodamage( 1, inflictor.origin, inflictor, inflictor, "left_hand", type ); + self.m_claw setcandamage( 0 ); + self notify( "claw_damaged" ); + } + } +} \ No newline at end of file diff --git a/t6/scripts/zm/zm_tomb/M/M_zm_tomb.gsc b/t6/scripts/zm/zm_tomb/M/M_zm_tomb.gsc new file mode 100644 index 0000000..9b97782 --- /dev/null +++ b/t6/scripts/zm/zm_tomb/M/M_zm_tomb.gsc @@ -0,0 +1,2194 @@ +// T6 GSC SOURCE +// Generated by https://github.com/xensik/gsc-tool +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zm_tomb_utility; +#include maps\mp\zm_tomb_gamemodes; +#include maps\mp\zm_tomb_fx; +#include maps\mp\zm_tomb_ffotd; +#include maps\mp\zm_tomb_tank; +#include maps\mp\zm_tomb_quest_fire; +#include maps\mp\zm_tomb_capture_zones; +#include maps\mp\zm_tomb_teleporter; +#include maps\mp\zm_tomb_giant_robot; +#include maps\mp\zombies\_zm; +#include maps\mp\animscripts\zm_death; +#include maps\mp\zm_tomb_amb; +#include maps\mp\zombies\_zm_ai_mechz; +#include maps\mp\zombies\_zm_ai_quadrotor; +#include maps\mp\zombies\_load; +#include maps\mp\gametypes_zm\_spawning; +#include maps\mp\zm_tomb_vo; +#include maps\mp\zombies\_zm_perk_divetonuke; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm_perk_electric_cherry; +#include maps\mp\zombies\_zm_weap_one_inch_punch; +#include maps\mp\zombies\_zm_weap_staff_fire; +#include maps\mp\zombies\_zm_weap_staff_water; +#include maps\mp\zombies\_zm_weap_staff_lightning; +#include maps\mp\zombies\_zm_weap_staff_air; +#include maps\mp\zm_tomb; +#include maps\mp\zm_tomb_achievement; +#include maps\mp\zm_tomb_distance_tracking; +#include maps\mp\zombies\_zm_magicbox_tomb; +#include maps\mp\zombies\_zm_spawner; +#include maps\mp\zm_tomb_challenges; +#include maps\mp\zombies\_zm_perk_random; +#include maps\mp\_sticky_grenade; +#include maps\mp\zombies\_zm_weap_beacon; +#include maps\mp\zombies\_zm_weap_claymore; +#include maps\mp\zombies\_zm_weap_riotshield_tomb; +#include maps\mp\zombies\_zm_weap_staff_revive; +#include maps\mp\zombies\_zm_weap_cymbal_monkey; +#include maps\mp\zm_tomb_ambient_scripts; +#include maps\mp\zm_tomb_dig; +#include maps\mp\zm_tomb_main_quest; +#include maps\mp\zm_tomb_ee_main; +#include maps\mp\zm_tomb_ee_side; +#include maps\mp\zombies\_zm_zonemgr; +#include maps\mp\zm_tomb_chamber; +#include maps\mp\_visionset_mgr; +#include maps\mp\zombies\_zm_audio; +#include character\c_usa_dempsey_dlc4; +#include character\c_rus_nikolai_dlc4; +#include character\c_ger_richtofen_dlc4; +#include character\c_jap_takeo_dlc4; +#include maps\mp\zombies\_zm_powerup_zombie_blood; +#include maps\mp\zombies\_zm_devgui; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_challenges; +#include maps\mp\zombies\_zm_laststand; + +gamemode_callback_setup() +{ + maps\mp\zm_tomb_gamemodes::init(); +} + +survival_init() +{ + level.force_team_characters = 1; + level.should_use_cia = 0; + + if ( randomint( 100 ) > 50 ) + level.should_use_cia = 1; + + level.precachecustomcharacters = ::precache_team_characters; + level.givecustomcharacters = ::give_team_characters; + flag_wait( "start_zombie_round_logic" ); +} + +zstandard_preinit() +{ + +} + +createfx_callback() +{ + ents = getentarray(); + + for ( i = 0; i < ents.size; i++ ) + { + if ( ents[i].classname != "info_player_start" ) + ents[i] delete(); + } +} + +main() +{ + level._no_equipment_activated_clientfield = 1; + level._no_navcards = 1; + level._wallbuy_override_num_bits = 1; + maps\mp\zm_tomb_fx::main(); + level thread maps\mp\zm_tomb_ffotd::main_start(); + level.default_game_mode = "zclassic"; + level.default_start_location = "tomb"; + setup_rex_starts(); + maps\mp\zm_tomb_tank::init_animtree(); + maps\mp\zm_tomb_quest_fire::init_animtree(); + maps\mp\zm_tomb_capture_zones::init_pap_animtree(); + maps\mp\zm_tomb_teleporter::init_animtree(); + maps\mp\zm_tomb_giant_robot::init_animtree(); + level.fx_exclude_edge_fog = 1; + level.fx_exclude_tesla_head_light = 1; + level.fx_exclude_default_explosion = 1; + level.fx_exclude_footsteps = 1; + level._uses_sticky_grenades = 1; + level.disable_fx_zmb_wall_buy_semtex = 1; + level._uses_taser_knuckles = 0; + level.disable_fx_upgrade_aquired = 1; + level._uses_default_wallbuy_fx = 0; + maps\mp\zombies\_zm::init_fx(); + maps\mp\animscripts\zm_death::precache_gib_fx(); + level.zombiemode = 1; + level._no_water_risers = 1; + level.riser_fx_on_client = 1; + maps\mp\zm_tomb_amb::main(); + maps\mp\zombies\_zm_ai_mechz::precache(); + maps\mp\zombies\_zm_ai_quadrotor::precache(); + level.n_active_ragdolls = 0; + level.ragdoll_limit_check = ::ragdoll_attempt; + level._limited_equipment = []; + level._limited_equipment[level._limited_equipment.size] = "equip_dieseldrone_zm"; + level._limited_equipment[level._limited_equipment.size] = "staff_fire_zm"; + level._limited_equipment[level._limited_equipment.size] = "staff_air_zm"; + level._limited_equipment[level._limited_equipment.size] = "staff_lightning_zm"; + level._limited_equipment[level._limited_equipment.size] = "staff_water_zm"; + level.a_func_vehicle_damage_override = []; + level.callbackvehicledamage = ::tomb_vehicle_damage_override_wrapper; + level.level_specific_stats_init = ::init_tomb_stats; + maps\mp\zombies\_load::main(); + setdvar( "zombiemode_path_minz_bias", 13 ); + setdvar( "tu14_bg_chargeShotExponentialAmmoPerChargeLevel", 1 ); + + if ( getdvar( #"createfx" ) == "1" ) + return; + + level_precache(); + maps\mp\gametypes_zm\_spawning::level_use_unified_spawning( 1 ); + level thread setup_tomb_spawn_groups(); + spawner_main_chamber_capture_zombies = getent( "chamber_capture_zombie_spawner", "targetname" ); + spawner_main_chamber_capture_zombies add_spawn_function( ::chamber_capture_zombie_spawn_init ); + level.has_richtofen = 0; + level.givecustomloadout = ::givecustomloadout; + level.precachecustomcharacters = ::precache_personality_characters; + level.givecustomcharacters = ::give_personality_characters; + level.setupcustomcharacterexerts = ::setup_personality_character_exerts; + level._zmbvoxlevelspecific = maps\mp\zm_tomb_vo::init_level_specific_audio; + level.custom_player_track_ammo_count = ::tomb_custom_player_track_ammo_count; + level.custom_player_fake_death = ::zm_player_fake_death; + level.custom_player_fake_death_cleanup = ::zm_player_fake_death_cleanup; + level.initial_round_wait_func = ::initial_round_wait_func; + level.zombie_init_done = ::zombie_init_done; + level._zombies_round_spawn_failsafe = ::tomb_round_spawn_failsafe; + level.random_pandora_box_start = 1; + level.zombiemode_using_pack_a_punch = 1; + level.zombiemode_reusing_pack_a_punch = 1; + level.zombiemode_using_juggernaut_perk = 1; + level.zombiemode_using_revive_perk = 1; + level.zombiemode_using_sleightofhand_perk = 1; + level.zombiemode_using_additionalprimaryweapon_perk = 1; + level.zombiemode_using_marathon_perk = 1; + level.zombiemode_using_deadshot_perk = 1; + level.zombiemode_using_doubletap_perk = 1; + level.zombiemode_using_random_perk = 1; + level.zombiemode_using_divetonuke_perk = 1; + maps\mp\zombies\_zm_perk_divetonuke::enable_divetonuke_perk_for_level(); + level.custom_electric_cherry_perk_threads = maps\mp\zombies\_zm_perks::register_perk_threads( "specialty_grenadepulldeath", ::tomb_custom_electric_cherry_reload_attack, maps\mp\zombies\_zm_perk_electric_cherry::electric_cherry_perk_lost ); + level.zombiemode_using_electric_cherry_perk = 1; + maps\mp\zombies\_zm_perk_electric_cherry::enable_electric_cherry_perk_for_level(); + level.flopper_network_optimized = 1; + level.perk_random_vo_func_usemachine = maps\mp\zm_tomb_vo::wunderfizz_used_vo; + maps\mp\zombies\_zm_weap_one_inch_punch::one_inch_precache(); + maps\mp\zombies\_zm_weap_staff_fire::precache(); + maps\mp\zombies\_zm_weap_staff_water::precache(); + maps\mp\zombies\_zm_weap_staff_lightning::precache(); + maps\mp\zombies\_zm_weap_staff_air::precache(); + level._custom_turn_packapunch_on = maps\mp\zm_tomb_capture_zones::pack_a_punch_dummy_init; + level.custom_vending_precaching = maps\mp\zm_tomb::custom_vending_precaching; + level.register_offhand_weapons_for_level_defaults_override = ::offhand_weapon_overrride; + level.zombiemode_offhand_weapon_give_override = ::offhand_weapon_give_override; + level._zombie_custom_add_weapons = ::custom_add_weapons; + level._allow_melee_weapon_switching = 1; + include_equipment( "equip_dieseldrone_zm" ); + include_equipment( "tomb_shield_zm" ); + level.custom_ai_type = []; + level.raygun2_included = 1; + include_weapons(); + include_powerups(); + include_perks_in_random_rotation(); + level maps\mp\zm_tomb_achievement::init(); + precacheitem( "death_throe_zm" ); + + if ( level.splitscreen && getdvarint( #"splitscreen_playerCount" ) > 2 ) + level.optimise_for_splitscreen = 1; + else + level.optimise_for_splitscreen = 0; + + if ( isdefined( level.optimise_for_splitscreen ) && level.optimise_for_splitscreen ) + level.culldist = 2500; + else + level.culldist = 5500; + + setculldist( level.culldist ); + level thread maps\mp\zm_tomb_distance_tracking::zombie_tracking_init(); + maps\mp\zombies\_zm_magicbox_tomb::init(); + level.special_weapon_magicbox_check = ::tomb_special_weapon_magicbox_check; + maps\mp\zombies\_zm::init(); + level.callbackactordamage = ::tomb_actor_damage_override_wrapper; + level._weaponobjects_on_player_connect_override = ::tomb_weaponobjects_on_player_connect_override; + maps\mp\zombies\_zm_spawner::register_zombie_death_event_callback( ::tomb_zombie_death_event_callback ); + level.player_intersection_tracker_override = ::tomb_player_intersection_tracker_override; + maps\mp\zm_tomb_challenges::challenges_init(); + maps\mp\zombies\_zm_perk_random::init(); + tomb_register_client_fields(); + register_burn_overlay(); + level thread maps\mp\_sticky_grenade::init(); + maps\mp\zm_tomb_tank::init(); + maps\mp\zombies\_zm_weap_beacon::init(); + maps\mp\zombies\_zm_weap_claymore::init(); + maps\mp\zombies\_zm_weap_riotshield_tomb::init(); + maps\mp\zombies\_zm_weap_staff_air::init(); + maps\mp\zombies\_zm_weap_staff_fire::init(); + maps\mp\zombies\_zm_weap_staff_lightning::init(); + maps\mp\zombies\_zm_weap_staff_water::init(); + maps\mp\zombies\_zm_weap_staff_revive::init(); + maps\mp\zombies\_zm_weap_cymbal_monkey::init(); + level._melee_weapons = []; + maps\mp\zm_tomb_giant_robot::init_giant_robot_glows(); + maps\mp\zm_tomb_giant_robot::init_giant_robot(); + level.can_revive = maps\mp\zm_tomb_giant_robot::tomb_can_revive_override; + maps\mp\zm_tomb_capture_zones::init_capture_zones(); + level.a_e_slow_areas = getentarray( "player_slow_area", "targetname" ); + maps\mp\zm_tomb_ambient_scripts::init_tomb_ambient_scripts(); + level thread maps\mp\zombies\_zm_ai_mechz::init(); + level thread maps\mp\zombies\_zm_perk_random::init_animtree(); + level thread maps\mp\zombies\_zm_ai_quadrotor::init(); + level.zombiemode_divetonuke_perk_func = ::tomb_custom_divetonuke_explode; + set_zombie_var( "zombie_perk_divetonuke_min_damage", 500 ); + set_zombie_var( "zombie_perk_divetonuke_max_damage", 2000 ); + level.custom_laststand_func = ::tomb_custom_electric_cherry_laststand; + maps\mp\zm_tomb_dig::init_shovel(); + level.n_crystals_pickedup = 0; + level thread maps\mp\zm_tomb_main_quest::main_quest_init(); + level thread maps\mp\zm_tomb_teleporter::teleporter_init(); + level thread maps\mp\zombies\_zm_perk_random::start_random_machine(); + level.closest_player_override = ::tomb_closest_player_override; + level.validate_enemy_path_length = ::tomb_validate_enemy_path_length; + level thread maps\mp\zm_tomb_ee_main::init(); + level thread maps\mp\zm_tomb_ee_side::init(); + level.zones = []; + level.zone_manager_init_func = ::working_zone_init; + init_zones[0] = "zone_start"; + level thread maps\mp\zombies\_zm_zonemgr::manage_zones( init_zones ); + + if ( isdefined( level.optimise_for_splitscreen ) && level.optimise_for_splitscreen ) + { + if ( is_classic() ) + level.zombie_ai_limit = 20; + + setdvar( "fx_marks_draw", 0 ); + setdvar( "disable_rope", 1 ); + setdvar( "cg_disableplayernames", 1 ); + setdvar( "disableLookAtEntityLogic", 1 ); + } + else + level.zombie_ai_limit = 24; + + level thread drop_all_barriers(); + level thread traversal_blocker(); + onplayerconnect_callback( ::on_player_connect ); + maps\mp\zombies\_zm::register_player_damage_callback( ::tomb_player_damage_callback ); + level.custom_get_round_enemy_array_func = ::zm_tomb_get_round_enemy_array; + flag_wait( "start_zombie_round_logic" ); + wait_network_frame(); + level notify( "specialty_additionalprimaryweapon_power_on" ); + wait_network_frame(); + level notify( "additionalprimaryweapon_on" ); + set_zombie_var( "zombie_use_failsafe", 0 ); + level check_solo_status(); + level thread adjustments_for_solo(); + level thread zone_capture_powerup(); + level thread clean_up_bunker_doors(); + level setclientfield( "lantern_fx", 1 ); + level thread maps\mp\zm_tomb_chamber::tomb_watch_chamber_player_activity(); +/# + maps\mp\zm_tomb_utility::setup_devgui(); +#/ + init_weather_manager(); + level thread maps\mp\zm_tomb_ffotd::main_end(); +} + +tomb_register_client_fields() +{ + registerclientfield( "scriptmover", "stone_frozen", 14000, 1, "int" ); + n_bits = getminbitcountfornum( 5 ); + registerclientfield( "world", "rain_level", 14000, n_bits, "int" ); + registerclientfield( "world", "snow_level", 14000, n_bits, "int" ); + registerclientfield( "toplayer", "player_weather_visionset", 14000, 2, "int" ); + n_bits = getminbitcountfornum( 6 ); + registerclientfield( "toplayer", "player_rumble_and_shake", 14000, n_bits, "int" ); + registerclientfield( "scriptmover", "sky_pillar", 14000, 1, "int" ); + registerclientfield( "scriptmover", "staff_charger", 14000, 3, "int" ); + registerclientfield( "toplayer", "player_staff_charge", 14000, 2, "int" ); + registerclientfield( "toplayer", "player_tablet_state", 14000, 2, "int" ); + registerclientfield( "actor", "zombie_soul", 14000, 1, "int" ); + registerclientfield( "zbarrier", "magicbox_runes", 14000, 1, "int" ); + registerclientfield( "scriptmover", "barbecue_fx", 14000, 1, "int" ); + registerclientfield( "world", "cooldown_steam", 14000, 2, "int" ); + registerclientfield( "world", "mus_zmb_egg_snapshot_loop", 14000, 1, "int" ); + registerclientfield( "world", "sndMaelstromPlr0", 14000, 1, "int" ); + registerclientfield( "world", "sndMaelstromPlr1", 14000, 1, "int" ); + registerclientfield( "world", "sndMaelstromPlr2", 14000, 1, "int" ); + registerclientfield( "world", "sndMaelstromPlr3", 14000, 1, "int" ); + registerclientfield( "world", "sndChamberMusic", 14000, 3, "int" ); + registerclientfield( "actor", "foot_print_box_fx", 14000, 1, "int" ); + registerclientfield( "scriptmover", "foot_print_box_glow", 14000, 1, "int" ); + registerclientfield( "world", "crypt_open_exploder", 14000, 1, "int" ); + registerclientfield( "world", "lantern_fx", 14000, 1, "int" ); + registerclientfield( "allplayers", "oneinchpunch_impact", 14000, 1, "int" ); + registerclientfield( "actor", "oneinchpunch_physics_launchragdoll", 14000, 1, "int" ); +} + +register_burn_overlay() +{ + level.zm_transit_burn_max_duration = 2; + + if ( !isdefined( level.vsmgr_prio_overlay_zm_transit_burn ) ) + level.vsmgr_prio_overlay_zm_transit_burn = 20; + + maps\mp\_visionset_mgr::vsmgr_register_info( "overlay", "zm_transit_burn", 14000, level.vsmgr_prio_overlay_zm_transit_burn, 15, 1, maps\mp\_visionset_mgr::vsmgr_duration_lerp_thread_per_player, 0 ); +} + +tomb_closest_player_override( v_zombie_origin, a_players_to_check ) +{ + e_player_to_attack = undefined; + + while ( !isdefined( e_player_to_attack ) ) + { + e_player_to_attack = tomb_get_closest_player_using_paths( v_zombie_origin, a_players_to_check ); + a_players = maps\mp\zm_tomb_tank::get_players_on_tank( 1 ); + + if ( a_players.size > 0 ) + { + e_player_closest_on_tank = undefined; + n_dist_tank_min = 99999999; + + foreach ( e_player in a_players ) + { + n_dist_sq = distance2dsquared( self.origin, e_player.origin ); + + if ( n_dist_sq < n_dist_tank_min ) + { + n_dist_tank_min = n_dist_sq; + e_player_closest_on_tank = e_player; + } + } + + if ( is_player_valid( e_player_to_attack ) ) + { + n_dist_for_path = distance2dsquared( self.origin, e_player_to_attack.origin ); + + if ( n_dist_tank_min < n_dist_for_path ) + e_player_to_attack = e_player_closest_on_tank; + } + else if ( is_player_valid( e_player_closest_on_tank ) ) + e_player_to_attack = e_player_closest_on_tank; + } + + wait 0.5; + } + + return e_player_to_attack; +} + +zm_tomb_get_round_enemy_array() +{ + enemies = []; + valid_enemies = []; + enemies = getaispeciesarray( level.zombie_team, "all" ); + + for ( i = 0; i < enemies.size; i++ ) + { + if ( isdefined( enemies[i].ignore_enemy_count ) && enemies[i].ignore_enemy_count && ( !isdefined( enemies[i].script_noteworthy ) || enemies[i].script_noteworthy != "capture_zombie" ) ) + continue; + + valid_enemies[valid_enemies.size] = enemies[i]; + } + + return valid_enemies; +} + +tomb_player_damage_callback( e_inflictor, e_attacker, n_damage, n_dflags, str_means_of_death, str_weapon, v_point, v_dir, str_hit_loc, psoffsettime, b_damage_from_underneath, n_model_index, str_part_name ) +{ + if ( isdefined( str_weapon ) ) + { + if ( issubstr( str_weapon, "staff" ) ) + return 0; + else if ( str_weapon == "t72_turret" ) + return 0; + else if ( str_weapon == "quadrotorturret_zm" || str_weapon == "quadrotorturret_upgraded_zm" ) + return 0; + else if ( str_weapon == "zombie_markiv_side_cannon" ) + return 0; + else if ( str_weapon == "zombie_markiv_turret" ) + return 0; + else if ( str_weapon == "zombie_markiv_cannon" ) + return 0; + } + + return n_damage; +} + +tomb_random_perk_weights() +{ + temp_array = []; + + if ( randomint( 4 ) == 0 ) + arrayinsert( temp_array, "specialty_rof", 0 ); + + if ( randomint( 4 ) == 0 ) + arrayinsert( temp_array, "specialty_deadshot", 0 ); + + if ( randomint( 4 ) == 0 ) + arrayinsert( temp_array, "specialty_additionalprimaryweapon", 0 ); + + if ( randomint( 4 ) == 0 ) + arrayinsert( temp_array, "specialty_flakjacket", 0 ); + + if ( randomint( 4 ) == 0 ) + arrayinsert( temp_array, "specialty_grenadepulldeath", 0 ); + + temp_array = array_randomize( temp_array ); + level._random_perk_machine_perk_list = array_randomize( level._random_perk_machine_perk_list ); + level._random_perk_machine_perk_list = arraycombine( level._random_perk_machine_perk_list, temp_array, 1, 0 ); + keys = getarraykeys( level._random_perk_machine_perk_list ); + return keys; +} + +level_precache() +{ + precacheshader( "specialty_zomblood_zombies" ); + precachemodel( "c_zom_guard" ); + precachemodel( "p6_zm_tm_orb_fire" ); + precachemodel( "p6_zm_tm_orb_wind" ); + precachemodel( "p6_zm_tm_orb_lightning" ); + precachemodel( "p6_zm_tm_orb_ice" ); + precachemodel( "fx_tomb_vortex_beam_mesh" ); + precachemodel( "fxuse_sky_pillar_new" ); +} + +on_player_connect() +{ + self thread revive_watcher(); + wait_network_frame(); + self thread player_slow_movement_speed_monitor(); + self thread sndmeleewpnsound(); +} + +sndmeleewpnsound() +{ + self endon( "disconnect" ); + level endon( "end_game" ); + + while ( true ) + { + while ( !self ismeleeing() ) + wait 0.05; + + current_melee_weapon = self get_player_melee_weapon(); + current_weapon = self getcurrentweapon(); + + if ( current_weapon == "tomb_shield_zm" ) + { + self playsound( "fly_riotshield_zm_swing" ); + + while ( self ismeleeing() ) + wait 0.05; + + continue; + } + + alias = "zmb_melee_whoosh_"; + + if ( isdefined( self.is_player_zombie ) && self.is_player_zombie ) + alias = "zmb_melee_whoosh_zmb_"; + else if ( current_melee_weapon == "bowie_knife_zm" ) + alias = "zmb_bowie_swing_"; + else if ( current_melee_weapon == "one_inch_punch_zm" ) + alias = "wpn_one_inch_punch_"; + else if ( current_melee_weapon == "one_inch_punch_upgraded_zm" ) + alias = "wpn_one_inch_punch_"; + else if ( current_melee_weapon == "one_inch_punch_fire_zm" ) + alias = "wpn_one_inch_punch_fire_"; + else if ( current_melee_weapon == "one_inch_punch_air_zm" ) + alias = "wpn_one_inch_punch_air_"; + else if ( current_melee_weapon == "one_inch_punch_ice_zm" ) + alias = "wpn_one_inch_punch_ice_"; + else if ( current_melee_weapon == "one_inch_punch_lightning_zm" ) + alias = "wpn_one_inch_punch_lightning_"; + else if ( sndmeleewpn_isstaff( current_melee_weapon ) ) + alias = "zmb_melee_staff_upgraded_"; + + self playsoundtoplayer( alias + "plr", self ); + wait_network_frame(); + + if ( maps\mp\zombies\_zm_audio::sndisnetworksafe() ) + self playsound( alias + "npc" ); + + while ( self ismeleeing() ) + wait 0.05; + + wait 0.05; + } +} + +sndmeleewpn_isstaff( weapon ) +{ + switch ( weapon ) + { + case "staff_air_melee_zm": + case "staff_fire_melee_zm": + case "staff_lightning_melee_zm": + case "staff_melee_zm": + case "staff_watermelee_zm": + isstaff = 1; + break; + default: + isstaff = 0; + } + + return isstaff; +} + +revive_watcher() +{ + self endon( "death_or_disconnect" ); + + while ( true ) + { + self waittill( "do_revive_ended_normally" ); + + if ( self hasperk( "specialty_quickrevive" ) ) + self notify( "quick_revived_player" ); + else + self notify( "revived_player" ); + } +} + +setup_tomb_spawn_groups() +{ + level.use_multiple_spawns = 1; + level.spawner_int = 1; + level waittill( "start_zombie_round_logic" ); + level.zones["ug_bottom_zone"].script_int = 2; + level.zones["zone_nml_19"].script_int = 2; + level.zones["zone_chamber_0"].script_int = 3; + level.zones["zone_chamber_1"].script_int = 3; + level.zones["zone_chamber_2"].script_int = 3; + level.zones["zone_chamber_3"].script_int = 3; + level.zones["zone_chamber_4"].script_int = 3; + level.zones["zone_chamber_5"].script_int = 3; + level.zones["zone_chamber_6"].script_int = 3; + level.zones["zone_chamber_7"].script_int = 3; + level.zones["zone_chamber_8"].script_int = 3; + level.zones["zone_ice_stairs"].script_int = 2; + level.zones["zone_bolt_stairs"].script_int = 2; + level.zones["zone_air_stairs"].script_int = 2; + level.zones["zone_fire_stairs"].script_int = 2; + level.zones["zone_bolt_stairs_1"].script_int = 2; + level.zones["zone_air_stairs_1"].script_int = 2; + level.zones["zone_fire_stairs_1"].script_int = 2; +} + +chamber_capture_zombie_spawn_init() +{ + self endon( "death" ); + self waittill( "completed_emerging_into_playable_area" ); + self setclientfield( "zone_capture_zombie", 1 ); +} + +tomb_round_spawn_failsafe() +{ + self endon( "death" ); + prevorigin = self.origin; + + while ( true ) + { + if ( isdefined( self.ignore_round_spawn_failsafe ) && self.ignore_round_spawn_failsafe ) + return; + + wait 15; + + if ( isdefined( self.is_inert ) && self.is_inert ) + continue; + + if ( isdefined( self.lastchunk_destroy_time ) ) + { + if ( gettime() - self.lastchunk_destroy_time < 8000 ) + continue; + } + + if ( self.origin[2] < -3000 ) + { + if ( isdefined( level.put_timed_out_zombies_back_in_queue ) && level.put_timed_out_zombies_back_in_queue && !flag( "dog_round" ) && !( isdefined( self.isscreecher ) && self.isscreecher ) ) + { + iPrintLn("Hmm, tomb 111"); + //level.zombie_total++; + //level.zombie_total_subtract++; + } + iPrintLn("Tomb dodamage 1"); + //self dodamage( self.health + 100, ( 0, 0, 0 ) ); + break; + } + + if ( distancesquared( self.origin, prevorigin ) < 576 ) + { + if ( isdefined( level.put_timed_out_zombies_back_in_queue ) && level.put_timed_out_zombies_back_in_queue && !flag( "dog_round" ) ) + { + if ( !self.ignoreall && !( isdefined( self.nuked ) && self.nuked ) && !( isdefined( self.marked_for_death ) && self.marked_for_death ) && !( isdefined( self.isscreecher ) && self.isscreecher ) && ( isdefined( self.has_legs ) && self.has_legs ) && !( isdefined( self.is_brutus ) && self.is_brutus ) ) + { + iPrintLn("Hmm, tomb 222"); + //level.zombie_total++; + //level.zombie_total_subtract++; + } + } + + level.zombies_timeout_playspace++; + iPrintLn("Tomb dodamage 2"); + //self dodamage( self.health + 100, ( 0, 0, 0 ) ); + break; + } + + prevorigin = self.origin; + } +} + +givecustomloadout( takeallweapons, alreadyspawned ) +{ + self giveweapon( "knife_zm" ); + self give_start_weapon( 1 ); +} + +precache_team_characters() +{ + precachemodel( "c_zom_player_cdc_fb" ); + precachemodel( "c_zom_hazmat_viewhands" ); + precachemodel( "c_zom_player_cia_fb" ); + precachemodel( "c_zom_suit_viewhands" ); +} + +precache_personality_characters() +{ + character\c_usa_dempsey_dlc4::precache(); + character\c_rus_nikolai_dlc4::precache(); + character\c_ger_richtofen_dlc4::precache(); + character\c_jap_takeo_dlc4::precache(); + precachemodel( "c_zom_richtofen_viewhands" ); + precachemodel( "c_zom_nikolai_viewhands" ); + precachemodel( "c_zom_takeo_viewhands" ); + precachemodel( "c_zom_dempsey_viewhands" ); +} + +give_personality_characters() +{ + if ( isdefined( level.hotjoin_player_setup ) && [[ level.hotjoin_player_setup ]]( "c_zom_arlington_coat_viewhands" ) ) + return; + + self detachall(); + + if ( !isdefined( self.characterindex ) ) + self.characterindex = assign_lowest_unused_character_index(); + + self.favorite_wall_weapons_list = []; + self.talks_in_danger = 0; +/# + if ( getdvar( #"_id_40772CF1" ) != "" ) + self.characterindex = getdvarint( #"_id_40772CF1" ); +#/ + + switch ( self.characterindex ) + { + case 0: + self character\c_usa_dempsey_dlc4::main(); + self setviewmodel( "c_zom_dempsey_viewhands" ); + level.vox maps\mp\zombies\_zm_audio::zmbvoxinitspeaker( "player", "vox_plr_", self ); + self set_player_is_female( 0 ); + self.character_name = "Dempsey"; + break; + case 1: + self character\c_rus_nikolai_dlc4::main(); + self setviewmodel( "c_zom_nikolai_viewhands" ); + level.vox maps\mp\zombies\_zm_audio::zmbvoxinitspeaker( "player", "vox_plr_", self ); + self set_player_is_female( 0 ); + self.character_name = "Nikolai"; + break; + case 2: + self character\c_ger_richtofen_dlc4::main(); + self setviewmodel( "c_zom_richtofen_viewhands" ); + level.vox maps\mp\zombies\_zm_audio::zmbvoxinitspeaker( "player", "vox_plr_", self ); + self set_player_is_female( 0 ); + self.character_name = "Richtofen"; + break; + case 3: + self character\c_jap_takeo_dlc4::main(); + self setviewmodel( "c_zom_takeo_viewhands" ); + level.vox maps\mp\zombies\_zm_audio::zmbvoxinitspeaker( "player", "vox_plr_", self ); + self set_player_is_female( 0 ); + self.character_name = "Takeo"; + break; + } + + self setmovespeedscale( 1 ); + self setsprintduration( 4 ); + self setsprintcooldown( 0 ); + self thread set_exert_id(); +} + +set_exert_id() +{ + self endon( "disconnect" ); + wait_network_frame(); + wait_network_frame(); + self maps\mp\zombies\_zm_audio::setexertvoice( self.characterindex + 1 ); +} + +assign_lowest_unused_character_index() +{ + charindexarray = []; + charindexarray[0] = 0; + charindexarray[1] = 1; + charindexarray[2] = 2; + charindexarray[3] = 3; + players = get_players(); + + if ( players.size == 1 ) + { + charindexarray = array_randomize( charindexarray ); + + if ( charindexarray[0] == 2 ) + level.has_richtofen = 1; + + return charindexarray[0]; + } + else + { + n_characters_defined = 0; + + foreach ( player in players ) + { + if ( isdefined( player.characterindex ) ) + { + arrayremovevalue( charindexarray, player.characterindex, 0 ); + n_characters_defined++; + } + } + + if ( charindexarray.size > 0 ) + { + if ( n_characters_defined == players.size - 1 ) + { + if ( !( isdefined( level.has_richtofen ) && level.has_richtofen ) ) + { + level.has_richtofen = 1; + return 2; + } + } + + charindexarray = array_randomize( charindexarray ); + + if ( charindexarray[0] == 2 ) + level.has_richtofen = 1; + + return charindexarray[0]; + } + } + + return 0; +} + +give_team_characters() +{ + self detachall(); + self set_player_is_female( 0 ); + + if ( !isdefined( self.characterindex ) ) + { + self.characterindex = 1; + + if ( self.team == "axis" ) + self.characterindex = 0; + } + + switch ( self.characterindex ) + { + case 0: + case 2: + self setmodel( "c_zom_player_cia_fb" ); + self.voice = "american"; + self.skeleton = "base"; + self setviewmodel( "c_zom_suit_viewhands" ); + self.characterindex = 0; + break; + case 1: + case 3: + self setmodel( "c_zom_player_cdc_fb" ); + self.voice = "american"; + self.skeleton = "base"; + self setviewmodel( "c_zom_hazmat_viewhands" ); + self.characterindex = 1; + break; + } + + self setmovespeedscale( 1 ); + self setsprintduration( 4 ); + self setsprintcooldown( 0 ); +} + +initcharacterstartindex() +{ + level.characterstartindex = randomint( 4 ); +} + +zm_player_fake_death_cleanup() +{ + if ( isdefined( self._fall_down_anchor ) ) + { + self._fall_down_anchor delete(); + self._fall_down_anchor = undefined; + } +} + +zm_player_fake_death( vdir ) +{ + level notify( "fake_death" ); + self notify( "fake_death" ); + stance = self getstance(); + self.ignoreme = 1; + self enableinvulnerability(); + self takeallweapons(); + + if ( isdefined( self.insta_killed ) && self.insta_killed ) + { + self maps\mp\zombies\_zm::player_fake_death(); + self allowprone( 1 ); + self allowcrouch( 0 ); + self allowstand( 0 ); + wait 0.25; + self freezecontrols( 1 ); + } + else + { + self freezecontrols( 1 ); + self thread fall_down( vdir, stance ); + wait 1; + } +} + +fall_down( vdir, stance ) +{ + self endon( "disconnect" ); + level endon( "game_module_ended" ); + self ghost(); + origin = self.origin; + xyspeed = ( 0, 0, 0 ); + angles = self getplayerangles(); + angles = ( angles[0], angles[1], angles[2] + randomfloatrange( -5, 5 ) ); + + if ( isdefined( vdir ) && length( vdir ) > 0 ) + { + xyspeedmag = 40 + randomint( 12 ) + randomint( 12 ); + xyspeed = xyspeedmag * vectornormalize( ( vdir[0], vdir[1], 0 ) ); + } + + linker = spawn( "script_origin", ( 0, 0, 0 ) ); + linker.origin = origin; + linker.angles = angles; + self._fall_down_anchor = linker; + self playerlinkto( linker ); + self playsoundtoplayer( "zmb_player_death_fall", self ); + falling = stance != "prone"; + + if ( falling ) + { + origin = playerphysicstrace( origin, origin + xyspeed ); + eye = self get_eye(); + floor_height = 10 + origin[2] - eye[2]; + origin = origin + ( 0, 0, floor_height ); + lerptime = 0.5; + linker moveto( origin, lerptime, lerptime ); + linker rotateto( angles, lerptime, lerptime ); + } + + self freezecontrols( 1 ); + + if ( falling ) + linker waittill( "movedone" ); + + self giveweapon( "death_throe_zm" ); + self switchtoweapon( "death_throe_zm" ); + + if ( falling ) + { + bounce = randomint( 4 ) + 8; + origin = origin + ( 0, 0, bounce ) - xyspeed * 0.1; + lerptime = bounce / 50.0; + linker moveto( origin, lerptime, 0, lerptime ); + linker waittill( "movedone" ); + origin = origin + ( 0, 0, bounce * -1 ) + xyspeed * 0.1; + lerptime = lerptime / 2.0; + linker moveto( origin, lerptime, lerptime ); + linker waittill( "movedone" ); + linker moveto( origin, 5, 0 ); + } + + wait 15; + linker delete(); +} + +initial_round_wait_func() +{ + flag_wait( "initial_blackscreen_passed" ); +} + +offhand_weapon_overrride() +{ + register_lethal_grenade_for_level( "frag_grenade_zm" ); + level.zombie_lethal_grenade_player_init = "frag_grenade_zm"; + register_lethal_grenade_for_level( "sticky_grenade_zm" ); + register_tactical_grenade_for_level( "cymbal_monkey_zm" ); + register_tactical_grenade_for_level( "emp_grenade_zm" ); + register_tactical_grenade_for_level( "beacon_zm" ); + register_placeable_mine_for_level( "claymore_zm" ); + register_melee_weapon_for_level( "knife_zm" ); + register_melee_weapon_for_level( "staff_air_melee_zm" ); + register_melee_weapon_for_level( "staff_fire_melee_zm" ); + register_melee_weapon_for_level( "staff_lightning_melee_zm" ); + register_melee_weapon_for_level( "staff_water_melee_zm" ); + level.zombie_melee_weapon_player_init = "knife_zm"; + register_equipment_for_level( "tomb_shield_zm" ); + level.zombie_equipment_player_init = undefined; + level.equipment_safe_to_drop = ::equipment_safe_to_drop; +} + +equipment_safe_to_drop( weapon ) +{ + if ( !isdefined( self.origin ) ) + return true; + + return true; +} + +offhand_weapon_give_override( str_weapon ) +{ + self endon( "death" ); + + if ( is_tactical_grenade( str_weapon ) && isdefined( self get_player_tactical_grenade() ) && !self is_player_tactical_grenade( str_weapon ) ) + { + self setweaponammoclip( self get_player_tactical_grenade(), 0 ); + self takeweapon( self get_player_tactical_grenade() ); + } + + return false; +} + +tomb_weaponobjects_on_player_connect_override() +{ + level.retrievable_knife_init_names = []; + onplayerconnect_callback( ::weaponobjects_on_player_connect_override_internal ); +} + +tomb_player_intersection_tracker_override( e_player ) +{ + if ( isdefined( e_player.b_already_on_tank ) && e_player.b_already_on_tank || isdefined( self.b_already_on_tank ) && self.b_already_on_tank ) + return true; + + if ( isdefined( e_player.giant_robot_transition ) && e_player.giant_robot_transition || isdefined( self.giant_robot_transition ) && self.giant_robot_transition ) + return true; + + return false; +} + +init_tomb_stats() +{ + self maps\mp\zm_tomb_achievement::init_player_achievement_stats(); +} + +custom_add_weapons() +{ + level.laststandpistol = "c96_zm"; + level.default_laststandpistol = "c96_zm"; + level.default_solo_laststandpistol = "c96_upgraded_zm"; + level.start_weapon = "c96_zm"; + add_zombie_weapon( "mg08_zm", "mg08_upgraded_zm", &"ZOMBIE_WEAPON_MG08", 50, "wpck_mg", "", undefined, 1 ); + add_zombie_weapon( "hamr_zm", "hamr_upgraded_zm", &"ZOMBIE_WEAPON_HAMR", 50, "wpck_mg", "", undefined, 1 ); + add_zombie_weapon( "type95_zm", "type95_upgraded_zm", &"ZOMBIE_WEAPON_TYPE95", 50, "wpck_rifle", "", undefined, 1 ); + add_zombie_weapon( "galil_zm", "galil_upgraded_zm", &"ZOMBIE_WEAPON_GALIL", 50, "wpck_rifle", "", undefined, 1 ); + add_zombie_weapon( "fnfal_zm", "fnfal_upgraded_zm", &"ZOMBIE_WEAPON_FNFAL", 50, "wpck_rifle", "", undefined, 1 ); + add_zombie_weapon( "m14_zm", "m14_upgraded_zm", &"ZOMBIE_WEAPON_M14", 500, "wpck_rifle", "", undefined, 1 ); + add_zombie_weapon( "mp44_zm", "mp44_upgraded_zm", &"ZMWEAPON_MP44_WALLBUY", 1400, "wpck_rifle", "", undefined, 1 ); + add_zombie_weapon( "scar_zm", "scar_upgraded_zm", &"ZOMBIE_WEAPON_SCAR", 50, "wpck_rifle", "", undefined, 1 ); + add_zombie_weapon( "870mcs_zm", "870mcs_upgraded_zm", &"ZOMBIE_WEAPON_870MCS", 900, "wpck_shotgun", "", undefined, 1 ); + add_zombie_weapon( "srm1216_zm", "srm1216_upgraded_zm", &"ZOMBIE_WEAPON_SRM1216", 50, "wpck_shotgun", "", undefined, 1 ); + add_zombie_weapon( "ksg_zm", "ksg_upgraded_zm", &"ZOMBIE_WEAPON_KSG", 1100, "wpck_shotgun", "", undefined, 1 ); + add_zombie_weapon( "ak74u_zm", "ak74u_upgraded_zm", &"ZOMBIE_WEAPON_AK74U", 1200, "wpck_smg", "", undefined, 1 ); + add_zombie_weapon( "ak74u_extclip_zm", "ak74u_extclip_upgraded_zm", &"ZOMBIE_WEAPON_AK74U", 1200, "wpck_smg", "", undefined, 1 ); + add_zombie_weapon( "pdw57_zm", "pdw57_upgraded_zm", &"ZOMBIE_WEAPON_PDW57", 1000, "wpck_smg", "", undefined, 1 ); + add_zombie_weapon( "thompson_zm", "thompson_upgraded_zm", &"ZMWEAPON_THOMPSON_WALLBUY", 1500, "wpck_smg", "", 800, 1 ); + add_zombie_weapon( "qcw05_zm", "qcw05_upgraded_zm", &"ZOMBIE_WEAPON_QCW05", 50, "wpck_smg", "", undefined, 1 ); + add_zombie_weapon( "mp40_zm", "mp40_upgraded_zm", &"ZOMBIE_WEAPON_MP40", 1300, "wpck_smg", "", undefined, 1 ); + add_zombie_weapon( "mp40_stalker_zm", "mp40_stalker_upgraded_zm", &"ZOMBIE_WEAPON_MP40", 1300, "wpck_smg", "", undefined, 1 ); + add_zombie_weapon( "evoskorpion_zm", "evoskorpion_upgraded_zm", &"ZOMBIE_WEAPON_EVOSKORPION", 50, "wpck_smg", "", undefined, 1 ); + add_zombie_weapon( "ballista_zm", "ballista_upgraded_zm", &"ZMWEAPON_BALLISTA_WALLBUY", 500, "wpck_snipe", "", undefined, 1 ); + add_zombie_weapon( "dsr50_zm", "dsr50_upgraded_zm", &"ZOMBIE_WEAPON_DR50", 50, "wpck_snipe", "", undefined, 1 ); + add_zombie_weapon( "beretta93r_zm", "beretta93r_upgraded_zm", &"ZOMBIE_WEAPON_BERETTA93r", 1000, "wpck_pistol", "", undefined, 1 ); + add_zombie_weapon( "beretta93r_extclip_zm", "beretta93r_extclip_upgraded_zm", &"ZOMBIE_WEAPON_BERETTA93r", 1000, "wpck_pistol", "", undefined, 1 ); + add_zombie_weapon( "kard_zm", "kard_upgraded_zm", &"ZOMBIE_WEAPON_KARD", 50, "wpck_pistol", "", undefined, 1 ); + add_zombie_weapon( "fiveseven_zm", "fiveseven_upgraded_zm", &"ZOMBIE_WEAPON_FIVESEVEN", 1100, "wpck_pistol", "", undefined, 1 ); + add_zombie_weapon( "python_zm", "python_upgraded_zm", &"ZOMBIE_WEAPON_PYTHON", 50, "wpck_pistol", "", undefined, 1 ); + add_zombie_weapon( "c96_zm", "c96_upgraded_zm", &"ZOMBIE_WEAPON_C96", 50, "wpck_pistol", "", undefined, 1 ); + add_zombie_weapon( "fivesevendw_zm", "fivesevendw_upgraded_zm", &"ZOMBIE_WEAPON_FIVESEVENDW", 50, "wpck_duel", "", undefined, 1 ); + add_zombie_weapon( "m32_zm", "m32_upgraded_zm", &"ZOMBIE_WEAPON_M32", 50, "wpck_crappy", "", undefined, 1 ); + add_zombie_weapon( "beacon_zm", undefined, &"ZOMBIE_WEAPON_BEACON", 2000, "wpck_explo", "", undefined, 1 ); + add_zombie_weapon( "claymore_zm", undefined, &"ZOMBIE_WEAPON_CLAYMORE", 1000, "wpck_explo", "", undefined, 1 ); + add_zombie_weapon( "cymbal_monkey_zm", undefined, &"ZOMBIE_WEAPON_SATCHEL_2000", 2000, "wpck_monkey", "", undefined, 1 ); + add_zombie_weapon( "frag_grenade_zm", undefined, &"ZOMBIE_WEAPON_FRAG_GRENADE", 250, "wpck_explo", "", 250 ); + add_zombie_weapon( "ray_gun_zm", "ray_gun_upgraded_zm", &"ZOMBIE_WEAPON_RAYGUN", 10000, "wpck_ray", "", undefined, 1 ); + + if ( isdefined( level.raygun2_included ) && level.raygun2_included ) + add_zombie_weapon( "raygun_mark2_zm", "raygun_mark2_upgraded_zm", &"ZOMBIE_WEAPON_RAYGUN_MARK2", 10000, "wpck_raymk2", "", undefined ); + + add_zombie_weapon( "sticky_grenade_zm", undefined, &"ZOMBIE_WEAPON_STICKY_GRENADE", 250, "wpck_explo", "", 250 ); + add_zombie_weapon( "staff_air_zm", undefined, &"AIR_STAFF", 50, "wpck_rpg", "", undefined, 1 ); + add_zombie_weapon( "staff_air_upgraded_zm", undefined, &"AIR_STAFF_CHARGED", 50, "wpck_rpg", "", undefined, 1 ); + add_zombie_weapon( "staff_fire_zm", undefined, &"FIRE_STAFF", 50, "wpck_rpg", "", undefined, 1 ); + add_zombie_weapon( "staff_fire_upgraded_zm", undefined, &"FIRE_STAFF_CHARGED", 50, "wpck_rpg", "", undefined, 1 ); + add_zombie_weapon( "staff_lightning_zm", undefined, &"LIGHTNING_STAFF", 50, "wpck_rpg", "", undefined, 1 ); + add_zombie_weapon( "staff_lightning_upgraded_zm", undefined, &"LIGHTNING_STAFF_CHARGED", 50, "wpck_rpg", "", undefined, 1 ); + add_zombie_weapon( "staff_water_zm", undefined, &"WATER_STAFF", 50, "wpck_rpg", "", undefined, 1 ); + add_zombie_weapon( "staff_water_zm_cheap", undefined, &"WATER_STAFF", 50, "wpck_rpg", "", undefined, 1 ); + add_zombie_weapon( "staff_water_upgraded_zm", undefined, &"WATER_STAFF_CHARGED", 50, "wpck_rpg", "", undefined, 1 ); + add_zombie_weapon( "staff_revive_zm", undefined, &"ZM_TOMB_WEAP_STAFF_REVIVE", 50, "wpck_rpg", "", undefined, 1 ); + change_weapon_cost( "mp40_zm", 1300 ); + level.weapons_using_ammo_sharing = 1; + add_shared_ammo_weapon( "ak74u_extclip_zm", "ak74u_zm" ); + add_shared_ammo_weapon( "mp40_stalker_zm", "mp40_zm" ); + add_shared_ammo_weapon( "beretta93r_extclip_zm", "beretta93r_zm" ); +} + +include_weapons() +{ + include_weapon( "hamr_zm" ); + include_weapon( "hamr_upgraded_zm", 0 ); + include_weapon( "mg08_zm" ); + include_weapon( "mg08_upgraded_zm", 0 ); + include_weapon( "type95_zm" ); + include_weapon( "type95_upgraded_zm", 0 ); + include_weapon( "galil_zm" ); + include_weapon( "galil_upgraded_zm", 0 ); + include_weapon( "fnfal_zm" ); + include_weapon( "fnfal_upgraded_zm", 0 ); + include_weapon( "m14_zm", 0 ); + include_weapon( "m14_upgraded_zm", 0 ); + include_weapon( "mp44_zm", 0 ); + include_weapon( "mp44_upgraded_zm", 0 ); + include_weapon( "scar_zm" ); + include_weapon( "scar_upgraded_zm", 0 ); + include_weapon( "870mcs_zm", 0 ); + include_weapon( "870mcs_upgraded_zm", 0 ); + include_weapon( "ksg_zm" ); + include_weapon( "ksg_upgraded_zm", 0 ); + include_weapon( "srm1216_zm" ); + include_weapon( "srm1216_upgraded_zm", 0 ); + include_weapon( "ak74u_zm", 0 ); + include_weapon( "ak74u_upgraded_zm", 0 ); + include_weapon( "ak74u_extclip_zm" ); + include_weapon( "ak74u_extclip_upgraded_zm", 0 ); + include_weapon( "pdw57_zm" ); + include_weapon( "pdw57_upgraded_zm", 0 ); + include_weapon( "thompson_zm" ); + include_weapon( "thompson_upgraded_zm", 0 ); + include_weapon( "qcw05_zm" ); + include_weapon( "qcw05_upgraded_zm", 0 ); + include_weapon( "mp40_zm", 0 ); + include_weapon( "mp40_upgraded_zm", 0 ); + include_weapon( "mp40_stalker_zm" ); + include_weapon( "mp40_stalker_upgraded_zm", 0 ); + include_weapon( "evoskorpion_zm" ); + include_weapon( "evoskorpion_upgraded_zm", 0 ); + include_weapon( "ballista_zm", 0 ); + include_weapon( "ballista_upgraded_zm", 0 ); + include_weapon( "dsr50_zm" ); + include_weapon( "dsr50_upgraded_zm", 0 ); + include_weapon( "beretta93r_zm", 0 ); + include_weapon( "beretta93r_upgraded_zm", 0 ); + include_weapon( "beretta93r_extclip_zm" ); + include_weapon( "beretta93r_extclip_upgraded_zm", 0 ); + include_weapon( "kard_zm" ); + include_weapon( "kard_upgraded_zm", 0 ); + include_weapon( "fiveseven_zm", 0 ); + include_weapon( "fiveseven_upgraded_zm", 0 ); + include_weapon( "python_zm" ); + include_weapon( "python_upgraded_zm", 0 ); + include_weapon( "c96_zm", 0 ); + include_weapon( "c96_upgraded_zm", 0 ); + include_weapon( "fivesevendw_zm" ); + include_weapon( "fivesevendw_upgraded_zm", 0 ); + include_weapon( "m32_zm" ); + include_weapon( "m32_upgraded_zm", 0 ); + include_weapon( "beacon_zm", 0 ); + include_weapon( "claymore_zm", 0 ); + include_weapon( "cymbal_monkey_zm" ); + include_weapon( "frag_grenade_zm", 0 ); + include_weapon( "knife_zm", 0 ); + include_weapon( "ray_gun_zm" ); + include_weapon( "ray_gun_upgraded_zm", 0 ); + include_weapon( "sticky_grenade_zm", 0 ); + include_weapon( "tomb_shield_zm", 0 ); + add_limited_weapon( "c96_zm", 0 ); + add_limited_weapon( "ray_gun_zm", 4 ); + add_limited_weapon( "ray_gun_upgraded_zm", 4 ); + include_weapon( "staff_air_zm", 0 ); + include_weapon( "staff_air_upgraded_zm", 0 ); + precacheitem( "staff_air_upgraded2_zm" ); + precacheitem( "staff_air_upgraded3_zm" ); + include_weapon( "staff_fire_zm", 0 ); + include_weapon( "staff_fire_upgraded_zm", 0 ); + precacheitem( "staff_fire_upgraded2_zm" ); + precacheitem( "staff_fire_upgraded3_zm" ); + include_weapon( "staff_lightning_zm", 0 ); + include_weapon( "staff_lightning_upgraded_zm", 0 ); + precacheitem( "staff_lightning_upgraded2_zm" ); + precacheitem( "staff_lightning_upgraded3_zm" ); + include_weapon( "staff_water_zm", 0 ); + include_weapon( "staff_water_zm_cheap", 0 ); + include_weapon( "staff_water_upgraded_zm", 0 ); + precacheitem( "staff_water_upgraded2_zm" ); + precacheitem( "staff_water_upgraded3_zm" ); + include_weapon( "staff_revive_zm", 0 ); + add_limited_weapon( "staff_air_zm", 0 ); + add_limited_weapon( "staff_air_upgraded_zm", 0 ); + add_limited_weapon( "staff_fire_zm", 0 ); + add_limited_weapon( "staff_fire_upgraded_zm", 0 ); + add_limited_weapon( "staff_lightning_zm", 0 ); + add_limited_weapon( "staff_lightning_upgraded_zm", 0 ); + add_limited_weapon( "staff_water_zm", 0 ); + add_limited_weapon( "staff_water_zm_cheap", 0 ); + add_limited_weapon( "staff_water_upgraded_zm", 0 ); + + if ( isdefined( level.raygun2_included ) && level.raygun2_included ) + { + include_weapon( "raygun_mark2_zm", 1 ); + include_weapon( "raygun_mark2_upgraded_zm", 0 ); + add_weapon_to_content( "raygun_mark2_zm", "dlc3" ); + add_limited_weapon( "raygun_mark2_zm", 1 ); + add_limited_weapon( "raygun_mark2_upgraded_zm", 1 ); + } +} + +include_powerups() +{ + include_powerup( "nuke" ); + include_powerup( "insta_kill" ); + include_powerup( "double_points" ); + include_powerup( "full_ammo" ); + include_powerup( "fire_sale" ); + include_powerup( "free_perk" ); + include_powerup( "zombie_blood" ); + include_powerup( "bonus_points_player" ); + include_powerup( "bonus_points_team" ); + level.level_specific_init_powerups = ::tomb_powerup_init; + level._zombiemode_powerup_grab = ::tomb_powerup_grab; +/# + setup_powerup_devgui(); +#/ +/# + setup_oneinchpunch_devgui(); +#/ +/# + setup_tablet_devgui(); +#/ +} + +include_perks_in_random_rotation() +{ + include_perk_in_random_rotation( "specialty_armorvest" ); + include_perk_in_random_rotation( "specialty_quickrevive" ); + include_perk_in_random_rotation( "specialty_fastreload" ); + include_perk_in_random_rotation( "specialty_rof" ); + include_perk_in_random_rotation( "specialty_longersprint" ); + include_perk_in_random_rotation( "specialty_deadshot" ); + include_perk_in_random_rotation( "specialty_additionalprimaryweapon" ); + include_perk_in_random_rotation( "specialty_flakjacket" ); + include_perk_in_random_rotation( "specialty_grenadepulldeath" ); + level.custom_random_perk_weights = ::tomb_random_perk_weights; +} + +tomb_powerup_init() +{ + maps\mp\zombies\_zm_powerup_zombie_blood::init( "c_zom_tomb_german_player_fb" ); +} + +tomb_powerup_grab( s_powerup, e_player ) +{ + if ( s_powerup.powerup_name == "zombie_blood" ) + level thread maps\mp\zombies\_zm_powerup_zombie_blood::zombie_blood_powerup( s_powerup, e_player ); +} + +setup_powerup_devgui() +{ +/# + setdvar( "zombie_blood", "off" ); + adddebugcommand( "devgui_cmd \"Zombies:2/Power Ups:2/Now:1/Drop Zombie Blood:1\" \"zombie_blood on\"\n" ); + level thread watch_devgui_zombie_blood(); +#/ +} + +setup_oneinchpunch_devgui() +{ +/# + setdvar( "test_oneinchpunch", "off" ); + adddebugcommand( "devgui_cmd \"Zombies:2/Tomb:1/OneInchPunch:2/OneInchPunch:1\" \"test_oneinchpunch on\"\n" ); + setdvar( "test_oneinchpunch_upgraded", "off" ); + adddebugcommand( "devgui_cmd \"Zombies:2/Tomb:1/OneInchPunch:2/OneInchPunch_Upgraded:1\" \"test_oneinchpunch_upgraded on\"\n" ); + setdvar( "test_oneinchpunch_air", "off" ); + adddebugcommand( "devgui_cmd \"Zombies:2/Tomb:1/OneInchPunch:2/OneInchPunch_Air:1\" \"test_oneinchpunch_air on\"\n" ); + setdvar( "test_oneinchpunch_fire", "off" ); + adddebugcommand( "devgui_cmd \"Zombies:2/Tomb:1/OneInchPunch:2/OneInchPunch_Fire:1\" \"test_oneinchpunch_fire on\"\n" ); + setdvar( "test_oneinchpunch_ice", "off" ); + adddebugcommand( "devgui_cmd \"Zombies:2/Tomb:1/OneInchPunch:2/OneInchPunch_Ice:1\" \"test_oneinchpunch_ice on\"\n" ); + setdvar( "test_oneinchpunch_lightning", "off" ); + adddebugcommand( "devgui_cmd \"Zombies:2/Tomb:1/OneInchPunch:2/OneInchPunch_Lightning:1\" \"test_oneinchpunch_lightning on\"\n" ); + level thread watch_devgui_oneinchpunch(); +#/ +} + +watch_devgui_oneinchpunch() +{ +/# + while ( true ) + { + if ( getdvar( #"test_oneinchpunch" ) == "on" ) + { + setdvar( "test_oneinchpunch", "off" ); + player = get_players()[0]; + player thread maps\mp\zombies\_zm_weap_one_inch_punch::one_inch_punch_melee_attack(); + } + else if ( getdvar( #"test_oneinchpunch_upgraded" ) == "on" ) + { + setdvar( "test_oneinchpunch_upgraded", "off" ); + player = get_players()[0]; + player.b_punch_upgraded = 1; + player.str_punch_element = "upgraded"; + player thread maps\mp\zombies\_zm_weap_one_inch_punch::one_inch_punch_melee_attack(); + } + else if ( getdvar( #"test_oneinchpunch_air" ) == "on" ) + { + setdvar( "test_oneinchpunch_air", "off" ); + player = get_players()[0]; + player.b_punch_upgraded = 1; + player.str_punch_element = "air"; + player thread maps\mp\zombies\_zm_weap_one_inch_punch::one_inch_punch_melee_attack(); + } + else if ( getdvar( #"test_oneinchpunch_fire" ) == "on" ) + { + setdvar( "test_oneinchpunch_fire", "off" ); + player = get_players()[0]; + player.b_punch_upgraded = 1; + player.str_punch_element = "fire"; + player thread maps\mp\zombies\_zm_weap_one_inch_punch::one_inch_punch_melee_attack(); + } + else if ( getdvar( #"test_oneinchpunch_ice" ) == "on" ) + { + setdvar( "test_oneinchpunch_ice", "off" ); + player = get_players()[0]; + player.b_punch_upgraded = 1; + player.str_punch_element = "ice"; + player thread maps\mp\zombies\_zm_weap_one_inch_punch::one_inch_punch_melee_attack(); + } + else if ( getdvar( #"test_oneinchpunch_lightning" ) == "on" ) + { + setdvar( "test_oneinchpunch_lightning", "off" ); + player = get_players()[0]; + player.b_punch_upgraded = 1; + player.str_punch_element = "lightning"; + player thread maps\mp\zombies\_zm_weap_one_inch_punch::one_inch_punch_melee_attack(); + } + + wait 0.1; + } +#/ +} + +setup_tablet_devgui() +{ +/# + setdvar( "test_player_tablet", "3" ); + adddebugcommand( "devgui_cmd \"Zombies:2/Tomb:1/Easter Ann:3/Tablet-None:1\" \"test_player_tablet 0\"\n" ); + adddebugcommand( "devgui_cmd \"Zombies:2/Tomb:1/Easter Ann:3/Tablet-Clean:1\" \"test_player_tablet 1\"\n" ); + adddebugcommand( "devgui_cmd \"Zombies:2/Tomb:1/Easter Ann:3/Tablet-Dirty:1\" \"test_player_tablet 2\"\n" ); + level thread watch_devgui_tablet(); +#/ +} + +watch_devgui_tablet() +{ +/# + while ( true ) + { + if ( getdvar( #"test_player_tablet" ) != "3" ) + { + player = get_players()[0]; + n_tablet_state = int( getdvar( #"test_player_tablet" ) ); + player setclientfieldtoplayer( "player_tablet_state", n_tablet_state ); + setdvar( "test_player_tablet", "3" ); + } + + wait 0.1; + } +#/ +} + +watch_devgui_zombie_blood() +{ +/# + while ( true ) + { + if ( getdvar( #"zombie_blood" ) == "on" ) + { + setdvar( "zombie_blood", "off" ); + level thread maps\mp\zombies\_zm_devgui::zombie_devgui_give_powerup( "zombie_blood", 1 ); + } + + wait 0.1; + } +#/ +} + +watch_devgui_double_points() +{ +/# + while ( true ) + { + if ( getdvar( #"double_points" ) == "on" ) + { + setdvar( "double_points", "off" ); + level thread maps\mp\zombies\_zm_devgui::zombie_devgui_give_powerup( "double_points", 1 ); + iprintlnbold( "change" ); + } + + wait 0.1; + } +#/ +} + +setup_rex_starts() +{ + add_gametype( "zclassic", ::dummy, "zclassic", ::dummy ); + add_gameloc( "tomb", ::dummy, "tomb", ::dummy ); +} + +dummy() +{ + +} + +working_zone_init() +{ + flag_init( "always_on" ); + flag_set( "always_on" ); + add_adjacent_zone( "zone_robot_head", "zone_robot_head", "always_on" ); + add_adjacent_zone( "zone_start", "zone_start_a", "always_on" ); + add_adjacent_zone( "zone_start", "zone_start_b", "always_on" ); + add_adjacent_zone( "zone_start_a", "zone_start_b", "always_on" ); + add_adjacent_zone( "zone_start_a", "zone_bunker_1a", "activate_zone_bunker_1" ); + add_adjacent_zone( "zone_bunker_1a", "zone_bunker_1", "activate_zone_bunker_1" ); + add_adjacent_zone( "zone_bunker_1a", "zone_bunker_1", "activate_zone_bunker_3a" ); + add_adjacent_zone( "zone_bunker_1", "zone_bunker_3a", "activate_zone_bunker_3a" ); + add_adjacent_zone( "zone_bunker_3a", "zone_bunker_3b", "activate_zone_bunker_3a" ); + add_adjacent_zone( "zone_bunker_3a", "zone_bunker_3b", "activate_zone_bunker_3b" ); + add_adjacent_zone( "zone_bunker_3b", "zone_bunker_5a", "activate_zone_bunker_3b" ); + add_adjacent_zone( "zone_bunker_5a", "zone_bunker_5b", "activate_zone_bunker_3b" ); + add_adjacent_zone( "zone_start_b", "zone_bunker_2a", "activate_zone_bunker_2" ); + add_adjacent_zone( "zone_bunker_2a", "zone_bunker_2", "activate_zone_bunker_2" ); + add_adjacent_zone( "zone_bunker_2a", "zone_bunker_2", "activate_zone_bunker_4a" ); + add_adjacent_zone( "zone_bunker_2", "zone_bunker_4a", "activate_zone_bunker_4a" ); + add_adjacent_zone( "zone_bunker_4a", "zone_bunker_4b", "activate_zone_bunker_4a" ); + add_adjacent_zone( "zone_bunker_4a", "zone_bunker_4c", "activate_zone_bunker_4a" ); + add_adjacent_zone( "zone_bunker_4b", "zone_bunker_4f", "activate_zone_bunker_4a" ); + add_adjacent_zone( "zone_bunker_4c", "zone_bunker_4d", "activate_zone_bunker_4a" ); + add_adjacent_zone( "zone_bunker_4c", "zone_bunker_4e", "activate_zone_bunker_4a" ); + add_adjacent_zone( "zone_bunker_4e", "zone_bunker_tank_c1", "activate_zone_bunker_4a" ); + add_adjacent_zone( "zone_bunker_4e", "zone_bunker_tank_d", "activate_zone_bunker_4a" ); + add_adjacent_zone( "zone_bunker_tank_c", "zone_bunker_tank_c1", "activate_zone_bunker_4a" ); + add_adjacent_zone( "zone_bunker_tank_d", "zone_bunker_tank_d1", "activate_zone_bunker_4a" ); + add_adjacent_zone( "zone_bunker_4a", "zone_bunker_4b", "activate_zone_bunker_4b" ); + add_adjacent_zone( "zone_bunker_4a", "zone_bunker_4c", "activate_zone_bunker_4b" ); + add_adjacent_zone( "zone_bunker_4b", "zone_bunker_4f", "activate_zone_bunker_4b" ); + add_adjacent_zone( "zone_bunker_4c", "zone_bunker_4d", "activate_zone_bunker_4b" ); + add_adjacent_zone( "zone_bunker_4c", "zone_bunker_4e", "activate_zone_bunker_4b" ); + add_adjacent_zone( "zone_bunker_4b", "zone_bunker_5a", "activate_zone_bunker_4b" ); + add_adjacent_zone( "zone_bunker_5a", "zone_bunker_5b", "activate_zone_bunker_4b" ); + add_adjacent_zone( "zone_bunker_4e", "zone_bunker_tank_c1", "activate_zone_bunker_4b" ); + add_adjacent_zone( "zone_bunker_4e", "zone_bunker_tank_d", "activate_zone_bunker_4b" ); + add_adjacent_zone( "zone_bunker_tank_c", "zone_bunker_tank_c1", "activate_zone_bunker_4b" ); + add_adjacent_zone( "zone_bunker_tank_d", "zone_bunker_tank_d1", "activate_zone_bunker_4b" ); + add_adjacent_zone( "zone_bunker_tank_a", "zone_nml_7", "activate_zone_nml" ); + add_adjacent_zone( "zone_bunker_tank_a", "zone_nml_7a", "activate_zone_nml" ); + add_adjacent_zone( "zone_bunker_tank_a", "zone_bunker_tank_a1", "activate_zone_nml" ); + add_adjacent_zone( "zone_bunker_tank_a1", "zone_bunker_tank_a2", "activate_zone_nml" ); + add_adjacent_zone( "zone_bunker_tank_a1", "zone_bunker_tank_b", "activate_zone_nml" ); + add_adjacent_zone( "zone_bunker_tank_b", "zone_bunker_tank_c", "activate_zone_nml" ); + add_adjacent_zone( "zone_bunker_tank_c", "zone_bunker_tank_c1", "activate_zone_nml" ); + add_adjacent_zone( "zone_bunker_tank_d", "zone_bunker_tank_d1", "activate_zone_nml" ); + add_adjacent_zone( "zone_bunker_tank_d1", "zone_bunker_tank_e", "activate_zone_nml" ); + add_adjacent_zone( "zone_bunker_tank_e", "zone_bunker_tank_e1", "activate_zone_nml" ); + add_adjacent_zone( "zone_bunker_tank_e1", "zone_bunker_tank_e2", "activate_zone_nml" ); + add_adjacent_zone( "zone_bunker_tank_e1", "zone_bunker_tank_f", "activate_zone_nml" ); + add_adjacent_zone( "zone_bunker_tank_f", "zone_nml_1", "activate_zone_nml" ); + add_adjacent_zone( "zone_bunker_5b", "zone_nml_2a", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_0", "zone_nml_1", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_0", "zone_nml_farm", "activate_zone_farm" ); + add_adjacent_zone( "zone_nml_1", "zone_nml_2", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_1", "zone_nml_4", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_1", "zone_nml_20", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_2", "zone_nml_2a", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_2", "zone_nml_2b", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_2", "zone_nml_3", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_3", "zone_nml_4", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_3", "zone_nml_13", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_4", "zone_nml_5", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_4", "zone_nml_13", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_5", "zone_nml_farm", "activate_zone_farm" ); + add_adjacent_zone( "zone_nml_6", "zone_nml_2b", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_6", "zone_nml_7", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_6", "zone_nml_7a", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_6", "zone_nml_8", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_7", "zone_nml_7a", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_7", "zone_nml_9", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_7", "zone_nml_10", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_8", "zone_nml_10a", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_8", "zone_nml_14", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_8", "zone_nml_16", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_9", "zone_nml_7a", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_9", "zone_nml_9a", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_9", "zone_nml_11", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_10", "zone_nml_10a", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_10", "zone_nml_11", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_10a", "zone_nml_12", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_10a", "zone_village_4", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_11", "zone_nml_9a", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_11", "zone_nml_11a", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_11", "zone_nml_12", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_12", "zone_nml_11a", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_12", "zone_nml_12a", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_13", "zone_nml_15", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_14", "zone_nml_15", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_15", "zone_nml_17", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_15a", "zone_nml_14", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_15a", "zone_nml_15", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_16", "zone_nml_2b", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_16", "zone_nml_16a", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_16", "zone_nml_18", "activate_zone_ruins" ); + add_adjacent_zone( "zone_nml_17", "zone_nml_17a", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_17", "zone_nml_18", "activate_zone_ruins" ); + add_adjacent_zone( "zone_nml_18", "zone_nml_19", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_farm", "zone_nml_celllar", "activate_zone_farm" ); + add_adjacent_zone( "zone_nml_farm", "zone_nml_farm_1", "activate_zone_farm" ); + add_adjacent_zone( "zone_nml_19", "ug_bottom_zone", "activate_zone_crypt" ); + add_adjacent_zone( "zone_village_0", "zone_nml_15", "activate_zone_village_0" ); + add_adjacent_zone( "zone_village_0", "zone_village_4b", "activate_zone_village_0" ); + add_adjacent_zone( "zone_village_1", "zone_village_1a", "activate_zone_village_0" ); + add_adjacent_zone( "zone_village_1", "zone_village_2", "activate_zone_village_1" ); + add_adjacent_zone( "zone_village_1", "zone_village_4b", "activate_zone_village_0" ); + add_adjacent_zone( "zone_village_1", "zone_village_5b", "activate_zone_village_0" ); + add_adjacent_zone( "zone_village_2", "zone_village_3", "activate_zone_village_1" ); + add_adjacent_zone( "zone_village_3", "zone_village_3a", "activate_zone_village_1" ); + add_adjacent_zone( "zone_village_3", "zone_ice_stairs", "activate_zone_village_1" ); + add_adjacent_zone( "zone_ice_stairs", "zone_ice_stairs_1", "activate_zone_village_1" ); + add_adjacent_zone( "zone_village_3a", "zone_village_3b", "activate_zone_village_1" ); + add_adjacent_zone( "zone_village_4", "zone_nml_14", "activate_zone_village_0" ); + add_adjacent_zone( "zone_village_4", "zone_village_4a", "activate_zone_village_0" ); + add_adjacent_zone( "zone_village_4", "zone_village_4b", "activate_zone_village_0" ); + add_adjacent_zone( "zone_village_5", "zone_nml_4", "activate_zone_village_0" ); + add_adjacent_zone( "zone_village_5", "zone_village_5a", "activate_zone_village_0" ); + add_adjacent_zone( "zone_village_5a", "zone_village_5b", "activate_zone_village_0" ); + add_adjacent_zone( "zone_village_6", "zone_village_5b", "activate_zone_village_0" ); + add_adjacent_zone( "zone_village_6", "zone_village_6a", "activate_zone_village_0" ); + add_adjacent_zone( "zone_chamber_0", "zone_chamber_1", "activate_zone_chamber" ); + add_adjacent_zone( "zone_chamber_0", "zone_chamber_3", "activate_zone_chamber" ); + add_adjacent_zone( "zone_chamber_0", "zone_chamber_4", "activate_zone_chamber" ); + add_adjacent_zone( "zone_chamber_1", "zone_chamber_2", "activate_zone_chamber" ); + add_adjacent_zone( "zone_chamber_1", "zone_chamber_3", "activate_zone_chamber" ); + add_adjacent_zone( "zone_chamber_1", "zone_chamber_4", "activate_zone_chamber" ); + add_adjacent_zone( "zone_chamber_1", "zone_chamber_5", "activate_zone_chamber" ); + add_adjacent_zone( "zone_chamber_2", "zone_chamber_4", "activate_zone_chamber" ); + add_adjacent_zone( "zone_chamber_2", "zone_chamber_5", "activate_zone_chamber" ); + add_adjacent_zone( "zone_chamber_3", "zone_chamber_4", "activate_zone_chamber" ); + add_adjacent_zone( "zone_chamber_3", "zone_chamber_6", "activate_zone_chamber" ); + add_adjacent_zone( "zone_chamber_3", "zone_chamber_7", "activate_zone_chamber" ); + add_adjacent_zone( "zone_chamber_4", "zone_chamber_5", "activate_zone_chamber" ); + add_adjacent_zone( "zone_chamber_4", "zone_chamber_6", "activate_zone_chamber" ); + add_adjacent_zone( "zone_chamber_4", "zone_chamber_7", "activate_zone_chamber" ); + add_adjacent_zone( "zone_chamber_4", "zone_chamber_8", "activate_zone_chamber" ); + add_adjacent_zone( "zone_chamber_5", "zone_chamber_7", "activate_zone_chamber" ); + add_adjacent_zone( "zone_chamber_5", "zone_chamber_8", "activate_zone_chamber" ); + add_adjacent_zone( "zone_chamber_6", "zone_chamber_7", "activate_zone_chamber" ); + add_adjacent_zone( "zone_chamber_7", "zone_chamber_8", "activate_zone_chamber" ); + add_adjacent_zone( "zone_bunker_1", "zone_bunker_1a", "activate_zone_bunker_1_tank" ); + add_adjacent_zone( "zone_bunker_1a", "zone_fire_stairs", "activate_zone_bunker_1_tank" ); + add_adjacent_zone( "zone_fire_stairs", "zone_fire_stairs_1", "activate_zone_bunker_1_tank" ); + add_adjacent_zone( "zone_bunker_2", "zone_bunker_2a", "activate_zone_bunker_2_tank" ); + add_adjacent_zone( "zone_bunker_4a", "zone_bunker_4b", "activate_zone_bunker_4_tank" ); + add_adjacent_zone( "zone_bunker_4a", "zone_bunker_4c", "activate_zone_bunker_4_tank" ); + add_adjacent_zone( "zone_bunker_4c", "zone_bunker_4d", "activate_zone_bunker_4_tank" ); + add_adjacent_zone( "zone_bunker_4c", "zone_bunker_4e", "activate_zone_bunker_4_tank" ); + add_adjacent_zone( "zone_bunker_4e", "zone_bunker_tank_c1", "activate_zone_bunker_4_tank" ); + add_adjacent_zone( "zone_bunker_4e", "zone_bunker_tank_d", "activate_zone_bunker_4_tank" ); + add_adjacent_zone( "zone_bunker_tank_c", "zone_bunker_tank_c1", "activate_zone_bunker_4_tank" ); + add_adjacent_zone( "zone_bunker_tank_d", "zone_bunker_tank_d1", "activate_zone_bunker_4_tank" ); + add_adjacent_zone( "zone_bunker_tank_b", "zone_bunker_6", "activate_zone_bunker_6_tank" ); + add_adjacent_zone( "zone_bunker_1", "zone_bunker_6", "activate_zone_bunker_6_tank" ); + level thread activate_zone_trig( "trig_zone_bunker_1", "activate_zone_bunker_1_tank" ); + level thread activate_zone_trig( "trig_zone_bunker_2", "activate_zone_bunker_2_tank" ); + level thread activate_zone_trig( "trig_zone_bunker_4", "activate_zone_bunker_4_tank" ); + level thread activate_zone_trig( "trig_zone_bunker_6", "activate_zone_bunker_6_tank", "activate_zone_bunker_1_tank" ); + add_adjacent_zone( "zone_bunker_1a", "zone_fire_stairs", "activate_zone_bunker_1" ); + add_adjacent_zone( "zone_fire_stairs", "zone_fire_stairs_1", "activate_zone_bunker_1" ); + add_adjacent_zone( "zone_bunker_1a", "zone_fire_stairs", "activate_zone_bunker_3a" ); + add_adjacent_zone( "zone_fire_stairs", "zone_fire_stairs_1", "activate_zone_bunker_3a" ); + add_adjacent_zone( "zone_nml_9", "zone_air_stairs", "activate_zone_nml" ); + add_adjacent_zone( "zone_air_stairs", "zone_air_stairs_1", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_celllar", "zone_bolt_stairs", "activate_zone_farm" ); + add_adjacent_zone( "zone_bolt_stairs", "zone_bolt_stairs_1", "activate_zone_farm" ); +} + +activate_zone_trig( str_name, str_zone1, str_zone2 ) +{ + trig = getent( str_name, "targetname" ); + trig waittill( "trigger" ); + + if ( isdefined( str_zone1 ) ) + flag_set( str_zone1 ); + + if ( isdefined( str_zone2 ) ) + flag_set( str_zone2 ); + + trig delete(); +} + +check_tank_platform_zone() +{ + while ( true ) + { + level waittill( "newzoneActive", activezone ); + + if ( activezone == "zone_bunker_3" ) + break; + + wait 1; + } + + flag_set( "activate_zone_nml" ); +} + +tomb_vehicle_damage_override_wrapper( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime, damagefromunderneath, modelindex, partname ) +{ + if ( isdefined( level.a_func_vehicle_damage_override[self.vehicletype] ) ) + return level.a_func_vehicle_damage_override[self.vehicletype]; + + return idamage; +} + +drop_all_barriers() +{ + zkeys = getarraykeys( level.zones ); + + for ( z = 0; z < level.zones.size; z++ ) + { + zbarriers = get_all_zone_zbarriers( zkeys[z] ); + + if ( !isdefined( zbarriers ) ) + continue; + + foreach ( zbarrier in zbarriers ) + { + zbarrier_pieces = zbarrier getnumzbarrierpieces(); + + for ( i = 0; i < zbarrier_pieces; i++ ) + { + zbarrier hidezbarrierpiece( i ); + zbarrier setzbarrierpiecestate( i, "open" ); + } + + wait 0.05; + } + } +} + +get_all_zone_zbarriers( zone_name ) +{ + if ( !isdefined( zone_name ) ) + return undefined; + + zone = level.zones[zone_name]; + return zone.zbarriers; +} + +tomb_special_weapon_magicbox_check( weapon ) +{ + if ( isdefined( level.raygun2_included ) && level.raygun2_included ) + { + if ( weapon == "ray_gun_zm" ) + { + if ( self has_weapon_or_upgrade( "raygun_mark2_zm" ) ) + return false; + } + + if ( weapon == "raygun_mark2_zm" ) + { + if ( self has_weapon_or_upgrade( "ray_gun_zm" ) ) + return false; + + if ( randomint( 100 ) >= 33 ) + return false; + } + } + + if ( weapon == "beacon_zm" ) + { + if ( isdefined( self.beacon_ready ) && self.beacon_ready ) + return true; + else + return false; + } + + if ( isdefined( level.zombie_weapons[weapon].shared_ammo_weapon ) ) + { + if ( self has_weapon_or_upgrade( level.zombie_weapons[weapon].shared_ammo_weapon ) ) + return false; + } + + return true; +} + +custom_vending_precaching() +{ + if ( level._custom_perks.size > 0 ) + { + a_keys = getarraykeys( level._custom_perks ); + + for ( i = 0; i < a_keys.size; i++ ) + { + if ( isdefined( level._custom_perks[a_keys[i]].precache_func ) ) + level [[ level._custom_perks[a_keys[i]].precache_func ]](); + } + } + + if ( isdefined( level.zombiemode_using_pack_a_punch ) && level.zombiemode_using_pack_a_punch ) + { + precacheitem( "zombie_knuckle_crack" ); + precachemodel( "p6_anim_zm_buildable_pap" ); + precachemodel( "p6_anim_zm_buildable_pap_on" ); + precachestring( &"ZOMBIE_PERK_PACKAPUNCH" ); + precachestring( &"ZOMBIE_PERK_PACKAPUNCH_ATT" ); + level._effect["packapunch_fx"] = loadfx( "maps/zombie/fx_zombie_packapunch" ); + level.machine_assets["packapunch"] = spawnstruct(); + level.machine_assets["packapunch"].weapon = "zombie_knuckle_crack"; + } + + if ( isdefined( level.zombiemode_using_additionalprimaryweapon_perk ) && level.zombiemode_using_additionalprimaryweapon_perk ) + { + precacheitem( "zombie_perk_bottle_additionalprimaryweapon" ); + precacheshader( "specialty_additionalprimaryweapon_zombies" ); + precachemodel( "p6_zm_tm_vending_three_gun" ); + precachestring( &"ZOMBIE_PERK_ADDITIONALWEAPONPERK" ); + level._effect["additionalprimaryweapon_light"] = loadfx( "misc/fx_zombie_cola_arsenal_on" ); + level.machine_assets["additionalprimaryweapon"] = spawnstruct(); + level.machine_assets["additionalprimaryweapon"].weapon = "zombie_perk_bottle_additionalprimaryweapon"; + level.machine_assets["additionalprimaryweapon"].off_model = "p6_zm_tm_vending_three_gun"; + level.machine_assets["additionalprimaryweapon"].on_model = "p6_zm_tm_vending_three_gun"; + level.machine_assets["additionalprimaryweapon"].power_on_callback = maps\mp\zm_tomb_capture_zones::custom_vending_power_on; + level.machine_assets["additionalprimaryweapon"].power_off_callback = maps\mp\zm_tomb_capture_zones::custom_vending_power_off; + } + + if ( isdefined( level.zombiemode_using_deadshot_perk ) && level.zombiemode_using_deadshot_perk ) + { + precacheitem( "zombie_perk_bottle_deadshot" ); + precacheshader( "specialty_ads_zombies" ); + precachemodel( "zombie_vending_ads" ); + precachemodel( "zombie_vending_ads_on" ); + precachestring( &"ZOMBIE_PERK_DEADSHOT" ); + level._effect["deadshot_light"] = loadfx( "misc/fx_zombie_cola_dtap_on" ); + level.machine_assets["deadshot"] = spawnstruct(); + level.machine_assets["deadshot"].weapon = "zombie_perk_bottle_deadshot"; + level.machine_assets["deadshot"].off_model = "zombie_vending_ads"; + level.machine_assets["deadshot"].on_model = "zombie_vending_ads_on"; + level.machine_assets["deadshot"].power_on_callback = maps\mp\zm_tomb_capture_zones::custom_vending_power_on; + level.machine_assets["deadshot"].power_off_callback = maps\mp\zm_tomb_capture_zones::custom_vending_power_off; + } + + if ( isdefined( level.zombiemode_using_divetonuke_perk ) && level.zombiemode_using_divetonuke_perk ) + { + precacheitem( "zombie_perk_bottle_nuke" ); + precacheshader( "specialty_divetonuke_zombies" ); + precachemodel( "zombie_vending_nuke" ); + precachemodel( "zombie_vending_nuke_on" ); + precachestring( &"ZOMBIE_PERK_DIVETONUKE" ); + level._effect["divetonuke_light"] = loadfx( "misc/fx_zombie_cola_dtap_on" ); + level.machine_assets["divetonuke"] = spawnstruct(); + level.machine_assets["divetonuke"].weapon = "zombie_perk_bottle_nuke"; + level.machine_assets["divetonuke"].off_model = "zombie_vending_nuke"; + level.machine_assets["divetonuke"].on_model = "zombie_vending_nuke_on"; + level.machine_assets["divetonuke"].power_on_callback = maps\mp\zm_tomb_capture_zones::custom_vending_power_on; + level.machine_assets["divetonuke"].power_off_callback = maps\mp\zm_tomb_capture_zones::custom_vending_power_off; + } + + if ( isdefined( level.zombiemode_using_doubletap_perk ) && level.zombiemode_using_doubletap_perk ) + { + precacheitem( "zombie_perk_bottle_doubletap" ); + precacheshader( "specialty_doubletap_zombies" ); + precachemodel( "zombie_vending_doubletap2" ); + precachemodel( "zombie_vending_doubletap2_on" ); + precachestring( &"ZOMBIE_PERK_DOUBLETAP" ); + level._effect["doubletap_light"] = loadfx( "misc/fx_zombie_cola_dtap_on" ); + level.machine_assets["doubletap"] = spawnstruct(); + level.machine_assets["doubletap"].weapon = "zombie_perk_bottle_doubletap"; + level.machine_assets["doubletap"].off_model = "zombie_vending_doubletap2"; + level.machine_assets["doubletap"].on_model = "zombie_vending_doubletap2_on"; + level.machine_assets["doubletap"].power_on_callback = maps\mp\zm_tomb_capture_zones::custom_vending_power_on; + level.machine_assets["doubletap"].power_off_callback = maps\mp\zm_tomb_capture_zones::custom_vending_power_off; + } + + if ( isdefined( level.zombiemode_using_juggernaut_perk ) && level.zombiemode_using_juggernaut_perk ) + { + precacheitem( "zombie_perk_bottle_jugg" ); + precacheshader( "specialty_juggernaut_zombies" ); + precachemodel( "zombie_vending_jugg" ); + precachemodel( "zombie_vending_jugg_on" ); + precachestring( &"ZOMBIE_PERK_JUGGERNAUT" ); + level._effect["jugger_light"] = loadfx( "misc/fx_zombie_cola_jugg_on" ); + level.machine_assets["juggernog"] = spawnstruct(); + level.machine_assets["juggernog"].weapon = "zombie_perk_bottle_jugg"; + level.machine_assets["juggernog"].off_model = "zombie_vending_jugg"; + level.machine_assets["juggernog"].on_model = "zombie_vending_jugg_on"; + level.machine_assets["juggernog"].power_on_callback = maps\mp\zm_tomb_capture_zones::custom_vending_power_on; + level.machine_assets["juggernog"].power_off_callback = maps\mp\zm_tomb_capture_zones::custom_vending_power_off; + } + + if ( isdefined( level.zombiemode_using_marathon_perk ) && level.zombiemode_using_marathon_perk ) + { + precacheitem( "zombie_perk_bottle_marathon" ); + precacheshader( "specialty_marathon_zombies" ); + precachemodel( "zombie_vending_marathon" ); + precachemodel( "zombie_vending_marathon_on" ); + precachestring( &"ZOMBIE_PERK_MARATHON" ); + level._effect["marathon_light"] = loadfx( "maps/zombie/fx_zmb_cola_staminup_on" ); + level.machine_assets["marathon"] = spawnstruct(); + level.machine_assets["marathon"].weapon = "zombie_perk_bottle_marathon"; + level.machine_assets["marathon"].off_model = "zombie_vending_marathon"; + level.machine_assets["marathon"].on_model = "zombie_vending_marathon_on"; + level.machine_assets["marathon"].power_on_callback = maps\mp\zm_tomb_capture_zones::custom_vending_power_on; + level.machine_assets["marathon"].power_off_callback = maps\mp\zm_tomb_capture_zones::custom_vending_power_off; + } + + if ( isdefined( level.zombiemode_using_revive_perk ) && level.zombiemode_using_revive_perk ) + { + precacheitem( "zombie_perk_bottle_revive" ); + precacheshader( "specialty_quickrevive_zombies" ); + precachemodel( "p6_zm_tm_vending_revive" ); + precachemodel( "p6_zm_tm_vending_revive_on" ); + precachestring( &"ZOMBIE_PERK_QUICKREVIVE" ); + level._effect["revive_light"] = loadfx( "misc/fx_zombie_cola_revive_on" ); + level._effect["revive_light_flicker"] = loadfx( "maps/zombie/fx_zmb_cola_revive_flicker" ); + level.machine_assets["revive"] = spawnstruct(); + level.machine_assets["revive"].weapon = "zombie_perk_bottle_revive"; + level.machine_assets["revive"].off_model = "p6_zm_tm_vending_revive"; + level.machine_assets["revive"].on_model = "p6_zm_tm_vending_revive_on"; + level.machine_assets["revive"].power_on_callback = maps\mp\zm_tomb_capture_zones::custom_vending_power_on; + level.machine_assets["revive"].power_off_callback = maps\mp\zm_tomb_capture_zones::custom_vending_power_off; + } + + if ( isdefined( level.zombiemode_using_sleightofhand_perk ) && level.zombiemode_using_sleightofhand_perk ) + { + precacheitem( "zombie_perk_bottle_sleight" ); + precacheshader( "specialty_fastreload_zombies" ); + precachemodel( "zombie_vending_sleight" ); + precachemodel( "zombie_vending_sleight_on" ); + precachestring( &"ZOMBIE_PERK_FASTRELOAD" ); + level._effect["sleight_light"] = loadfx( "misc/fx_zombie_cola_on" ); + level.machine_assets["speedcola"] = spawnstruct(); + level.machine_assets["speedcola"].weapon = "zombie_perk_bottle_sleight"; + level.machine_assets["speedcola"].off_model = "zombie_vending_sleight"; + level.machine_assets["speedcola"].on_model = "zombie_vending_sleight_on"; + level.machine_assets["speedcola"].power_on_callback = maps\mp\zm_tomb_capture_zones::custom_vending_power_on; + level.machine_assets["speedcola"].power_off_callback = maps\mp\zm_tomb_capture_zones::custom_vending_power_off; + } + + if ( isdefined( level.zombiemode_using_tombstone_perk ) && level.zombiemode_using_tombstone_perk ) + { + precacheitem( "zombie_perk_bottle_tombstone" ); + precacheshader( "specialty_tombstone_zombies" ); + precachemodel( "zombie_vending_tombstone" ); + precachemodel( "zombie_vending_tombstone_on" ); + precachemodel( "ch_tombstone1" ); + precachestring( &"ZOMBIE_PERK_TOMBSTONE" ); + level._effect["tombstone_light"] = loadfx( "misc/fx_zombie_cola_on" ); + level.machine_assets["tombstone"] = spawnstruct(); + level.machine_assets["tombstone"].weapon = "zombie_perk_bottle_tombstone"; + level.machine_assets["tombstone"].off_model = "zombie_vending_tombstone"; + level.machine_assets["tombstone"].on_model = "zombie_vending_tombstone_on"; + level.machine_assets["tombstone"].power_on_callback = maps\mp\zm_tomb_capture_zones::custom_vending_power_on; + level.machine_assets["tombstone"].power_off_callback = maps\mp\zm_tomb_capture_zones::custom_vending_power_off; + } + + if ( isdefined( level.zombiemode_using_chugabud_perk ) && level.zombiemode_using_chugabud_perk ) + { + precacheitem( "zombie_perk_bottle_whoswho" ); + precacheshader( "specialty_quickrevive_zombies" ); + precachemodel( "p6_zm_vending_chugabud" ); + precachemodel( "p6_zm_vending_chugabud_on" ); + precachemodel( "ch_tombstone1" ); + precachestring( &"ZOMBIE_PERK_TOMBSTONE" ); + level._effect["tombstone_light"] = loadfx( "misc/fx_zombie_cola_on" ); + level.machine_assets["whoswho"] = spawnstruct(); + level.machine_assets["whoswho"].weapon = "zombie_perk_bottle_whoswho"; + level.machine_assets["whoswho"].off_model = "p6_zm_vending_chugabud"; + level.machine_assets["whoswho"].on_model = "p6_zm_vending_chugabud_on"; + level.machine_assets["whoswho"].power_on_callback = maps\mp\zm_tomb_capture_zones::custom_vending_power_on; + level.machine_assets["whoswho"].power_off_callback = maps\mp\zm_tomb_capture_zones::custom_vending_power_off; + } +} + +tomb_actor_damage_override_wrapper( inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, shitloc, psoffsettime, boneindex ) +{ + if ( isdefined( self.b_zombie_blood_damage_only ) && self.b_zombie_blood_damage_only ) + { + if ( !isplayer( attacker ) || !attacker.zombie_vars["zombie_powerup_zombie_blood_on"] ) + return 0; + } + + if ( isdefined( self.script_noteworthy ) && self.script_noteworthy == "capture_zombie" && isdefined( attacker ) && isplayer( attacker ) ) + { + if ( damage >= self.health ) + { + if ( 100 * level.round_number > attacker.n_capture_zombie_points ) + { + attacker maps\mp\zombies\_zm_score::player_add_points( "rebuild_board", 10 ); + attacker.n_capture_zombie_points = attacker.n_capture_zombie_points + 10; + } + } + } + + return_val = self maps\mp\zombies\_zm::actor_damage_override_wrapper( inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, shitloc, psoffsettime, boneindex ); + + if ( damage >= self.health ) + { + if ( weapon == "zombie_markiv_cannon" && meansofdeath == "MOD_CRUSH" ) + self thread zombie_gib_guts(); + else if ( isdefined( self.b_on_tank ) && self.b_on_tank || isdefined( self.b_climbing_tank ) && self.b_climbing_tank ) + self maps\mp\zm_tomb_tank::zombie_on_tank_death_animscript_callback( inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, shitloc, psoffsettime, boneindex ); + } + + return return_val; +} + +tomb_zombie_death_event_callback() +{ + if ( isdefined( self ) && isdefined( self.damagelocation ) && isdefined( self.damagemod ) && isdefined( self.damageweapon ) && isdefined( self.attacker ) && isplayer( self.attacker ) ) + { + if ( is_headshot( self.damageweapon, self.damagelocation, self.damagemod ) && maps\mp\zombies\_zm_challenges::challenge_exists( "zc_headshots" ) && !( !isdefined( self.script_noteworthy ) && !isdefined( "capture_zombie" ) || isdefined( self.script_noteworthy ) && isdefined( "capture_zombie" ) && self.script_noteworthy == "capture_zombie" ) ) + self.attacker maps\mp\zombies\_zm_challenges::increment_stat( "zc_headshots" ); + } +} + +zombie_init_done() +{ + self.allowpain = 0; + self thread maps\mp\zm_tomb_distance_tracking::escaped_zombies_cleanup_init(); +} + +tomb_validate_enemy_path_length( player ) +{ + max_dist = 1296; + d = distancesquared( self.origin, player.origin ); + + if ( d <= max_dist ) + return true; + + return false; +} + +show_zombie_count() +{ + self endon( "death_or_disconnect" ); + flag_wait( "start_zombie_round_logic" ); + + while ( true ) + { + n_round_zombies = get_current_zombie_count(); + str_hint = "Alive: " + n_round_zombies + "\\nTo Spawn: " + level.zombie_total; + iprintln( str_hint ); + wait 5; + } +} + +tomb_custom_divetonuke_explode( attacker, origin ) +{ + radius = level.zombie_vars["zombie_perk_divetonuke_radius"]; + min_damage = level.zombie_vars["zombie_perk_divetonuke_min_damage"]; + max_damage = level.zombie_vars["zombie_perk_divetonuke_max_damage"]; + + if ( isdefined( level.flopper_network_optimized ) && level.flopper_network_optimized ) + attacker thread tomb_custom_divetonuke_explode_network_optimized( origin, radius, max_damage, min_damage, "MOD_GRENADE_SPLASH" ); + else + radiusdamage( origin, radius, max_damage, min_damage, attacker, "MOD_GRENADE_SPLASH" ); + + playfx( level._effect["divetonuke_groundhit"], origin ); + attacker playsound( "zmb_phdflop_explo" ); + maps\mp\_visionset_mgr::vsmgr_activate( "visionset", "zm_perk_divetonuke", attacker ); + wait 1; + maps\mp\_visionset_mgr::vsmgr_deactivate( "visionset", "zm_perk_divetonuke", attacker ); +} + +tomb_custom_divetonuke_explode_network_optimized( origin, radius, max_damage, min_damage, damage_mod ) +{ + self endon( "disconnect" ); + a_all_zombies = getaispeciesarray( "axis", "all" ); + a_zombies = get_array_of_closest( origin, a_all_zombies, undefined, undefined, radius ); + network_stall_counter = 0; + + if ( isdefined( a_zombies ) ) + { + for ( i = 0; i < a_zombies.size; i++ ) + { + e_zombie = a_zombies[i]; + + if ( !isdefined( e_zombie ) || !isalive( e_zombie ) ) + continue; + + dist = distance( e_zombie.origin, origin ); + damage = min_damage + ( max_damage - min_damage ) * ( 1.0 - dist / radius ); + e_zombie dodamage( damage, e_zombie.origin, self, self, 0, damage_mod ); + network_stall_counter--; + + if ( network_stall_counter <= 0 ) + { + wait_network_frame(); + network_stall_counter = randomintrange( 1, 3 ); + } + } + } +} + +tomb_custom_electric_cherry_laststand() +{ + visionsetlaststand( "zombie_last_stand", 1 ); + + if ( isdefined( self ) ) + { + playfx( level._effect["electric_cherry_explode"], self.origin ); + self playsound( "zmb_cherry_explode" ); + self notify( "electric_cherry_start" ); + wait 0.05; + a_zombies = getaispeciesarray( "axis", "all" ); + a_zombies = get_array_of_closest( self.origin, a_zombies, undefined, undefined, 500 ); + + for ( i = 0; i < a_zombies.size; i++ ) + { + if ( isalive( self ) ) + { + if ( a_zombies[i].health <= 1000 ) + { + a_zombies[i] thread maps\mp\zombies\_zm_perk_electric_cherry::electric_cherry_death_fx(); + + if ( isdefined( self.cherry_kills ) ) + self.cherry_kills++; + + self maps\mp\zombies\_zm_score::add_to_player_score( 40 ); + } + else + { + a_zombies[i] thread maps\mp\zombies\_zm_perk_electric_cherry::electric_cherry_stun(); + a_zombies[i] thread maps\mp\zombies\_zm_perk_electric_cherry::electric_cherry_shock_fx(); + } + + wait 0.1; + a_zombies[i] dodamage( 1000, self.origin, self, self, "none" ); + } + } + + self notify( "electric_cherry_end" ); + } +} + +tomb_custom_electric_cherry_reload_attack() +{ + self endon( "death" ); + self endon( "disconnect" ); + self endon( "stop_electric_cherry_reload_attack" ); + self.wait_on_reload = []; + self.consecutive_electric_cherry_attacks = 0; + + while ( true ) + { + self waittill( "reload_start" ); + str_current_weapon = self getcurrentweapon(); + + if ( isinarray( self.wait_on_reload, str_current_weapon ) ) + continue; + + self.wait_on_reload[self.wait_on_reload.size] = str_current_weapon; + self.consecutive_electric_cherry_attacks++; + n_clip_current = self getweaponammoclip( str_current_weapon ); + n_clip_max = weaponclipsize( str_current_weapon ); + n_fraction = n_clip_current / n_clip_max; + perk_radius = linear_map( n_fraction, 1.0, 0.0, 32, 128 ); + perk_dmg = linear_map( n_fraction, 1.0, 0.0, 1, 1045 ); + self thread maps\mp\zombies\_zm_perk_electric_cherry::check_for_reload_complete( str_current_weapon ); + + if ( isdefined( self ) ) + { + switch ( self.consecutive_electric_cherry_attacks ) + { + case 0: + case 1: + n_zombie_limit = undefined; + break; + case 2: + n_zombie_limit = 8; + break; + case 3: + n_zombie_limit = 4; + break; + case 4: + n_zombie_limit = 2; + break; + default: + n_zombie_limit = 0; + } + + self thread maps\mp\zombies\_zm_perk_electric_cherry::electric_cherry_cooldown_timer( str_current_weapon ); + + if ( isdefined( n_zombie_limit ) && n_zombie_limit == 0 ) + continue; + + self thread electric_cherry_reload_fx( n_fraction ); + self notify( "electric_cherry_start" ); + self playsound( "zmb_cherry_explode" ); + a_zombies = getaispeciesarray( "axis", "all" ); + a_zombies = get_array_of_closest( self.origin, a_zombies, undefined, undefined, perk_radius ); + n_zombies_hit = 0; + + for ( i = 0; i < a_zombies.size; i++ ) + { + if ( isalive( self ) && isalive( a_zombies[i] ) ) + { + if ( isdefined( n_zombie_limit ) ) + { + if ( n_zombies_hit < n_zombie_limit ) + n_zombies_hit++; + else + break; + } + + if ( a_zombies[i].health <= perk_dmg ) + { + a_zombies[i] thread maps\mp\zombies\_zm_perk_electric_cherry::electric_cherry_death_fx(); + + if ( isdefined( self.cherry_kills ) ) + self.cherry_kills++; + + self maps\mp\zombies\_zm_score::add_to_player_score( 40 ); + } + else + { + if ( !isdefined( a_zombies[i].is_mechz ) ) + a_zombies[i] thread maps\mp\zombies\_zm_perk_electric_cherry::electric_cherry_stun(); + + a_zombies[i] thread maps\mp\zombies\_zm_perk_electric_cherry::electric_cherry_shock_fx(); + } + + wait 0.1; + + if ( isalive( a_zombies[i] ) ) + a_zombies[i] dodamage( perk_dmg, self.origin, self, self, "none" ); + } + } + + self notify( "electric_cherry_end" ); + } + } +} + +tomb_custom_player_track_ammo_count() +{ + self notify( "stop_ammo_tracking" ); + self endon( "disconnect" ); + self endon( "stop_ammo_tracking" ); + ammolowcount = 0; + ammooutcount = 0; + + while ( true ) + { + wait 0.5; + weap = self getcurrentweapon(); + + if ( !isdefined( weap ) || weap == "none" || !tomb_can_track_ammo_custom( weap ) ) + continue; + + if ( self getammocount( weap ) > 5 || self maps\mp\zombies\_zm_laststand::player_is_in_laststand() ) + { + ammooutcount = 0; + ammolowcount = 0; + continue; + } + + if ( self getammocount( weap ) > 0 ) + { + if ( ammolowcount < 1 ) + { + self maps\mp\zombies\_zm_audio::create_and_play_dialog( "general", "ammo_low" ); + ammolowcount++; + } + } + else if ( ammooutcount < 1 ) + { + self maps\mp\zombies\_zm_audio::create_and_play_dialog( "general", "ammo_out" ); + ammooutcount++; + } + + wait 20; + } +} + +tomb_can_track_ammo_custom( weap ) +{ + if ( !isdefined( weap ) ) + return false; + + switch ( weap ) + { + case "alcatraz_shield_zm": + case "chalk_draw_zm": + case "death_throe_zm": + case "equip_dieseldrone_zm": + case "equip_gasmask_zm": + case "falling_hands_tomb_zm": + case "humangun_upgraded_zm": + case "humangun_zm": + case "lower_equip_gasmask_zm": + case "no_hands_zm": + case "none": + case "one_inch_punch_air_zm": + case "one_inch_punch_fire_zm": + case "one_inch_punch_ice_zm": + case "one_inch_punch_lightning_zm": + case "one_inch_punch_upgraded_zm": + case "one_inch_punch_zm": + case "riotshield_zm": + case "screecher_arms_zm": + case "slowgun_upgraded_zm": + case "slowgun_zm": + case "staff_revive_zm": + case "tazer_knuckles_upgraded_zm": + case "tazer_knuckles_zm": + case "time_bomb_detonator_zm": + case "time_bomb_zm": + case "zombie_bowie_flourish": + case "zombie_builder_zm": + case "zombie_fists_zm": + case "zombie_knuckle_crack": + case "zombie_one_inch_punch_flourish": + case "zombie_one_inch_punch_upgrade_flourish": + case "zombie_sickle_flourish": + case "zombie_tazer_flourish": + return false; + default: + if ( is_zombie_perk_bottle( weap ) || is_placeable_mine( weap ) || is_equipment( weap ) || issubstr( weap, "knife_ballistic_" ) || getsubstr( weap, 0, 3 ) == "gl_" || weaponfuellife( weap ) > 0 || weap == level.revive_tool ) + return false; + } + + return true; +} diff --git a/t6/scripts/zm/zm_tomb/boss_ivo1.gsc b/t6/scripts/zm/zm_tomb/boss_ivo1.gsc new file mode 100644 index 0000000..f70cc9a --- /dev/null +++ b/t6/scripts/zm/zm_tomb/boss_ivo1.gsc @@ -0,0 +1,1637 @@ + +/* + * Copyright 2023 K Mod. All rights reserved. + * + * This code, including any associated documentation or files, is the + * intellectual property of K Mod. You may not + * use, modify, reproduce, distribute, or disclose this code without + * explicit written permission from the owner. + * + * Unauthorized use, reproduction, or distribution of this code or any + * portion thereof is strictly prohibited and may result in severe legal + * consequences. For licensing inquiries or permission requests, please + * contact eizekiels@gmail.com. + */ + +/* -------- STARTER GUIDE ---------- + + --------- HOW TO MAKE THE BOSS LOOKS COOL, Spawn an object to a specific location --------- + + model = "t6_wpn_zmb_staff_tip_lightning_world"; + + self.fx = spawn( "script_model", self.origin ); // create objet + self.fx linkto( self, "J_SpineLower", (0, -10, 15), (180, 90, 70)); // link to the boss (anchor) + wait 0.05; + self.fx setmodel( model ); // apply the model + + --------- HOW TO MAKE BOSS ATTACK SPECIAL EFFECTS, Spawn a FX on an fx --------------------- + + fx_origin = level.boss.origin; //set origin of effect + fx = spawn( "script_model", (fx_origin[0], fx_origin[1], -390)); // spawn object + fx setmodel( "tag_origin" ); // set three D default object + wait 0.05; + playfxontag( level._effect["whirlwind"], fx, "tag_origin" ); // <- only thing to change is the level._effect, go search it in the stock script (ctrl + F) + + --------- HOW TO ADD SOUND TO ATTACKS ------------------------------------------------------- + + self playsound( "evt_medal_acquired" ); // search playsound in stock script (CTRL + F) + + --------- HOW TO MAKE BOSS SHINY ------------------------------------------------------------ + + (Pick one or more) + level.boss.fx_element_glow = playfxontag( localclientnum, level._effect["fire_glow"], level.boss, "tag_origin" ); + level.boss.fx_element_glow = playfxontag( localclientnum, level._effect["air_glow"], level.boss, "tag_origin" ); + level.boss.fx_element_glow = playfxontag( localclientnum, level._effect["elec_glow"], level.boss, "tag_origin" ); + level.boss.fx_element_glow = playfxontag( localclientnum, level._effect["ice_glow"], level.boss, "tag_origin" ); + + + --------- USEFUL COORDINATES ----------------------------------------------------------------- + level.fire_spawn_origin = (9463, -8560, -398); + level.ice_spawn_origin = (11211, -7058.7, -345.875); + level.wind_spawn_origin = (11253, -8655, -408); + level.lightning_spawn_origin = (9623.4, -7016.2, -345.875); + level.pap_spawn_origin = (10760.4, -7980.47, -463.875); + level.center_spawn_origin = (10314.5, -7889.91, -411.875); + level.fire_puzzle_origin = (9891.5, -8764, -452); + +*/ +//BACKUP BEFORE PHASES ! +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_magicbox; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\zombies\_zm_power; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\_demo; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_chugabud; +#include maps\mp\_visionset_mgr; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\zombies\_zm_spawner; + +#include Maps\Origins\clientscripts\mp\zm_tomb_tank; +#include maps\mp\zombies\_zm_ai_mechz; +#include clientscripts\mp\_utility; +#include clientscripts\mp\_fx; +#include clientscripts\mp\zombies\_zm_utility; +#include clientscripts\mp\zombies\_zm_weapons; +#include maps\mp\gametypes_zm\_weapon_utils; +#include Maps\Origins\clientscripts\mp\zombies\_zm_weap_beacon; +#include Maps\Origins\clientscripts\mp\zombies; +#include Maps\Tranzit\maps\mp\zombies\_zm_ai_avogadro; +#include maps\mp\gametypes_zm\_shellshock; +#include maps\mp\zombies\_zm_zonemgr; +#include maps\mp\zombies\_zm_ai_mechz_ffotd; +#include maps\mp\zombies\_zm_sidequests; +#include maps\mp\zm_tomb_ee_main; +#include maps\mp\zm_tomb_utility; +#include maps\mp\zm_tomb_vo; +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\gametypes_zm\_hud; +#include maps\mp\zm_tomb_chamber; +#include maps\mp\zm_tomb; +#include maps\mp\zm_spawner; +#include maps\zombie_alcatraz\fx_alcatraz_lightning_lg; +#include maps\mp\zombies\_zm_traps; + +#include scripts\zm\zm_tomb\raid_boss; +/* +init()//delete +{ + flag_wait("initial_blackscreen_passed"); + level thread setup_boss_ivo1(); +} +*/ +init_levelvars() +{ + level.is_zombie_level = 1; + level.laststandpistol = "m1911_zm"; + level.default_laststandpistol = "m1911_zm"; + level.default_solo_laststandpistol = "m1911_upgraded_zm"; + level.start_weapon = "m1911_zm"; + level.first_round = 1; + level.start_round = getgametypesetting( "startRound" ); + level.round_number = level.start_round; + level.enable_magic = getgametypesetting( "magic" ); + level.headshots_only = getgametypesetting( "headshotsonly" ); + level.player_starting_points = level.round_number * 500; + level.round_start_time = 0; + level.pro_tips_start_time = 0; + level.intermission = 0; + level.dog_intermission = 0; + level.zombie_total = 0; + level.total_zombies_killed = 0; + level.hudelem_count = 0; + level.zombie_spawn_locations = []; + level.zombie_rise_spawners = []; + level.current_zombie_array = []; + level.current_zombie_count = 0; + level.zombie_total_subtract = 0; + level.destructible_callbacks = []; + level.zombie_vars = []; + + foreach ( team in level.teams ) + level.zombie_vars[team] = []; + + difficulty = 1; + column = int( difficulty ) + 1; + set_zombie_var( "zombie_health_increase", 100, 0, column ); + set_zombie_var( "zombie_health_increase_multiplier", 0.1, 1, column ); + set_zombie_var( "zombie_health_start", 20000, 0, column ); + set_zombie_var( "zombie_spawn_delay", 0.05, 0, column ); + set_zombie_var( "zombie_new_runner_interval", 10, 0, column ); + set_zombie_var( "zombie_move_speed_multiplier", 8, 0, column ); + set_zombie_var( "zombie_move_speed_multiplier_easy", 2, 0, column ); + set_zombie_var( "zombie_max_ai", 24, 0, column ); + set_zombie_var( "zombie_ai_per_player", 6, 0, column ); + set_zombie_var( "below_world_check", -1000 ); + set_zombie_var( "spectators_respawn", 1 ); + set_zombie_var( "zombie_use_failsafe", 1 ); + set_zombie_var( "zombie_between_round_time", 10 ); + set_zombie_var( "zombie_intermission_time", 15 ); + set_zombie_var( "game_start_delay", 0, 0, column ); + set_zombie_var( "penalty_no_revive", 0.1, 1, column ); + set_zombie_var( "penalty_died", 0.0, 1, column ); + set_zombie_var( "penalty_downed", 0.05, 1, column ); + set_zombie_var( "starting_lives", 1, 0, column ); + set_zombie_var( "zombie_score_kill_4player", 50 ); + set_zombie_var( "zombie_score_kill_3player", 50 ); + set_zombie_var( "zombie_score_kill_2player", 50 ); + set_zombie_var( "zombie_score_kill_1player", 50 ); + set_zombie_var( "zombie_score_kill_4p_team", 30 ); + set_zombie_var( "zombie_score_kill_3p_team", 35 ); + set_zombie_var( "zombie_score_kill_2p_team", 45 ); + set_zombie_var( "zombie_score_kill_1p_team", 0 ); + set_zombie_var( "zombie_score_damage_normal", 10 ); + set_zombie_var( "zombie_score_damage_light", 10 ); + set_zombie_var( "zombie_score_bonus_melee", 80 ); + set_zombie_var( "zombie_score_bonus_head", 50 ); + set_zombie_var( "zombie_score_bonus_neck", 20 ); + set_zombie_var( "zombie_score_bonus_torso", 10 ); + set_zombie_var( "zombie_score_bonus_burn", 10 ); + set_zombie_var( "zombie_flame_dmg_point_delay", 500 ); + set_zombie_var( "zombify_player", 0 ); + + if ( issplitscreen() ) + set_zombie_var( "zombie_timer_offset", 280 ); + + level thread init_player_levelvars(); + level.gamedifficulty = getgametypesetting( "zmDifficulty" ); + + if ( level.gamedifficulty == 0 ) + level.zombie_move_speed = level.round_number * level.zombie_vars["zombie_move_speed_multiplier_easy"]; + else + level.zombie_move_speed = level.round_number * level.zombie_vars["zombie_move_speed_multiplier"]; + + if ( level.round_number == 1 ) + level.zombie_move_speed = 1; + else + { + for ( i = 1; i <= level.round_number; i++ ) + { + timer = level.zombie_vars["zombie_spawn_delay"]; + + if ( timer > 0.08 ) + { + level.zombie_vars["zombie_spawn_delay"] = timer * 0.95; + continue; + } + + if ( timer < 0.08 ) + level.zombie_vars["zombie_spawn_delay"] = 0.08; + } + } + + level.speed_change_max = 0; + level.speed_change_num = 0; +} + +NoPowerups_Ivo1() +{ + for(;;) + { + if(flag("zombie_drop_powerups")) + { + flag_clear( "zombie_drop_powerups" ); + // iPrintLn("Powerup Deleted"); + } + + + wait 0.05; + } +} + +should_do_flamethrower_attack()//change put this whole function in +{ + assert( isdefined( self.favoriteenemy ) ); +/# + if ( getdvarint( #"_id_E7121222" ) > 1 ) + println( "\\n\\tMZ: Checking should flame\\n" ); +#/ + + if ( isdefined( self.disable_complex_behaviors ) && self.disable_complex_behaviors ) + { +/# + if ( getdvarint( #"_id_E7121222" ) > 1 ) + println( "\\n\\t\\tMZ: Not doing flamethrower because doing force aggro\\n" ); +#/ + return false; + } + + if ( isdefined( self.not_interruptable ) && self.not_interruptable ) + { +/# + if ( getdvarint( #"_id_E7121222" ) > 1 ) + println( "\\n\\t\\tMZ: Not doing flamethrower because another behavior has set not_interruptable\\n" ); +#/ + return false; + } + + if ( !self mechz_check_in_arc( 26 ) ) + { +/# + if ( getdvarint( #"_id_E7121222" ) > 1 ) + println( "\\n\\t\\tMZ: Not doing flamethrower because target is not in front arc\\n" ); +#/ + return false; + } + + if ( isdefined( self.last_flamethrower_time ) && gettime() - self.last_flamethrower_time < level.mechz_flamethrower_cooldown_time ) + { +/# + if ( getdvarint( #"_id_E7121222" ) > 1 ) + println( "\\n\\t\\tMZ: Not doing flamethrower because it is still on cooldown\\n" ); +#/ + return false; + } + + n_dist_sq = distancesquared( self.origin, self.favoriteenemy.origin ); + + if ( n_dist_sq < 1444 || n_dist_sq > 160000 ) + { +/# + if ( getdvarint( #"_id_E7121222" ) > 1 ) + println( "\\n\\t\\tMZ: Not doing flamethrower because target is not in range\\n" ); +#/ + return false; + } + + b_cansee = bullettracepassed( self.origin + vectorscale( ( 0, 0, 1 ), 36.0 ), self.favoriteenemy.origin + vectorscale( ( 0, 0, 1 ), 36.0 ), 0, undefined ); + + if ( !b_cansee ) + { +/# + if ( getdvarint( #"_id_E7121222" ) > 1 ) + println( "\\n\\t\\tMZ: Not doing flamethrower because cannot see target\\n" ); +#/ + return false; + } + + return true; +} + +player_flame_damage()//Panzer Flamethrower Damage +{ + self endon( "zombified" ); + self endon( "death" ); + self endon( "disconnect" ); + n_player_dmg = 500;//Damage + n_jugga_dmg = 500;//Damage + n_burn_time = 1;//DamFunc + + if ( isdefined( self.is_zombie ) && self.is_zombie ) + return; + + self thread player_stop_burning(); + + if ( !isdefined( self.is_burning ) && is_player_valid( self, 1, 0 ) ) + { + self.is_burning = 1; + maps\mp\_visionset_mgr::vsmgr_activate( "overlay", "zm_transit_burn", self, n_burn_time, level.zm_transit_burn_max_duration ); + self notify( "burned" ); + + if ( !self hasperk( "specialty_armorvest" ) ) + { + self dodamage_wrapper(n_player_dmg); + wait 0.05; + self shellshock( "lava_small", 0.1 );//DamFunc + } + else + { + self dodamage_wrapper(n_jugga_dmg); + wait 0.05; + self shellshock( "lava_small", 0.1 );//DamFunc + } + + + wait 0.25; + self.is_burning = undefined; + } +} + +get_favorite_enemy_custom(origin, players)//Panzer Pathing Fix +{ + closest_distance = 999999999; + closest_player = undefined; + foreach (player in level.players) + { + if ( player.sessionstate == "intermission" ) + return undefined; + if ( isdefined( player.intermission ) && player.intermission ) + return undefined; + if(player.sessionstate == "spectator" || player maps\mp\zombies\_zm_laststand::player_is_in_laststand()) + continue; + p_dist = distancesquared(self.origin, player.origin); + if (p_dist < closest_distance) + { + closest_player = player; + closest_distance = p_dist; + } + } + return closest_player; +} + +dodamage_wrapper(damage) +{ + if (isdefined(self.shield) && self.shield > 0) + { + old_damage = damage; + damage -= self.shield; + if (old_damage < self.shield) + self.shield -= old_damage; + else + self.shield = 0; + } + self dodamage(damage, self.origin); +} + +setup_boss_ivo1() +{ + setdvar( "g_ai", "1" ); + level.boss_name = "^1Panzer Lord"; + level thread Chat1_Ivo1();//change + + level.dead = 0; + + level.fire = (9458.41, -8561.4, -398); + level.ice = (11233, -7047.87, -345.875); + level.wind = (11256, -8661.66, -408); + level.lightning = (9629, -7009.4, -345.875); + level.pap_spawn_origin = (10760.4, -7980.47, -463.875); + level.center_spawn_origin = (10341.6, -7907.17, -411.875); + level.fire_puzzle_origin = (9891.5, -8764, -452); + level.places = array( level.ice, level.fire, level.lightning, level.wind, level.center_spawn_origin); + level.player_out_of_playable_area_monitor = false; //disable instant death when entering out of bound area + //Variables + level.phase = 0; + //flag_set( "activate_zone_chamber" ); //activate Agartha zm spawn + level.mechz_spawners[0].is_enabled = 1; + //flag_wait("initial_blackscreen_passed"); + //wait 6.1; + //wait 0.05; + //wait 1; + + replaceFunc(maps\mp\zombies\_zm_ai_mechz::mechz_spawn, scripts\zm\zm_tomb\M\M_zm_ai_mechz::mechz_spawn); + replaceFunc(maps\mp\zombies\_zm_ai_mechz_ft::player_flame_damage, ::player_flame_damage); + replaceFunc(maps\mp\zombies\_zm_ai_mechz_claw::claw_grapple, scripts\zm\zm_tomb\M\M_zm_ai_mechz_claw::claw_grapple); + replaceFunc(maps\mp\zombies\_zm_ai_mechz_claw::check_for_claw_move_complete, scripts\zm\zm_tomb\M\M_zm_ai_mechz_claw::check_for_claw_move_complete); + replaceFunc(maps\mp\zombies\_zm_ai_mechz_claw::mechz_claw_cleanup, scripts\zm\zm_tomb\M\M_zm_ai_mechz_claw::mechz_claw_cleanup); + replaceFunc(maps\mp\zombies\_zm_ai_mechz_claw::check_for_players_mid_grapple, scripts\zm\zm_tomb\M\M_zm_ai_mechz_claw::check_for_players_mid_grapple); + replaceFunc(maps\mp\zombies\_zm_ai_mechz_claw::mechz_zombie_flamethrower_gib, scripts\zm\zm_tomb\M\M_zm_ai_mechz_claw::mechz_zombie_flamethrower_gib); + replaceFunc(maps\mp\zombies\_zm_ai_mechz_claw::mechz_claw_shot_pain_reaction, scripts\zm\zm_tomb\M\M_zm_ai_mechz_claw::mechz_claw_shot_pain_reaction); + replaceFunc(maps\mp\zombies\_zm_ai_mechz_claw::mechz_claw_detach, scripts\zm\zm_tomb\M\M_zm_ai_mechz_claw::mechz_claw_detach); + replaceFunc(maps\mp\zombies\_zm_ai_mechz_claw::mechz_claw_damage_trigger_thread, scripts\zm\zm_tomb\M\M_zm_ai_mechz_claw::mechz_claw_damage_trigger_thread); + replaceFunc(maps\mp\zombies\_zm_ai_mechz_ft::should_do_flamethrower_attack, ::should_do_flamethrower_attack);//change the flamethrower change above + replaceFunc(maps\mp\zombies\_zm_ai_mechz_claw::should_do_claw_attack, scripts\zm\zm_tomb\M\M_zm_ai_mechz_claw::should_do_claw_attack);//change the hook distance change in the script its inside + /* + level waittill("start_of_round");//dont know if you need it//delete + + wait 0.1; + */ + // replaceFunc(maps\mp\zombies\_zm::init_levelvars, ::init_levelvars); + if (level.players.size < 3)//change added 3 player HP + { + level.zombie_health = 40000;//NOTES: they feel easy to kill somewhat + } + else if (level.players.size == 3) + { + level.zombie_health = 100000; + } + else + { + level.zombie_health = 150000; + } + + wait 0.05; + + //foreach (player in level.players) + //player playSound( "zmb_ai_mechz_incoming_alarm" );//Boss Summon Sound, these wait times fit well with the boss summon + playsoundatposition( "zmb_ai_mechz_incoming_alarm", ( 0, 0, 0 ) ); + level thread SUPER_PANZERS_Ivo1(); + + level thread NoPowerups_Ivo1(); + + zombies = GetAIArray(level.zombie_team); // get the zombie array + + //transform the zm into the raid boss + zombies[0].boss = 1; + level.boss = zombies[0]; //set the raid boss as a global variable accessible from all code (no need to pass it as parameter) + level.boss.name = "Panzer Lord"; + level.boss setcandamage( 0 );//prevent boss taking damage + level.boss.candamage = 0; + + if (level.players.size < 3)//change added 3 player HP + { + level.boss.maxhealth = 5000000;//delete + } + else if (level.players.size == 3) + { + level.boss.maxhealth = 12000000; + } + else + { + level.boss.maxhealth = 15000000; + } + + level.boss.health = level.boss.maxhealth; + level.boss set_zombie_run_cycle("super_sprint"); + level.boss.meleedamage = 2000;//DamFunc + level.is_boss_spawned = 1; + level.boss.ignore_nuke = 1; + + level.boss.instakill_func = ::Boss_instakill_Ivo1; + + wait 0.05; + //boss skin + level.boss setmodel( "c_zom_mech_body", 1 ); + wait 0.05; + + helmet = spawn( "script_model", level.boss.origin ); + helmet linkto( level.boss, "J_Helmet", ( 4, 0, -5 ), ( -20, 0, 0 )); + wait 0.05; + helmet setmodel( "c_zom_mech_faceplate" ); + wait 0.05; + helmet notSolid(); + + claw = spawn( "script_model", level.boss.origin ); + claw linkto( level.boss, "J_Wrist_LE", ( 0, 0, 0 ), ( 180, 0, 0)); + wait 0.05; + claw setmodel( "c_zom_mech_claw"); + + level.boss attach( "c_zom_mech_armor_shoulder_right", "J_ShoulderArmor_RI", 0 ); + wait 0.05; + + level.boss attach( "c_zom_mech_armor_shoulder_left", "J_ShoulderArmor_LE", 0 ); + wait 0.05; + + level.boss attach( "c_zom_mech_armor_knee_right", "J_Knee_attach_RI", 0 ); + wait 0.05; + + level.boss attach( "c_zom_mech_armor_knee_left", "J_Knee_attach_LE", 0 ); + wait 0.5; + + playFXOnTag( level._effect["air_puzzle_smoke"], level.boss, "tag_origin"); + wait 0.05; + + level.boss thread boss_think_Ivo1(); //call the raid boss attacks loop + + level.boss thread Melee_Aura_ivo1(); //change added + + + for (;;)//after killing boss effects and sound//change the working ending function + { + if (level.boss.health <= 0 && !level.intermission)//level.end != 0 ) + { + iPrintLn("^3[ ^1" + level.boss_name + " ^7] : ^3Well done, you lived up to your reputation"); + playsoundatposition( "mus_zombie_game_over_ee", ( 0, 0, 0 ) ); + foreach(player in level.players) + { + player thread ending_ivo1(); + } + wait 3.5; + iPrintLn("^3[ ^1" + level.boss_name + " ^7] : ^3We will see each other again some other time..."); + for(i = 0; i <= 1000; i++) // find all zombies in the zombie array and kill + { + zombies = getaiarray(level.zombie_team); + zombies[0] dodamage( zombies[0].health + 100, zombies[0].origin); + wait 0.05; + } + break; + } + wait 0.05; + } +} + +Melee_Aura_ivo1()//change add +{ + self endon("death"); + + for(;;) + { + foreach(player in level.players) + { + player thread Melee_Aura_Damage_Ivo1(); + } + wait 0.1; + } +} + + +Melee_Aura_Damage_Ivo1()//change add +{ + if (distance(level.boss.origin, self.origin) <= 50) //if close to //DamFunc + { + self dodamage_wrapper(600); // deal damage to self (you gotta run away !) //DamFunc + vsmgr_activate( "overlay", "zm_transit_burn", self, 1, 1 );//visual burn effect + wait 0.05; + self shellshock( "lava_small", 0.1 );//stun //DamFunc + } +} + +Chat1_ivo1()//change added +{ + iPrintLn("^3[ ??? ^7] : ^3Hmm...I see..."); + wait 3.5; + iPrintLn("^3[ ??? ^7] : ^3The Keeper of Agartha told me about you...");//PIA Boss reference + wait 3.5; + iPrintLn("^3[ ^1" + level.boss_name + " ^7] : ^3Let us see if you are up for the challenge"); +} + +Boss_instakill_Ivo1() +{ + //iPrintLn("MORE DAMAGE"); + //self dodamage_wrapper(667); +} + +ending_Ivo1() +{ + if (self.sessionstate == "playing") + { + //self playsound("mus_zombie_game_over_ee"); + //wait 0.05; + self fadetoblackforxsec( 0, 1, 0.5, 0.5, "white" ); + end = 1; + return end; + } + else //if (self.sessionstate == "spectator" || self.sessionstate == "dead" ) + { + empty = 0; + } +} + +SUPER_PANZERS_Ivo1() +{ + //flag_wait("initial_blackscreen_passed"); + + //level waittill("start_of_round"); + //wait 0.1; + //panzers health + if (level.players.size < 3)//change added 3 player HP + { + level.mechz_max_health = 60000;// + level.mechz_base_health = 60000; + } + else if (level.players.size == 3) + { + level.mechz_max_health = 180000;// + level.mechz_base_health = 180000; + } + else + { + level.mechz_max_health = 250000;// + level.mechz_base_health = 250000; + } + + + level.mechz_health = level.mechz_base_health; + level.mechz_health_increase = 0; + + //to make sure that there is always room, used for the old way + level.mechz_zombie_per_round = 1000; + level.mechz_jump_delay = 0.05; + //DamFunc + level.mechz_meleedamage = 1000;//melee + level.mechz_claw_cooldown_time = 3500;//hook cooldown + level.mechz_flamethrower_cooldown_time = 2500;//flamethrower cooldown + level.mechz_aggro_dist_sq = 1225;//change the aggro distance in which the melee gets activated and hook and flamethrower disabled + level.mechz_flogger_stun_time = 0.1; + level.mechz_powerplant_stun_time = 0.1; + level.mechz_explosive_dmg_to_cancel_claw_percentage = 0.1; +} + +spawn_panzer() +{ + ai = spawn_zombie( level.mechz_spawners[0] ); + ai.custom_origin = (10314.5, -7889.91, -411.875); + ai.custom_angle = (0, 0, 0); + ai thread mechz_spawn(); + return ai; +} + + +boss_think_Ivo1() // After boss spawned, start the attacks rotation +{ + self endon("death"); //on boss death, stop the script + + wait 10; // let the boss time to get to the middle//change instead of wait 7 its wait 5 and wait 2, 5 + 2 = 7 + level thread Chat2_Ivo1();//<--------//change + wait 2;//change + + level thread Phase_check1_Ivo1(); + level.boss setcandamage( 1 );//now boss takes damage + level.boss.candamage = 1; + for(;;) //start the attack rotation loop + { + + level.boss thread Flamethrower_Easy_Ivo1();//FLAMETHROWER/AURA, DONE.//change names + wait 15; + + level Phase_Starter_Ivo1(); + + level.boss thread Electric_Easy_Ivo1();//Electric shot, DONE. + wait 22; + + level Phase_Starter_Ivo1(); + + level.boss thread AirStrike_Easy_Ivo1();//ROCKETS Air Strike, DONE. + wait 15; + + level Phase_Starter_Ivo1(); + + level.boss thread Wipe_Easy_Ivo1();//Wipe Attack DONE. + wait 15; + + level Phase_Starter_Ivo1(); + } +} + +Chat2_Ivo1()//change added more dialogue +{ + iPrintLn("^3[ ^1" + level.boss_name + " ^7] : ^3The flames consume ALL..."); + wait 15; + iPrintLn("^3[ ^1" + level.boss_name + " ^7] : ^3Don't stop moving, Dance for me"); + wait 22; + iPrintLn("^3[ ^1" + level.boss_name + " ^7] : ^3There is NO escaping the rockets"); + wait 15; + iPrintLn("^3[ ^1" + level.boss_name + " ^7] : ^3Protect yourself or else..."); +} + +Flamethrower_Easy_Ivo1() +{ + self endon("death"); + //setting fire aura, might also add boss being set on flames too + fire_aura = spawn( "script_model", level.boss.origin ); + fire_aura linkto( level.boss, "tag_origin" ); + fire_aura setmodel( "tag_origin" ); + wait 0.05; + + playfxontag( level._effect["fire_sacrifice_flame"], fire_aura, "tag_origin" ); + playfxontag( level._effect["wagon_fire"], fire_aura, "tag_origin" ); + + wait 1; + + level.boss playsound( "zmb_ai_mechz_flame_start" );//flame sounds to match panzer sounds + level.boss playloopsound( "zmb_ai_mechz_flame_loop", 0.6 ); + // + + for (i = 0; i <= 7 ; i++) + { + //where the flames come from + playfxontag( level._effect["wagon_fire"], fire_aura, "tag_origin" ); + playfxontag( level._effect["fire_sacrifice_flame"], fire_aura, "tag_origin" ); + playfxontag( level._effect["mech_wpn_flamethrower"], level.boss, "tag_origin" ); + playfxontag( level._effect["mech_wpn_flamethrower"], level.boss, "J_Root_Attach_LE" ); + playfxontag( level._effect["mech_wpn_flamethrower"], level.boss, "J_Root_Attach_RI" ); + playfxontag( level._effect["mech_wpn_flamethrower"], level.boss, "J_spinelower" ); + + foreach(player in level.players) + { + player thread BURN_ALL_Ivo1(); + } + wait 0.75; + } + + level.boss StopLoopSound(); + wait 2; + fire_aura delete(); + +} + +BURN_ALL_Ivo1() +{ + if (distance(level.boss.origin, self.origin) <= 325) //if close to boss + { + self dodamage_wrapper(400); // deal damage to self (you gotta run away !) //DamFunc + vsmgr_activate( "overlay", "zm_transit_burn", self, 2, 2 );//visual burn effect + wait 0.05; + self shellshock( "lava_small", 0.1 );//stun + } +} + + +Electric_Easy_Ivo1() +{ + self endon("death"); + elec_aura = spawn( "script_model", level.boss.origin ); + elec_aura linkto( level.boss, "tag_origin" ); + elec_aura setmodel( "tag_origin" ); + //Electric aura + playfxontag( level._effect["tesla_elec_kill"], elec_aura, "tag_origin" ); + playfxontag( level._effect["fx_tomb_probe_elec_on"], elec_aura, "tag_origin" ); + wait 0.05; + playfxontag( level._effect["electric_cherry_explode"], elec_aura, "tag_origin" ); + level.boss playsound("zmb_cherry_explode"); + foreach(player in level.players) + { + player thread Cherry_Boom_Ivo1(); + } + wait 0.05; + playfxontag( level._effect["tesla_elec_kill"], elec_aura, "tag_origin" ); + wait 2; + playfxontag( level._effect["electric_cherry_explode"], elec_aura, "tag_origin" ); + level.boss playsound("zmb_cherry_explode"); + foreach(player in level.players) + { + player thread Cherry_Boom_Ivo1(); + } + playfxontag( level._effect["tesla_elec_kill"], elec_aura, "tag_origin" ); + shoot_bolt_Ivo1(); + wait 0.3; //DamFunc for all shoot wait + shoot_bolt_Ivo1(); + wait 0.3; + shoot_bolt_Ivo1(); + wait 0.3; + shoot_bolt_Ivo1(); + wait 0.3; + playfxontag( level._effect["tesla_elec_kill"], elec_aura, "tag_origin" ); + wait 1; + playfxontag( level._effect["tesla_elec_kill"], elec_aura, "tag_origin" ); + playfxontag( level._effect["electric_cherry_explode"], elec_aura, "tag_origin" ); + level.boss playsound("zmb_cherry_explode"); + foreach(player in level.players) + { + player thread Cherry_Boom_Ivo1(); + } + shoot_bolt_Ivo1(); + wait 0.3; + shoot_bolt_Ivo1(); + wait 0.3; + shoot_bolt_Ivo1(); + wait 0.3; + shoot_bolt_Ivo1(); + wait 0.3; + playfxontag( level._effect["tesla_elec_kill"], elec_aura, "tag_origin" ); + wait 1; + playfxontag( level._effect["tesla_elec_kill"], elec_aura, "tag_origin" ); + playfxontag( level._effect["electric_cherry_explode"], elec_aura, "tag_origin" ); + level.boss playsound("zmb_cherry_explode"); + foreach(player in level.players) + { + player thread Cherry_Boom_Ivo1(); + } + shoot_bolt_Ivo1(); + wait 0.3; + shoot_bolt_Ivo1(); + wait 0.3; + shoot_bolt_Ivo1(); + wait 0.3; + shoot_bolt_Ivo1(); + wait 0.3; + playfxontag( level._effect["tesla_elec_kill"], elec_aura, "tag_origin" ); + wait 1; + playfxontag( level._effect["tesla_elec_kill"], elec_aura, "tag_origin" ); + playfxontag( level._effect["electric_cherry_explode"], elec_aura, "tag_origin" ); + level.boss playsound("zmb_cherry_explode"); + foreach(player in level.players) + { + player thread Cherry_Boom_Ivo1(); + } + shoot_bolt_Ivo1(); + wait 0.3; + shoot_bolt_Ivo1(); + wait 0.3; + shoot_bolt_Ivo1(); + wait 0.3; + shoot_bolt_Ivo1(); + wait 0.3; + playfxontag( level._effect["tesla_elec_kill"], elec_aura, "tag_origin" ); + wait 1.5; + elec_aura delete(); +} + +Cherry_Boom_Ivo1() +{ + if (distance(level.boss.origin, self.origin) < 330) //if close to boss + { + self dodamage_wrapper(1000); // deal damage to self (you gotta run away !) //DamFunc + wait 0.05; + self shellshock( "lava_small", 0.1 );//stun + } +} + +shoot_bolt_Ivo1() +{ + r = randomint(level.players.size); + if (!level.players[r] maps\mp\zombies\_zm_laststand::player_is_in_laststand() && level.players[r].sessionstate == "playing") + { + target = level.players[r]; + //target add_to_player_score(100); + } + + else //if (level.players[r] maps\mp\zombies\_zm_laststand::player_is_in_laststand()) + { + return shoot_bolt_Ivo1(); + } + + + source_pos = level.boss gettagorigin( "J_Helmet" ); + target_pos = target geteye(); + + bolt = spawn( "script_model", source_pos ); + bolt setmodel( "tag_origin" ); + wait 0.1; //DamFunc + + fx = playfxontag( level._effect["qd_revive"], bolt, "tag_origin" ); + bolt moveto( target_pos, 0.2 ); + bolt waittill( "movedone" ); + bolt.owner = self; + bolt check_bolt_impact( target ); + bolt delete();//wpn_revivestaff_revive_plr +} + +check_bolt_impact( target ) +{ + if ( is_player_valid( target )) + { + target_eye_pos = target geteye(); + dist_sq = distancesquared( self.origin, target_eye_pos ); + + if ( dist_sq < 4096 ) + { + passed = bullettracepassed( self.origin, target_eye_pos, 0, undefined ); + + if ( passed ) + { + target dodamage_wrapper(500); //DamFunc + vsmgr_activate( "overlay", "zm_transit_burn", target, 1, 1 ); + wait 0.05; + target shellshock( "lava_small", 0.1 );//stun + target playsoundtoplayer( "wpn_revivestaff_proj_impact", target ); + + } + } + } +} + + +AirStrike_Easy_Ivo1() +{ + self endon("death"); + LaunchPlace = spawn( "script_model", level.boss.origin ); + LaunchPlace linkto( level.boss, "tag_origin", (0, 0, 0), (-90, -90, -90)); + LaunchPlace setmodel( "tag_origin" ); + + self playsound( "zmb_homingbeacon_missiile_alarm" ); + wait 0.05; + + foreach(player in level.players) + { + player thread BombStun_Ivo1(); + } + + playfxontag( level._effect["beacon_launch_fx"], LaunchPlace, ( "tag_origin" ) );//ROCKET LAUNCH fx, need to aim at at up + self playsound( "zmb_homingbeacon_missile_fire" ); + + wait 0.7; + + foreach(player in level.players) + { + player thread BombStun_Ivo1(); + } + + playfxontag( level._effect["beacon_launch_fx"], LaunchPlace, ( "tag_origin" ) );//ROCKET LAUNCH + self playsound( "zmb_homingbeacon_missile_fire" ); + + wait 0.7; + + foreach(player in level.players) + { + player thread BombStun_Ivo1(); + } + + playfxontag( level._effect["beacon_launch_fx"], LaunchPlace, ( "tag_origin" ) );//ROCKET LAUNCH + self playsound( "zmb_homingbeacon_missile_fire" ); + + wait 0.7; + + foreach(player in level.players) + { + player thread BombStun_Ivo1(); + } + + playfxontag( level._effect["beacon_launch_fx"], LaunchPlace, ( "tag_origin" ) );//ROCKET LAUNCH + self playsound( "zmb_homingbeacon_missile_fire" ); + + + waitrandom = randomFloatRange( 2.3 , 5.1 ); + //iPrintLn(waitrandom); + wait waitrandom; + + foreach (player in level.players) + { + player thread BombBoom_Ivo1(); + } + +} + +BombStun_Ivo1() +{ + self shellshock( "lava_small", 0.8 );//stun for each rocket launch +} + +BombBoom_Ivo1() +{ + if (!self maps\mp\zombies\_zm_laststand::player_is_in_laststand() && self.sessionstate == "playing") + { + self playsound( "zmb_homingbeacon_missile_incoming" );// small window to activate Tank effect + wait 1; + self dodamage_wrapper(1800); // Rocket Damage //DamFunc + playfxontag( level._effect["beacon_shell_explosion"], self, "tag_origin" );//ROCKET BOOM + self playsound( "zmb_homingbeacon_missile_impact" ); + wait 0.05; + self shellshock( "frag_grenade_mp", 2 );//stun + } +} + + +Wipe_Easy_Ivo1() +{ + self endon("death"); + + //teleport boss to center and give immunity + level.boss setanimstatefromasd("zm_idle"); + level.boss forceteleport(level.boss.origin + (0, 0, -500)); + wait 0.05; + level.boss forceteleport(level.center_spawn_origin + (0, 0, -500)); + wait 0.05; + level.boss forceteleport(level.center_spawn_origin); + + beam = spawn( "script_model", level.boss.origin ); + beam linkto( level.boss, "tag_origin" ); + beam setmodel( "tag_origin" ); + wait 0.05; + playfxontag( level._effect["ee_beam"], beam, "tag_origin" ); + + vortex = spawn( "script_model", level.boss.origin ); + vortex linkto( level.boss, "tag_origin", ( 0, 0, 225) ); + vortex setmodel( "tag_origin" ); + + level.boss setanimstatefromasd("zm_idle");//so boss stay in center + level.boss set_zombie_run_cycle("super_sprint");//so boss stay in center + wait 0.05; + level.boss setanimstatefromasd("zm_idle"); + playFXOnTag( level._effect["ee_vortex"], vortex, "tag_origin"); + level.boss setcandamage( 0 );//prevent boss taking damage + level.boss.candamage = 0; + level.boss setanimstatefromasd("zm_idle"); + wait 0.5; + level.boss setanimstatefromasd("zm_idle"); + setdvar( "g_ai", "0" ); + level.boss thread Floating_Ivo1(); + + foreach( player in level.players) + { + player playlocalsound( level.zmb_laugh_alias );//so they know the attack started + player allowcrouch( 1 );//crouch and prone disabled for the entire boss fight, + player allowprone( 1 );//only enabled during the attack. + player thread Safe_Zone_Ivo1(); + } + + wait 7;//DamFunc + foreach (player in level.players)//wipe or stay alive + { + player Dead_or_Alive_Ivo1(); + if (level.dead != 0) + { + foreach (player in level.players) + { + player thread Dead_Ivo1(); + } + } + } + // if (level.dead != 0) + // wait 3; + + level.dead = 0; + + level.boss forceteleport(level.center_spawn_origin); + setdvar( "g_ai", "1" ); + level.boss setcandamage( 1 ); + level.boss.candamage = 1; + level.boss set_zombie_run_cycle("super_sprint"); + wait 0.05; + + vortex delete(); + beam delete(); + + foreach( player in level.players) + { + player allowcrouch( 0 );//no crouch or prone allowed in my boss fight + player allowprone( 0 );//they only get crouch and prone during wipe attack + //vsmgr_deactivate( "overlay", "zm_powerup_zombie_blood_overlay", player); + } +} + +Safe_Zone_Ivo1() +{ + for (i = 0; i <= 140; i++)// Visual zombie blood effect to know you are in position //DamFunc + { + if ((distance(level.ice, self.origin) < 25) || (distance(level.fire, self.origin) < 25) || (distance(level.wind, self.origin) < 25) || (distance(level.lightning, self.origin) < 25)) + vsmgr_activate( "overlay", "zm_powerup_zombie_blood_overlay", self); + else + vsmgr_deactivate( "overlay", "zm_powerup_zombie_blood_overlay", self); + wait 0.05; + } + vsmgr_deactivate( "overlay", "zm_powerup_zombie_blood_overlay", self); +} + +Dead_or_Alive_Ivo1() +{ + //stance = self getstance(); + //if (stance == "prone") + if (((distance(level.ice, self.origin) < 25) || (distance(level.fire, self.origin) < 25) || (distance(level.wind, self.origin) < 25) || (distance(level.lightning, self.origin) < 25))) + { + + //iPrintLn("Alive!"); + //continue; + } + else if (self.sessionstate != "spectator" && !(self maps\mp\zombies\_zm_laststand::player_is_in_laststand())) + { + //iPrintLn("Dead..."); + level.dead++; + //return dead; + } +} + +Dead_Ivo1() +{ + iPrintLnBold("^1Death Awaits..."); + playfxontag( level._effect["ee_beam"], self, "tag_origin" ); + wait 0.05; + + playFXOnTag( level._effect["ee_vortex"], self, "tag_origin"); + + + setdvar( "timescale", "0.6" ); + for (i = 0; i <= 2; i++) + { + self playlocalsound( level.zmb_laugh_alias ); + wait 0.7; + self doDamage_wrapper(self.health + 10000); + setdvar( "timescale", "1" ); + } +} + +Floating_Ivo1() +{ + for(i=0;i<120;i++) + { + level.boss.origin = level.boss.origin + ( 0, 0, 1 ); + wait 0.05; + } + +} + +//Phases +Phase_Starter_Ivo1() +{ + if (level.phase == 1) + { + level.boss thread IvoPhase1_H1_Ivo1(); + wait 0.05; + level.boss setcandamage( 0 ); + level.boss.candamage = 0; + level.phase++; + for (;;) + { + if (isdefined(level.boss.should_return) && level.boss.should_return == 1) + break; + wait 0.5; + } + wait 3; + } +} + +IvoPhase1_H1_Ivo1()//60 +{ + level.boss ForceTeleport(( 2754.93, 5402.57, -358.25 )); + + wait 1; + + level.zombie_total += 4; + + for(;;) + { + if (isdefined(level.inferno1) && isdefined(level.inferno2) && isdefined(level.electric1) && isdefined(level.electric2)) + break; + zombies = GetAIArray(level.zombie_team); + foreach(zombie in zombies) + { + if (isdefined(zombie.boss)) + continue; + if (zombie && zombie.completed_emerging_into_playable_area == 1 && !isdefined(zombie.miniboss)) + { + zombie.miniboss = 1; + if (!isdefined(level.inferno1)) + { + level.inferno1 = zombie; + level.inferno1 thread Infernos1_Ivo1(); + } + else if (!isdefined(level.inferno2)) + { + level.inferno2 = zombie; + level.inferno2 thread Infernos2_Ivo1(); + } + else if (!isdefined(level.electric1)) + { + level.electric1 = zombie; + level.electric1 thread Electrics1_Ivo1(); + } + else if (!isdefined(level.electric2)) + { + level.electric2 = zombie; + level.electric2 thread Electrics2_Ivo1(); + } + } + } + wait 1; + } + + wait 20; + iPrintLn("^3[ ^1" + level.boss_name + " ^7] : ^3Helmets ON lads");// Botb Boss Reference + wait 2; + level thread spawn_panzer(); + level thread spawn_panzer(); + + for(;;)//change added the panzer aura function + { + if (isdefined(level.Mechz_inferno1) && isdefined(level.Mechz_inferno2)) + break; + zombies = GetAIArray(level.zombie_team); + foreach(zombie in zombies) + { + if (isdefined(zombie.boss)) + continue; + if (zombie && zombie.completed_emerging_into_playable_area == 1 && !isdefined(zombie.miniboss) && isDefined(zombie.is_mechz) && zombie.is_mechz) + { + zombie.miniboss = 1; + if (!isdefined(level.Mechz_inferno1)) + { + level.Mechz_inferno1 = zombie; + level.Mechz_inferno1 thread Mechz_infernos1(); + } + else if (!isdefined(level.Mechz_inferno2)) + { + level.Mechz_inferno2 = zombie; + level.Mechz_inferno2 thread Mechz_infernos2(); + } + } + } + wait 1; + } + + for(;;) + { + zombies = getaiarray(level.zombie_team); + if (zombies.size == 1) + break; + wait 0.5; + } + level.boss.should_return = 1; + random = level.places[randomint(level.places.size)]; + level.boss ForceTeleport(random); + level.boss setcandamage( 1 ); + level.boss.candamage = 1; + //iPrintLn("end phase 1"); +} + +Infernos1_Ivo1() +{ + self endon("death"); + iPrintLn("^3[ ^1" + level.boss_name + " ^7] : ^3INFERNOS COME FOURTH!"); + //self ForceTeleport(level.Ice); + self set_zombie_run_cycle("super_sprint"); + //skin + self setmodel( "c_zom_tomb_german_body_1a" ); + self.headmodel = codescripts\character::randomelement( xmodelalias\c_zom_tomb_german_head_als::main() ); + self attach( self.headmodel, "", 1 ); + self.hatmodel = "c_zom_tomb_german_hat_1"; + self attach( self.hatmodel ); + self.voice = "american"; + self.skeleton = "base"; + self.torsodmg1 = "c_zom_tomb_german_body_g_upclean_1a"; + self.torsodmg2 = "c_zom_tomb_german_body_g_rarm_1a"; + self.torsodmg3 = "c_zom_tomb_german_body_g_larm_1a"; + self.torsodmg5 = "c_zom_tomb_german_body_g_behead"; + self.legdmg1 = "c_zom_tomb_german_body_g_lowclean_1a"; + self.legdmg2 = "c_zom_tomb_german_body_g_rleg_1a"; + self.legdmg3 = "c_zom_tomb_german_body_g_lleg_1a"; + self.legdmg4 = "c_zom_tomb_german_body_g_legsoff_1a"; + self.gibspawn1 = "c_zom_buried_g_rarmspawn"; + self.gibspawntag1 = "J_Elbow_RI"; + self.gibspawn2 = "c_zom_buried_g_larmspawn"; + self.gibspawntag2 = "J_Elbow_LE"; + self.gibspawn3 = "c_zom_buried_g_rlegspawn"; + self.gibspawntag3 = "J_Knee_RI"; + self.gibspawn4 = "c_zom_buried_g_llegspawn"; + self.gibspawntag4 = "J_Knee_LE"; + self.gibspawn5 = "c_zom_tomb_german_hat_1"; + self.gibspawntag5 = "J_Head"; + self.custom_item_dmg = 100000; + wait 3; + for (;;) + { + self setclientfield( "fire_char_fx", 1 ); + playfxontag( level._effect["wagon_fire"], level.inferno1, "tag_origin" ); + + // playfxontag( level._effect["fire_sacrifice_flame"], level.inferno1, "J_Wrist_LE" ); + + playfxontag( level._effect["wagon_fire"], level.inferno1, "J_Wrist_RI" ); + + // playfxontag( level._effect["fire_sacrifice_flame"], level.inferno1, "J_spinelower" ); + + foreach(player in level.players) + { + player thread Inferno_BURN1_Ivo1(); + } + wait 1; + self setclientfield( "fire_char_fx", 0 ); + wait 0.05; + } +} + +Inferno_BURN1_Ivo1() +{ + if (distance(level.inferno1.origin, self.origin) <= 210) //if close to boss //DamFunc + { + self dodamage_wrapper(600); // deal damage to self (you gotta run away !) //DamFunc + vsmgr_activate( "overlay", "zm_transit_burn", self, 1, 1 );//visual burn effect + wait 0.05; + self shellshock( "lava_small", 0.1 );//stun //DamFunc + } +} + +Infernos2_Ivo1() +{ + self endon("death"); + //self ForceTeleport(level.Fire); + self set_zombie_run_cycle("super_sprint"); + //skin + self setmodel( "c_zom_tomb_german_body_1b" ); + self.headmodel = codescripts\character::randomelement( xmodelalias\c_zom_tomb_german_head_als::main() ); + self attach( self.headmodel, "", 1 ); + self.hatmodel = "c_zom_tomb_german_hat_2"; + self attach( self.hatmodel ); + self.voice = "american"; + self.skeleton = "base"; + self.torsodmg1 = "c_zom_tomb_german_body_g_upclean_1b"; + self.torsodmg2 = "c_zom_tomb_german_body_g_rarm_1b"; + self.torsodmg3 = "c_zom_tomb_german_body_g_larm_1b"; + self.torsodmg5 = "c_zom_tomb_german_body_g_behead"; + self.legdmg1 = "c_zom_tomb_german_body_g_lowclean_1b"; + self.legdmg2 = "c_zom_tomb_german_body_g_rleg_1b"; + self.legdmg3 = "c_zom_tomb_german_body_g_lleg_1b"; + self.legdmg4 = "c_zom_tomb_german_body_g_legsoff_1b"; + self.gibspawn1 = "c_zom_buried_g_rarmspawn"; + self.gibspawntag1 = "J_Elbow_RI"; + self.gibspawn2 = "c_zom_buried_g_larmspawn"; + self.gibspawntag2 = "J_Elbow_LE"; + self.gibspawn3 = "c_zom_buried_g_rlegspawn"; + self.gibspawntag3 = "J_Knee_RI"; + self.gibspawn4 = "c_zom_buried_g_llegspawn"; + self.gibspawntag4 = "J_Knee_LE"; + self.gibspawn5 = "c_zom_tomb_german_hat_2"; + self.gibspawntag5 = "J_Head"; + self.custom_item_dmg = 100000; + wait 3; + for (;;) + { + self setclientfield( "fire_char_fx", 1 ); + playfxontag( level._effect["wagon_fire"], level.inferno2, "tag_origin" ); + + // playfxontag( level._effect["fire_sacrifice_flame"], level.inferno2, "J_Wrist_LE" ); + + playfxontag( level._effect["wagon_fire"], level.inferno2, "J_Wrist_RI" ); + + // playfxontag( level._effect["fire_sacrifice_flame"], level.inferno2, "J_spinelower" ); + + foreach(player in level.players) + { + player thread Inferno_BURN2_Ivo1(); + } + wait 1; + self setclientfield( "fire_char_fx", 0 ); + wait 0.05; + } +} + +Inferno_BURN2_Ivo1() +{ + if (distance(level.inferno2.origin, self.origin) <= 210) //if close to boss //DamFunc + { + self dodamage_wrapper(600); // deal damage to self (you gotta run away !) //DamFunc + vsmgr_activate( "overlay", "zm_transit_burn", self, 1, 1 );//visual burn effect + wait 0.05; + self shellshock( "lava_small", 0.1 );//stun //DamFunc + } +} + + +Electrics1_Ivo1() +{ + self endon("death"); + //self ForceTeleport(level.Ice); + self set_zombie_run_cycle("super_sprint"); + //skin + self setmodel( "c_zom_tomb_german_body_1a" ); + self.headmodel = codescripts\character::randomelement( xmodelalias\c_zom_tomb_german_head_als::main() ); + self attach( self.headmodel, "", 1 ); + self.hatmodel = "c_zom_tomb_german_hat_1"; + self attach( self.hatmodel ); + self.voice = "american"; + self.skeleton = "base"; + self.torsodmg1 = "c_zom_tomb_german_body_g_upclean_1a"; + self.torsodmg2 = "c_zom_tomb_german_body_g_rarm_1a"; + self.torsodmg3 = "c_zom_tomb_german_body_g_larm_1a"; + self.torsodmg5 = "c_zom_tomb_german_body_g_behead"; + self.legdmg1 = "c_zom_tomb_german_body_g_lowclean_1a"; + self.legdmg2 = "c_zom_tomb_german_body_g_rleg_1a"; + self.legdmg3 = "c_zom_tomb_german_body_g_lleg_1a"; + self.legdmg4 = "c_zom_tomb_german_body_g_legsoff_1a"; + self.gibspawn1 = "c_zom_buried_g_rarmspawn"; + self.gibspawntag1 = "J_Elbow_RI"; + self.gibspawn2 = "c_zom_buried_g_larmspawn"; + self.gibspawntag2 = "J_Elbow_LE"; + self.gibspawn3 = "c_zom_buried_g_rlegspawn"; + self.gibspawntag3 = "J_Knee_RI"; + self.gibspawn4 = "c_zom_buried_g_llegspawn"; + self.gibspawntag4 = "J_Knee_LE"; + self.gibspawn5 = "c_zom_tomb_german_hat_1"; + self.gibspawntag5 = "J_Head"; + self.custom_item_dmg = 100000; + wait 3; + for (;;) + { + self setclientfield( "lightning_arc_fx", 1 ); + playfxontag( level._effect["tesla_elec_kill"], level.electric1, "tag_origin" ); + + // playfxontag( level._effect["fire_sacrifice_flame"], level.electric1, "J_Wrist_LE" ); + + playfxontag( level._effect["electric_cherry_explode"], level.electric1, "tag_origin" ); + + // playfxontag( level._effect["fire_sacrifice_flame"], level.electric1, "J_spinelower" ); + level.electric1 playsound("zmb_cherry_explode"); + foreach(player in level.players) + { + player thread Electric_Shot1_Ivo1(); + player thread Phase_Cherry1_Ivo1(); + } + wait 4; + self setclientfield( "lightning_arc_fx", 0 ); + wait 0.05; + } +} + +Electric_Shot1_Ivo1() +{ + r = randomint(level.players.size); + if (!level.players[r] maps\mp\zombies\_zm_laststand::player_is_in_laststand() && level.players[r].sessionstate == "playing") + { + target = level.players[r]; + //target add_to_player_score(100); + } + + else //if (level.players[r] maps\mp\zombies\_zm_laststand::player_is_in_laststand()) + { + return Electric_Shot1_Ivo1(); + } + + + source_pos = level.electric1 gettagorigin( "J_Helmet" ); + target_pos = target geteye(); + + bolt = spawn( "script_model", source_pos ); + bolt setmodel( "tag_origin" ); + wait 0.1; //DamFunc + + fx = playfxontag( level._effect["qd_revive"], bolt, "tag_origin" ); + bolt moveto( target_pos, 0.3 ); + bolt waittill( "movedone" ); + bolt.owner = self; + bolt check_bolt_impactPhase_Ivo1( target ); + bolt delete();//wpn_revivestaff_revive_plr +} + +Phase_Cherry1_Ivo1() +{ + if (distance(level.electric1.origin, self.origin) < 200) //if close to boss + { + self dodamage_wrapper(300); // deal damage to self (you gotta run away !) + wait 0.05; + self shellshock( "lava_small", 0.1 );//stun //DamFunc + } +} + +Electrics2_Ivo1() +{ + self endon("death"); + iPrintLn("^3[ ^1" + level.boss_name + " ^7] : ^3Let's up the voltage ^1:)");// Titb Boss reference + //self ForceTeleport(level.Fire); + self set_zombie_run_cycle("super_sprint"); + //skin + self setmodel( "c_zom_tomb_german_body_1b" ); + self.headmodel = codescripts\character::randomelement( xmodelalias\c_zom_tomb_german_head_als::main() ); + self attach( self.headmodel, "", 1 ); + self.hatmodel = "c_zom_tomb_german_hat_2"; + self attach( self.hatmodel ); + self.voice = "american"; + self.skeleton = "base"; + self.torsodmg1 = "c_zom_tomb_german_body_g_upclean_1b"; + self.torsodmg2 = "c_zom_tomb_german_body_g_rarm_1b"; + self.torsodmg3 = "c_zom_tomb_german_body_g_larm_1b"; + self.torsodmg5 = "c_zom_tomb_german_body_g_behead"; + self.legdmg1 = "c_zom_tomb_german_body_g_lowclean_1b"; + self.legdmg2 = "c_zom_tomb_german_body_g_rleg_1b"; + self.legdmg3 = "c_zom_tomb_german_body_g_lleg_1b"; + self.legdmg4 = "c_zom_tomb_german_body_g_legsoff_1b"; + self.gibspawn1 = "c_zom_buried_g_rarmspawn"; + self.gibspawntag1 = "J_Elbow_RI"; + self.gibspawn2 = "c_zom_buried_g_larmspawn"; + self.gibspawntag2 = "J_Elbow_LE"; + self.gibspawn3 = "c_zom_buried_g_rlegspawn"; + self.gibspawntag3 = "J_Knee_RI"; + self.gibspawn4 = "c_zom_buried_g_llegspawn"; + self.gibspawntag4 = "J_Knee_LE"; + self.gibspawn5 = "c_zom_tomb_german_hat_2"; + self.gibspawntag5 = "J_Head"; + self.custom_item_dmg = 100000; + wait 3; + for (;;) + { + self setclientfield( "lightning_arc_fx", 1 ); + playfxontag( level._effect["tesla_elec_kill"], level.electric2, "tag_origin" ); + + // playfxontag( level._effect["fire_sacrifice_flame"], level.electric2, "J_Wrist_LE" ); + + playfxontag( level._effect["electric_cherry_explode"], level.electric2, "tag_origin" ); + + // playfxontag( level._effect["fire_sacrifice_flame"], level.electric2, "J_spinelower" ); + level.electric2 playsound("zmb_cherry_explode"); + foreach(player in level.players) + { + player thread Electric_Shot2_Ivo1(); + player thread Phase_Cherry2_Ivo1(); + } + wait 4; + self setclientfield( "lightning_arc_fx", 0 ); + wait 0.05; + } +} + +Electric_Shot2_Ivo1() +{ + r = randomint(level.players.size); + if (!level.players[r] maps\mp\zombies\_zm_laststand::player_is_in_laststand() && level.players[r].sessionstate == "playing") + { + target = level.players[r]; + //target add_to_player_score(100); + } + + else //if (level.players[r] maps\mp\zombies\_zm_laststand::player_is_in_laststand()) + { + return Electric_Shot2_Ivo1(); + } + + + source_pos = level.electric2 gettagorigin( "J_Helmet" ); + target_pos = target geteye(); + + bolt = spawn( "script_model", source_pos ); + bolt setmodel( "tag_origin" ); + wait 0.1; //DamFunc + + fx = playfxontag( level._effect["qd_revive"], bolt, "tag_origin" ); + bolt moveto( target_pos, 0.3 ); + bolt waittill( "movedone" ); + bolt.owner = self; + bolt check_bolt_impactPhase_Ivo1( target ); + bolt delete();//wpn_revivestaff_revive_plr +} + +Phase_Cherry2_Ivo1() +{ + if (distance(level.electric2.origin, self.origin) < 200) //if close to boss + { + self dodamage_wrapper(300); // deal damage to self (you gotta run away !) + wait 0.05; + self shellshock( "lava_small", 0.1 );//stun //DamFunc + } +} + +check_bolt_impactPhase_Ivo1( target ) +{ + if ( is_player_valid( target )) + { + target_eye_pos = target geteye(); + dist_sq = distancesquared( self.origin, target_eye_pos ); + + if ( dist_sq < 4096 ) + { + passed = bullettracepassed( self.origin, target_eye_pos, 0, undefined ); + + if ( passed ) + { + target dodamage_wrapper(400); //DamFunc + vsmgr_activate( "overlay", "zm_transit_burn", target, 2, 2 ); + wait 0.05; + target shellshock( "lava_small", 0.1 );//DamFunc + target playsoundtoplayer( "wpn_revivestaff_proj_impact", target ); + + } + } + } +} + +Mechz_infernos1()//change add +{ + self endon("death"); + + for(;;) + { + foreach(player in level.players) + { + player thread Mechz_BURN1_Ivo1(); + } + wait 0.1; + } +} + + +Mechz_BURN1_Ivo1()//change add +{ + if (distance(level.Mechz_inferno1.origin, self.origin) <= 40) //if close to //DamFunc + { + self dodamage_wrapper(600); // deal damage to self (you gotta run away !) //DamFunc + vsmgr_activate( "overlay", "zm_transit_burn", self, 1, 1 );//visual burn effect + wait 0.05; + self shellshock( "lava_small", 0.1 );//stun //DamFunc + } +} + +Mechz_infernos2()//change add +{ + self endon("death"); + + for(;;) + { + foreach(player in level.players) + { + player thread Mechz_BURN2_Ivo1(); + } + wait 0.1; + } +} + + +Mechz_BURN2_Ivo1()//change add +{ + if (distance(level.Mechz_inferno2.origin, self.origin) <= 40) //if close to //DamFunc + { + self dodamage_wrapper(600); // deal damage to self (you gotta run away !) //DamFunc + vsmgr_activate( "overlay", "zm_transit_burn", self, 1, 1 );//visual burn effect + wait 0.05; + self shellshock( "lava_small", 0.1 );//stun //DamFunc + } +} + +Phase_check1_Ivo1() +{ + for (;;) + { + if (level.boss.health <= level.boss.maxhealth * 0.33)//33% HP + { + level.boss setcandamage( 0 ); + level.boss.candamage = 0; + level.phase = 1; + iPrintLn("^3[ ^1" + level.boss_name + " ^7] : ^3Let's see how you handle this !");// Botb Boss Reference + break; + } + wait 0.05; + } +} diff --git a/t6/scripts/zm/zm_tomb/boss_kiels1.gsc b/t6/scripts/zm/zm_tomb/boss_kiels1.gsc new file mode 100644 index 0000000..f8faa32 --- /dev/null +++ b/t6/scripts/zm/zm_tomb/boss_kiels1.gsc @@ -0,0 +1,326 @@ +#include maps\mp\zombies\_zm_utility; +#include maps\mp\_utility; +#include scripts\zm\zm_tomb\raid_boss; + +setup_boss_kiels1() +{ + zombies = getaiarray(level.zombie_team); + zombies[0].maxhealth = level.boss_hp; + zombies[0].health = level.boss_hp; + zombies[0].meleedamage = 1900; + zombies[0].custom_item_dmg = 600000000; + wait 1; + zombies = getaiarray(level.zombie_team); + zombies[0] add_skin_kiels1(); + zombies[0].maxhealth = level.boss_hp; + zombies[0].health = level.boss_hp; + zombies[0].meleedamage = 1900; + zombies[0] set_zombie_run_cycle("super_sprint"); + level.boss = zombies[0]; + level.boss.name = "Templar"; + level.is_boss_spawned = 1; + level thread boss_think_kiels1(); +} + +add_skin_kiels1() +{ + model_u = "t6_wpn_zmb_staff_tip_lightning_world"; + model_fx = level._effect["elec_glow"]; + model_u = "t6_wpn_zmb_staff_tip_air_world"; + model_fx = level._effect["air_glow"]; + model_u = "t6_wpn_zmb_staff_tip_water_world"; + model_fx = level._effect["ice_glow"]; + model_u = "t6_wpn_zmb_staff_tip_fire_world"; + model_fx = level._effect["fire_glow"]; + + + model_u2 = "t6_wpn_zmb_staff_tip_lightning_world"; + model_fx2 = level._effect["elec_glow"]; + model_u2 = "t6_wpn_zmb_staff_tip_air_world"; + model_fx2 = level._effect["air_glow"]; + model_u2 = "t6_wpn_zmb_staff_tip_water_world"; + model_fx2 = level._effect["ice_glow"]; + /* model_u2 = "t6_wpn_zmb_staff_tip_fire_world"; + model_fx2 = level._effect["fire_glow"];*/ + + self.staff_u = spawn( "script_model", self.origin ); + self.staff_u linkto( self, "J_SpineLower", (0, -10, 15), (180, 90, 70)); + wait 0.1; + self.staff_u setmodel( model_u ); + + self.fx = spawn( "script_model", self.staff_u.origin ); + wait 0.1; + self.fx setmodel( "tag_origin" ); + playfxontag( model_fx, self.staff_u, "tag_origin" ); + self.fx linkto( self, "J_SpineLower", self.staff_u.origin, (0, 0, 0)); + + self.staff_u2 = spawn( "script_model", self.origin ); + self.staff_u2 linkto( self, "J_SpineLower", (0, -10, -15), (180, 90, 110)); + wait 0.1; + self.staff_u2 setmodel( model_u2 ); + + self.fx2 = spawn( "script_model", self.staff_u2.origin ); + wait 0.1; + self.fx2 setmodel( "tag_origin" ); + playfxontag( model_fx2, self.staff_u2, "tag_origin" ); + self.fx2 linkto( self, "J_SpineLower", self.staff_u2.origin, (0, 0, 0)); + +} + +boss_think_kiels1() +{ + level endon("game_ended"); + + wait 3; + level.boss_attacks_cooldown = 15; + for (;;) + { + if (level.boss.health && level.boss.health < level.boss.health * 0.4) + level.boss_attacks_cooldown = 12; + if (level.boss.health && level.boss.health < level.boss.health * 0.2) + level.boss_attacks_cooldown = 9; + if (!isdefined(level.boss) || !isdefined(!level.boss.health) || level.boss.health < 1) + return; + level.boss.elem_fx setclientfield( "element_glow_fx", 3 ); + wait 3; + level thread do_lightning_attack_kiels1(); + level.boss.elem_fx setclientfield( "element_glow_fx", 0 ); + wait level.boss_attacks_cooldown; + level.boss.elem_fx setclientfield( "element_glow_fx", 1 ); + wait 3; + level thread do_fire_attack_kiels1(); + level.boss.elem_fx setclientfield( "element_glow_fx", 0 ); + wait level.boss_attacks_cooldown; + level.boss.elem_fx setclientfield( "element_glow_fx", 2 ); + wait 3; + level thread do_wind_attack_kiels1(); + level.boss.elem_fx setclientfield( "element_glow_fx", 0 ); + + /* if (level.boss.health < level.boss.maxhealth * 0.33) + { + r = RandomInt(3); + if (r == 0) + { + level.boss thread miniboss_lightning_think(0); + } + else if (r == 1) + { + level.boss thread miniboss_wind_think(0); + } + else if (r == 2) + { + level.boss thread miniboss_ice_think(0); + } + else if (r == 3) + { + level.boss thread miniboss_fire_think(0); + } + + }*/ + wait level.boss_attacks_cooldown; + } +} + +do_fire_attack_kiels1() +{ + level endon("game_ended"); + + lock = 0; + for (h = 0; h < 2; h++) + { + x = randomintrange(0, 2); + if (x == 0) + { + iprintln("^1HIGH Firewall^7"); + z = -20; + iteration = 3; + } + else + { + iprintln("^1LOW Firewall^7"); + z = -70; + iteration = 2; + } + for (j = 0; j < iteration; j++) + { + x = 75; + z += 50; + for (i = 0; i < 35; i++) + { + level thread spawn_firewall_kiels1(x, z); + x += 75; + } + wait 0.1; + } + wait 1; + level notify("firewall_setup"); + wait 5; + } +} + +spawn_firewall_kiels1(x_offset, z_offset) +{ + level endon("game_ended"); + + fx_origin = ((8895 + x_offset), -9270, (-450 + z_offset)); + fx_destination_origin = ((8895 + x_offset), -6800, (-450 + z_offset)); + fx = spawn( "script_model", fx_origin); + fx setmodel( "tag_origin" ); + wait 1; + playfxontag( level._effect["fx_tomb_fire_lg"], fx, "tag_origin" ); + level waittill("firewall_setup"); + fx moveto( fx_destination_origin, level.firewall_duration ); + for (i = 0; i < (level.firewall_duration * 10); i++) + { + foreach(player in level.players) + { + stance = player GetStance(); + player_origin_offset = 0; + if (stance == "prone") + player_origin_offset = 30; + if (distancesquared((fx.origin), (player.origin - (0, 0, player_origin_offset))) < 1700 && player.ignoreme != true) + player thread dodamage_wrapper(1000); + } + wait 0.1; + } + fx delete(); + level notify("fire_attack_end"); +} + +do_lightning_attack_kiels1() +{ + level endon("game_ended"); + + a_aoe = []; + c = 0; + delay = 1; + for (j = 0; j < 4; j++) + { + offset = 100; + for(i = 0; i < 20; i++) + { + a_aoe[0] = (offset, 0, 0); + a_aoe[1] = (offset, offset, 0); + a_aoe[2] = (0, offset, 0); + a_aoe[3] = (offset, offset, 0); + a_aoe[4] = (0, -(offset), 0); + a_aoe[5] = (-(offset), -(offset), 0); + a_aoe[6] = (offset, -(offset), 0); + a_aoe[7] = (-(offset), 0, 0); + a_aoe[8] = (-(offset), offset, 0); + foreach(aoe in a_aoe) + { + level thread spawn_orb_kiels1(aoe, c); + c++; + } + offset += 100; + wait 0.1; + } + wait delay; + delay = delay / 2; + } +} + +spawn_orb_kiels1(target_origin, c) +{ + level endon("game_ended"); + + + + fx_origin = level.boss.origin + target_origin; + + fx = spawn( "script_model", (fx_origin[0], fx_origin[1], -390)); + fx setmodel( "tag_origin" ); + wait 0.1; + playfxontag( level._effect["elec_piano_glow"], fx, "tag_origin" ); + for (i = 0; i < 8; i++) + { + foreach(player in level.players) + { + if (distancesquared(fx_origin, player.origin) < 7000) + player shellshock( "explosion", 0.4 ); + } + wait 0.1; + } + fx delete(); + fx = spawn( "script_model", (fx_origin[0], fx_origin[1], -390)); + fx setmodel( "tag_origin" ); + wait 0.1; + playfxontag( level._effect["ice_explode"], fx, "tag_origin" ); + foreach(player in level.players) + { + if (distancesquared(fx_origin, player.origin) < 7000 && player.ignoreme != true) + player thread dodamage_wrapper(1000); + } + wait 0.5; + fx delete(); +} + +do_wind_attack_kiels1() +{ + level endon("game_ended"); + + level.is_boss_casting = 1; + a_aoe = []; + offset = 300; + for (i = 0; i < 8; i++) + { + a_aoe[0] = (offset, 0, 0); + a_aoe[1] = (0, offset, 0); + a_aoe[2] = (0, -(offset), 0); + a_aoe[3] = (-(offset), 0, 0); + foreach (aoe in a_aoe) + level thread spawn_tornado_kiels1(aoe); + offset += 300; + } + iprintln("^11"); + level thread rumble_players_kiels1(2, 1); + wait 1.1; + iprintln("^12"); + level thread rumble_players_kiels1(2, 1); + wait 1.1; + foreach(player in level.players) + { + player thread dodamage_wrapper(2000); + } + level thread rumble_players_kiels1(5, 2); + 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.3; + wait 0.5; + fadetowhite fadeovertime( 0.5 ); + fadetowhite.alpha = 0; + wait 1.1; + fadetowhite destroy(); + level.is_boss_casting = 0; +} + +spawn_tornado_kiels1(target_origin) +{ + level endon("game_ended"); + + fx_origin = level.boss.origin + target_origin; + fx = spawn( "script_model", (fx_origin[0], fx_origin[1], -390)); + fx setmodel( "tag_origin" ); + wait 0.1; + playfxontag( level._effect["whirlwind"], fx, "tag_origin" ); + wait 4.6; + fx delete(); +} + +rumble_players_kiels1(strenght, time) +{ + strength = strength * 4; + foreach(player in level.players) + player setclientfieldtoplayer( "player_rumble_and_shake", strenght ); + wait(time); + foreach(player in level.players) + player setclientfieldtoplayer( "player_rumble_and_shake", 0 ); +} \ No newline at end of file diff --git a/t6/scripts/zm/zm_tomb/nomudslow.gsc b/t6/scripts/zm/zm_tomb/nomudslow.gsc new file mode 100644 index 0000000..3e18a0b --- /dev/null +++ b/t6/scripts/zm/zm_tomb/nomudslow.gsc @@ -0,0 +1,90 @@ +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_net; +#include maps\mp\zombies\_zm_spawner; +#include maps\mp\zombies\_zm_craftables; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zm_tomb_teleporter; +#include maps\mp\zm_tomb_vo; +#include maps\mp\zombies\_zm_ai_basic; +#include maps\mp\animscripts\zm_shared; +#include maps\mp\zombies\_zm_unitrigger; +#include maps\mp\zombies\_zm_zonemgr; +#include maps\mp\zm_tomb_chamber; +#include maps\mp\zombies\_zm_challenges; +#include maps\mp\zm_tomb_challenges; +#include maps\mp\zm_tomb_tank; +#include maps\mp\zm_tomb_craftables; + +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zm_tomb_utility; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\gametypes_zm\_globallogic_score; + + + +main() +{ + replaceFunc(maps\mp\zm_tomb_utility::player_slow_movement_speed_monitor, ::noMudSlow); +} + +noMudSlow() +{ + self endon( "disconnect" ); + n_movescale_delta_no_perk = 0.4 / 4.0; + n_movescale_delta_staminup = 0.3 / 6.0; + n_new_move_scale = 1.0; + n_move_scale_delta = 1.0; + self.n_move_scale = n_new_move_scale; + + while ( true ) + { + is_player_slowed = 0; + self.is_player_slowed = 0; + + foreach ( area in level.a_e_slow_areas ) + { + if ( self istouching( area ) ) + { + self setclientfieldtoplayer( "sndMudSlow", 1 ); + is_player_slowed = 1; + self.is_player_slowed = 1; + + if ( !( isdefined( self.played_mud_vo ) && self.played_mud_vo ) && !( isdefined( self.dontspeak ) && self.dontspeak ) ) + self thread maps\mp\zm_tomb_vo::struggle_mud_vo(); + + if ( self hasperk( "specialty_longersprint" ) ) + { + n_new_move_scale = 0.7; + n_move_scale_delta = n_movescale_delta_staminup; + } + else + { + n_new_move_scale = 0.6; + n_move_scale_delta = n_movescale_delta_no_perk; + } + + break; + } + } + + if ( !is_player_slowed ) + { + self setclientfieldtoplayer( "sndMudSlow", 0 ); + self notify( "mud_slowdown_cleared" ); + n_new_move_scale = 1.0; + } + + if ( self.n_move_scale != n_new_move_scale ) + { + if ( self.n_move_scale > n_new_move_scale + n_move_scale_delta ) + self.n_move_scale -= n_move_scale_delta; + else + self.n_move_scale = n_new_move_scale; + + // self setmovespeedscale( self.n_move_scale ); + } + wait 0.1; + } +} \ No newline at end of file diff --git a/t6/scripts/zm/zm_tomb/origin_ee.gsc b/t6/scripts/zm/zm_tomb/origin_ee.gsc new file mode 100644 index 0000000..bc3f2bc --- /dev/null +++ b/t6/scripts/zm/zm_tomb/origin_ee.gsc @@ -0,0 +1,129 @@ +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_sidequests; +#include maps\mp\zm_tomb_ee_main; +#include maps\mp\zm_tomb_utility; +#include maps\mp\zm_tomb_vo; +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\gametypes_zm\_hud; +#include maps\mp\zm_tomb_chamber; + +init() +{ + level.start_time = GetTime(); + setDvar("EE_Completion", "0"); + setdvar("stepCompleted", "0"); + level thread EEFix(); + level thread CheckEECompletion(); + level thread onPlayerConnect(); +} + + +onPlayerConnect() +{ + while( 1 ) + { + level waittill( "connected", player ); + player thread onPlayerSpawned(); + } +} + +onPlayerSpawned() +{ + self endon( "disconnect" ); + level endon( "game_ended" ); + self waittill( "spawned_player" ); + flag_wait("initial_blackscreen_passed"); + for (;;) + { + if (getDvar("stepCompleted") == "1") + { + for (i = 0; i < level.players.size; i++) + { + if (level.players[i].b_punch_upgraded != 1) + { + level.players[i].b_punch_upgraded = 1; + + if ( level.players[i] hasweapon( "staff_fire_upgraded_zm" ) ) + level.players[i].str_punch_element = "fire"; + else if ( level.players[i] hasweapon( "staff_air_upgraded_zm" ) ) + level.players[i].str_punch_element = "air"; + else if ( level.players[i] hasweapon( "staff_lightning_upgraded_zm" ) ) + level.players[i].str_punch_element = "lightning"; + else if ( level.players[i] hasweapon( "staff_water_upgraded_zm" ) ) + level.players[i].str_punch_element = "ice"; + else + level.players[i].str_punch_element = "upgraded"; + + level.players[i] thread maps\mp\zombies\_zm_weap_one_inch_punch::one_inch_punch_melee_attack(); + } + } + } + wait 3; + } +} + +EEFix() +{ + flag_wait("initial_blackscreen_passed"); + stepcompleted = 0; + for (;;) + { + if (level._cur_stage_name == "step_6") + { + for (i = 0; i < level.players.size; i++) + { + if (level.players[i].b_punch_upgraded == 1) + { + setDvar("stepCompleted", "1"); + } + } + if (getDvar("stepCompleted") == "1") + { + for (i = 0; i < level.players.size; i++) + { + level.players[i].b_punch_upgraded = 1; + + if ( level.players[i] hasweapon( "staff_fire_upgraded_zm" ) ) + level.players[i].str_punch_element = "fire"; + else if ( level.players[i] hasweapon( "staff_air_upgraded_zm" ) ) + level.players[i].str_punch_element = "air"; + else if ( level.players[i] hasweapon( "staff_lightning_upgraded_zm" ) ) + level.players[i].str_punch_element = "lightning"; + else if ( level.players[i] hasweapon( "staff_water_upgraded_zm" ) ) + level.players[i].str_punch_element = "ice"; + else + level.players[i].str_punch_element = "upgraded"; + + level.players[i] thread maps\mp\zombies\_zm_weap_one_inch_punch::one_inch_punch_melee_attack(); + } + flag_set( "ee_all_players_upgraded_punch" ); + } + + } + wait 5; + } +} + +CheckEECompletion() +{ + level endon( "game_ended" ); + flag_wait("initial_blackscreen_passed"); + level waittill("tomb_sidequest_complete"); + setDvar("EE_Completion", "1"); + max_time = (30 * 60 * 1000); + if (GetTime() - level.start_time < max_time) + { + str = ""; + foreach(index, player in level.players) + { + str += player getguid(); + if (index + 1 < level.players.size) + str += ";"; + } + setdvar("ee_speedrun", str); + } + iprintln("^3EE completed^7 in : ^2" + ((GetTime() - level.start_time) / 1000 / 60) + "^7 minutes !"); + return; +} \ No newline at end of file diff --git a/t6/scripts/zm/zm_tomb/panzerwave.gsc b/t6/scripts/zm/zm_tomb/panzerwave.gsc new file mode 100644 index 0000000..937bb3c --- /dev/null +++ b/t6/scripts/zm/zm_tomb/panzerwave.gsc @@ -0,0 +1,5814 @@ +#include maps\mp\zombies\_zm_magicbox; +#include maps\mp\zombies\_zm_zonemgr; +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\animscripts\zm_utility; +#include maps\mp\zombies\_zm_spawner; +#include maps\mp\animscripts\zm_shared; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zombies\_zm_ai_basic; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\animscripts\shared; +#include maps\mp\zombies\_zm_unitrigger; +#include maps\mp\zombies\_zm_weap_riostshield_prison; +#include maps\mp\animscripts\zm_death; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm_craftables; +#include maps\mp\gametypes_zm\_zm_gametype; + +#include maps\mp\_ambientpackage; +#include maps\mp\zombies\_zm_sidequests; + +#include maps\_utility; +#include maps\_vehicle; +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\gametypes_zm\_hud; + +#include maps\mp\zombies\_zm_pers_upgrades_system; +#include maps\mp\zombies\_zm_pers_upgrades; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include scripts\AATs_Perks; +#include maps\mp\_visionset_mgr; +#include character\c_zom_cellbreaker; + +#include maps\mp\zombies\_zm_net; +#include maps\mp\zm_tomb_tank; +#include maps\mp\zombies\_zm_ai_mechz_dev; +#include maps\mp\zombies\_zm_ai_mechz_claw; +#include maps\mp\zombies\_zm_ai_mechz_ft; +#include maps\mp\zombies\_zm_ai_mechz_booster; +#include maps\mp\zombies\_zm_ai_mechz_ffotd; +#include maps\mp\zombies\_zm_ai_mechz; +#include maps\mp\zm_tomb_chamber; +#include maps\mp\zm_tomb; +#include maps\mp\zm_tomb_capture_zones; + +#include maps\mp\zombies\_zm; +#include maps\mp\_demo; +#include maps\mp\zombies\_zm_power; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_weap_staff_lightning; +#include maps\mp\gametypes_zm\_hostmigration; +#include maps\mp\zm_tomb_distance_tracking; +#include maps\mp\zm_tomb_quest_air; +#include maps\mp\zm_tomb_quest_fire; +#include maps\mp\zm_tomb_quest_ice; +#include maps\mp\zm_tomb_quest_elec; + +#include maps\mp\zm_tomb_utility; +#include maps\mp\zm_tomb_teleporter; + +#include maps\mp\animscripts\traverse\shared; +#include maps\mp\animscripts\traverse\zm_shared; +#include maps\mp\zm_tomb_amb; +#include maps\mp\gametypes_zm\_globallogic_score; +// raycast for boss wipe aoe attack (zm_ai_mech_ft l464) +// b_cansee = bullettracepassed( self.origin + vectorscale( ( 0, 0, 1 ), 36.0 ), self.favoriteenemy.origin + vectorscale( ( 0, 0, 1 ), 36.0 ), 0, undefined ); + +main() +{ + replaceFunc(maps\mp\zm_tomb_capture_zones::pack_a_punch_init, ::pack_a_punch_init_custom); + replaceFunc(maps\mp\zombies\_zm_ffotd::main_start, ::modified_main_start); + replaceFunc(maps\mp\zombies\_zm_pers_upgrades::is_pers_system_active, ::always_pers_system_active); + replaceFunc(maps\mp\zombies\_zm_pers_upgrades::is_pers_system_disabled, ::never_pers_system_disabled); + replaceFunc(maps\mp\zombies\_zm_ai_mechz::mechz_spawn, ::mechz_spawn_custom); + + //Freeing vars + replaceFunc(maps\mp\zombies\_zm_stats::initializematchstats, ::initializematchstats_custom); + replaceFunc(maps\mp\gametypes_zm\_hostmigration::waitlongdurationwithhostmigrationpause, ::waitlongdurationwithhostmigrationpause_custom); + replaceFunc(maps\mp\zombies\_zm_ai_mechz::mechz_setup_armor_pieces, ::mechz_setup_armor_pieces_custom); + + //replaceFunc(maps\mp\zombies\_zm_ai_mechz::get_favorite_enemy, ::get_favorite_enemy_custom); + replaceFunc(maps\mp\zm_tomb_quest_ice::process_gem_shooting, ::process_gem_shooting_custom); + replaceFunc(maps\mp\zm_tomb_quest_ice::ceiling_tile_process_damage, ::ceiling_tile_process_damage_custom); + replaceFunc(maps\mp\zm_tomb_quest_ice::change_ice_gem_value, ::change_ice_gem_value_custom); + replaceFunc(maps\mp\zm_tomb_quest_elec::piano_keys_stop, ::piano_keys_stop_custom); + replaceFunc(maps\mp\zm_tomb_quest_elec::electric_puzzle_watch_staff, ::electric_puzzle_watch_staff_custom); + replaceFunc(maps\mp\zombies\_zm_utility::get_closest_valid_player, ::get_closest_valid_player_custom); + replaceFunc(maps\mp\zm_tomb_amb::sndmaelstrom, ::sndmaelstrom_custom); + // replaceFunc(maps\mp\zombies\_zm_zonemgr::make_zone_adjacent, ::make_zone_adjacent_custom); +// replacefunc(maps\mp\zombies\_zm_powerups::powerup_hud_monitor, ::powerup_hud_monitor_custom); + // replacefunc(maps\mp\zombies\_zm_weap_staff_lightning::init, ::init_staff_lightning_custom); + replaceFunc(maps\mp\zombies\_zm_ai_mechz::mechz_find_flesh, ::mechz_find_flesh_custom); + + // replaceFunc(maps\mp\zombies\_zm_spawner::zombie_pathing, ::zombie_pathing_custom); + // replaceFunc(maps\mp\zombies\_zm_spawner::zombie_follow_enemy, ::zombie_follow_enemy_custom); + // replaceFunc(maps\mp\zombies\_zm_ai_basic::find_flesh, ::find_flesh_custom); + + replaceFunc(maps\mp\zombies\_zm_ai_mechz_ft::player_flame_damage, ::player_flame_damage_custom); + replaceFunc(maps\mp\zombies\_zm_ai_mechz::mechz_damage_override, ::mechz_damage_override_custom); +} + +init() +{ + setDvar("lock", "0"); + setDvar("EE_Completion", "0"); + setDvar("isPanzer", ""); + setDvar("game_end", "0"); + setDvar("panzer_trap", "0"); + setDvar("wave", "0"); + setDvar("color", ""); + setDvar("boss_hp", "150000"); + setDvar("king_lock", "0"); + level.blessing_count = 7; + level.net_port_pia = []; + level.net_port_pia[level.net_port_pia.size] = "30010"; + level.is_miniboss = 0; + level.is_midboss = 0; + level.votes = 0; + + level.zombie_ai_limit = 32; + level.zombie_actor_limit = 40; + + + level.extra_hp = 0; + level.extra_panzer = 0; + level.extra_speed = 0; + level.is_boss_casting = 0; + level.primaryprogressbarwidth = 400; + level.primaryprogressbarheight = 15; + level.primaryprogressbarfontsize = 1; + + level.player_out_of_playable_area_monitor = false; // wtf bruh + level.panzer_helmet_on = 0; + level.is_trap_down = 0; + level.simon_is_showing = 0; + level.staff_player_id = -1; + level.fireRadiusOrigin = (9463, -8560, -398); + level.iceRadiusOrigin = (11211, -7058.7, -345.875); + level.windRadiusOrigin = (11253, -8655, -408); + level.lightningRadiusOrigin = (9623.4, -7016.2, -345.875); + level.papRadiusOrigin = (10760.4, -7980.47, -463.875); + level.centerRadiusOrigin = (10314.5, -7889.91, -411.875); + level.firePuzzleRadiusOrigin =(9891.5, -8764, -452); + level.panzer_hp = 500; + level.isStamOn = false; + level.isJuggOn = false; + level.isQuickOn = false; + level.isReloadOn = false; + level.wave_modifier = 1.5; + level.firewall_duration = 15; + level.mechz_reset_dist_sq = 16385; + level.mechz_aggro_dist_sq = 16384; + + level.panzer_faster_pull = 0; + level.flamethrower_damage = 30; + level.panzer_hook_speed = 1200; + level.panzer_hook_max_range = 800000; + level.panzer_hook_min_range = 90000; + level.panzer_hook_bad_retract_time = 1000; + level.panzer_hook_good_retract_time = 200; + level.panzer_hp_increase = 85; + + level.fireKillCount = 0; + level.iceKillCount = 0; + level.windKillCount = 0; + level.lightningKillCount = 0; + level.panzerKillCount = 0; + level.area_completed = 0; + + level.final_wave = 0; + + level.boss_name = "^1Panzer Primis^3"; + level.game_started = 0; + level.difficulty_selected = 0; + level.ez_difficulty_vote_count = 0; + level.chad_difficulty_vote_count = 0; + level.gigachad_difficulty_vote_count = 0; + level.gamemode_difficulty = "^2Ez^7"; + level.vote_required = 8; + + level.round_number = 0; + level thread onPlayerConnect(); + level thread story(); + level thread spawnPanzer(); + level thread zmWatcher(); + level thread perk_machine_spawn_init_customized(); + level thread papGenWatcher(); + level.zombie_vars["riotshield_hit_points"] = level.zombie_vars["riotshield_hit_points"] * 20; + level thread enable_panzer_spawner(); + level thread change_puzzles_solutions(); + level thread puzzle_watcher(); + level thread init_staff_player(); + level thread difficulty_watcher(); + level thread player_spawn_watcher(); + level thread headshot_watcher(); + level thread team_buff(); +} + +mechz_damage_override_custom( inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, shitloc, poffsettime, boneindex ) +{ + if (isdefined(attacker.slayer_multiplier)) + { + damage *= (1 + float(attacker.kills / 100)); + } + num_tiers = level.mechz_armor_info.size + 1; + old_health_tier = int( num_tiers * self.health / self.maxhealth ); + bonename = getpartname( "c_zom_mech_body", boneindex ); + + if ( isdefined( attacker ) && isalive( attacker ) && isplayer( attacker ) && ( level.zombie_vars[attacker.team]["zombie_insta_kill"] || isdefined( attacker.personal_instakill ) && attacker.personal_instakill ) ) + { + n_mechz_damage_percent = 1.0; + n_mechz_headshot_modifier = 2.0; + } + else + { + n_mechz_damage_percent = level.mechz_damage_percent; + n_mechz_headshot_modifier = 1.0; + } + + if ( isdefined( weapon ) && is_weapon_shotgun( weapon ) ) + { + n_mechz_damage_percent *= level.mechz_shotgun_damage_mod; + n_mechz_headshot_modifier *= level.mechz_shotgun_damage_mod; + } + + if ( damage <= 10 ) + n_mechz_damage_percent = 1.0; + + if ( is_explosive_damage( meansofdeath ) || issubstr( weapon, "staff" ) ) + { + if ( n_mechz_damage_percent < 0.5 ) + n_mechz_damage_percent = 0.5; + + if ( !( isdefined( self.has_helmet ) && self.has_helmet ) && issubstr( weapon, "staff" ) && n_mechz_damage_percent < 1.0 ) + n_mechz_damage_percent = 1.0; + + final_damage = damage * n_mechz_damage_percent; + + if ( !isdefined( self.explosive_dmg_taken ) ) + self.explosive_dmg_taken = 0; + + self.explosive_dmg_taken += final_damage; + self.helmet_dmg += final_damage; + + if ( isdefined( self.explosive_dmg_taken_on_grab_start ) ) + { + if ( isdefined( self.e_grabbed ) && self.explosive_dmg_taken - self.explosive_dmg_taken_on_grab_start > level.mechz_explosive_dmg_to_cancel_claw ) + { + if ( isdefined( self.has_helmet ) && self.has_helmet && self.helmet_dmg < self.helmet_dmg_for_removal || !( isdefined( self.has_helmet ) && self.has_helmet ) ) + self thread mechz_claw_shot_pain_reaction(); + + self thread ent_released_from_claw_grab_achievement( attacker, self.e_grabbed ); + self thread mechz_claw_release(); + } + } + } + else if ( shitloc != "head" && shitloc != "helmet" ) + { + if ( bonename == "tag_powersupply" ) + { + final_damage = damage * n_mechz_damage_percent; + + if ( !( isdefined( self.powerplant_covered ) && self.powerplant_covered ) ) + self.powerplant_dmg += final_damage; + else + self.powerplant_cover_dmg += final_damage; + } + + if ( isdefined( self.e_grabbed ) && ( shitloc == "left_hand" || shitloc == "left_arm_lower" || shitloc == "left_arm_upper" ) ) + { + if ( isdefined( self.e_grabbed ) ) + self thread mechz_claw_shot_pain_reaction(); + + self thread ent_released_from_claw_grab_achievement( attacker, self.e_grabbed ); + self thread mechz_claw_release( 1 ); + } + + final_damage = damage * n_mechz_damage_percent; + } + else if ( !( isdefined( self.has_helmet ) && self.has_helmet ) ) + final_damage = damage * n_mechz_headshot_modifier; + else + { + final_damage = damage * n_mechz_damage_percent; + self.helmet_dmg += final_damage; + } + + if ( !isdefined( weapon ) || weapon == "none" ) + { + if ( !isplayer( attacker ) ) + final_damage = 0; + } + + new_health_tier = int( num_tiers * ( self.health - final_damage ) / self.maxhealth ); + + if ( old_health_tier > new_health_tier ) + { + while ( old_health_tier > new_health_tier ) + { +/# + if ( getdvarint( _hash_E7121222 ) > 0 ) + println( "\\nMZ: Old tier: " + old_health_tier + " New Health Tier: " + new_health_tier + " Launching armor piece" ); +#/ + if ( old_health_tier < num_tiers ) + self mechz_launch_armor_piece(); + + old_health_tier--; + } + } + + if ( isdefined( self.has_helmet ) && self.has_helmet && self.helmet_dmg >= self.helmet_dmg_for_removal ) + { + self.has_helmet = 0; + self detach( "c_zom_mech_faceplate", "J_Helmet" ); + + if ( sndmechzisnetworksafe( "destruction" ) ) + self playsound( "zmb_ai_mechz_destruction" ); + + if ( sndmechzisnetworksafe( "angry" ) ) + self playsound( "zmb_ai_mechz_vox_angry" ); + + self.fx_field |= 1024; + self.fx_field &= ~2048; + self setclientfield( "mechz_fx", self.fx_field ); + + if ( !( isdefined( self.not_interruptable ) && self.not_interruptable ) && !( isdefined( self.is_traversing ) && self.is_traversing ) ) + { + self mechz_interrupt(); + self animscripted( self.origin, self.angles, "zm_pain_faceplate" ); + self maps\mp\animscripts\zm_shared::donotetracks( "pain_anim_faceplate" ); + } + + self thread shoot_mechz_head_vo(); + } + + if ( isdefined( self.powerplant_covered ) && self.powerplant_covered && self.powerplant_cover_dmg >= self.powerplant_cover_dmg_for_removal ) + { + self.powerplant_covered = 0; + self detach( "c_zom_mech_powersupply_cap", "tag_powersupply" ); + cap_model = spawn( "script_model", self gettagorigin( "tag_powersupply" ) ); + cap_model.angles = self gettagangles( "tag_powersupply" ); + cap_model setmodel( "c_zom_mech_powersupply_cap" ); + cap_model physicslaunch( cap_model.origin, anglestoforward( cap_model.angles ) ); + cap_model thread mechz_delayed_item_delete(); + + if ( sndmechzisnetworksafe( "destruction" ) ) + self playsound( "zmb_ai_mechz_destruction" ); + + if ( !( isdefined( self.not_interruptable ) && self.not_interruptable ) && !( isdefined( self.is_traversing ) && self.is_traversing ) ) + { + self mechz_interrupt(); + self animscripted( self.origin, self.angles, "zm_pain_powercore" ); + self maps\mp\animscripts\zm_shared::donotetracks( "pain_anim_powercore" ); + } + } + else if ( !( isdefined( self.powerplant_covered ) && self.powerplant_covered ) && ( isdefined( self.has_powerplant ) && self.has_powerplant ) && self.powerplant_dmg >= self.powerplant_dmg_for_destroy ) + { + self.has_powerplant = 0; + self thread mechz_stun( level.mechz_powerplant_stun_time ); + + if ( sndmechzisnetworksafe( "destruction" ) ) + self playsound( "zmb_ai_mechz_destruction" ); + } +/# + if ( getdvarint( _hash_E7121222 ) > 0 ) + { + println( "\\nMZ: Doing " + final_damage + " damage to mechz, Health Remaining: " + self.health ); + + if ( self.helmet_dmg < self.helmet_dmg_for_removal ) + println( "\\nMZ: Current helmet dmg: " + self.helmet_dmg + " Required helmet dmg: " + self.helmet_dmg_for_removal ); + } +#/ + return final_damage; +} + +player_flame_damage_custom() +{ + self endon( "zombified" ); + self endon( "death" ); + self endon( "disconnect" ); + n_player_dmg = 30; + n_jugga_dmg = 45; + n_burn_time = 1.5; + + if ( isdefined( self.is_zombie ) && self.is_zombie ) + return; + + self thread player_stop_burning(); + + if ( !isdefined( self.is_burning ) && is_player_valid( self, 1, 0 ) ) + { + self.is_burning = 1; + maps\mp\_visionset_mgr::vsmgr_activate( "overlay", "zm_transit_burn", self, n_burn_time, level.zm_transit_burn_max_duration ); + self notify( "burned" ); + + if (getdvar("net_port") == "30010" && self.ignoreme != true) + { + self dodamage( level.flamethrower_damage, self.origin ); + } + else + { + if ( !self hasperk( "specialty_armorvest" ) && self.ignoreme != true) + self dodamage( n_player_dmg, self.origin ); + else if (self.ignoreme != true) + self dodamage( n_jugga_dmg, self.origin ); + } + + + wait 0.5; + self.is_burning = undefined; + } +} + + +donotetracksfortimeproc_custom( donotetracksforeverfunc, time, flagname, customfunction, ent, var1 ) +{ + ent endon( "stop_notetracks" ); + [[ donotetracksforeverfunc ]]( flagname, undefined, customfunction, var1 ); +} + +powerup_hud_monitor_custom() +{ + if (getdvar("net_port") == "30010") + return; + 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 ); + + for ( powerup_key_index = 0; powerup_key_index < powerup_keys.size; powerup_key_index++ ) + { + 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; + } + } + + client_field_keys = getarraykeys( client_fields ); + + while ( true ) + { + wait 0.05; + waittillframeend; + players = get_players(); + + for ( playerindex = 0; playerindex < players.size; playerindex++ ) + { + for ( client_field_key_index = 0; client_field_key_index < client_field_keys.size; client_field_key_index++ ) + { + player = players[playerindex]; +/# + if ( isdefined( player.pers["isBot"] ) && player.pers["isBot"] ) + continue; +#/ + if ( isdefined( level.powerup_player_valid ) ) + { + if ( ![[ level.powerup_player_valid ]]( player ) ) + continue; + } + + client_field_name = client_fields[client_field_keys[client_field_key_index]].client_field_name; + time_name = client_fields[client_field_keys[client_field_key_index]].time_name; + on_name = client_fields[client_field_keys[client_field_key_index]].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 ); + continue; + } + + player setclientfieldtoplayer( client_field_name, 0 ); + } + } + } +} + +make_zone_adjacent_custom( main_zone_name, adj_zone_name, flag_name ) +{ + if (getdvar("net_port") == "30010") + return; + main_zone = level.zones[main_zone_name]; + + if ( !isdefined( main_zone.adjacent_zones[adj_zone_name] ) ) + { + main_zone.adjacent_zones[adj_zone_name] = spawnstruct(); + adj_zone = main_zone.adjacent_zones[adj_zone_name]; + adj_zone.is_connected = 0; + adj_zone.flags_do_or_check = 0; + + if ( isarray( flag_name ) ) + adj_zone.flags = flag_name; + else + adj_zone.flags[0] = flag_name; + } + else + { + assert( !isarray( flag_name ), "make_zone_adjacent: can't mix single and arrays of flags" ); + adj_zone = main_zone.adjacent_zones[adj_zone_name]; + size = adj_zone.flags.size; + adj_zone.flags_do_or_check = 1; + adj_zone.flags[size] = flag_name; + } +} + +sndmaelstrom_custom() +{ + // if (getdvar("net_port") == "30010") + return; + /* trig = getent( "sndMaelstrom", "targetname" ); + + if ( !isdefined( trig ) ) + return; + + while ( true ) + { + trig waittill( "trigger", who ); + + if ( isplayer( who ) && !is_true( who.sndmaelstrom ) ) + { + who.sndmaelstrom = 1; + level setclientfield( "sndMaelstromPlr" + who getentitynumber(), 1 ); + } + + who thread sndmaelstrom_timeout(); + wait 0.1; + }*/ +} + +find_flesh_custom() +{ + self endon( "death" ); + level endon( "intermission" ); + self endon( "stop_find_flesh" ); + + if ( level.intermission ) + return; + + self.ai_state = "find_flesh"; + self.helitarget = 1; + self.ignoreme = 0; + self.nododgemove = 1; + self.ignore_player = []; + self maps\mp\zombies\_zm_spawner::zombie_history( "find flesh -> start" ); + self.goalradius = 32; + + if ( isdefined( self.custom_goalradius_override ) ) + self.goalradius = self.custom_goalradius_override; + + while ( true ) + { + wait 0.1; + zombie_poi = undefined; + + if ( isdefined( level.zombietheaterteleporterseeklogicfunc ) ) + self [[ level.zombietheaterteleporterseeklogicfunc ]](); + + if ( isdefined( level._poi_override ) ) + zombie_poi = self [[ level._poi_override ]](); + + if ( !isdefined( zombie_poi ) ) + zombie_poi = self get_zombie_point_of_interest( self.origin ); + + players = get_players(); + + if ( !isdefined( self.ignore_player ) || players.size == 1 ) + self.ignore_player = []; + else if ( !isdefined( level._should_skip_ignore_player_logic ) || ![[ level._should_skip_ignore_player_logic ]]() ) + { + i = 0; + + while ( i < self.ignore_player.size ) + { + if ( isdefined( self.ignore_player[i] ) && isdefined( self.ignore_player[i].ignore_counter ) && self.ignore_player[i].ignore_counter > 3 ) + { + self.ignore_player[i].ignore_counter = 0; + self.ignore_player = arrayremovevalue( self.ignore_player, self.ignore_player[i] ); + + if ( !isdefined( self.ignore_player ) ) + self.ignore_player = []; + + i = 0; + continue; + } + + i++; + } + } + + player = get_closest_valid_player( self.origin, self.ignore_player ); + + if ( !isdefined( player ) && !isdefined( zombie_poi ) ) + { + self maps\mp\zombies\_zm_spawner::zombie_history( "find flesh -> can't find player, continue" ); + + if ( isdefined( self.ignore_player ) ) + { + if ( isdefined( level._should_skip_ignore_player_logic ) && [[ level._should_skip_ignore_player_logic ]]() ) + { + wait 1; + continue; + } + + self.ignore_player = []; + } + + wait 1; + continue; + } + + if ( !isdefined( level.check_for_alternate_poi ) || ![[ level.check_for_alternate_poi ]]() ) + { + self.enemyoverride = zombie_poi; + self.favoriteenemy = player; + } + + self thread zombie_pathing(); + + if ( players.size > 1 ) + { + for ( i = 0; i < self.ignore_player.size; i++ ) + { + if ( isdefined( self.ignore_player[i] ) ) + { + if ( !isdefined( self.ignore_player[i].ignore_counter ) ) + { + self.ignore_player[i].ignore_counter = 0; + continue; + } + + self.ignore_player[i].ignore_counter += 1; + } + } + } + + self thread attractors_generated_listener(); + + if ( isdefined( level._zombie_path_timer_override ) ) + self.zombie_path_timer = [[ level._zombie_path_timer_override ]](); + else + self.zombie_path_timer = gettime() + randomfloatrange( 1, 3 ) * 1000; + + while ( gettime() < self.zombie_path_timer ) + wait 0.1; + + self notify( "path_timer_done" ); + self maps\mp\zombies\_zm_spawner::zombie_history( "find flesh -> bottom of loop" ); + debug_print( "Zombie is re-acquiring enemy, ending breadcrumb search" ); + self notify( "zombie_acquire_enemy" ); + // iprintln("target acquired"); + } +} + +zombie_pathing_custom() +{ + self endon( "death" ); + self endon( "zombie_acquire_enemy" ); + level endon( "intermission" ); + assert( isdefined( self.favoriteenemy ) || isdefined( self.enemyoverride ) ); + self._skip_pathing_first_delay = 1; + self thread zombie_follow_enemy(); + + self waittill( "bad_path" ); + + level.zombie_pathing_failed++; + + if ( isdefined( self.enemyoverride ) ) + { + debug_print( "Zombie couldn't path to point of interest at origin: " + self.enemyoverride[0] + " Falling back to breadcrumb system" ); + + if ( isdefined( self.enemyoverride[1] ) ) + { + self.enemyoverride = self.enemyoverride[1] invalidate_attractor_pos( self.enemyoverride, self ); + self.zombie_path_timer = 0; + return; + } + } + else if ( isdefined( self.favoriteenemy ) ) + debug_print( "Zombie couldn't path to player at origin: " + self.favoriteenemy.origin + " Falling back to breadcrumb system" ); + else + debug_print( "Zombie couldn't path to a player ( the other 'prefered' player might be ignored for encounters mode ). Falling back to breadcrumb system" ); + + if ( !isdefined( self.favoriteenemy ) ) + { + self.zombie_path_timer = 0; + return; + } + else + self.favoriteenemy endon( "disconnect" ); + + players = get_players(); + valid_player_num = 0; + + for ( i = 0; i < players.size; i++ ) + { + if ( is_player_valid( players[i], 1 ) ) + valid_player_num += 1; + } + + if ( players.size > 1 ) + { + if ( isdefined( level._should_skip_ignore_player_logic ) && [[ level._should_skip_ignore_player_logic ]]() ) + { + self.zombie_path_timer = 0; + return; + } + + if ( array_check_for_dupes( self.ignore_player, self.favoriteenemy ) ) + self.ignore_player[self.ignore_player.size] = self.favoriteenemy; + + if ( self.ignore_player.size < valid_player_num ) + { + self.zombie_path_timer = 0; + return; + } + } + + crumb_list = self.favoriteenemy.zombie_breadcrumbs; + bad_crumbs = []; + + while ( true ) + { + wait 0.1; + if ( !is_player_valid( self.favoriteenemy, 1 ) ) + { + self.zombie_path_timer = 0; + return; + } + + goal = zombie_pathing_get_breadcrumb( self.favoriteenemy.origin, crumb_list, bad_crumbs, randomint( 100 ) < 20 ); + + if ( !isdefined( goal ) ) + { + debug_print( "Zombie exhausted breadcrumb search" ); + level.zombie_breadcrumb_failed++; + goal = self.favoriteenemy.spectator_respawn.origin; + } + + debug_print( "Setting current breadcrumb to " + goal ); + self.zombie_path_timer += 100; + self setgoalpos( goal ); + + self waittill( "bad_path" ); + + debug_print( "Zombie couldn't path to breadcrumb at " + goal + " Finding next breadcrumb" ); + + for ( i = 0; i < crumb_list.size; i++ ) + { + if ( goal == crumb_list[i] ) + { + bad_crumbs[bad_crumbs.size] = i; + break; + } + } + } +} + +zombie_follow_enemy_custom() +{ + self endon( "death" ); + self endon( "zombie_acquire_enemy" ); + self endon( "bad_path" ); + level endon( "intermission" ); + + if ( !isdefined( level.repathnotifierstarted ) ) + { + level.repathnotifierstarted = 1; + level thread zombie_repath_notifier(); + } + + if ( !isdefined( self.zombie_repath_notify ) ) + self.zombie_repath_notify = "zombie_repath_notify_" + self getentitynumber() % 4; + + while ( true ) + { + wait 0.1; + if ( !isdefined( self._skip_pathing_first_delay ) ) + level waittill( self.zombie_repath_notify ); + else + self._skip_pathing_first_delay = undefined; + + if ( !( isdefined( self.ignore_enemyoverride ) && self.ignore_enemyoverride ) && isdefined( self.enemyoverride ) && isdefined( self.enemyoverride[1] ) ) + { + if ( distancesquared( self.origin, self.enemyoverride[0] ) > 1 ) + self orientmode( "face motion" ); + else + self orientmode( "face point", self.enemyoverride[1].origin ); + + self.ignoreall = 1; + goalpos = self.enemyoverride[0]; + + if ( isdefined( level.adjust_enemyoverride_func ) ) + goalpos = self [[ level.adjust_enemyoverride_func ]](); + + self setgoalpos( goalpos ); + } + else if ( isdefined( self.favoriteenemy ) ) + { + self.ignoreall = 0; + self orientmode( "face default" ); + goalpos = self.favoriteenemy.origin; + + if ( isdefined( level.enemy_location_override_func ) ) + goalpos = [[ level.enemy_location_override_func ]]( self, self.favoriteenemy ); + + self setgoalpos( goalpos ); + + if ( !isdefined( level.ignore_path_delays ) ) + { + distsq = distancesquared( self.origin, self.favoriteenemy.origin ); + + if ( distsq > 10240000 ) + wait( 2.0 + randomfloat( 1.0 ) ); + else if ( distsq > 4840000 ) + wait( 1.0 + randomfloat( 0.5 ) ); + else if ( distsq > 1440000 ) + wait( 0.5 + randomfloat( 0.5 ) ); + } + } + + if ( isdefined( level.inaccesible_player_func ) ) + self [[ level.inaccessible_player_func ]](); + } +} + + + + +get_closest_valid_player_custom(origin, players) +{ + closest_dist = 9999999; + closest_player = undefined; + foreach(player in level.players) + { + if ( player.sessionstate == "intermission" ) + return undefined; + if ( isdefined( player.intermission ) && player.intermission ) + return undefined; + if (player.sessionstate == "spectator" || player maps\mp\zombies\_zm_laststand::player_is_in_laststand() ) + continue; + dist = distancesquared(origin, player.origin); + if (dist < closest_dist) + { + closest_dist = dist; + closest_player = player; + } + } + return closest_player; +} + +headshot_watcher() +{ + flag_wait("initial_blackscreen_passed"); + if (getdvar("net_port") != "30010") + return; + + for (;;) + { + foreach(player in level.players) + { + if (player.headshots >= 50 && player.sessionstate != "spectator") + { + weapon_loadout = player GetWeaponsListPrimaries(); + if (weapon_loadout.size >= 2) + player TakeWeapon(player GetCurrentWeapon()); + player GiveWeapon("evoskorpion_upgraded_zm"); + player SwitchToWeapon("evoskorpion_upgraded_zm"); + player iprintln("The ^1SMG God^7 gave you his ^5blessing"); + return; + } + } + wait 2; + } +} + +get_favorite_enemy_custom(origin, players) +{ + closest_distance = 999999999; + closest_player = undefined; + foreach (player in level.players) + { + if ( player.sessionstate == "intermission" ) + return undefined; + if ( isdefined( player.intermission ) && player.intermission ) + return undefined; + if(player.sessionstate == "spectator" || player maps\mp\zombies\_zm_laststand::player_is_in_laststand()) + continue; + p_dist = distancesquared(origin, player.origin); + if (p_dist < closest_distance) + { + closest_player = player; + closest_distance = p_dist; + } + } + return closest_player; +} + +get_favorite_enemy_custom2(origin, players) +{ + closest_distance = 999999999; + closest_player = undefined; + foreach (player in level.players) + { + if ( player.sessionstate == "intermission" ) + return undefined; + if ( isdefined( player.intermission ) && player.intermission ) + return undefined; + if(player.sessionstate == "spectator" || player maps\mp\zombies\_zm_laststand::player_is_in_laststand()) + continue; + p_dist = distancesquared(self.origin, player.origin); + if (p_dist < closest_distance) + { + closest_player = player; + closest_distance = p_dist; + } + } + return closest_player; +} + +player_spawn_watcher() +{ + flag_wait("initial_blackscreen_passed"); + + if (getdvar("net_port") != "30010") + return; + + second = 0; + wait 5; + for (;;) + { + for (i = 0; i < level.players.size; i++) + { + if(level.players[i] maps\mp\zombies\_zm_laststand::player_is_in_laststand()) + { + level.players[i] thread maps\mp\zombies\_zm_laststand::auto_revive(level.players[i]); + } + } + second++; + if (second >= 10) //15s + break; + wait 1.5; + } +} + +team_buff() +{ + if (getdvar("net_port") != "30010") + return; + + m_id = 0; + r = randomint(100); + r2 = randomint(100); + flag_wait("initial_blackscreen_passed"); + wait 3; + foreach (player in level.players) + { + level.isStamOn = true; + level.isReloadOn = true; + level.isQuickOn = true; + level.isJuggOn = true; + + level.perk_machine SetModel("p6_zm_tm_vending_revive_on"); + level.perk_machine thread perk_fx( "revive_light" ); + + if (r > 90) + { + m_id = 1; + level.str1 = "^2Agarthan power^7\n- All players receive a random staff"; + if (isAlive(player)) + { + weapon_loadout = player GetWeaponsListPrimaries(); + if (weapon_loadout.size >= 2) + player TakeWeapon(player GetCurrentWeapon()); + random = randomint(4); + if (random == 0) + staff_elem = "lightning"; + if (random == 1) + staff_elem = "air"; + if (random == 2) + staff_elem = "fire"; + if (random == 3) + staff_elem = "water"; + weapon_loadout = self GetWeaponsListPrimaries(); + if (weapon_loadout.size >= 2) + self TakeWeapon(self GetCurrentWeapon()); + player GiveWeapon("staff_" + staff_elem + "_zm"); + player SwitchToWeapon("staff_" + staff_elem + "lightning_zm"); + } + } + else if (r > 80) + { + m_id = 2; + level.str1 = "^2Mechanic^7\n- All generators are turned on"; + level.isStamOn = true; + level.isReloadOn = true; + level.isQuickOn = true; + level.isJuggOn = true; + + level.perk_machine SetModel("p6_zm_tm_vending_revive_on"); + level.perk_machine thread perk_fx( "revive_light" ); + for (i = 0; i < 7; i++) + { + turn_gen_on(i); + wait 0.3; + } + } + else if (r > 70) + { + m_id = 3; + level.str1 = "^2Drone Swarm^7\n- All players receive a pet drone\n- ^3Melee^7 to activate drone skill"; + has_drone = 0; + foreach(guid in level.drone_pass_list) + { + if (player getguid() == guid) + has_drone = 1; + } + if (has_drone == 0) + player thread scripts\zm\zm_tomb\pet_drones::on_player_spawned(); + } + else if (r > 55) + { + m_id = 4; + level.str1 = "^2Running in the 90s^7\n- Your team is zooming"; + level.extra_speed = 0.4; + player SetMoveSpeedScale(1.45); + } + else if (r > 0) + { + m_id = 5; + level.str1 = "^2Double Tap 3.0^7\n- Grant an empowered Double Tap\n- Lost if downed"; + setdvar("perk_weapRateMultiplier", "0.5"); + setdvar("fire_rate", "0.5"); + if (player HasPerk("specialty_rof") == 0) + player thread maps\mp\zombies\_zm_perks::wait_give_perk("specialty_rof", 1); + } + else if (r > 20) + { + m_id = 6; + level.str1 = "^2Medic Squad^7\n- Increased revive speed"; + level.faster_revive = 1; + } + else if (r > 0) + { + m_id = 7; + level.str1 = "^2Panzer Slayer^7\n- Each kill grant 6 permanent HP"; + level.hp_stack = 1; + } + //ENEMY BUFF + if (r2 > 80) + { + level.str2 = "^1Lock out^7\n- The walls drops earlier"; + level.lockout = 1; + } + else if (r2 > 60) + { + level.str2 = "^1Juggernauts^7\n- Panzers are beefy"; + level.panzer_hp = level.panzer_hp * 1.25; + level.panzer_hp_increase = level.panzer_hp_increase * 1.25; + } + else if (r2 > 40) + { + level.str2 = "^1Roadhog time^7\n- Panzer hook cooldown decreased"; + level.mechz_claw_cooldown_time = 3000; + } + else if (r2 > 20) + { + level.str2 = "^1Endless Horde^7\n- More Panzer spawns"; + level.extra_panzer = 4; + } + else if (r2 > 0) + { + level.str2 = "^2None^7\n- You lucky nugget !"; + } + } + for (;;) + { + if (getdvar("guild_modifier") == "1") + { + break; + } + else if (getdvar("guild_modifier") == "2") + break; + wait 0.5; + } + + if (getdvar("guild_modifier") == "1") + { + for (;;) + { + r = randomint(100); + if (r > 90 && m_id != 1) + break; + else if (r > 80 && m_id != 2) + break; + else if (r > 70 && m_id != 3) + break; + else if (r > 55 && m_id != 4) + break; + else if (r > 35 && m_id != 5) + break; + else if (r > 20 && m_id != 6) + break; + else if (r > 0 && m_id != 7) + break; + wait 0.05; + } + + foreach (player in level.players) + { + level.str1 += "\n ^6[GUILD]^7 "; + if (r > 90) + { + level.str1 += "^2Agarthan power^7\n- All players receive a random staff"; + if (isAlive(player)) + { + weapon_loadout = player GetWeaponsListPrimaries(); + if (weapon_loadout.size >= 2) + player TakeWeapon(player GetCurrentWeapon()); + random = randomint(4); + if (random == 0) + staff_elem = "lightning"; + if (random == 1) + staff_elem = "air"; + if (random == 2) + staff_elem = "fire"; + if (random == 3) + staff_elem = "water"; + weapon_loadout = self GetWeaponsListPrimaries(); + if (weapon_loadout.size >= 2) + self TakeWeapon(self GetCurrentWeapon()); + player GiveWeapon("staff_" + staff_elem + "_zm"); + player SwitchToWeapon("staff_" + staff_elem + "lightning_zm"); + } + } + else if (r > 80) + { + level.str1 += "^2Mechanic^7\n- All generators are turned on"; + level.isStamOn = true; + level.isReloadOn = true; + level.isQuickOn = true; + level.isJuggOn = true; + + level.perk_machine SetModel("p6_zm_tm_vending_revive_on"); + level.perk_machine thread perk_fx( "revive_light" ); + for (i = 0; i < 7; i++) + { + turn_gen_on(i); + wait 0.3; + } + } + else if (r > 70) + { + level.str1 += "^2Drone Swarm^7\n- All players receive a pet drone\n- ^3Melee^7 to activate drone skill"; + has_drone = 0; + foreach(guid in level.drone_pass_list) + { + if (player getguid() == guid) + has_drone = 1; + } + if (has_drone == 0) + player thread scripts\zm\zm_tomb\pet_drones::on_player_spawned(); + } + else if (r > 55) + { + level.str1 += "^2Running in the 90s^7\n- Your team is zooming"; + level.extra_speed = 0.4; + player SetMoveSpeedScale(1.45); + } + else if (r > 35) + { + level.str1 += "^2Double Tap 3.0^7\n- Grant an empowered Double Tap\n- Lost if downed"; + setdvar("perk_weapRateMultiplier", "0.5"); + setdvar("fire_rate", "0.5"); + level waittill("start_of_round"); + if (player HasPerk("specialty_rof") == 0) + player thread maps\mp\zombies\_zm_perks::wait_give_perk("specialty_rof", 1); + } + else if (r > 20) + { + level.str1 += "^2Medic Squad^7\n- Increased revive speed"; + level.faster_revive = 1; + } + else if (r > 0) + { + level.str1 += "^2Panzer Slayer^7\n- Each kill grant 6 permanent HP"; + level.hp_stack = 1; + } + } + } + level.modif_lock = 1; +} + +init_staff_player() +{ + flag_wait("initial_blackscreen_passed"); + level.staff_player_id = randomintrange(0, level.players.size); +} + +piano_keys_stop_custom() +{ + if (getdvar("net_port") == "30010") + return; + level notify( "piano_keys_stop" ); + level.a_piano_keys_playing = []; +} + +electric_puzzle_watch_staff_custom() +{ + self endon( "disconnect" ); + + if (getdvar("net_port") == "30010") + { + while ( true ) + { + self waittill( "projectile_impact", str_weap_name, v_explode_point, n_radius, e_projectile, n_impact ); + + if (level.simon_is_showing == 0) + { + if ( !flag( "electric_puzzle_1_complete" ) && maps\mp\zm_tomb_chamber::is_chamber_occupied() ) + { + n_index = get_closest_index( v_explode_point, level.a_piano_keys, 20.0 ); + + if ( isdefined( n_index ) ) + { + if (level.a_piano_keys[n_index] == level.key_to_hit) + { + level.a_piano_keys[n_index].e_fx.origin = level.a_key_origin[n_index]; + level notify ("simon_hit"); + } + else + { + foreach(player in level.players) + { + if (distancesquared(level.lightningRadiusOrigin, player.origin ) < 65000 && player.ignoreme != true) + player dodamage(player.maxhealth + 666, player.origin); + } + level thread piano_fail_flash(); + } + + } + } + } + } + } + else + { + a_piano_keys = getstructarray( "piano_key", "script_noteworthy" ); + while ( true ) + { + self waittill( "projectile_impact", str_weap_name, v_explode_point, n_radius, e_projectile, n_impact ); + + if ( str_weap_name == "staff_lightning_zm" ) + { + if ( !flag( "electric_puzzle_1_complete" ) && maps\mp\zm_tomb_chamber::is_chamber_occupied() ) + { + n_index = get_closest_index( v_explode_point, a_piano_keys, 20.0 ); + + if ( isdefined( n_index ) ) + { + a_piano_keys[n_index] notify( "piano_key_shot" ); + a_players = getplayers(); + + foreach ( e_player in a_players ) + { + if ( e_player hasweapon( "staff_lightning_zm" ) ) + level notify( "vo_try_puzzle_lightning1", e_player ); + } + } + } + } + } + } + +} + +change_ice_gem_value_custom() +{ + ice_gem = getent( "ice_chamber_gem", "targetname" ); + + if (getdvar("net_port") == "30010") + { + if ( level.unsolved_tiles.size != 0 ) + { + for (;;) + { + correct_tile = random( level.unsolved_tiles ); + if (correct_tile == level.ice_puzzle_order[level.index]) + { + ice_gem.value = correct_tile.value; + level.index++; + break; + } + wait 0.1; + } + level notify( "update_ice_chamber_digits", -1 ); + } + else + level notify( "update_ice_chamber_digits", -1 ); + } + else + { + if ( level.unsolved_tiles.size != 0 ) + { + correct_tile = random( level.unsolved_tiles ); + ice_gem.value = correct_tile.value; + level notify( "update_ice_chamber_digits", ice_gem.value ); + } + else + level notify( "update_ice_chamber_digits", -1 ); + } +} + +ceiling_tile_process_damage_custom() +{ + level endon( "ice_puzzle_1_complete" ); + ice_gem = getent( "ice_chamber_gem", "targetname" ); + self setcandamage( 1 ); + + if (getdvar("net_port") == "30010") + { + while ( true ) + { + self waittill( "damage", damage, attacker, direction_vec, point, mod, tagname, modelname, partname, weaponname ); + if (self.showing_tile_side && !flag( "ice_tile_flipping" ) ) + { + level notify( "vo_try_puzzle_water1", attacker ); + flag_set( "ice_tile_flipping" ); + if ( ice_gem.value == self.value ) + { + level notify( "vo_puzzle_good", attacker ); + self ceiling_tile_flip( 0 ); + rumble_nearby_players( self.origin, 1500, 2 ); + wait 0.2; + } + else + { + level.index = 0; + level notify( "vo_puzzle_bad", attacker ); + reset_tiles(); + rumble_nearby_players( self.origin, 1500, 2 ); + wait 2.0; + } + + change_ice_gem_value(); + flag_clear( "ice_tile_flipping" ); + } + else + level notify( "vo_puzzle_confused", attacker ); + } + } + else + { + while ( true ) + { + self waittill( "damage", damage, attacker, direction_vec, point, mod, tagname, modelname, partname, weaponname ); + + if ( issubstr( weaponname, "water" ) && self.showing_tile_side && !flag( "ice_tile_flipping" ) ) + { + level notify( "vo_try_puzzle_water1", attacker ); + flag_set( "ice_tile_flipping" ); + + if ( ice_gem.value == self.value ) + { + level notify( "vo_puzzle_good", attacker ); + self ceiling_tile_flip( 0 ); + rumble_nearby_players( self.origin, 1500, 2 ); + wait 0.2; + } + else + { + level notify( "vo_puzzle_bad", attacker ); + reset_tiles(); + rumble_nearby_players( self.origin, 1500, 2 ); + wait 2.0; + } + + change_ice_gem_value(); + flag_clear( "ice_tile_flipping" ); + } + else + level notify( "vo_puzzle_confused", attacker ); + } + } + +} + +process_gem_shooting_custom() +{ + level endon( "ice_puzzle_1_complete" ); + + ice_gem = getent( "ice_chamber_gem", "targetname" ); + ice_gem.value = -1; + ice_gem setcandamage( 1 ); + + if (getdvar("net_port") == "30010") + { + while ( true ) + { + // level notify( "update_ice_chamber_digits", -1 ); + self waittill( "damage", damage, attacker, direction_vec, point, mod, tagname, modelname, partname, weaponname ); + change_ice_gem_value(); + } + } + else + { + while ( true ) + { + self waittill( "damage", damage, attacker, direction_vec, point, mod, tagname, modelname, partname, weaponname ); + if ( weaponname == "staff_water_zm" ) + change_ice_gem_value(); + } + } +} + +ceiling_ring_run_custom() +{ + level endon("disconnected"); + level endon( "air_puzzle_1_complete" ); + self setcandamage( 1 ); + self.position = 0; + ceiling_ring_randomize(); + n_rotations = 0; + if (getdvar("net_port") == "30010") + { + while ( true ) + { + self waittill( "damage", damage, attacker, direction_vec, point, mod, tagname, modelname, partname, weaponname ); + + + level notify( "vo_try_puzzle_air1", attacker ); + self ceiling_ring_rotate(); + rumble_nearby_players( self.origin, 1500, 2 ); + n_rotations++; + + if ( n_rotations % 4 == 0 ) + level notify( "vo_puzzle_bad", attacker ); + } + } + else + { + while ( true ) + { + self waittill( "damage", damage, attacker, direction_vec, point, mod, tagname, modelname, partname, weaponname ); + + if ( weaponname == "staff_air_zm" ) + { + level notify( "vo_try_puzzle_air1", attacker ); + self ceiling_ring_rotate(); + rumble_nearby_players( self.origin, 1500, 2 ); + n_rotations++; + + if ( n_rotations % 4 == 0 ) + level notify( "vo_puzzle_bad", attacker ); + } + else + level notify( "vo_puzzle_confused", attacker ); + } + } +} + +puzzle_watcher() +{ + level endon("disconnect"); + flag_wait("initial_blackscreen_passed"); + + if (getdvar("net_port") != "30010") + return; + level thread wind_gen_watcher(); + level thread lightning_gen_watcher(); + level thread ice_gen_watcher(); + level thread fire_gen_watcher(); + level thread randomize_ice_puzzle(); + level thread simon_game_lightning(); +} + +simon_game_lightning() +{ + level.a_key_origin = []; + + level.a_piano_keys = getstructarray( "piano_key", "script_noteworthy" ); + foreach(key in level.a_piano_keys) + { + key.e_fx = spawn( "script_model", key.origin ); + key.e_fx.angles = key.angles; + key.e_fx setmodel( "tag_origin" ); + key.e_fx playloopsound( "zmb_kbd_" + key.script_string ); + wait 1; + playfxontag( level._effect["elec_piano_glow"], key.e_fx, "tag_origin" ); + level.a_key_origin[level.a_key_origin.size] = key.origin; + key.e_fx.origin = (0, 0, 0); + } + + level.puzzle_solution = []; + + for (i = 0; i < 7; i++) + { + rnd = randomintrange(0, 12); + level.puzzle_solution[level.puzzle_solution.size] = rnd; + wait 0.1; + } + level thread simon_game_start(); +} + +show_simon_path(iteration) +{ + level.simon_is_showing = 1; + for (i = 0; i < iteration; i++) + { + level.a_piano_keys[level.puzzle_solution[i]].e_fx.origin = level.a_key_origin[level.puzzle_solution[i]]; + wait 1; + level.a_piano_keys[level.puzzle_solution[i]].e_fx.origin = (0, 0, 0); + wait 0.2; + } + level.simon_is_showing = 0; +} + +simon_game_timeout_watcher() +{ + level endon ("simon_failed"); + level endon ("simon_hit"); + level endon ( "simon_next_iteration" ); + wait 10; + level thread piano_fail_flash(); +} + +piano_fail_flash() +{ + for (i = 0; i < 3 ; i++) + { + x = 0; + foreach(index, key in level.a_piano_keys) + { + key.e_fx.origin = level.a_key_origin[index]; + x++; + } + wait 0.3; + foreach(key in level.a_piano_keys) + { + key.e_fx.origin = (0, 0, 0); + } + wait 0.1; + } + level notify( "simon_failed" ); + wait 1; + level thread simon_game_start(); +} + +simon_game_start() +{ + level endon("simon_failed"); + iteration = 3; + level thread simon_game_timeout_watcher(); + for (;;) + { + level thread show_simon_path(iteration); + wait_time = (iteration * 1.2) + 0.1; + wait wait_time; + for (i = 0; i < iteration; i++) + { + level.key_to_hit = level.a_piano_keys[level.puzzle_solution[i]]; + level waittill("simon_hit"); + level thread simon_game_timeout_watcher(); + if (i == 6) + { + level.simon_is_showing = 1; + wait 1.5; + flag_set("electric_puzzle_1_complete"); + foreach(key in level.a_piano_keys) + { + key.e_fx delete(); + } + return; + } + } + level notify( "simon_next_iteration" ); + level.simon_is_showing = 1; + wait 1.5; + foreach(key in level.a_piano_keys) + { + key.e_fx.origin = (0, 0, 0); + } + wait 1; + iteration++; + } + +} + +randomize_ice_puzzle() +{ + level.unsolved_tiles_cpy = []; + level.ice_puzzle_order = []; + foreach (tile in level.unsolved_tiles) + { + level.unsolved_tiles_cpy[level.unsolved_tiles_cpy.size] = tile; + } + for (i = 0; i < level.unsolved_tiles.size; i++) + { + correct_tile = random( level.unsolved_tiles_cpy ); + level.ice_puzzle_order[level.ice_puzzle_order.size] = correct_tile; + arrayremovevalue( level.unsolved_tiles_cpy, correct_tile, 0 ); + } +} + +wind_gen_watcher() +{ + flag_wait("air_puzzle_1_complete"); + turn_gen_on(5); + level.isStamOn = true; +} + +lightning_gen_watcher() +{ + flag_wait("electric_puzzle_1_complete"); + turn_gen_on(3); + level.isReloadOn = true; +} + +ice_gen_watcher() +{ + flag_wait("ice_puzzle_1_complete"); + turn_gen_on(1); + level.isQuickOn = true; +} + +fire_gen_watcher() +{ + flag_wait("fire_puzzle_1_complete"); + turn_gen_on(4); + level.isJuggOn = true; +} + +change_puzzles_solutions() +{ + level endon("disconnect"); + flag_wait("initial_blackscreen_passed"); + + if (getdvar("net_port") != "30010") + return; + array_thread( level.a_ceiling_rings, ::ceiling_ring_run_custom ); + wait 5; + level.a_ceiling_rings[0].script_int = 1; + level.a_ceiling_rings[1].script_int = 3; + level.a_ceiling_rings[2].script_int = 1; + level.a_ceiling_rings[3].script_int = 1; +} + +waitlongdurationwithhostmigrationpause_custom( duration ) +{ + if (getdvar("net_port") == "30010") + return; + if ( duration == 0 ) + return; + + assert( duration > 0 ); + starttime = gettime(); + endtime = gettime() + duration * 1000; + + while ( gettime() < endtime ) + { + waittillhostmigrationstarts( ( endtime - gettime() ) / 1000 ); + + if ( isdefined( level.hostmigrationtimer ) ) + { + timepassed = waittillhostmigrationdone(); + endtime += timepassed; + } + } + + if ( gettime() != endtime ) + { +/# + println( "SCRIPT WARNING: gettime() = " + gettime() + " NOT EQUAL TO endtime = " + endtime ); +#/ + } + + waittillhostmigrationdone(); + return gettime() - starttime; +} + +initializematchstats_custom() +{ + if (getdvar("net_port") == "30010") + return; + if ( !level.onlinegame || !gamemodeismode( level.gamemode_public_match ) ) + return; + + self.pers["lastHighestScore"] = self getdstat( "HighestStats", "highest_score" ); + currgametype = level.gametype; + self gamehistorystartmatch( getgametypeenumfromname( currgametype, 0 ) ); +} + +init_staff_lightning_custom() +{ + level._effect["lightning_miss"] = loadfx( "weapon/zmb_staff/fx_zmb_staff_elec_ug_impact_miss" ); + level._effect["lightning_arc"] = loadfx( "weapon/zmb_staff/fx_zmb_staff_elec_trail_bolt_cheap" ); + level._effect["lightning_impact"] = loadfx( "weapon/zmb_staff/fx_zmb_staff_elec_ug_impact_hit_torso" ); + level._effect["tesla_shock_eyes"] = loadfx( "maps/zombie/fx_zombie_tesla_shock_eyes" ); + registerclientfield( "actor", "lightning_impact_fx", 14000, 1, "int" ); + registerclientfield( "scriptmover", "lightning_miss_fx", 14000, 1, "int" ); + registerclientfield( "actor", "lightning_arc_fx", 14000, 1, "int" ); + set_zombie_var( "tesla_head_gib_chance", 50 ); + onplayerconnect_callback( ::onplayerconnect ); + maps\mp\zombies\_zm_spawner::register_zombie_damage_callback( ::staff_lightning_zombie_damage_response_custom ); + maps\mp\zombies\_zm_spawner::register_zombie_death_event_callback( ::staff_lightning_death_event ); +} + +staff_lightning_zombie_damage_response_custom( mod, hit_location, hit_origin, player, amount ) +{ + return; + /* if (getdvar("net_port") == "30010") + return; + if ( self is_staff_lightning_damage() && self.damagemod != "MOD_RIFLE_BULLET" ) + self thread stun_zombie(); + + return 0;*/ +} + +mechz_setup_armor_pieces_custom() +{ + + level.mechz_armor_info = []; + // level.mechz_armor_info[0] = spawnstruct(); + level.mechz_armor_info[0].model = "c_zom_mech_armor_knee_left"; + level.mechz_armor_info[0].tag = "J_Knee_Attach_LE"; + // level.mechz_armor_info[1] = spawnstruct(); + level.mechz_armor_info[1].model = "c_zom_mech_armor_knee_right"; + level.mechz_armor_info[1].tag = "J_Knee_attach_RI"; + // level.mechz_armor_info[2] = spawnstruct(); + level.mechz_armor_info[2].model = "c_zom_mech_armor_shoulder_left"; + level.mechz_armor_info[2].tag = "J_ShoulderArmor_LE"; +// level.mechz_armor_info[3] = spawnstruct(); + level.mechz_armor_info[3].model = "c_zom_mech_armor_shoulder_right"; + level.mechz_armor_info[3].tag = "J_ShoulderArmor_RI"; + // level.mechz_armor_info[4] = spawnstruct(); + level.mechz_armor_info[4].tag = "J_Root_Attach_LE"; + // level.mechz_armor_info[5] = spawnstruct(); + level.mechz_armor_info[5].tag = "J_Root_Attach_RI"; + for ( i = 0; i < level.mechz_armor_info.size; i++ ) + { + if ( isdefined( level.mechz_armor_info[i].model ) ) + precachemodel( level.mechz_armor_info[i].model ); + } + return; +} + +enable_panzer_spawner() +{ + for (;;) + { + level.mechz_spawners[0].is_enabled = 1; + wait 5; + } +} + +onPlayerConnect() +{ + while( 1 ) + { + level waittill( "connected", player ); + player thread onPlayerSpawned(); + player thread WaveWatcher(); + player thread ammoRegen(); + player thread gamemode_hud(); + } +} + +gamemode_hud() +{ + self endon("disconnect"); + level endon("game_ended"); + + if (getdvar("net_port") != "30010") + return; + flag_wait("initial_blackscreen_passed"); + wait 0.1; + for (;;) + { + if (isdefined(level.str1) && isdefined(level.str2) && isdefined(level.modif_lock)) + break; + wait 0.1; + } + self.team_buff = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1 ); + self.team_buff maps\mp\gametypes_zm\_hud_util::setPoint( "CENTER", "LEFT", 0, -220 ); + self.team_buff.alpha = 0.8; + self.team_buff SetText("^3MODIFIERS :^7\n" + level.str1 + "\n\n" + level.str2); + + for (;;) + { + if (level.game_started == 1) + { + wait 1; + self.difficulty_hud = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1.5 ); + self.difficulty_hud maps\mp\gametypes_zm\_hud_util::setPoint( "TOP", "RIGHT", 0, -190 ); + self.difficulty_hud.label = &"^1Difficulty : ^2"; + if (level.gamemode_difficulty == "^1Chad^7") + self.difficulty_hud.label = &"^5Difficulty : ^1"; + else if (level.gamemode_difficulty == "^6GigaChad^7") + self.difficulty_hud.label = &"^5Difficulty : ^6"; + self.difficulty_hud.alpha = 0.8; + self.difficulty_hud settext(level.gamemode_difficulty); + return; + } + wait 0.1; + } +} + +rumblePlayers(strenght, time) +{ + foreach(player in level.players) + player setclientfieldtoplayer( "player_rumble_and_shake", strenght ); + wait(time); + foreach(player in level.players) + player setclientfieldtoplayer( "player_rumble_and_shake", 0 ); +} + +papGenWatcher() +{ + level endon ("game_ended"); + level waittill("initial_blackscreen_passed"); + +if (getdvar("net_port") != "30010") + return; + for(;;) + { + foreach(player in level.players) + { + if (!(player.sessionstate == "spectator")) + { + dist = distancesquared(level.papRadiusOrigin, player.origin); + if (distancesquared(level.papRadiusOrigin, player.origin) < 4000 && player getstance() == "prone") + { + turn_gen_on(2); + return; + } + } + } + wait 0.5; + } + +} + +light_plinth_custom(origin) +{ + level endon("game_ended"); + e_fx = spawn( "script_model", origin ); + e_fx setmodel( "tag_origin" ); + playfxontag( level._effect["fire_torch"], e_fx, "tag_origin" ); + e_fx.angles = vectorscale( ( -1, 0, 0 ), 90.0 ); + e_fx playsound( "zmb_squest_fire_torch_ignite" ); + e_fx playloopsound( "zmb_squest_fire_torch_loop", 0.6 ); +} + +PanzerDeathWatcher() +{ + level endon ("game_ended"); + self waittill("death"); + self.is_dead = 1; + if (level.panzerKillCount < 4 && distancesquared(level.firePuzzleRadiusOrigin, self.origin ) < 65000) + { + origin = (0, 0, 0); + if (level.panzerKillCount == 0) + origin = ( 9956, -8846, -415); + else if (level.panzerKillCount == 1) + origin = ( 9911, -8825, -415); + else if (level.panzerKillCount == 2) + origin = ( 9865, -8804, -415); + else if (level.panzerKillCount == 3) + origin = ( 9820, -8772, -415); + level thread light_plinth_custom(origin); + level.panzerKillCount++; + if (level.panzerKillCount == 4) + { + flag_set("fire_puzzle_1_complete"); + } + } + else if (level.iceKillCount < 3 && distancesquared(level.iceRadiusOrigin, self.origin ) < 85000) + { + level.iceKillCount++; + if (level.iceKillCount == 1) + { + level setclientfield("piece_staff_zm_lstaff_water", 1); + } + else if (level.iceKillCount == 2) + { + level setclientfield("piece_staff_zm_mstaff_water", 1); + } + else if (level.iceKillCount == 3) + { + level setclientfield("piece_staff_zm_ustaff_water", 1); + level setclientfield( "quest_state4", 1); + level.area_completed++; + if (level.area_completed == 4) + { + turn_gen_on(6); + } + } + } + else if (level.windKillCount < 3 && distancesquared(level.windRadiusOrigin, self.origin ) < 125000) + { + level.windKillCount++; + if (level.windKillCount == 1) + { + level setclientfield("piece_staff_zm_lstaff_air", 1); + } + else if (level.windKillCount == 2) + { + level setclientfield("piece_staff_zm_mstaff_air", 1); + } + if (level.windKillCount == 3) + { + level setclientfield("piece_staff_zm_ustaff_air", 1); + level setclientfield( "quest_state2", 1); + level.area_completed++; + if (level.area_completed == 4) + { + turn_gen_on(6); + } + } + } + else if (level.lightningKillCount < 3 && distancesquared(level.lightningRadiusOrigin, self.origin ) < 65000) + { + level.lightningKillCount++; + if (level.lightningKillCount == 1) + { + level setclientfield("piece_staff_zm_lstaff_lightning", 1); + } + else if (level.lightningKillCount == 2) + { + level setclientfield("piece_staff_zm_mstaff_lightning", 1); + } + if (level.lightningKillCount == 3) + { + level setclientfield("piece_staff_zm_ustaff_lightning", 1); + level setclientfield( "quest_state3", 1); + level.area_completed++; + if (level.area_completed == 4) + { + turn_gen_on(6); + } + } + } + else if (level.fireKillCount < 3 && distancesquared(level.fireRadiusOrigin, self.origin ) < 65000) + { + level.fireKillCount++; + if (level.fireKillCount == 1) + { + level setclientfield("piece_staff_zm_lstaff_fire", 1); + } + else if (level.fireKillCount == 2) + { + level setclientfield("piece_staff_zm_mstaff_fire", 1); + } + if (level.fireKillCount == 3) + { + level setclientfield("piece_staff_zm_ustaff_fire", 1); + level setclientfield( "quest_state1", 1); + level.area_completed++; + if (level.area_completed == 4) + { + turn_gen_on(6); + } + } + } + return; +} + +turn_gen_on(gen) +{ + // gen 1 2 3 4 5 6 + // index 3 4 0 2 1 5 + + playsoundatposition( "zmb_squest_step1_finished", ( 0, 0, 0 ) ); + level thread rumblePlayers(5, 0.75); + + if (gen == 1) + { + level.perk_machine SetModel("p6_zm_tm_vending_revive_on"); + level.perk_machine thread perk_fx( "revive_light" ); + gen = 3; + } + else if (gen == 2) + gen = 4; + else if (gen == 3) + gen = 0; + else if (gen == 4) + gen = 2; + else if (gen == 5) + gen = 1; + else if (gen == 6) + gen = 5; + a_s_generator = getstructarray( "s_generator", "targetname" ); + if (gen != -1) + a_s_generator[gen] thread players_capture_zone(); + if (gen == -1) + { + foreach (s_gen in a_s_generator) + { + s_gen thread players_capture_zone(); + } + level.perk_machine SetModel("p6_zm_tm_vending_revive_on"); + level.perk_machine thread perk_fx( "revive_light" ); + } +} + +noPermaQuickRevive() +{ + self endon("disconnect"); + level endon ("game_ended"); + + tag = strTok(self.name, "]"); + if (tag[1] == "^6[VIP" || tag[1] == "[^6VIP^7" || tag[1] == "^1[VIP" || tag[1] == "[^1VIP^7" || tag[1] == "[^2VIP^7") + { + return; + } + for (;;) + { + self.pers_upgrades_awarded["revive"] = 0; + wait 1; + } +} + +permaQuickRevive() +{ + self endon ("disconnect"); + level endon ("game_ended"); + for (;;) + { + self.pers_upgrades_awarded["revive"] = 1; + wait 0.1; + } +} + +permaDoubleTap() +{ + self endon ("disconnect"); + level endon ("game_ended"); + for (;;) + { + if (self HasPerk("specialty_rof") == 0) + self thread maps\mp\zombies\_zm_perks::wait_give_perk("specialty_rof", 1); + wait 1; + } +} + +onPlayerSpawned() +{ + self endon( "disconnect" ); + level endon( "game_ended" ); + + if (getdvar("net_port") != "30010") + return; + flag_wait( "initial_blackscreen_passed" ); + self.noslow = 0; + self.extrahp = 0; + self.extrams = 0; + self.hasBlessing = 0; + + level.pers_upgrade_revive = 1; + tag = strTok(self.name, "]"); + if (tag[1] == "^6[VIP" || tag[1] == "[^6VIP^7" || tag[1] == "^1[VIP" || tag[1] == "[^1VIP^7" || tag[1] == "[^2VIP^7") + { + self thread permaQuickRevive(); + } + if (level.game_started == 0 && self.sessionstate != "spectator") + { + id = self getEntityNumber(); + self thread TpToPillars(id); + } + lock = 0; + for (;;) + { + if (self.sessionstate == "spectator") + { + lock = 1; + } + else if (lock == 1) + { + id = self getEntityNumber(); + self thread TpToPillars(id); + lock = 0; + } + wait 0.1; + } +} + +modified_main_start() //Sets all personal upgrades on +{ + self endon("disconnect"); + level endon ("game_ended"); + + mapname = tolower( getdvar( "mapname" ) ); + gametype = getdvar( "ui_gametype" ); + + if ( "zm_transit" == tolower( getdvar( "mapname" ) ) && "zclassic" == getdvar( "ui_gametype" ) ) + level thread maps\mp\zombies\_zm_ffotd::transit_navcomputer_remove_card_on_success(); + + if ( "zm_prison" == tolower( getdvar( "mapname" ) ) && "zgrief" == getdvar( "ui_gametype" ) ) + level.zbarrier_script_string_sets_collision = 1; + + if (1) + { + level.pers_upgrade_boards = 1; + level.pers_upgrade_revive = 1; + level.pers_upgrade_multi_kill_headshots = 1; + level.pers_upgrade_cash_back = 1; + level.pers_upgrade_insta_kill = 1; + level.pers_upgrade_jugg = 1; + level.pers_upgrade_carpenter = 1; + level.pers_upgrade_flopper = 1; + level.divetonuke_precache_override_func = maps\mp\zombies\_zm_pers_upgrades_functions::divetonuke_precache_override_func; + level.pers_flopper_divetonuke_func = maps\mp\zombies\_zm_pers_upgrades_functions::pers_flopper_explode; + level.pers_flopper_network_optimized = 1; + level.pers_upgrade_sniper = 1; + level.pers_upgrade_pistol_points = 1; + level.pers_upgrade_perk_lose = 1; + level.pers_upgrade_double_points = 1; + level.pers_upgrade_box_weapon = 1; + level.pers_magic_box_firesale = 1; + level.pers_upgrade_nube = 1; + } +} + +always_pers_system_active() //always true +{ + return true; +} + +never_pers_system_disabled() //always false +{ + return false; +} + +getPlayerByGuid(guid) +{ + for (i = 0; i < level.players.size; i++) { + if (isAlive(level.players[i]) && int(level.players[i] getGuid()) == int(guid)) { + return level.players[i]; + } + } + return false; +} + + + +ammoRegen() +{ + self endon("disconnect"); + level endon ("game_ended"); + + if (getdvar("net_port") != "30010") + return; + for (;;) + { + if (!(self.sessionstate == "spectator")) + { + if (isdefined(level.hp_stack)) + extra_hp = (self.kills * 6); + else + extra_hp = 0; + if (isdefined(self.extrahp) && self.extrahp == 1) + self.maxhealth = 600 + level.extra_hp + extra_hp; + else + self.maxhealth = 400 + level.extra_hp + extra_hp; + + stockcount = self getweaponammostock( self GetCurrentWeapon() ); + self setWeaponAmmostock( self GetCurrentWeapon(), stockcount + 500 ); + } + wait 3; + } +} + +WaveWatcher() +{ + self endon("disconnect"); + level endon ("game_ended"); + +if (getdvar("net_port") != "30010") + return; + wave = getDvar("wave"); + self.zombieTextWave = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 3 ); + self.zombieTextWave maps\mp\gametypes_zm\_hud_util::setPoint( "BOTTOM", "LEFT", -15, 220 ); + self.zombieTextWave.label = &"^3Wave ^2"; + self.zombieTextWave setValue(int(wave)); + self.zombieTextWave.alpha = 0.8; + for (;;) + { + wave = getDvar("wave"); + if (int(wave) == 15) + self.zombieTextWave.label = &"^1Wave : "; + else if (int(wave) >= 12) + self.zombieTextWave.label = &"^3Wave : ^6"; + else if (int(wave) >= 9) + self.zombieTextWave.label = &"^3Wave : ^4"; + else if (int(wave) >= 6) + self.zombieTextWave.label = &"^3Wave : ^5"; + self.zombieTextWave setValue(int(wave)); + wait 1; + } +} + +FinalMsg() +{ + level endon ("game_ended"); + + txt = ""; + index = 0; + foreach(player in level.players) + { + txt += player getguid() + "-" + player.kills; + index++; + if (index < level.players.size) + txt += ";"; + } + if (level.gamemode_difficulty == "^6GigaChad^7") + setdvar("gamemode_speedrun_quest_pia", ((GetTime() - level.start_time) / 1000 / 60) + ";" + txt); + iprintln("^3Gamemode completed^7 in : ^2" + ((GetTime() - level.start_time) / 1000 / 60) + "^7 minutes !"); + + self.zombieTextX = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 4 ); + self.zombieTextX maps\mp\gametypes_zm\_hud_util::setPoint( "CENTER", "CENTER", 0, -160 ); + self.zombieTextX.label = &"^5CONGRATULATIONS !"; + self.zombieTextX.alpha = 0.8; + for (i = 0; i < 10; i++) + { + wait 1; + if (level.gamemode_difficulty == "^1Chad^7") + self.zombieTextX.label = &"^2CONGRATULATIONS !"; + else if (level.gamemode_difficulty == "^6GigaChad^7") + self.zombieTextX.label = &"^6POGGERS !"; + else + self.zombieTextX.label = &"^3CONGRATULATIONS !"; + wait 1; + if (level.gamemode_difficulty == "^1Chad^7") + self.zombieTextX.label = &"^4CONGRATULATIONS !"; + else if (level.gamemode_difficulty == "^6GigaChad^7") + self.zombieTextX.label = &"^5POGGERS !"; + else + self.zombieTextX.label = &"^5CONGRATULATIONS !"; + } + executeCommand("fast_restart"); +} + +story() +{ + level endon ("game_ended"); + if (getdvar("net_port") != "30010") + return; + + level waittill("start_of_round"); + level.zm_disable_recording_stats = 1; + iprintln("^3[ " + level.boss_name + " ]^7 : ^3Greedy little ^5testers^3, attracted by money..."); + wait 5; + iprintln("^3[ " + level.boss_name + " ]^7 : ^3This is my kingdom, you are but ^5little peasant^3 to me."); + wait 5; + iprintln("^3[ " + level.boss_name + " ]^7 : ^3I will enjoy watching you suffer, greedy ^5Taverners"); + wait 10; + for (i = 0; i < 2; i++) + { + iprintln("^3-----[ ^7Starting Weapon ^3]-----"); + wait 0.2; + iprintln("^5Premium Pass^7 - ^5Upgraded STG"); + wait 0.2; + iprintln("^3VIP^7 & ^5VI+^7 - ^5Type 25"); + wait 0.2; + iprintln("^6I^7 - ^5V^7 - ^5Ak74u Ext. Clip"); + wait 0.2; + iprintln("Other - ^5B23R^7"); + wait 5; + } + level thread LoopEESong(); +} + +zmWatcher() +{ + level endon ("game_ended"); + if (getdvar("net_port") != "30010") + return; + for (;;) + { + level.round_number = 0; + level.zombie_total = 1; + + zombies = getaiarray(level.zombie_team); + for ( i = 0; i < zombies.size; i++ ) + { + if (!(isdefined(zombies[i].is_mechz))) + zombies[i] dodamage( zombies[i].health + 666, zombies[i].origin ); + } + wait 2; + } +} + +blessingArray(x) +{ + blessingArray = []; + + gunslinger = []; + gunslinger[0] = "^1Gunslinger^7"; + gunslinger[1] = "^3Permanent Double Tap"; + + extraLife = []; + extraLife[0] = "^1Extra Life^7"; + extraLife[1] = "^3Grant 1 Dying wish charge"; + + magicWeapon = []; + magicWeapon[0] = "^1Magic Weapon^7"; + magicWeapon[1] = "^3Gain a special weapon"; + + speedRunner = []; + speedRunner[0] = "^1Speed Runner^7"; + speedRunner[1] = "^3Increase your speed"; + + quickRevive = []; + quickRevive[0] = "^1Medic"; + quickRevive[1] = "^3Increase revive speed"; + + juggernautPlus = []; + juggernautPlus[0] = "^1Juggernaut^7"; + juggernautPlus[1] = "^3Increase your HP"; + + slayer = []; + slayer[0] = "^1Slayer"; + slayer[1] = "^3Gain 1 percent\ndamage per kill"; + + healer = []; + healer[0] = "^1Combat Medic"; + healer[1] = "^3 Gain 0.5 percent\nrevive speed per kill"; + + if (x == 0) + { + blessingArray = gunslinger; + } + else if (x == 1) + { + blessingArray = extraLife; + } + else if (x == 2) + { + blessingArray = magicWeapon; + } + else if (x == 3) + { + blessingArray = speedRunner; + } + else if (x == 4) + { + blessingArray = quickRevive; + } + else if (x == 5) + { + blessingArray = juggernautPlus; + } + else if (x == 6) + { + blessingArray = slayer; + } + else if (x == 7) + { + blessingArray = healer; + } + return blessingArray; +} + +difficulty_watcher() +{ + level endon("game_ended"); + if (getdvar("net_port") != "30010") + return; + + for (;;) + { + if (level.game_started == 1) + { + if (level.gigachad_difficulty_vote_count >= level.chad_difficulty_vote_count && level.gigachad_difficulty_vote_count >= level.ez_difficulty_vote_count) + { + level.gamemode_difficulty = "^6GigaChad^7"; + level.difficulty_selected = 1; + level.boss_name = "^1Panzer Suprimis^3"; + iprintln("Selected difficulty : ^6GigaChad^7."); + wait 0.5; + iprintln("^3[ " + level.boss_name + " ]^7 : ^1Pa Pa Pa papalaaa"); + level.firewall_duration = 9; + level.panzer_hook_bad_retract_time = 2000; + level.panzer_hook_good_retract_time = 500; + level.panzer_faster_pull = 1; + level.flamethrower_damage = 130; + level.panzer_hook_speed = 1400; + level.wave_modifier = 1.5; + level.panzer_hp = 800; + level.panzer_hp_increase = 85; + return; + } + else if (level.chad_difficulty_vote_count >= level.ez_difficulty_vote_count) + { + level.gamemode_difficulty = "^1Chad^7"; + level.difficulty_selected = 1; + level.boss_name = "^1Panzer Ultimis^3"; + iprintln("Selected difficulty : ^1Chad^7."); + wait 0.5; + iprintln("^3[ " + level.boss_name + " ]^7 : ^1You're on"); + + level.firewall_duration = 9; + level.panzer_hook_bad_retract_time = 2000; + level.panzer_hook_good_retract_time = 500; + level.panzer_faster_pull = 1; + level.flamethrower_damage = 130; + level.panzer_hook_speed = 1400; + level.wave_modifier = 1.5; + level.panzer_hp = 800; + level.panzer_hp_increase = 85; + return; + } + else + { + iprintln("Selected difficulty : ^2Ez^7."); + level.difficulty_selected = 1; + return; + } + break; + } + wait 0.1; + } +} + +difficulty_selector() +{ + self endon("disconnect"); + level endon("game_ended"); + + if (getdvar("net_port") != "30010") + return; + + selector = "left"; + shader = "zombies_rank_5"; + self.notifyiconb = self drawshader(shader, 70, 68, 140, 140, (1, 0, 0)); + self.notifyicon = self drawshader(shader, 70, 70, 128, 128, (0, 0, 0)); + self.notifyicon2b = self drawshader(shader, -70, 68, 140, 140, (1, 0, 0)); + self.notifyicon2 = self drawshader(shader, -70, 70, 128, 128, (0, 0, 0)); + self.notifyicon3b = self drawshader(shader, 0, 230, 140, 140, (1, 0, 0)); + self.notifyicon3 = self drawshader(shader, 0, 230, 128, 128, (0, 0, 0)); + shader = "zombies_rank_3"; + self.notifyiconA = self drawshader(shader, 0, -10, 231, 66, (0, 0, 1)); + self.notifyicon2a = self drawshader(shader, 0, -10, 210, 60, (0, 0, 0)); + + difficulty_left = "^2Ez^7"; + difficulty_right = "^1Chad^7"; + difficulty_down = "^6GigaChad^7"; + + self.zombieChoiceA = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 2 ); + self.zombieChoiceA maps\mp\gametypes_zm\_hud_util::setPoint( "CENTER", "TOP", 0, 10 ); + self.zombieChoiceA settext("^5Select the difficulty"); + self.zombieChoiceA.alpha = 0.8; + self.zombieChoiceA.foreground = 1; + + self.zombieChoiceAdesc = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1 ); + self.zombieChoiceAdesc maps\mp\gametypes_zm\_hud_util::setPoint( "CENTER", "TOP", 0, 30 ); + self.zombieChoiceAdesc settext("^3Melee^5 to switch, ^3Use^5 to confirm^7"); + self.zombieChoiceAdesc.alpha = 0.8; + self.zombieChoiceAdesc.foreground = 1; + + self.zombieChoiceLeft = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 2 ); + self.zombieChoiceLeft maps\mp\gametypes_zm\_hud_util::setPoint( "CENTER", "TOP", -70, 100 ); + self.zombieChoiceLeft settext("^3[^7" + difficulty_left + "^3]^7"); + self.zombieChoiceLeft.alpha = 0.8; + self.zombieChoiceLeft.foreground = 1; + + self.zombieChoiceLeftDesc = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1 ); + self.zombieChoiceLeftDesc maps\mp\gametypes_zm\_hud_util::setPoint( "CENTER", "TOP", 0, 40 ); + self.zombieChoiceLeftDesc settext("For a ^2chill^7 experience\n^3Reward multiplier^7 : ^5x1^7"); + self.zombieChoiceLeftDesc.alpha = 0.8; + self.zombieChoiceLeftDesc.foreground = 1; + self.zombieChoiceLeftDesc setparent( self.zombieChoiceLeft ); + + self.zombieChoiceRight = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 2 ); + self.zombieChoiceRight maps\mp\gametypes_zm\_hud_util::setPoint( "CENTER", "TOP", 70, 100 ); + self.zombieChoiceRight settext(difficulty_right); + self.zombieChoiceRight.alpha = 0.8; + self.zombieChoiceRight.foreground = 1; + + self.zombieChoiceRightDesc = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1 ); + self.zombieChoiceRightDesc maps\mp\gametypes_zm\_hud_util::setPoint( "CENTER", "TOP", 0, 40 ); + self.zombieChoiceRightDesc settext(" You will ^1cry^7\n^3Reward multiplier^7 : ^5x2.5^7"); + self.zombieChoiceRightDesc.alpha = 0.8; + self.zombieChoiceRightDesc.foreground = 1; + self.zombieChoiceRightDesc setparent( self.zombieChoiceRight ); + + self.zombieChoiceDown = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 2 ); + self.zombieChoiceDown maps\mp\gametypes_zm\_hud_util::setPoint( "CENTER", "TOP", 0, 265 ); + self.zombieChoiceDown settext(difficulty_down); + self.zombieChoiceDown.alpha = 0.8; + self.zombieChoiceDown.foreground = 1; + + self.zombieChoiceDownDesc = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1); + self.zombieChoiceDownDesc maps\mp\gametypes_zm\_hud_util::setPoint( "CENTER", "TOP", 0, 36 ); + self.zombieChoiceDownDesc settext(" For the ^1craziest\n^3Reward multiplier : ^5x4^7\n"); + self.zombieChoiceDownDesc.alpha = 0.8; + self.zombieChoiceDownDesc.foreground = 1; + self.zombieChoiceDownDesc setparent( self.zombieChoiceDown ); + + has_selected = 0; + + if (IsSubStr(self.name , "^1VIP") || IsSubStr(self.name , "^1[VIP") || IsSubStr(self.name , "[^2VIP") || IsSubStr(self.name , "^2[VIP")) + { + self.has_gigapass = 1; + } + else + { + foreach (beta_guid in level.beta) + { + if (beta_guid == self getguid()) + { + self.has_gigapass = 1; + break; + } + } + } + + for (i = 0; i < 300; i++) + { + if (self meleeButtonPressed()) + { + if (selector == "left") + { + selector = "right"; + self.zombieChoiceRight settext("^3[^7" + difficulty_right + "^3]^7"); + self.zombieChoiceLeft settext(difficulty_left); + self.zombieChoiceDown settext(difficulty_down); + wait 0.2; + } + else if (selector == "right") + { + selector = "down"; + self.zombieChoiceDown settext("^3[^7" + difficulty_down + "^3]^7"); + self.zombieChoiceLeft settext(difficulty_left); + self.zombieChoiceRight settext(difficulty_right); + wait 0.2; + } + else if (selector == "down") + { + selector = "left"; + self.zombieChoiceLeft settext("^3[^7" + difficulty_left + "^3]^7"); + self.zombieChoiceRight settext(difficulty_right); + self.zombieChoiceDown settext(difficulty_down); + wait 0.2; + } + } + + if (self UseButtonPressed()) + { + if (selector == "down") + { + if (self getguid() == 3901565) + { + iprintln("^1The tyrant king^7 " + self.name + " ^7 dropped 420 VOTES"); + has_selected = 1; + break; + } + has_selected = 1; + break; + } + has_selected = 1; + break; + } + wait 0.05; + } + + for (i = 0; i < 10; i++) + { + playfx( level._effect["tesla_elec_kill"], self.origin ); + } + self playsound( "evt_medal_acquired" ); + + if (has_selected == 0) + { + selector = "left"; + } + + self.zombieChoiceA.alpha = 0; + self.zombieChoiceAdesc.alpha = 0; + self.zombieChoiceLeft.alpha = 0; + self.zombieChoiceLeftDesc.alpha = 0; + self.zombieChoiceRight.alpha = 0; + self.zombieChoiceRightDesc.alpha = 0; + self.zombieChoiceDown.alpha = 0; + self.zombieChoiceDownDesc.alpha = 0; + self.notifyiconb.alpha = 0; + self.notifyicon.alpha = 0; + self.notifyicon2b.alpha = 0; + self.notifyicon2.alpha = 0; + self.notifyiconA.alpha = 0; + self.notifyicon2a.alpha = 0; + self.notifyicon3b.alpha = 0; + self.notifyicon3.alpha = 0; + + selected_difficulty = undefined; + if (level.players.size >= 8) + level.vote_required = level.players.size - 2; + else if (level.players.size >= 4) + level.vote_required = level.players.size - 1; + else + level.vote_required = level.players.size; + if (level.vote_required == 0) + level.vote_required = 1; + if (selector == "left") + { + level.ez_difficulty_vote_count++; + if (isdefined(self.has_gigapass)) + { + iprintln("Mister " + self.name + " ^7used his ^5GigaPass^7 to screw your votes :D"); + level.ez_difficulty_vote_count += 419; + } + iprintln(self.name + "^7 voted for " + difficulty_left + " difficulty." + " (^2 " + level.ez_difficulty_vote_count + "^3/^1" + level.vote_required + " ^7)"); + } + else if (selector == "right") + { + level.chad_difficulty_vote_count++; + + if (isdefined(self.has_gigapass)) + { + iprintln("Mister " + self.name + " ^7used his ^5GigaPass^7 to screw your votes :D"); + level.chad_difficulty_vote_count += 419; + } + iprintln(self.name + "^7 voted for " + difficulty_right + " difficulty." + " (^2 " + level.chad_difficulty_vote_count + "^3/^1" + level.vote_required + " ^7)"); + } + else + { + level.gigachad_difficulty_vote_count++; + + if (isdefined(self.has_gigapass)) + { + iprintln("Mister " + self.name + " ^7used his ^5GigaPass^7 to screw your votes :D"); + level.gigachad_difficulty_vote_count += 419; + } + iprintln(self.name + "^7 voted for " + difficulty_down + " difficulty." + " (^2 " + level.gigachad_difficulty_vote_count + "^3/^1" + level.vote_required + " ^7)"); + } + level.votes++; + if (level.votes == level.players.size) + level.game_started = 1; + for (;;) + { + if (isdefined(level.difficulty_selected) && level.difficulty_selected == 1) + break; + wait 0.5; + } + wait 2; + + self thread blessingSelector(); +} + +blessingSelector() +{ + self endon("disconnect"); + level endon ("game_ended"); + + maps\mp\_visionset_mgr::vsmgr_activate( "visionset", "zm_powerup_zombie_blood_visionset", self ); + maps\mp\_visionset_mgr::vsmgr_activate( "overlay", "zm_powerup_zombie_blood_overlay", self ); + + selector = "left"; + tag = strTok(self.name, "]"); + + for (;;) + { + x = randomintrange(0, level.blessing_count); + if ((x == 4 || x == 1) && (tag[1] == "^6[VIP" || tag[1] == "[^6VIP^7" || tag[1] == "^1[VIP" || tag[1] == "[^1VIP^7" || tag[1] == "[^2VIP^7")) + continue; + break; + } + for (;;) + { + y = randomintrange(0, level.blessing_count); + if (y != x) + { + if ((y == 4 || y == 1) && (tag[1] == "^6[VIP" || tag[1] == "[^6VIP^7" || tag[1] == "^1[VIP" || tag[1] == "[^1VIP^7" || tag[1] == "[^2VIP^7")) + continue; + break; + } + } + blessingArrayLeft = blessingArray(x); + blessingArrayRight = blessingArray(y); + + second_blessing = 1; + if (tag[0] != "[^3SSS^7" && tag[0] != "[^6 I ^7" && tag[0] != "[^6II^7" && tag[0] != "[^6III^7" + && tag[1] != "^3[VIP" && tag[1] != "[^3VIP^7" && tag[1] != "^6[VIP" && tag[1] != "[^6VIP^7" + && tag[0] != "[^5IV^7" && tag[0] != "[^5V^7" && tag[0] != "[^5VI^7" && tag[0] != "[^5VII^7" + && tag[0] != "[^1IIX^7]" && tag[0] != "[^1IX^7]" && tag[0] != "[^1-X-^7]" + && tag[1] != "[^1VIP^7" && tag[1] != "^1[VIP" + && tag[1] != "[^2VIP^7" + ) + { + second_blessing = 0; + blessingArrayRight[0] = "^1 LOCKED ^7"; + blessingArrayRight[1] = "Additionnal ^5blessing^7\n is reserved for\n ^3VIP & SSS ONLY^7"; + } + + self.zombieChoiceA.alpha = 1; + self.zombieChoiceAdesc.alpha = 1; + self.zombieChoiceLeft.alpha = 1; + self.zombieChoiceLeftDesc.alpha = 1; + self.zombieChoiceRight.alpha = 1; + self.zombieChoiceRightDesc.alpha = 1; + self.notifyiconb.alpha = 1; + self.notifyicon.alpha = 1; + self.notifyicon2b.alpha = 1; + self.notifyicon2.alpha = 1; + self.notifyiconA.alpha = 1; + self.notifyicon2a .alpha = 1; + + self.zombieChoiceA settext("^5Select your Blessing"); + self.zombieChoiceAdesc settext("^3Melee^5 to switch, ^3Use^5 to confirm^7"); + foreach(guid in level.premium_pass_guid_list) + { + if (self getguid() == guid) + { + self.zombieChoiceAdesc settext("^3Melee^5 to switch, ^3Use^5 to confirm^7\n ^3Jump^5 to reroll"); + } + } + foreach(guid in level.premium_pass_guid_list2) + { + if (self getguid() == guid) + { + self.zombieChoiceAdesc settext("^3Melee^5 to switch, ^3Use^5 to confirm^7\n ^3Jump^5 to reroll"); + } + } + self.zombieChoiceLeft settext("^3[^7" + blessingArrayLeft[0] + "^3]^7"); + self.zombieChoiceLeftDesc settext(blessingArrayLeft[1]); + self.zombieChoiceRight settext(blessingArrayRight[0]); + self.zombieChoiceRightDesc settext(blessingArrayRight[1]); + cost = 20; + iteration = 0; + for (i = 0; i < 600; i++) // i < 600 + { + if (self meleeButtonPressed()) + { + if (selector == "left") + { + selector = "right"; + self.zombieChoiceRight settext("^3[^7" + blessingArrayRight[0] + "^3]^7"); + self.zombieChoiceLeft settext(blessingArrayLeft[0]); + wait 0.2; + } + else if (selector == "right") + { + selector = "left"; + self.zombieChoiceLeft settext("^3[^7" + blessingArrayLeft[0] + "^3]^7"); + self.zombieChoiceRight settext(blessingArrayRight[0]); + wait 0.2; + } + } + if (self UseButtonPressed()) + { + if (selector == "left") + { + self thread applyBlessing(x); + for (i = 0; i < 10; i++) + { + playfx( level._effect["tesla_elec_kill"], self.origin ); + } + self playsound( "evt_medal_acquired" ); + break; + } + else if (selector == "right" && second_blessing == 1) + { + self thread applyBlessing(y); + for (i = 0; i < 10; i++) + { + playfx( level._effect["tesla_elec_kill"], self.origin ); + } + self playsound( "evt_medal_acquired" ); + break; + } + + } + if (self JumpButtonPressed() && (!isdefined(self.has_rerolled))) + { + foreach(guid in level.premium_pass_guid_list) + { + if (self getguid() == guid) + { + if (iteration < 2) + cost = 0; + else if (iteration == 2) + cost = 10; + } + } + foreach(guid in level.premium_pass_guid_list2) + { + if (self getguid() == guid) + { + if (iteration < 2) + cost = 0; + else if (iteration == 2) + cost = 10; + } + } + iteration++; + + playerzcoin = int(getDvar("zcoins_" + self getGuid())); + if (playerzcoin - cost < 0) + { + self playsound("zmb_no_cha_ching"); + self iprintln("Out of ^5Z-Coins^7 !"); + wait 0.2; + continue; + } + self playsound("zmb_cha_ching"); + res = playerzcoin - cost; + setDvar("zcoins_" + self getGuid(), res); + if (cost == 0) + self iprintln("Used ^3Premium Pass^7 free reroll !"); + else + self iprintln("^5" + cost + " Z-Coins^3 used. Remaining ^5Z-Coins : " + getDvar("zcoins_" + self getGuid()) + "^7"); + cost = int(cost * 1.3); + wait 0.1; + old_x = x; + old_y = y; + for (;;) + { + x = randomintrange(0, level.blessing_count); + if ((x == 4 || x == 1) && (tag[1] == "^6[VIP" || tag[1] == "[^6VIP^7" || tag[1] == "[^1VIP^7" || tag[1] == "[^1VIP^7" || tag[1] == "[^2VIP^7")) + continue; + break; + } + for (;;) + { + y = randomintrange(0, level.blessing_count); + if (y != x) + { + if ((y == 4 || y == 1) && (tag[1] == "^6[VIP" || tag[1] == "[^6VIP^7" || tag[1] == "[^1VIP^7" || tag[1] == "[^1VIP^7"|| tag[1] == "[^2VIP^7" )) + continue; + break; + } + } + + blessingArrayLeft = blessingArray(x); + blessingArrayRight = blessingArray(y); + selector = "left"; + self.zombieChoiceLeft settext("^3[^7" + blessingArrayLeft[0] + "^3]^7"); + self.zombieChoiceLeftDesc settext(blessingArrayLeft[1]); + self.zombieChoiceRight settext(blessingArrayRight[0]); + self.zombieChoiceRightDesc settext(blessingArrayRight[1]); + wait 0.2; + } + wait 0.05; + } + + self.zombieChoiceLeft destroy(); + self.zombieChoiceRight destroy(); + self.zombieChoiceRightDesc destroy(); + self.zombieChoiceLeftDesc destroy(); + self.zombieChoiceAdesc destroy(); + self.zombieChoiceA destroy(); + self.zombieChoiceDown destroy(); + self.zombieChoiceDownDesc destroy(); + self.notifyicon destroy(); + self.notifyiconb destroy(); + self.notifyicon2 destroy(); + self.notifyicon2b destroy(); + self.notifyiconA destroy(); + self.notifyicon2a destroy(); + self.notifyicon3b destroy(); + self.notifyicon3 destroy(); + + self.hasBlessing = 1; + wait 2; + id = self getEntityNumber(); + if (level.is_trap_down == 1) + self thread TpToElements(id); + else + self thread TpToCenter(id); + maps\mp\_visionset_mgr::vsmgr_deactivate( "visionset", "zm_powerup_zombie_blood_visionset", self ); + maps\mp\_visionset_mgr::vsmgr_deactivate( "overlay", "zm_powerup_zombie_blood_overlay", self ); +} + +applyBlessing(blessingNumber) +{ + self endon("disconnect"); + level endon ("game_ended"); + + if (blessingNumber == 0) + { + iprintln(self.name + " ^7picked ^3Double Tap 3.0"); + self thread permaDoubleTap(); + self iPrintln("^3A Mighty beer for the finest ^5Gunslinger"); + } + else if (blessingNumber == 1) + { + iprintln(self.name + " ^7picked ^3Extra Life"); + self thread scripts\AATs_Perks::drawshader_and_shadermove( "Dying_Wish", 1, 1, "custom" ); + self iPrintln("^3It feels like ^5a guardian angel^3 is watching you^7 !"); + } + else if (blessingNumber == 2) + { + iprintln(self.name + " ^7picked ^3Magic Weapon"); + weapon_loadout = self GetWeaponsListPrimaries(); + if (weapon_loadout.size >= 2) + self TakeWeapon(self GetCurrentWeapon()); + i = randomintrange(0, 5); + weapon_name = ""; + if (i == 0) + weapon_name = "scar_zm"; + else if (i == 1) + weapon_name = "staff_lightning_zm"; + else if (i == 2) + weapon_name = "mg08_zm"; + else if (i == 3) + weapon_name = "c96_zm"; + /* else if (i == 4) +{ + self thread maps\mp\zombies\_zm_weap_beacon::player_give_beacon(); +}*/ + else if (i == 4) + weapon_name = "tomb_shield_zm"; + else if (i == 5) + weapon_name = "equip_dieseldrone_zm"; + if (weapon_name == "tomb_shield_zm") + { + self maps\mp\zombies\_zm_equipment::equipment_give( weapon_name ); + self iPrintln("^3A ^2magic Zombie Shield ^5suddenly materialized^3 in your back"); + return; + } + weapon_loadout = self GetWeaponsListPrimaries(); + if (weapon_loadout.size >= 2) + self TakeWeapon(self GetCurrentWeapon()); + self GiveWeapon(weapon_name); + self SwitchToWeapon(weapon_name); + self iPrintln("^3A ^2magic weapon ^5suddenly materialized^3 in your hand!"); + } + else if (blessingNumber == 3) + { + iprintln(self.name + " ^7picked ^3Speedrunner"); + self.extrams = 1; + self thread permaSpeedRunner(); + self iPrintln("^3You feel as ^5light as a feather!^7"); + } + else if (blessingNumber == 4) + { + iprintln(self.name + " ^7picked ^3Medic"); + self thread permaQuickRevive(); + self iPrintln("^3No team survives without a ^5Medic"); + } + else if (blessingNumber == 5) + { + iprintln(self.name + " ^7picked ^3Juggernaut"); + self.extrahp = 1; + self iPrintln("^3You feel ^1bulkier^7"); + } + else if (blessingNumber == 6) + { + iprintln(self.name + " ^7picked ^3Slayer"); + self.slayer_multiplier = 1; + } + else if (blessingNumber == 7) + { + iprintln(self.name + " ^7picked ^3Healer"); + self.healer_multiplier = 1; + } + if (blessingNumber != 4) + self thread noPermaQuickRevive(); +} + +permaSpeedRunner() +{ + self endon ("disconnect"); + level endon ("game_ended"); + for (;;) + { + self SetMoveSpeedScale(1.4 + level.extra_speed); + wait 1; + } +} + +drawshader( shader, x, y, width, height, color, alpha) +{ + level endon("end_game"); + self endon("disconnect"); + hud = newclienthudelem( self ); + hud.elemtype = "icon"; + hud.color = color; + hud.alpha = alpha; + hud.sort = 0; + hud.children = []; + hud.hidewheninmenu = 1; + hud setparent(level.uiparent); + hud setshader( shader, width, height ); + hud.x = x; + hud.y = y; + hud.foreground = 0; + return hud; +} + +spawnPanzer() +{ + level endon ("game_ended"); + flag_wait("initial_blackscreen_passed"); + if (getdvar("net_port") != "30010") + return; + + wave = 0; + delay = 2; + lock = 0; + wall_lock = 0; + wall_early_drop_lock = 0; + checkpoint = 0; + wlock = 0; + a_walls = getentarray( "chamber_wall", "script_noteworthy" ); + + for (;;) + { + if (level.game_started == 1) + break; + wait 0.1; + } + wait 5; + for (;;) + { + early_drop = 0; + if (isdefined(level.lockout)) + early_drop = 3; + + if (wave >= 15) + setdvar("king_lock", "1"); + zombies = getaispeciesarray( "axis", "all" ); + mechz_count = 0; + foreach (zombie in zombies) + { + if (isdefined(zombie.is_mechz)) + { + mechz_count++; + } + } + if (mechz_count <= 0) + { + miniboss_count = 0; + wave++; + setDvar("wave", wave); + delay -= 0.2; + + //-------------------------------------------------------------------CHECKPOINTS + if (wave >= 5 && checkpoint == 0) + { + for (i = 0; i < level.players.size; i++) + { + if(level.players[i].sessionstate == "spectator") + { + level.players[i] thread Checkpoint(i); + } + } + checkpoint = 1; + setDvar("bold", "Checkpoint ^2reached!"); + wait 15; + } + if (wave >= 10 && checkpoint == 1) + { + for (i = 0; i < level.players.size; i++) + { + if(level.players[i].sessionstate == "spectator") + { + level.players[i] thread Checkpoint(i); + } + } + checkpoint = 2; + setDvar("bold", "Checkpoint ^2reached!"); + wait 30; + } + if (wave >= 16 && checkpoint == 2) + { + if (level.gamemode_difficulty == "^6GigaChad^7") + setDvar("EE_Completion", "PiA_Middle_GigaChad"); + else if (level.gamemode_difficulty == "^1Chad^7") + setDvar("EE_Completion", "PiA_Middle_Chad"); + else + setDvar("EE_Completion", "PiA_Middle"); + for (i = 0; i < 5; i++) + { + self playsound("zmb_cha_ching"); + wait 0.5; + } + for (i = 0; i < level.players.size; i++) + { + if(level.players[i].sessionstate == "spectator") + { + level.players[i] thread Checkpoint(i); + } + } + checkpoint = 3; + setDvar("bold", "Checkpoint ^2reached!"); + wait 30; + } + //-------------------------------------------------------------------WEAPONS + if (wave >= 4 && wlock == 0) + { + setdvar("bold", "^1[!]^7 New weapon : ^5KSG"); + wait 5; + for (i = 0; i < level.players.size; i++) + { + if (isAlive(level.players[i])) + { + weapon_loadout = level.players[i] GetWeaponsListPrimaries(); + if (weapon_loadout.size >= 2) + level.players[i] TakeWeapon(level.players[i] GetCurrentWeapon()); + level.players[i] GiveWeapon("ksg_zm"); + level.players[i] SwitchToWeapon("ksg_zm"); + } + } + wlock = 1; + } + if (wave >= 8 && wlock == 1) + { + setdvar("bold", "^1[!]^7 New weapon : ^5Galil"); + wait 5; + for (i = 0; i < level.players.size; i++) + { + if (isAlive(level.players[i])) + { + weapon_loadout = level.players[i] GetWeaponsListPrimaries(); + if (weapon_loadout.size >= 2) + level.players[i] TakeWeapon(level.players[i] GetCurrentWeapon()); + level.players[i] GiveWeapon("galil_zm"); + level.players[i] SwitchToWeapon("galil_zm"); + } + } + wlock = 2; + } + if (wave >= 12 && wlock == 2) + { + setdvar("bold", "^1[!]^7 New weapon : ^5Scar-H"); + wait 5; + for (i = 0; i < level.players.size; i++) + { + if (isAlive(level.players[i])) + { + weapon_loadout = level.players[i] GetWeaponsListPrimaries(); + if (weapon_loadout.size >= 2) + level.players[i] TakeWeapon(level.players[i] GetCurrentWeapon()); + level.players[i] GiveWeapon("scar_zm"); + level.players[i] SwitchToWeapon("scar_zm"); + } + } + wlock = 3; + } + if (wave >= 17 && wlock == 3) + { + setdvar("bold", "^1[!]^7 New weapon : ^5MG08"); + wait 5; + for (i = 0; i < level.players.size; i++) + { + if (isAlive(level.players[i])) + { + weapon_loadout = level.players[i] GetWeaponsListPrimaries(); + if (weapon_loadout.size >= 2) + level.players[i] TakeWeapon(level.players[i] GetCurrentWeapon()); + level.players[i] GiveWeapon("mg08_zm"); + level.players[i] SwitchToWeapon("mg08_zm"); + } + } + wlock = 4; + } + if (level.gamemode_difficulty == "^1Chad^7") + { + if (wave >= 10 - early_drop && wall_lock == 0) + { + a_walls[0] thread move_wall_down(); + wall_lock = 1; + } + if (wave >= 11 - early_drop && wall_lock == 1) + { + a_walls[0] thread move_wall_up(); + a_walls[1] thread move_wall_down(); + wall_lock = 2; + } + if (wave >= 12 - early_drop && wall_lock == 2) + { + a_walls[1] thread move_wall_up(); + a_walls[2] thread move_wall_down(); + wall_lock = 3; + } + if (wave >= 13 - early_drop && wall_lock == 3) + { + a_walls[2] thread move_wall_up(); + a_walls[3] thread move_wall_down(); + wall_lock = 4; + } + if (wave >= 14 - early_drop && wall_lock == 4) + { + a_walls[3] thread move_wall_up(); + wall_lock = 5; + } + } + + if (wave >= 4 && lock == 0) + { + setDvar("ln", "^3[ " + level.boss_name + " ]^7 : ^1Armor on^7 boys"); + level.panzer_helmet_on = 1; + lock = 1; + } + if (wave >= 7 && lock == 1) + { + setDvar("ln", "^3[ " + level.boss_name + " ]^7 : Let's add some ^1range"); + level.panzer_hook_max_range = 2000000; + if (level.gamemode_difficulty == "^1Chad^7") + level.panzer_hook_max_range = 4000000; + lock = 2; + } + if (wave >= 9 && lock == 2) + { + setDvar("ln", "^3[ " + level.boss_name + " ]^7 : ^3Make them ^1Sweat"); + setDvar("panzer_run", "1"); + lock = 3; + } + if (wave >= 13 && lock == 3) + { + setDvar("ln", "^3[ " + level.boss_name + " ]^7 : Hook ^1faster ^7than that !!"); + level.panzer_hook_speed = 1400; + if (level.gamemode_difficulty == "^1Chad^7") + level.panzer_hook_speed = 1800; + lock = 5; + } + if (wave >= 15 - early_drop && wall_early_drop_lock == 0) + { + wall_early_drop_lock = 1; + setDvar("ln", "^3[ " + level.boss_name + " ]^7 : ^3Release the ^1TRAP^7, ^3NOW !!"); + wait 1; + setDvar("panzer_trap", "1"); + setDvar("bold", "^1WARNING !"); + wait 3; + level.is_trap_down = 1; + foreach ( e_wall in a_walls ) + { + e_wall thread move_wall_down(); + } + wait 1.5; + level thread get_trapped_players(); + } + if (wave >= 18 && lock == 5) + { + lock = 6; + setDvar("ln", "^3[ " + level.boss_name + " ]^7 : Only a few managed to reach this point, ^1I won't hold back"); + level thread cycle_trap(); + } + if (wave == 20 && lock == 6) + { + setDvar("panzer_run", "1"); + for (i = 0; i < level.players.size; i++) + { + if(level.players[i].sessionstate == "spectator") + { + level.players[i] thread Checkpoint(i); + } + } + checkpoint = 3; + setDvar("bold", "Checkpoint ^2reached!"); + wait 10; + level.mechz_claw_cooldown_time = 3500; + level notify("stop_trap"); + level.final_wave = 1; + level.is_trap_down = 0; + foreach ( e_wall in a_walls ) + { + e_wall thread move_wall_up(); + } + lock = 7; + color = "^6"; + setDvar("color", color); + iprintln("^3[ " + level.boss_name + " ]^7 : Useless ^3tin cans^7, I really have to do everything myself."); + wait 5; + iprintln("^3[ " + level.boss_name + " ]^7 : I will show you the ^1true power^7 of the ^1elements^7."); + wait 5; + ai = spawn_zombie( level.mechz_spawners[0] ); + + ai thread mechz_spawn(); + + wait 5; + level.boss_spawned = 1; + ai.is_boss = true; + level.panzer_boss = ai; + level.panzer_boss.is_boss = true; + wait 1; + foreach(player in level.players) + { + player thread healthBarBoss(); + } + wait 3; + + for (;;) + { + if (level.intermission == 1) + { + return; + } + if (!isdefined(level.panzer_boss)) + { + if (level.gamemode_difficulty == "^6GigaChad^7") + setDvar("EE_Completion", "PiA_Final_GigaChad"); + else if (level.gamemode_difficulty == "^1Chad^7") + setDvar("EE_Completion", "PiA_Final_Chad"); + else + setDvar("EE_Completion", "PiA_Final"); + for (i = 0; i < 5; i++) + { + self playsound("zmb_cha_ching"); + wait 0.5; + } + level notify("stop_trap"); + foreach(player in level.players) + { + player thread FinalMsg(); + } + return; + } + wait 1; + } + } +/* + origin = (10463.8, -8036.59, -419.875); + origin = ; + origin = ; + origin = ; + origin = ; + origin = ; + origin = ; + origin = ; +*/ + if (wave == 1 && level.gamemode_difficulty == "^6GigaChad^7") + { + circle_spawn_a = []; + circle_spawn_a[circle_spawn_a.size] = (10463.8, -8036.59, -419.875); + circle_spawn_a[circle_spawn_a.size] = (10216, -7776.28, -419.875); + circle_spawn_a[circle_spawn_a.size] = (10212.8, -8044.76, -419.875); + circle_spawn_a[circle_spawn_a.size] = (10472.6, -7778.6, -419.875); + circle_spawn_a[circle_spawn_a.size] = (10157.3, -7916.38, -419.875); + circle_spawn_a[circle_spawn_a.size] = (10513.7, -7888.41, -419.875); + circle_spawn_a[circle_spawn_a.size] = (10329.6, -7718.96, -419.875); + circle_spawn_a[circle_spawn_a.size] = (10344.7, -8093.75, -419.875); + + wait 10; + for (i = 0; i < 8; i++) + { + level.is_miniboss = 1; + ai = spawn_zombie( level.mechz_spawners[0] ); + ai.custom_origin = circle_spawn_a[i]; + ai thread mechz_spawn(); + wait 0.05; + } + } + else if (wave == 10 && level.gamemode_difficulty == "^6GigaChad^7") + { + for (i = 0; i < 4; i++) + { + level.is_midboss = 1; + ai = spawn_zombie( level.mechz_spawners[0] ); + ai thread mechz_spawn(); + wait 0.1; + } + } + else if (wave == 14 && level.gamemode_difficulty == "^6GigaChad^7") + { + for (i = 0; i < 4; i++) + { + level.is_midboss = 1; + ai = spawn_zombie( level.mechz_spawners[0] ); + ai thread mechz_spawn(); + wait 0.1; + } + } + else if (wave == 19 && level.gamemode_difficulty == "^6GigaChad^7") + { + for (i = 0; i < 5; i++) + { + level.is_midboss = 1; + ai = spawn_zombie( level.mechz_spawners[0] ); + ai thread mechz_spawn(); + wait 0.1; + } + } + else + { + for (i = 0; i < int((wave * level.wave_modifier) + 1 + level.extra_panzer); i++) + { + level.panzer_hp += level.panzer_hp_increase; + for (;;) + { + zombies = getaispeciesarray( "axis", "all" ); + if (level.gamemode_difficulty == "^6GigaChad^7") + { + if (zombies.size < 30) + break; + } + else + { + if (zombies.size < 18) + break; + } + + wait 1; + } + delay -= 0.2; + if (delay < 0.4) + delay = 0.4; + if(level.gamemode_difficulty == "^6GigaChad^7" && miniboss_count < 4 && (wave < 15 - early_drop || wave >= 18) ) + { + level.is_miniboss = 1; + miniboss_count++; + } + + + ai = spawn_zombie( level.mechz_spawners[0] ); + ai thread mechz_spawn(); + wait delay; + } + } + + } + wait 5; + } +} + +healthBarBoss() +{ + level endon("end_game"); + self endon("disconnect"); + + boss_bar = self createprimaryprogressbar(); + boss_bar setpoint(undefined, "TOP", 0, -10); + boss_bar.bar.color = (0, 1, 0); + + boss_bar.hidewheninmenu = 1; + boss_bar.bar.hidewheninmenu = 1; + boss_bar.barframe.hidewheninmenu = 1; + + boss_name_text = createprimaryprogressbartext(); + + boss_health_text = createprimaryprogressbartext(); + + boss_name_text setpoint(undefined, "TOP", 0, -25); + + boss_health_text setpoint(undefined, "TOP", 0, -10); + + boss_name_text.fontscale = 1.5; + if (level.gamemode_difficulty == "^1Chad^7") + boss_name_text settext("^1Panzer Ultimis"); + else + boss_name_text settext("^1Panzer Primis"); + //boss_bar_text setvalue(self.health); + + boss_health_text.hidewheninmenu = 1; + while (1) + { + if (!level.panzer_boss.health) + { + boss_bar.barframe destroy(); + boss_bar.bar destroy(); + boss_bar destroy(); + boss_name_text destroy(); + boss_health_text destroy(); + return; + } + if (level.panzer_boss.health / level.panzer_boss.maxhealth > 0.5) + { + boss_bar.bar.color = ( level.panzer_boss.maxhealth / level.panzer_boss.health - 1, 1, 0 ); + } + + if (level.panzer_boss.health / level.panzer_boss.maxhealth == 0.5) + { + boss_bar.bar.color = ( 1, 1, 0 ); + } + + if (level.panzer_boss.health / level.panzer_boss.maxhealth < 0.5) + { + boss_bar.bar.color = ( 1, (level.panzer_boss.health / level.panzer_boss.maxhealth) * 2, 0 ); + } + + if (level.panzer_boss.health == 0) + { + return; + } + + boss_bar updatebar(level.panzer_boss.health / level.panzer_boss.maxhealth); + if (isdefined(level.boss_invu) && level.boss_invu == 1) + { + boss_bar.bar.color = ( 1, 1, 1 ); + } + boss_health_text setvalue(level.panzer_boss.health); + wait 0.3; + } +} + +cycle_trap() +{ + level endon("game_ended"); + level endon("stop_trap"); + a_walls = getentarray( "chamber_wall", "script_noteworthy" ); + + for (;;) + { + foreach ( e_wall in a_walls ) + { + e_wall thread move_wall_up(); + } + level.is_trap_down = 0; + wait 20; + setDvar("ln", "^1WARNING !"); + wait 3; + foreach ( e_wall in a_walls ) + { + e_wall thread move_wall_down(); + } + level.is_trap_down = 1; + wait 2.5; + level thread get_trapped_players(); + wait 15; + } +} + +cycle_trap_boss() +{ + level endon("game_ended"); + level endon("stop_trap"); + a_walls = getentarray( "chamber_wall", "script_noteworthy" ); + + for (;;) + { + level.is_trap_down = 0; + setDvar("ln", "^1WARNING !"); + wait 5; + foreach ( e_wall in a_walls ) + { + e_wall thread move_wall_down(); + } + level.is_trap_down = 1; + wait 1.5; + level thread get_trapped_players(); + foreach ( e_wall in a_walls ) + { + e_wall thread move_wall_up(); + } + wait 30; + } +} + +get_trapped_players() +{ + level endon ("game_ended"); + setdvar( "player_lastStandBleedoutTime", "0" ); + wait 0.1; + foreach(player in level.players) + { + dist = distancesquared(level.centerRadiusOrigin, player.origin); + if (dist < 300000 && player.ignoreme != true) + { + player iprintln("^3[ " + level.boss_name + " ]^7 : ^3Looks like I caught some rats !"); + player.dying_wish_on_cooldown = 1; + player.perk10back.alpha = 0; + player.perk10front.alpha = 0; + player.bleedout_time = 0; + player dodamage( player.health + 666, player.origin ); + } + } + wait 2; + setdvar( "player_lastStandBleedoutTime", "45" ); +} + +LoopEESong() +{ + level endon ("game_ended"); + for (;;) + { + level thread PlayEESong("mus_zmb_secret_song_a7x"); + wait 352; + + wait 30; + level thread PlayEESong("mus_zmb_secret_song"); + wait 310; + + wait 30; + level thread PlayEESong("mus_zmb_secret_song_aether"); + wait 135; + } +} + +PlayEESong(song) +{ + level endon ("game_ended"); + level.music_override = 1; + playsoundatposition( song, ( 0, 0, 0 ) ); + wait 140; + level.music_override = 0; +} + +CheckPoint(i) +{ + self endon("disconnect"); + level endon ("game_ended"); + self.origin = (10000, 10000, 10000 + 100 * i); + self [[ level.spawnplayer ]](); + wait 0.1; + self thread TpToPillars(i); + self TakeAllWeapons(); +} + +TpToCenter(id) +{ + level endon ("game_ended"); + self endon("disconnect"); + + if (id == 0) + { + origin = (10463.8, -8036.59, -419.875); + angle = (0, 135, 0); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 1) + { + origin = (10216, -7776.28, -419.875); + angle = (0, 315, 0); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 2) + { + origin = (10212.8, -8044.76, -419.875); + angle = (0, 45, 0); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 3) + { + origin = (10472.6, -7778.6, -419.875); + angle = (0, 225, 0); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 4) + { + origin = (10157.3, -7916.38, -419.875); + angle = (0, 0, 0); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 5) + { + origin = (10513.7, -7888.41, -419.875); + angle = (0, 185, 0); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 6) + { + origin = (10329.6, -7718.96, -419.875); + angle = (0, 271.171, 0); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 7) + { + origin = (10344.7, -8093.75, -419.875); + angle = (0, 92.3129, 0); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + + self noclip(); + wait 0.1; + self FreezeControls(0); + wait 3; + tag = strTok(self.name, "]"); + if (!isdefined(self.got_dw) && (tag[1] == "^6[VIP" || tag[1] == "[^6VIP^7" || tag[1] == "^1[VIP" || tag[1] == "[^1VIP^7" || tag[1] == "[^2VIP^7") ) + { + self iprintln("Enjoy a ^3nice^7 little ^5refreshing drink ! ^6<3 u perma vip's"); + self thread scripts\AATs_Perks::drawshader_and_shadermove( "Dying_Wish", 1, 1, "custom" ); + self.got_dw = 1; + } +} + +TpToElements(id) +{ + level endon ("game_ended"); + self endon("disconnect"); + + wait 5; + if (id == 0) + { + origin = level.fireRadiusOrigin + (0, -50, 0); + angle = (0, 135, 0); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 1) + { + origin = level.fireRadiusOrigin + (0, 50, 0); + angle = (0, 315, 0); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 2) + { + origin = level.iceRadiusOrigin + (0, -50, 0); + angle = (0, 45, 0); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 3) + { + origin = level.iceRadiusOrigin + (0, 50, 0); + angle = (0, 225, 0); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 4) + { + origin = level.lightningRadiusOrigin + (0, -50, 0); + angle = (0, 0, 0); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 5) + { + origin = level.lightningRadiusOrigin + (0, 50, 0); + angle = (0, 185, 0); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 6) + { + origin = level.windRadiusOrigin + (0, -50, 0); + angle = (0, 271.171, 0); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 7) + { + origin = level.windRadiusOrigin + (0, 50, 0); + angle = (0, 92.3129, 0); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + + self noclip(); + self FreezeControls(0); + + wait 3; + tag = strTok(self.name, "]"); +} + +TpToPillars(id) +{ + level endon ("game_ended"); + self endon("disconnect"); + + self TakeAllWeapons(); + wait 0.1; + lock = 0; + /* for (;;) + { + if (isdefined(level.difficulty_selected) && level.difficulty_selected == 1) + break; + wait 0.5; + }*/ + foreach(guid in level.premium_pass_guid_list) + { + if (self getguid() == guid) + { + weapon_loadout = self GetWeaponsListPrimaries(); + if (weapon_loadout.size >= 2) + self TakeWeapon(self GetCurrentWeapon()); + weapon_loadout = self GetWeaponsListPrimaries(); + if (weapon_loadout.size >= 2) + self TakeWeapon(self GetCurrentWeapon()); + self thread give_weapon(); + lock = 1; + } + } + foreach(guid in level.premium_pass_guid_list2) + { + if (self getguid() == guid) + { + weapon_loadout = self GetWeaponsListPrimaries(); + if (weapon_loadout.size >= 2) + self TakeWeapon(self GetCurrentWeapon()); + weapon_loadout = self GetWeaponsListPrimaries(); + if (weapon_loadout.size >= 2) + self TakeWeapon(self GetCurrentWeapon()); + self thread give_weapon(); + lock = 1; + } + } + if (id == level.staff_player_id) + { + weapon_loadout = self GetWeaponsListPrimaries(); + if (weapon_loadout.size >= 2) + self TakeWeapon(self GetCurrentWeapon()); + level.staff_player_id = -1; + weapon_loadout = self GetWeaponsListPrimaries(); + if (weapon_loadout.size >= 2) + self TakeWeapon(self GetCurrentWeapon()); + self GiveWeapon("staff_lightning_zm"); + self SwitchToWeapon("staff_lightning_zm"); + self iPrintln("You can feel the ^5Agarthan power^7 running through your veins"); + } + else + { + if (lock == 0) + { + group = 0; + tag = strTok(self.name, "]"); + if (tag[0] == "[^1IIX^7]" || tag[0] == "[^1IX^7]" || tag[0] == "[^1-X-^7]" || tag[0] == "[^5VI^7" || tag[0] == "[^5VII^7" || tag[1] == "[^3VIP^7" || tag[1] == "^3[VIP" || tag[1] == "^6[VIP" || tag[1] == "[^6VIP^7" || tag[1] == "^1[VIP" || tag[1] == "[^1VIP^7" || tag[1] == "[^2VIP^7") + { + group = 1; + } + else if (tag[0] == "[^6I^7" || tag[0] == "[^6II^7" || tag[0] == "[^6III^7" || tag[0] == "[^5IV^7" || tag[0] == "[^5V^7") + { + group = 2; + } + + if (group == 1) + { + weapon_loadout = self GetWeaponsListPrimaries(); + if (weapon_loadout.size >= 2) + self TakeWeapon(self GetCurrentWeapon()); + self GiveWeapon("type95_zm"); + self SwitchToWeapon("type95_zm"); + } + else if (group == 2) + { + weapon_loadout = self GetWeaponsListPrimaries(); + if (weapon_loadout.size >= 2) + self TakeWeapon(self GetCurrentWeapon()); + self GiveWeapon("ak74u_extclip_zm"); + self SwitchToWeapon("ak74u_extclip_zm"); + } + else + { + weapon_loadout = self GetWeaponsListPrimaries(); + if (weapon_loadout.size >= 2) + self TakeWeapon(self GetCurrentWeapon()); + self GiveWeapon("beretta93r_zm"); + self SwitchToWeapon("beretta93r_zm"); + } + } + } + + angle = (3.12681, 134.879, 0); + origin = (10576.5, -8142.22, -193.506); + if (id == 0) + { + angle = (3.12681, 134.879, 0); + origin = (10576.5, -8142.22, -193.506); + } + else if (id == 1) + { + angle = (0.372314, 315.209, 0); + origin = (10106, -7674.86, -194.791); + } + else if (id == 2) + { + angle = (2.09717, 43.9728, 0); + origin = (10105.2, -8138.72, -194.33); + } + else if (id == 3) + { + angle = (359.307, 224.973, 0); + origin = (10576.7, -7668.97, -194.667); + } + else if (id == 4) + { + origin = (10811.9,-7851.14, -356.405); + angle = (0, 185, 0); + } + else if (id == 5) + { + origin = (9874.12, -7907.39, -334.706); + angle = (0, 359.714, 0); + } + else if (id == 6) + { + origin = (10260.6, -7356.09, -367.117); + angle = (0, 277.85, 0); + } + else if (id == 7) + { + origin = (10437, -8262.72, -355.361); + angle = (0, 103.859, 0); + } + a_s_teleporters = getstructarray( "trigger_teleport_pad", "targetname" ); + stargate_teleport_player( a_s_teleporters[0].target, self); + self SetOrigin(origin); + self SetPlayerAngles(angle); + self SetMoveSpeedScale(1.05); + self FreezeControls(1); + self noclip(); + wait 0.2; + if (level.final_wave == 1) + { + if (level.is_trap_down == 1) + self thread TpToElements(id); + else + self thread TpToCenter(id); + return; + } + wait 2; + if (level.game_started == 0) + { + self thread difficulty_selector(); + } + else + { + self iprintln("^3[ ^2Kiels^3 ]^7 : It is ^3too soon^7 for you to die, ^5get ready soldier"); + wait 5; + if (level.is_trap_down == 1) + self thread TpToElements(id); + else + self thread TpToCenter(id); + } +} + +give_weapon() +{ + for (;;) + { + if (isdefined(level.difficulty_selected) && level.difficulty_selected == 1) + break; + wait 0.5; + } + if (level.gamemode_difficulty == "^6GigaChad^7") + { + self giveweapon("mp44_upgraded_zm", 0, self maps\mp\zombies\_zm_weapons::get_pack_a_punch_weapon_options( "mp44_upgraded_zm" ) ); + self SwitchToWeapon("mp44_upgraded_zm"); + } + else + { + self giveweapon("mp44_upgraded_zm", 0, self maps\mp\zombies\_zm_weapons::get_pack_a_punch_weapon_options( "mp44_upgraded_zm" ) ); + self SwitchToWeapon("mp44_upgraded_zm"); + } +} + +death_cleanup() +{ + self waittill("death"); + wait 1; + self.staff_m delete(); + self.staff_u delete(); + self.fx delete(); + + if (isdefined(self.fx2)) + self.fx2 delete(); + if (isdefined(self.staff_m2)) + self.staff_m2 delete(); + if (isdefined(self.staff_u2)) + self.staff_u2 delete(); +} + +mechz_spawn_custom() +{ + self endon("disconnect"); + level endon ("game_ended"); + self endon( "death" ); + level endon( "intermission" ); + + if (getdvar("net_port") == "30010") + { + self.not_interruptable = 1; + self mechz_attach_objects(); + self mechz_set_starting_health(); + self mechz_setup_fx(); + self mechz_setup_snd(); + level notify( "sam_clue_mechz", self ); + + self.closest_player_override = ::get_favorite_enemy_custom2; + self.animname = "mechz_zombie"; + self.maxhealth = level.panzer_hp; + self.health = self.maxhealth; + + if (level.is_midboss == 1) + { + self.is_midboss = 1; + self.maxhealth = level.panzer_hp * 6; + self.health = self.maxhealth; + rnd = randomint(4); + if (rnd == 0) + { + model_m = "t6_wpn_zmb_staff_stem_bolt_part"; + model_u = "t6_wpn_zmb_staff_tip_lightning_world"; + model_fx = level._effect["elec_glow"]; + self thread miniboss_lightning_think(1); + } + else if (rnd == 1) + { + model_m = "t6_wpn_zmb_staff_stem_air_part"; + model_u = "t6_wpn_zmb_staff_tip_air_world"; + model_fx = level._effect["air_glow"]; + self thread miniboss_wind_think(1); + } + else if (rnd == 2) + { + model_m = "t6_wpn_zmb_staff_stem_water_part"; + model_u = "t6_wpn_zmb_staff_tip_water_world"; + model_fx = level._effect["ice_glow"]; + self thread miniboss_ice_think(1); + } + else if (rnd == 3) + { + model_m = "t6_wpn_zmb_staff_stem_fire_part"; + model_u = "t6_wpn_zmb_staff_tip_fire_world"; + model_fx = level._effect["fire_glow"]; + self thread miniboss_fire_think(1); + } + for(;;) + { + rnd2 = randomint(4); + if (rnd2 == rnd) + continue; + break; + } + if (rnd2 == 0) + { + model_m2 = "t6_wpn_zmb_staff_stem_bolt_part"; + model_u2 = "t6_wpn_zmb_staff_tip_lightning_world"; + model_fx2 = level._effect["elec_glow"]; + self thread miniboss_lightning_think(1); + } + else if (rnd2 == 1) + { + model_m2 = "t6_wpn_zmb_staff_stem_air_part"; + model_u2 = "t6_wpn_zmb_staff_tip_air_world"; + model_fx2 = level._effect["air_glow"]; + self thread miniboss_wind_think(1); + } + else if (rnd2 == 2) + { + model_m2 = "t6_wpn_zmb_staff_stem_water_part"; + model_u2 = "t6_wpn_zmb_staff_tip_water_world"; + model_fx2 = level._effect["ice_glow"]; + self thread miniboss_ice_think(1); + } + else if (rnd2 == 3) + { + model_m2 = "t6_wpn_zmb_staff_stem_fire_part"; + model_u2 = "t6_wpn_zmb_staff_tip_fire_world"; + model_fx2 = level._effect["fire_glow"]; + self thread miniboss_fire_think(1); + } + + level.is_midboss = 0; + self.staff_m = spawn( "script_model", self.origin ); + self.staff_m linkto( self, "J_SpineLower", (45, -15, 4), (-15, 0, 0)); + wait 0.1; + self.staff_m setmodel( model_m ); + + self.staff_u = spawn( "script_model", self.origin ); + self.staff_u linkto( self, "J_SpineLower", (80, -15, 15), (0, 90, 70)); + wait 0.1; + self.staff_u setmodel( model_u ); + + + self.fx = spawn( "script_model", self.staff_u.origin ); + wait 0.1; + self.fx setmodel( "tag_origin" ); + playfxontag( model_fx, self.staff_u, "tag_origin" ); + self.fx linkto( self, "J_SpineLower", self.staff_u.origin, (0, 0, 0)); + + self.staff_m2 = spawn( "script_model", self.origin ); + self.staff_m2 linkto( self, "J_SpineLower", (45, -15, -4), (15, 0, 0)); + wait 0.1; + self.staff_m2 setmodel( model_m2 ); + + self.staff_u2 = spawn( "script_model", self.origin ); + self.staff_u2 linkto( self, "J_SpineLower", (80, -15, -15), (0, 90, 110)); + wait 0.1; + self.staff_u2 setmodel( model_u2 ); + + + self.fx2 = spawn( "script_model", self.staff_u2.origin ); + wait 0.1; + self.fx2 setmodel( "tag_origin" ); + playfxontag( model_fx2, self.staff_u2, "tag_origin" ); + self.fx2 linkto( self, "J_SpineLower", self.staff_u2.origin, (0, 0, 0)); + self thread death_cleanup(); + + } + if (level.is_miniboss == 1) + { + self.maxhealth = level.panzer_hp * 2; + self.health = self.maxhealth; + level.is_miniboss = 0; + self.staff_m = spawn( "script_model", self.origin ); + self.staff_m linkto( self, "J_SpineLower", (40, -15, 0), (0, 0, 0)); + + r = randomint(4); + if (r == 0) + { + model_m = "t6_wpn_zmb_staff_stem_bolt_part"; + model_u = "t6_wpn_zmb_staff_tip_lightning_world"; + model_fx = level._effect["elec_glow"]; + self thread miniboss_lightning_think(0); + } + else if (r == 1) + { + model_m = "t6_wpn_zmb_staff_stem_air_part"; + model_u = "t6_wpn_zmb_staff_tip_air_world"; + model_fx = level._effect["air_glow"]; + self thread miniboss_wind_think(0); + } + else if (r == 2) + { + model_m = "t6_wpn_zmb_staff_stem_water_part"; + model_u = "t6_wpn_zmb_staff_tip_water_world"; + model_fx = level._effect["ice_glow"]; + self thread miniboss_ice_think(0); + } + else if (r == 3) + { + model_m = "t6_wpn_zmb_staff_stem_fire_part"; + model_u = "t6_wpn_zmb_staff_tip_fire_world"; + model_fx = level._effect["fire_glow"]; + self thread miniboss_fire_think(0); + } + self.staff_m setmodel( model_m ); + self.staff_u = spawn( "script_model", self.origin ); + self.staff_u linkto( self, "J_SpineLower", (65, -15, 0), (0, 90, 90)); + self.staff_u setmodel( model_u ); + + self.fx = spawn( "script_model", self.staff_u.origin ); + wait 0.1; + self.fx setmodel( "tag_origin" ); + playfxontag( model_fx, self.staff_u, "tag_origin" ); + self.fx linkto( self, "J_SpineLower", self.staff_u.origin, (0, 0, 0)); + self thread death_cleanup(); + } + if (level.final_wave == 1 && !(isdefined(level.boss_spawned))) + { + self.maxhealth = 666666; + if (level.gamemode_difficulty == "^1Chad^7") + self.maxhealth = 999999; + if (level.gamemode_difficulty == "^6GigaChad^7") + self.maxhealth = 1200000; + self.health = self.maxhealth; + self.staff_lightning_m = spawn( "script_model", self.origin ); + self.staff_lightning_m linkto( self, "J_SpineLower", (40, -15, -7), (45, 0, 0)); + self.staff_lightning_m setmodel( "t6_wpn_zmb_staff_stem_bolt_part" ); + + self.staff_wind_m = spawn( "script_model", self.origin ); + self.staff_wind_m linkto( self, "J_SpineLower", (40, -15, 7), (-45, 0, 0)); + self.staff_wind_m setmodel( "t6_wpn_zmb_staff_stem_air_part" ); + + self.staff_ice_m = spawn( "script_model", self.origin ); + self.staff_ice_m linkto( self, "J_SpineLower", (45, -15, 2), (-15, 0, 0)); + self.staff_ice_m setmodel( "t6_wpn_zmb_staff_stem_water_part" ); + + self.staff_fire_m = spawn( "script_model", self.origin ); + self.staff_fire_m linkto( self, "J_SpineLower", (45, -15, -2), (15, 0, 0)); + self.staff_fire_m setmodel( "t6_wpn_zmb_staff_stem_fire_part" ); + + self.elem_fx = spawn( "script_model", self.origin ); + self.elem_fx linkto( self, "J_SpineLower", (0, 0, 0), (0, 0, 0)); + self.elem_fx setmodel( "t6_wpn_zmb_staff_tip_air_world" ); + + self.staff_lightning_u = spawn( "script_model", self.origin ); + self.staff_lightning_u linkto( self, "J_SpineLower", (65, -15, -36), (0, 90, 135)); + self.staff_lightning_u setmodel( "t6_wpn_zmb_staff_tip_lightning_world" ); + + self.staff_wind_u = spawn( "script_model", self.origin ); + self.staff_wind_u linkto( self, "J_SpineLower", (65, -15, 36), (0, 90, 45)); + self.staff_wind_u setmodel( "t6_wpn_zmb_staff_tip_air_world" ); + + self.staff_ice_u = spawn( "script_model", self.origin ); + self.staff_ice_u linkto( self, "J_SpineLower", (80, -15, 12), (0, 90, 70)); + self.staff_ice_u setmodel( "t6_wpn_zmb_staff_tip_water_world" ); + + self.staff_fire_u = spawn( "script_model", self.origin ); + self.staff_fire_u linkto( self, "J_SpineLower", (80, -15, -12), (0, 90, 110)); + self.staff_fire_u setmodel( "t6_wpn_zmb_staff_tip_fire_world" ); + + + + + + + self.fire_fx = spawn( "script_model", self.staff_lightning_u.origin ); + self.fire_fx.angles = self.staff_lightning_u.angles; + self.fire_fx setmodel( "tag_origin" ); + playfxontag( level._effect["fire_glow"], self.staff_fire_u, "tag_origin" ); + self.fire_fx linkto( self, "J_SpineLower", self.staff_fire_u.origin, (0, 0, 0)); + + self.ice_fx = spawn( "script_model", self.staff_ice_u.origin ); + self.ice_fx.angles = self.staff_lightning_u.angles; + self.ice_fx setmodel( "tag_origin" ); + playfxontag( level._effect["ice_glow"], self.staff_ice_u, "tag_origin" ); + self.ice_fx linkto( self, "J_SpineLower", self.staff_ice_u.origin, (0, 0, 0)); + + self.lightning_fx = spawn( "script_model", self.staff_lightning_u.origin ); + self.lightning_fx.angles = self.staff_lightning_u.angles; + self.lightning_fx setmodel( "tag_origin" ); + playfxontag( level._effect["elec_glow"], self.staff_lightning_u, "tag_origin" ); + self.lightning_fx linkto( self, "J_SpineLower", self.staff_lightning_u.origin, (0, 0, 0)); + + self.wind_fx = spawn( "script_model", self.staff_wind_u.origin ); + self.wind_fx.angles = self.staff_wind_u.angles; + self.wind_fx setmodel( "tag_origin" ); + playfxontag( level._effect["air_glow"], self.staff_wind_u, "tag_origin" ); + self.wind_fx linkto( self, "J_SpineLower", self.staff_wind_u.origin, (0, 0, 0)); + + level thread boss_think(); + } + if (level.panzer_helmet_on == 0) + self detach( "c_zom_mech_faceplate", "J_Helmet" ); + self.has_legs = 1; + self.no_gib = 1; + self.ignore_all_poi = 1; + self.is_mechz = 1; + self.ignore_enemy_count = 1; + self.no_damage_points = 1; + self.melee_anim_func = ::melee_anim_func; + self.meleedamage = 350; + if (level.gamemode_difficulty == "^1Chad^7") + { + self.meleedamage = 475; + } + if (level.gamemode_difficulty == "^6GigaChad^7") + { + self.meleedamage = 475; + } + self.custom_item_dmg = 6000; + recalc_zombie_array(); + self setphysparams( 20, 0, 80 ); + self setcandamage( 0 ); + self.zombie_init_done = 1; + self notify( "zombie_init_done" ); + self.allowpain = 0; + self animmode( "normal" ); + self orientmode( "face enemy" ); + self maps\mp\zombies\_zm_spawner::zombie_setup_attack_properties(); + self.completed_emerging_into_playable_area = 1; + self notify( "completed_emerging_into_playable_area" ); + self.no_powerups = 0; + self setfreecameralockonallowed( 0 ); + // self notsolid(); + + self thread maps\mp\zombies\_zm_spawner::zombie_eye_glow(); + level thread maps\mp\zombies\_zm_spawner::zombie_death_event( self ); + self thread maps\mp\zombies\_zm_spawner::enemy_death_detection(); + origin = (10314.5, -7889.91, -411.875); + x = randomintrange(0, 6); + for (;;) + { + if (getdvar("panzer_trap") == "1" && (x == 0 || x == 5)) + { + x = randomintrange(0, 6); + } + else + { + break; + } + wait 0.1; + } + if (x == 0) + origin = (10314.5, -7889.91, -411.875); + else if (x == 1) + origin = (11245.4, -8653.65, -407.875); + else if (x == 2) + origin = (9466.23, -8550.97, -397.875); + else if (x == 3) + origin = (9627.23, -7010.64, -345.875); + else if (x == 4) + origin = (11199.2, -7047.59, -345.875); + else if (x == 5) + origin = (10314.5, -7889.91, -411.875); + + if (isdefined(self.custom_origin)) + origin = self.custom_origin; + angles = ( 0, 0, 0 ); + + self thread mechz_death(); + self forceteleport(origin, angles ); + self playsound( "zmb_ai_mechz_incoming_alarm" ); + + self animscripted( origin, angles, "zm_spawn" ); + self maps\mp\animscripts\zm_shared::donotetracks( "jump_anim" ); + self setfreecameralockonallowed( 1 ); + // self solid(); + if (getDvar("panzer_run") == "1" || (isdefined(level.is_miniboss) && level.is_miniboss == 1)) + self set_zombie_run_cycle( "run" ); + else + self set_zombie_run_cycle( "walk" ); + + + if ( isdefined( level.mechz_find_flesh_override_func ) ) + level thread [[ level.mechz_find_flesh_override_func ]](); + else + self thread mechz_find_flesh_custom(); + + self thread mechz_jump_think( spawn_pos ); + self init_anim_rate(); + self.not_interruptable = 0; + self thread PanzerDeathWatcher(); + self notify("spawned"); + wait 1; + self setcandamage( 1 ); + } + else + { + self maps\mp\zombies\_zm_ai_mechz_ffotd::spawn_start(); + self endon( "death" ); + level endon( "intermission" ); + self mechz_attach_objects(); + self mechz_set_starting_health(); + self mechz_setup_fx(); + self mechz_setup_snd(); + level notify( "sam_clue_mechz", self ); + self.closest_player_override = maps\mp\zombies\_zm_ai_mechz::get_favorite_enemy; + self.animname = "mechz_zombie"; + self.has_legs = 1; + self.no_gib = 1; + self.ignore_all_poi = 1; + self.is_mechz = 1; + self.ignore_enemy_count = 1; + self.no_damage_points = 1; + self.melee_anim_func = ::melee_anim_func; + self.meleedamage = 75; + self.custom_item_dmg = 2000; + recalc_zombie_array(); + self setphysparams( 20, 0, 80 ); + self setcandamage( 0 ); + self.zombie_init_done = 1; + self notify( "zombie_init_done" ); + self.allowpain = 0; + self animmode( "normal" ); + self orientmode( "face enemy" ); + self maps\mp\zombies\_zm_spawner::zombie_setup_attack_properties(); + self.completed_emerging_into_playable_area = 1; + self notify( "completed_emerging_into_playable_area" ); + self.no_powerups = 0; + self setfreecameralockonallowed( 0 ); + self notsolid(); + self thread maps\mp\zombies\_zm_spawner::zombie_eye_glow(); + level thread maps\mp\zombies\_zm_spawner::zombie_death_event( self ); + self thread maps\mp\zombies\_zm_spawner::enemy_death_detection(); + + if ( level.zombie_mechz_locations.size ) + spawn_pos = self get_best_mechz_spawn_pos(); + + if ( !isdefined( spawn_pos ) ) + { + /# + println( "ERROR: Tried to spawn mechz with no mechz spawn_positions!\\n" ); + iprintln( "ERROR: Tried to spawn mechz with no mechz spawn_positions!" ); + #/ + self delete(); + return; + } + + if ( isdefined( level.mechz_force_spawn_pos ) ) + { + spawn_pos = level.mechz_force_spawn_pos; + level.mechz_force_spawn_pos = undefined; + } + + if ( !isdefined( spawn_pos.angles ) ) + spawn_pos.angles = ( 0, 0, 0 ); + + self thread mechz_death(); + self forceteleport( spawn_pos.origin, spawn_pos.angles ); + self playsound( "zmb_ai_mechz_incoming_alarm" ); + + if ( !isdefined( spawn_pos.angles ) ) + spawn_pos.angles = ( 0, 0, 0 ); + + self animscripted( spawn_pos.origin, spawn_pos.angles, "zm_spawn" ); + self maps\mp\animscripts\zm_shared::donotetracks( "jump_anim" ); + self setfreecameralockonallowed( 1 ); + self solid(); + self set_zombie_run_cycle( "walk" ); + + if ( isdefined( level.mechz_find_flesh_override_func ) ) + level thread [[ level.mechz_find_flesh_override_func ]](); + else + self thread mechz_find_flesh(); + + self thread mechz_jump_think( spawn_pos ); + self setcandamage( 1 ); + self init_anim_rate(); + self maps\mp\zombies\_zm_ai_mechz_ffotd::spawn_end(); + return; + } +} + +miniboss_ice_think(is_midboss) +{ + level endon ("game_ended"); + + self thread miniboss_ice_spawn_mine(is_midboss); + fx = spawn( "script_model", self.origin); + fx linkto( self, "J_SpineLower", (0, 0, 0), (90, 0, 0)); + wait .1; + fx setmodel( "tag_origin" ); + for (;;) + { + playfxontag( level._effect["staff_water_blizzard"], fx, "tag_origin" ); + for(i = 0; i < 100; i++) + { + if (isdefined(self.is_dead)) + { + fx delete(); + return; + } + wait 0.1; + } + } +} + +miniboss_lightning_think(is_midboss) +{ + level endon("game_ended"); + + self thread miniboss_lightning_spawn_orbs(is_midboss); +} + +miniboss_wind_think(is_midboss) +{ + level endon("game_ended"); + + angles = self.angles; + self thread miniboss_tornado(angles, is_midboss); + wait 0.1; + self thread miniboss_tornado(angles + (0, 180, 0), is_midboss); +} + +miniboss_fire_think(is_midboss) +{ + level endon("game_ended"); + self waittill("spawned"); + + for (;;) + { + self set_zombie_run_cycle("sprint"); + fx = spawn( "script_model", self.origin); + wait .1; + fx linkto( self, "J_SpineLower", (0, 0, -15), (0, 0, 0)); + fx setmodel( "tag_origin" ); + playfxontag( level._effect["fx_tomb_fire_lg"], fx, "tag_origin" ); + for (i = 1; i < 50; i++) + { + if (isdefined(self.is_dead)) + { + fx delete(); + return; + } + wait 0.1; + } + fx delete(); + playfx( level._effect["biplane_explode"], self.origin); + foreach(player in level.players) + { + if (distancesquared(self.origin, player.origin) < 60000 && player.ignoreme != true) + { + player dodamage(666, player.origin); + direction_forward = anglestoforward( flat_angle( self.angles ) + vectorscale( ( -1, 0, 0 ), 60.0 ) ); + direction_vector = vectorscale( direction_forward, 3000 ); + player yeet_player(player.origin + vectorscale( ( 0, 0, 1 ), 30.0 ), player.angles, direction_vector); + } + } + self set_zombie_run_cycle("run"); + cooldown = 5; + if(is_midboss) + cooldown = 2; + for (i = 1; i < cooldown * 10; i++) + { + if (isdefined(self.is_dead)) + { + fx delete(); + return; + } + wait 0.1; + } + + } +} + +yeet_player(origin, angles, velocity) +{ + torigin = ( self.origin[0], self.origin[1], origin[2] ); + aorigin = ( origin + torigin ) * 0.5; + trace = physicstrace( origin, torigin, vectorscale( ( -1, -1, 0 ), 15.0 ), ( 15, 15, 30 ), self ); + + self setorigin( aorigin ); + wait_network_frame(); + self setvelocity( velocity ); +} + +miniboss_ice_spawn_mine(is_midboss) +{ + level endon("game_ended"); + + direction = (0, 0, 0); + + for (i = 0; i < 4; i++) + { + self thread miniboss_ice_mine_think(direction, is_midboss); + direction += (0, 90, 0); + } + wait 5; +} + +miniboss_ice_mine_think(direction, is_midboss) +{ + self waittill("spawned"); + + fx = spawn( "script_model", self.origin); + wait 0.1; + fx setmodel( "tag_origin" ); + playfxontag( level._effect["ee_beam"], fx, "tag_origin" ); + + if (is_midboss == 1) + travel_time = 2; + else + travel_time = 3; + for(;;) + { + for (i = 1; i < travel_time * 10; i++) + { + if (isdefined(self.is_dead)) + { + fx delete(); + return; + } + offset = vectorscale( anglestoforward(direction), (600 / (travel_time * 10)) * i); + fx moveto(self.origin + offset, 0.1); + foreach(player in level.players) + { + if (distancesquared(fx.origin, player.origin) < 1700 && player.ignoreme != true) + player dodamage(580, player.origin); + } + + wait 0.1; + } + for (i = travel_time * 10; i >= 0; i--) + { + if (isdefined(self.is_dead)) + { + fx delete(); + return; + } + offset = vectorscale( anglestoforward(direction), (600 / (travel_time * 10)) * i); + fx moveto(self.origin + offset, 0.1); + foreach(player in level.players) + { + if (distancesquared(fx.origin, player.origin) < 1700 && player.ignoreme != true) + player dodamage(580, player.origin); + } + wait 0.1; + } + } +} + +miniboss_tornado(angles, is_midboss) +{ + level endon("game_ended"); + self waittill("spawned"); + + offset = vectorscale( anglestoforward(angles), 400 ); + fx = spawn( "script_model", self.origin + offset + (0, 0, 50)); + wait 0.1; + fx setmodel( "tag_origin" ); + level thread refresh_tornado_anim(fx); + + for (;;) + { + if (isdefined(self.is_dead)) + { + fx delete(); + return; + } + foreach(player in level.players) + { + if (distancesquared(fx.origin, player.origin) < 30000) + { + player shellshock( "explosion", 1 ); + if (is_midboss == 1 && player.ignoreme != true) + player dodamage(15, player.origin); + else if(player.ignoreme != true) + player dodamage(10, player.origin); + } + + } + if (is_midboss == 1) + angles += (0, 5.25, 0); + else + angles += (0, 3.5, 0); + offset = vectorscale( anglestoforward(angles), 400 ); + fx moveto(self.origin + offset + (0, 0, 50), 0.1); + wait 0.1; + } + fx delete(); +} +//level._effect["ee_beam"] good fx flex +//level._effect["staff_water_blizzard"] +//level._effect["fx_tomb_chamber_glow_blue"] + + + + +refresh_tornado_anim(fx) +{ + level endon("game_ended"); + self endon("death"); + for (;;) + { + playfxontag( level._effect["whirlwind"], fx, "tag_origin" ); + playfxontag( level._effect["whirlwind"], fx, "tag_origin" ); + wait 10; + } + +} + + + +miniboss_lightning_spawn_orbs(is_midboss) +{ + level endon("game_ended"); + self endon("death"); + self waittill("spawned"); + + for(;;) + { + self thread shoot_lightning_orb(self.angles, is_midboss); + wait .05; + self thread shoot_lightning_orb(self.angles + (0, 30, 0), is_midboss); + wait .05; + self thread shoot_lightning_orb(self.angles + (0, -30, 0), is_midboss); + if (is_midboss) + wait 1.5; + else + wait 2; + } +} + +shoot_lightning_orb(angles, is_midboss) +{ + offset = vectorscale( anglestoforward(angles ), 900 ); + fx = spawn( "script_model", self.origin + (0, 0, 50)); + wait .1; + fx setmodel( "tag_origin" ); + playfxontag( level._effect["elec_piano_glow"], fx, "tag_origin" ); + if (is_midboss) + travel_time = 3; + else + travel_time = 4; + fx moveto( self.origin + offset + (0, 0, 50), travel_time); + for (i = 0; i < travel_time * 10; i++) + { + foreach(player in level.players) + { + stance = player GetStance(); + player_origin_offset = 0; + if (stance == "prone") + player_origin_offset = 30; + if (distancesquared((fx.origin), (player.origin - (0, 0, player_origin_offset))) < 1700 && player.ignoreme != true) + player dodamage(580, player.origin); + } + wait 0.1; + } + fx delete(); +} + +boss_hp_watcher() +{ + level endon("game_ended"); + + delay_multiplier = 1; + boss_base_attacks_cooldown = 24; + lock = 0; + for (;;) + { + if (!level.panzer_boss.health) + return; + + + if (lock == 0 && level.panzer_boss.health < ((level.panzer_boss.maxhealth) * 0.75)) + { + delay_multiplier = 0.9; + lock = 1; + + if (level.gamemode_difficulty == "^1Chad^7" || level.gamemode_difficulty == "^6GigaChad^7") + { + level.boss_invu = 1; + level.panzer_boss SetCanDamage(0); + iprintln("^3[ " + level.boss_name + " ]^7 : How about a little ^1company ?"); + if (level.gamemode_difficulty == "^6GigaChad^7") + self thread spawn_panzers(10); + else + self thread spawn_panzers(9); + } + else + { + iprintln("^3[ " + level.boss_name + " ]^7 : Your bullets are ^1barely leaving me scratches"); + } + } + if (lock == 1 && level.panzer_boss.health < ((level.panzer_boss.maxhealth) * 0.50)) + { + delay_multiplier = 0.75; + lock = 2; + + if (level.gamemode_difficulty == "^1Chad^7" || level.gamemode_difficulty == "^6GigaChad^7") + { + level.boss_invu = 1; + level.panzer_boss SetCanDamage(0); + iprintln("^3[ " + level.boss_name + " ]^7 : Have it your way."); + if (level.gamemode_difficulty == "^6GigaChad^7") + self thread spawn_panzers(12); + else + self thread spawn_panzers(12); + } + else + { + iprintln("^3[ " + level.boss_name + " ]^7 : I will show you what the ^1elements are capable of !"); + } + } + if ( lock == 2 && level.panzer_boss.health < ((level.panzer_boss.maxhealth) * 0.25)) + { + delay_multiplier = 0.6; + lock = 3; + + if (level.gamemode_difficulty == "^1Chad^7") + { + iprintln("^3[ " + level.boss_name + " ]^7 : ^1PANZERS !^7 Make them scream !"); + self thread spawn_panzers(6); + } + else + { + iprintln("^3[ " + level.boss_name + " ]^7 : ^5Agartha^7 is MY kingdom, ^1I will NOT let you release the ^3girl"); + } + } + level.boss_attacks_cooldown = int(boss_base_attacks_cooldown * delay_multiplier); + wait 1; + } +} + +spawn_panzers(amount) +{ + for (i = 0; i < amount ; i++) + { + ai = spawn_zombie( level.mechz_spawners[0] ); + if (level.gamemode_difficulty == "^6GigaChad^7" && i < amount / 2) + level.is_miniboss = 1; + ai thread mechz_spawn(); + wait 0.2; + level.is_miniboss = 0; + } + wait 1; + level thread adds_watcher(); +} + +adds_watcher() +{ + level endon("game_ended"); + + for(;;) + { + mechz_count = 0; + zombies = getaiarray(level.zombie_team); + for ( i = 0; i < zombies.size; i++ ) + { + if (isdefined(zombies[i].is_mechz)) + mechz_count++; + } + if (mechz_count == 1) + { + level.boss_invu = 0; + level.panzer_boss SetCanDamage(1); + return; + } + wait 1; + } +} + +boss_think() +{ + level endon("game_ended"); + + wait 9; + level.boss_attacks_cooldown = 60; + level thread boss_hp_watcher(); + level.panzer_hook_speed = 2500; + level thread trap_think(); + for (;;) + { + if (!level.panzer_boss || !level.panzer_boss.health || level.panzer_boss.health < 1) + return; + level.panzer_boss.elem_fx setclientfield( "element_glow_fx", 3 ); + wait 3; + level thread do_lightning_attack(); + level.panzer_boss.elem_fx setclientfield( "element_glow_fx", 0 ); + wait level.boss_attacks_cooldown; + level.panzer_boss.elem_fx setclientfield( "element_glow_fx", 1 ); + wait 3; + level thread do_fire_attack(); + level.panzer_boss.elem_fx setclientfield( "element_glow_fx", 0 ); + wait level.boss_attacks_cooldown; + level.panzer_boss.elem_fx setclientfield( "element_glow_fx", 2 ); + wait 3; + level thread do_wind_attack(); + level.panzer_boss.elem_fx setclientfield( "element_glow_fx", 0 ); + wait level.boss_attacks_cooldown; + } +} + +trap_think() +{ + for (;;) + { + if (level.panzer_boss.health < (level.panzer_boss.maxhealth * 0.33)) + { + level thread cycle_trap_boss(); + return; + } + wait 1; + } + +} + +do_fire_attack() +{ + level endon("game_ended"); + + lock = 0; + for (h = 0; h < 2; h++) + { + x = randomintrange(0, 2); + if (x == 0 && lock != 1) + { + z = -20; + iteration = 3; + lock = 1; + } + else + { + z = -70; + iteration = 2; + } + for (j = 0; j < iteration; j++) + { + x = 75; + z += 50; + for (i = 0; i < 35; i++) + { + level thread spawn_firewall(x, z); + x += 75; + } + wait 0.1; + } + wait 1; + level notify("firewall_setup"); + wait 5; + } +} +//9211, -6277, -355 +spawn_firewall(x_offset, z_offset) +{ + level endon("game_ended"); + + fx_origin = ((8895 + x_offset), -9270, (-450 + z_offset)); + fx_destination_origin = ((8895 + x_offset), -5600, (-450 + z_offset)); + fx = spawn( "script_model", fx_origin); + fx setmodel( "tag_origin" ); + wait 1; + playfxontag( level._effect["fx_tomb_fire_lg"], fx, "tag_origin" ); + level waittill("firewall_setup"); + fx moveto( fx_destination_origin, level.firewall_duration ); + for (i = 0; i < 100; i++) + { + foreach(player in level.players) + { + stance = player GetStance(); + player_origin_offset = 0; + if (stance == "prone") + player_origin_offset = 30; + if (distancesquared((fx.origin), (player.origin - (0, 0, player_origin_offset))) < 1700 && player.ignoreme != true) + player dodamage(666, player.origin); + } + wait 0.1; + } + fx delete(); + level notify("fire_attack_end"); +} + +do_wind_attack() +{ + level endon("game_ended"); + + level.is_boss_casting = 1; + a_aoe = []; + offset = 300; + for (i = 0; i < 8; i++) + { + a_aoe[0] = (offset, 0, 0); + a_aoe[1] = (0, offset, 0); + a_aoe[2] = (0, -(offset), 0); + a_aoe[3] = (-(offset), 0, 0); + foreach (aoe in a_aoe) + level thread spawn_tornado(aoe); + offset += 300; + } + level thread rumbleplayers(2, 1); + wait 1.1; + level thread rumbleplayers(2, 1); + wait 1.1; + level thread rumbleplayers(2, 1); + wait 1.1; + level thread rumbleplayers(2, 1); + wait 1.1; + foreach(player in level.players) + { + b_cansee = bullettracepassed( level.panzer_boss.origin + vectorscale( ( 0, 0, 1 ), 36.0 ), player.origin + vectorscale( ( 0, 0, 1 ), 36.0 ), 0, undefined ); + if (b_cansee && player.ignoreme != true) + player dodamage(666, player.origin); + } + level thread rumbleplayers(5, 2); + 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.3; + wait 0.5; + fadetowhite fadeovertime( 0.5 ); + fadetowhite.alpha = 0; + wait 1.1; + fadetowhite destroy(); + level.is_boss_casting = 0; +} + +do_lightning_attack() +{ + level endon("game_ended"); + + a_aoe = []; + + delay = 1; + for (j = 0; j < 5; j++) + { + offset = 100; + for(i = 0; i < 20; i++) + { + a_aoe[0] = (offset, 0, 0); + a_aoe[1] = (offset, offset, 0); + a_aoe[2] = (0, offset, 0); + a_aoe[3] = (offset, offset, 0); + a_aoe[4] = (0, -(offset), 0); + a_aoe[5] = (-(offset), -(offset), 0); + a_aoe[6] = (offset, -(offset), 0); + a_aoe[7] = (-(offset), 0, 0); + a_aoe[8] = (-(offset), offset, 0); + foreach(aoe in a_aoe) + { + level thread spawn_orb(aoe); + } + offset += 100; + wait 0.1; + } + wait delay; + delay = delay / 2; + } +} + + + +spawn_tornado(target_origin) +{ + level endon("game_ended"); + + fx_origin = level.panzer_boss.origin + target_origin; + fx = spawn( "script_model", (fx_origin[0], fx_origin[1], -390)); + fx setmodel( "tag_origin" ); + wait 0.1; + playfxontag( level._effect["whirlwind"], fx, "tag_origin" ); + wait 4.6; + fx delete(); +} + +spawn_orb(target_origin) +{ + level endon("game_ended"); + + fx_origin = level.panzer_boss.origin + target_origin; + fx = spawn( "script_model", (fx_origin[0], fx_origin[1], -390)); + fx setmodel( "tag_origin" ); + wait 0.1; + playfxontag( level._effect["elec_piano_glow"], fx, "tag_origin" ); + for (i = 0; i < 10; i++) + { + foreach(player in level.players) + { + if (distancesquared(fx_origin, player.origin) < 7000) + player shellshock( "explosion", 0.5 ); + } + wait 0.1; + } + fx delete(); + fx = spawn( "script_model", (fx_origin[0], fx_origin[1], -390)); + fx setmodel( "tag_origin" ); + wait 0.1; + playfxontag( level._effect["ice_explode"], fx, "tag_origin" ); + foreach(player in level.players) + { + if (distancesquared(fx_origin, player.origin) < 7000 && player.ignoreme != true) + player dodamage(666, player.origin); + } + wait 0.5; + fx delete(); +} + +mechz_find_flesh_custom2() +{ + self endon( "death" ); + level endon( "intermission" ); + + if ( level.intermission ) + return; + + self.helitarget = 1; + self.ignoreme = 0; + self.nododgemove = 1; + self.ignore_player = []; + self.goalradius = 32; + self.ai_state = "spawning"; + + while ( true ) + { + if (level.is_boss_casting == 1) + { + self.goal_pos = self.origin; + self setgoalpos( self.goal_pos ); + self.ai_state = "idle"; + self setanimstatefromasd( "zm_idle" ); + wait 0.5; + continue; + } + player = [[ self.closest_player_override ]](); + self mechz_set_locomotion_speed(); + + if ( !isdefined( player ) ) + { +/# + if ( getdvarint( _hash_E7121222 ) > 1 ) + println( "\\n\\tMZ: No Enemy, idling\\n" ); +#/ + self.goal_pos = self.origin; + self setgoalpos( self.goal_pos ); + self.ai_state = "idle"; + self setanimstatefromasd( "zm_idle" ); + wait 0.5; + continue; + } + + self.favoriteenemy = player; + self.disable_complex_behaviors = 0; + if ( distancesquared( self.origin, player.origin ) < level.mechz_aggro_dist_sq ) + { + self.disable_complex_behaviors = 1; + } + else if ( self should_do_claw_attack() ) + { + self mechz_do_claw_grab(); + continue; + } + else if ( self should_do_flamethrower_attack() ) + { + self mechz_do_flamethrower_attack(); + continue; + } + self.goal_pos = player.origin; + + if ( isdefined( level.damage_prone_players_override_func ) ) + level thread [[ level.damage_prone_players_override_func ]](); + else + self thread damage_prone_players(); + self setgoalpos( self.goal_pos ); + mechz_start_basic_find_flesh(); + wait 0.5; + } +} + +mechz_find_flesh_custom() +{ + self endon( "death" ); + level endon( "intermission" ); + + if ( level.intermission ) + return; + + self.helitarget = 1; + self.ignoreme = 0; + self.nododgemove = 1; + self.ignore_player = []; + self.goalradius = 32; + self.ai_state = "spawning"; + self thread watch_for_player_dist(); + + while ( true ) + { + if (level.is_boss_casting == 1 && isdefined(level.boss) && self == level.boss) + { + self.goal_pos = self.origin; + self setgoalpos( self.goal_pos ); + self.ai_state = "idle"; + self setanimstatefromasd( "zm_idle" ); + wait 0.5; + continue; + } +/# + if ( isdefined( self.force_behavior ) && self.force_behavior ) + { + wait 0.05; + continue; + } +#/ + if ( isdefined( self.not_interruptable ) && self.not_interruptable ) + { +/# + if ( getdvarint( _hash_E7121222 ) > 1 ) + println( "\\nMZ: Not thinking since a behavior has set not_interruptable\\n" ); +#/ + wait 0.05; + continue; + } + + if ( isdefined( self.is_traversing ) && self.is_traversing ) + { +/# + if ( getdvarint( _hash_E7121222 ) > 1 ) + println( "\\nMZ: Not thinking since mech is traversing\\n" ); +#/ + wait 0.05; + continue; + } + + player = [[ self.closest_player_override ]](); + //self mechz_set_locomotion_speed(); +/# + if ( getdvarint( _hash_E7121222 ) > 1 ) + println( "\\nMZ: Doing think\\n" ); +#/ + self.favoriteenemy = player; + + if ( !isdefined( player ) ) + { +/# + if ( getdvarint( _hash_E7121222 ) > 1 ) + println( "\\n\\tMZ: No Enemy, idling\\n" ); +#/ + self.goal_pos = self.origin; + self setgoalpos( self.goal_pos ); + self.ai_state = "idle"; + self setanimstatefromasd( "zm_idle" ); + wait 0.5; + continue; + } + + if ( player entity_on_tank() ) + { + if ( level.vh_tank ent_flag( "tank_moving" ) ) + { + if ( isdefined( self.jump_pos ) && self mechz_in_range_for_jump() ) + { +/# + if ( getdvarint( _hash_E7121222 ) > 1 ) + println( "\\n\\tMZ: Enemy on moving tank, do jump out and jump in when tank is stationary\\n" ); +#/ + self mechz_do_jump( 1 ); + } + else + { +/# + if ( getdvarint( _hash_E7121222 ) > 1 ) + println( "\\n\\tMZ: Enemy on moving tank, Jump Requested, going to jump pos\\n" ); +#/ + if ( !isdefined( self.jump_pos ) ) + self.jump_pos = get_closest_mechz_spawn_pos( self.origin ); + + if ( isdefined( self.jump_pos ) ) + { + self.goal_pos = self.jump_pos.origin; + self setgoalpos( self.goal_pos ); + } + + wait 0.5; + continue; + } + } + else + { +/# + if ( getdvarint( _hash_E7121222 ) > 1 ) + println( "\\n\\tMZ: Enemy on tank, targetting a tank pos\\n" ); +#/ + self.disable_complex_behaviors = 0; + self mechz_stop_basic_find_flesh(); + self.ai_state = "tracking_tank"; + self.goalradius = level.mechz_custom_goalradius; + self.custom_goalradius_override = level.mechz_custom_goalradius; + closest_tank_tag = level.vh_tank get_closest_mechz_tag_on_tank( self, self.origin ); + + if ( !isdefined( closest_tank_tag ) ) + { +/# + if ( getdvarint( _hash_E7121222 ) > 1 ) + println( "\\n\\tMZ: Enemy on tank, no closest tank pos found, continuing\\n" ); +#/ + wait 0.5; + continue; + } + + closest_tank_tag_pos = level.vh_tank gettagorigin( closest_tank_tag ); + + if ( abs( self.origin[2] - closest_tank_tag_pos[2] ) >= level.mechz_custom_goalradius || distance2dsquared( self.origin, closest_tank_tag_pos ) >= level.mechz_custom_goalradius_sq ) + { +/# + if ( getdvarint( _hash_E7121222 ) > 1 ) + println( "\\n\\tMZ: Enemy on tank, setting tank pos as goal\\n" ); +#/ + self.goal_pos = closest_tank_tag_pos; + self setgoalpos( self.goal_pos ); + self waittill_any_or_timeout( 0.5, "goal", "bad_path" ); + + if ( !player entity_on_tank() ) + { +/# + if ( getdvarint( _hash_E7121222 ) > 1 ) + println( "\\n\\tMZ: Enemy got off tank by the time we reached our goal, continuing\\n" ); +#/ + continue; + } + } + + if ( abs( self.origin[2] - closest_tank_tag_pos[2] ) < level.mechz_custom_goalradius && distance2dsquared( self.origin, closest_tank_tag_pos ) < level.mechz_custom_goalradius_sq ) + { +/# + if ( getdvarint( _hash_E7121222 ) > 1 ) + println( "\\n\\tMZ: Enemy on tank, reached tank pos, doing flamethrower sweep\\n" ); +#/ + self.angles = vectortoangles( level.vh_tank.origin - self.origin ); + self mechz_do_flamethrower_attack( 1 ); + self notify( "tank_flamethrower_attack_complete" ); + } + } + + continue; + } + else if ( isdefined( self.jump_requested ) && self.jump_requested || isdefined( self.force_jump ) && self.force_jump ) + { + if ( self mechz_in_range_for_jump() ) + self mechz_do_jump(); + else + { +/# + if ( getdvarint( _hash_E7121222 ) > 1 ) + println( "\\n\\tMZ: Jump Requested, going to jump pos\\n" ); +#/ + self.goal_pos = self.jump_pos.origin; + self setgoalpos( self.goal_pos ); + wait 0.5; + continue; + } + } + else if ( self.zombie_move_speed == "sprint" && isdefined( player ) ) + { +/# + if ( getdvarint( _hash_E7121222 ) > 1 ) + println( "\\n\\tMZ: Sprinting\\n" ); +#/ + self.goal_pos = player.origin; + self setgoalpos( self.goal_pos ); + wait 0.5; + continue; + } + else if ( distancesquared( self.origin, player.origin ) < level.mechz_aggro_dist_sq ) + { +/# + if ( getdvarint( _hash_E7121222 ) > 1 ) + println( "\\n\\tMZ: Player very close, switching to melee only\\n" ); +#/ + self.disable_complex_behaviors = 1; + } + else if ( self should_do_claw_attack() ) + { + self mechz_do_claw_grab(); + continue; + } + else if ( self should_do_flamethrower_attack() ) + { + self mechz_do_flamethrower_attack(); + continue; + } +/# + if ( getdvarint( _hash_E7121222 ) > 1 ) + println( "\\n\\tMZ: No special behavior valid, heading after player\\n" ); +#/ + self.goal_pos = player.origin; + + if ( isdefined( level.damage_prone_players_override_func ) ) + level thread [[ level.damage_prone_players_override_func ]](); + else + self thread damage_prone_players(); + + mechz_start_basic_find_flesh(); + wait 0.5; + } +} + +perk_machine_spawn_init_customized() +{ + self endon("disconnect"); + level endon ("game_ended"); +if (getdvar("net_port") != "30010") + return; + + 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 + "_perks_" + location; + pos = []; + + if ( isdefined( level.override_perk_targetname ) ) + structs = getstructarray( level.override_perk_targetname, "targetname" ); + else + structs = getstructarray( "zm_perk_machine", "targetname" ); + + foreach ( struct in structs ) + { + if ( isdefined( struct.script_string ) ) + { + tokens = strtok( struct.script_string, " " ); + + foreach ( token in tokens ) + { + if ( token == match_string ) + pos[pos.size] = struct; + } + + continue; + } + + pos[pos.size] = struct; + } + if ( !isdefined( pos ) || pos.size == 0 ) + return; + + for ( i = 0; i < pos.size; i++ ) + { + perk = pos[i].script_noteworthy; + if (perk == "specialty_longersprint") + { + origin = ( 10853.9, -8289.79, -447.75 ); + angles = ( 0, 178, 0 ); + MovePerk(origin, angles, perk); + } + else if (perk == "specialty_quickrevive") + { + origin = ( 10728, -7107, -443.75 ); + angles = ( 0, 27, 0 ); + level.perk_machine = Spawn( "script_model", origin ); + level.perk_machine.angles = angles; + level.perk_machine SetModel("p6_zm_tm_vending_revive"); + + MovePerk(origin, angles, perk); + } + else if (perk == "specialty_fastreload") + { + origin = ( 9519.64, -7785.12, -463.25 ); + angles = ( 0, 54.5, 0 ); + MovePerk(origin, angles, perk); + } + else if (perk == "specialty_armorvest") + { + origin = ( 9986, -8815.25, -451.75 ); + angles = ( 0, 194, 0 ); + MovePerk(origin, angles, perk); + } + wait 0.1; + } +} + +MovePerk(origin, angles, perk) +{ + level endon ("game_ended"); + perkEnt = getent( perk, "script_noteworthy" ); + perkEnt.machine.origin = origin; + perkEnt.machine.angles = angles; + perkEnt.clip.origin = origin; + perkEnt.clip.angles = angles; + perkEnt.bump.origin = origin; + perkEnt.bump.angles = angles; + Trigger = spawn( "trigger_radius", perkEnt.machine.origin, 1, 70, 90 ); + Trigger enableLinkTo(); + Trigger linkto(perkEnt.machine); + + Trigger.targetname = "zombie_vending"; + Trigger.script_noteworthy = perk; + Trigger TriggerIgnoreTeam(); + Trigger.script_sound = "mus_perks_revive_jingle"; + Trigger.script_string = "revive_perk"; + Trigger.script_label = "mus_perks_revive_sting"; + Trigger.target = "vending_sleight"; + Trigger.machine = perkEnt.machine; + Trigger SetCursorHint( "HINT_NOICON" ); + Trigger thread vending_trigger_think_customized(); + + /* vending_triggers = getentarray( "zombie_vending", "targetname" ); + for ( i = 0; i < vending_triggers.size; i++ ) + { + if ( isdefined( vending_triggers[i].script_noteworthy ) && vending_triggers[i].script_noteworthy == perk ) + { + // vending_triggers[i].origin = origin; + // vending_triggers[i].angles = angles; + vending_triggers[i] destroy(); + + vending_triggers[i] = spawn( "trigger_radius", perkEnt.machine.origin, 1, 60, 80 ); + vending_triggers[i] enableLinkTo(); + vending_triggers[i] linkto(perkEnt.machine); + vending_triggers[i] SetCursorHint( "HINT_NOICON" ); + vending_triggers[i] sethintstring( " Hold ^3&&1^7 for Pack-a-Punch [Cost: 5000] \n Weapons can be pack a punched multiple times" ); + } + }*/ +} + +pack_a_punch_init_custom() +{ + level endon ("game_ended"); + + vending_weapon_upgrade_trigger = getentarray( "specialty_weapupgrade", "script_noteworthy" ); + level.pap_triggers = vending_weapon_upgrade_trigger; + + t_pap = getent( "specialty_weapupgrade", "script_noteworthy" ); + + for (;;) + { + if (getdvar("net_port") == "30010") + { + t_pap.machine.origin = (10760.4, -7980.47, -463.875); + t_pap.machine.angles = (358.801, 260, 0); + t_pap.clip.origin = (10760.4, -7980.47, -463.875); + t_pap.clip.angles = (358.801, 260, 0); + t_pap.bump enablelinkto(); + t_pap.bump linkto( t_pap ); + level thread pack_a_punch_think(); + vending_triggers = getentarray( "zombie_vending", "targetname" ); + for ( i = 0; i < vending_triggers.size; i++ ) + { + if ( isdefined( vending_triggers[i].script_noteworthy ) && vending_triggers[i].script_noteworthy == "specialty_weapupgrade" ) + { + vending_triggers[i].origin = (10760.4, -7980.47, -463.875); + vending_triggers[i].angles = (358.801, 260, 0); + } + } + return; + } + else + { + t_pap.machine ghost(); + t_pap.machine notsolid(); + t_pap.bump enablelinkto(); + t_pap.bump linkto( t_pap ); + level thread pack_a_punch_think(); + return; + } + wait 0.5; + } +} + +vending_trigger_think_customized() +{ + self endon( "death" ); + level endon( "game_ended" ); + wait 0.01; + perk = self.script_noteworthy; + solo = 0; + start_on = 0; + level.revive_machine_is_solo = 0; + + if ( isdefined( perk ) && ( perk == "specialty_quickrevive" || perk == "specialty_quickrevive_upgrade" ) ) + { + flag_wait( "start_zombie_round_logic" ); + solo = use_solo_revive(); + self endon( "stop_quickrevive_logic" ); + level.quick_revive_trigger = self; + + if ( solo ) + { + if ( !is_true( level.revive_machine_is_solo ) ) + { + start_on = 1; + players = get_players(); + + foreach ( player in players ) + { + if ( !isdefined( player.lives ) ) + player.lives = 0; + } + + level maps\mp\zombies\_zm::set_default_laststand_pistol( 1 ); + } + level.revive_machine_is_solo = 1; + } + } + + self sethintstring( &"ZOMBIE_NEED_POWER" ); + self setcursorhint( "HINT_NOICON" ); + self usetriggerrequirelookat(); + cost = level.zombie_vars["zombie_perk_cost"]; + + zcoinCost = 9999999; + cost = 9999999; + switch ( perk ) + { + case "specialty_armorvest": + perkname = "^1Juggernog^7"; + cost = 100000; + costString = "100K"; + zcoinCost = 0; + break; + case "specialty_quickrevive": + perkname = "^5Quick Revive^7"; + cost = 300000; + costString = "300K"; + zcoinCost = 5; + break; + case "specialty_fastreload": + perkname = "^2Speed Cola^7"; + cost = 100000; + costString = "100K"; + zcoinCost = 1; + break; + case "specialty_rof": + perkname = "^3Double Tap^7"; + cost = 200000; + costString = "200K"; + zcoinCost = 5; + break; + case "specialty_longersprint": + perkname = "^3Stamin'Up^7"; + cost = 200000; + costString = "200K"; + zcoinCost = 3; + break; + case "specialty_deadshot": + case "specialty_additionalprimaryweapon": + case "specialty_scavenger": + case "specialty_finalstand": + default: + self sethintstring( "error :)" ); + } + self sethintstring("^3Some ^5steps^7 ^3must be completed..."); + + if ( isdefined( level._custom_perks[perk] ) && isdefined( level._custom_perks[perk].cost ) ) + cost = level._custom_perks[perk].cost; + + self.cost = cost; + + notify_name = perk + "_power_on"; + level waittill( notify_name ); + + + if ( !isdefined( level._perkmachinenetworkchoke ) ) + level._perkmachinenetworkchoke = 0; + else + level._perkmachinenetworkchoke++; + + for ( i = 0; i < level._perkmachinenetworkchoke; i++ ) + wait_network_frame(); + + self thread maps\mp\zombies\_zm_audio::perks_a_cola_jingle_timer(); + self thread check_player_has_perk( perk ); + + if ( isdefined( level._custom_perks[perk] ) && isdefined( level._custom_perks[perk].hint_string ) ) + self sethintstring( level._custom_perks[perk].hint_string, cost ); + + perkStamName = "specialty_longersprint"; + perkJuggName = "specialty_armorvest"; + perkQuickName = "specialty_quickrevive"; + perkReloadName = "specialty_fastreload"; + + stamLock = 0; + juggLock = 0; + quickLock = 0; + reloadLock = 0; + + for (;;) + { + if (stamLock == 0 && level.isStamOn == true && perkStamName == perk) + { + self sethintstring("Hold ^3Use^7 for " + perkname + " [^3Cost^7: ^2" + costString + "^7 & ^5" + zcoinCost + " Z-Coins^7]"); + stamLock = 1; + } + if (juggLock == 0 && level.isJuggOn == true && perkJuggName == perk) + { + self sethintstring("Hold ^3Use^7 for " + perkname + " [^3Cost^7: ^2" + costString + "^7 & ^5" + zcoinCost + " Z-Coins^7]"); + juggLock = 1; + } + if (quickLock == 0 && level.isQuickOn == true && perkQuickName == perk) + { + self sethintstring("Hold ^3Use^7 for " + perkname + " [^3Cost^7: ^2" + costString + "^7 & ^5" + zcoinCost + " Z-Coins^7]"); + quickLock = 1; + } + if (reloadLock == 0 && level.isReloadOn == true && perkReloadName == perk) + { + self sethintstring("Hold ^3Use^7 for " + perkname + " [^3Cost^7: ^2" + costString + "^7 & ^5" + zcoinCost + " Z-Coins^7]"); + reloadLock = 1; + } + wait 0.1; + self waittill( "trigger", player ); + if (player UseButtonPressed()) + { + index = maps\mp\zombies\_zm_weapons::get_player_index( player ); + + if (level.isStamOn != true && perkStamName == perk) + { + wait 0.1; + continue; + } + if (level.isJuggOn != true && perkJuggName == perk) + { + wait 0.1; + continue; + } + if (level.isQuickOn != true && perkQuickName == perk) + { + wait 0.1; + continue; + } + if (level.isReloadOn != true && perkReloadName == perk) + { + wait 0.1; + continue; + } + + if ( player maps\mp\zombies\_zm_laststand::player_is_in_laststand() || isdefined( player.intermission ) && player.intermission ) + continue; + + if ( player in_revive_trigger() ) + continue; + + if ( !player maps\mp\zombies\_zm_magicbox::can_buy_weapon() ) + { + wait 0.1; + continue; + } + + if ( player isthrowinggrenade() ) + { + wait 0.1; + continue; + } + + if ( player isswitchingweapons() ) + { + wait 0.1; + continue; + } + + if ( player.is_drinking > 0 ) + { + wait 0.1; + continue; + } + + if ( player hasperk( perk ) || player has_perk_paused( perk ) ) + { + cheat = 0; + /# + if ( getdvarint( _hash_FA81816F ) >= 5 ) + cheat = 1; + #/ + if ( cheat != 1 ) + { + self playsound( "deny" ); + player maps\mp\zombies\_zm_audio::create_and_play_dialog( "general", "perk_deny", undefined, 1 ); + continue; + } + } + + /* if ( isdefined( level.custom_perk_validation ) ) + { + valid = self [[ level.custom_perk_validation ]]( player ); + + if ( !valid ) + continue; + }*/ + + current_cost = cost; + playerzcoin = int(getDvar("zcoins_" + player getGuid())); + if ( player maps\mp\zombies\_zm_pers_upgrades_functions::is_pers_double_points_active() ) + current_cost = player maps\mp\zombies\_zm_pers_upgrades_functions::pers_upgrade_double_points_cost( current_cost ); + + if (playerzcoin < zcoinCost) + { + self playsound( "evt_perk_deny" ); + player maps\mp\zombies\_zm_audio::create_and_play_dialog( "general", "perk_deny", undefined, 0 ); + player iPrintln("Not enough ^5Z-Coins^7 to make that purchase"); + wait 2; + continue; + } + if ( player.score < current_cost ) + { + self playsound( "evt_perk_deny" ); + player maps\mp\zombies\_zm_audio::create_and_play_dialog( "general", "perk_deny", undefined, 0 ); + player iPrintln("Not enough ^2Points^7 to make that purchase"); + wait 2; + continue; + } + + if ( player.num_perks >= player get_player_perk_purchase_limit() ) + { + self playsound( "evt_perk_deny" ); + player maps\mp\zombies\_zm_audio::create_and_play_dialog( "general", "sigh" ); + continue; + } + + sound = "evt_bottle_dispense"; + playsoundatposition( sound, self.origin ); + player maps\mp\zombies\_zm_score::minus_to_player_score( current_cost, 1 ); + setDvar("zcoins_" + player getGuid(), playerzcoin - zcoinCost); + player iprintln("^5" + zcoinCost + " Z-Coins^3 used. Remaining ^5Z-Coins : " + getDvar("zcoins_" + player getGuid()) + "^7"); + player.perk_purchased = perk; + self thread maps\mp\zombies\_zm_audio::play_jingle_or_stinger( self.script_label ); + self thread vending_trigger_post_think( player, perk ); + wait 5; + } + } +} + +check_for_pia_port() +{ + found = 0; + if (isdefined(level.net_port_pia)) + { + foreach(port in level.net_port_pia) + { + if (getdvar("net_port") == port) + found = 1; + } + } + if (found == 0) + return false; + return true; +} \ No newline at end of file diff --git a/t6/scripts/zm/zm_tomb/pet_drones.gsc b/t6/scripts/zm/zm_tomb/pet_drones.gsc new file mode 100644 index 0000000..8480b1c --- /dev/null +++ b/t6/scripts/zm/zm_tomb/pet_drones.gsc @@ -0,0 +1,318 @@ +#include maps\mp\_utility; +#include maps\mp\animscripts\zm_utility; +#include common_scripts\utility; + +init() +{ + if (getDvar("net_port") == "30009") + return; + level.drone_pass_list = []; + level.drone_pass_list[level.drone_pass_list.size] = 1409392; + level.drone_pass_list[level.drone_pass_list.size] = 3793690; + level.drone_pass_list[level.drone_pass_list.size] = 76319; + level.drone_pass_list[level.drone_pass_list.size] = 4207912; + level.drone_pass_list[level.drone_pass_list.size] = 3562334; + level.drone_pass_list[level.drone_pass_list.size] = 3562334; + level.drone_pass_list[level.drone_pass_list.size] = 3651663; + level.drone_pass_list[level.drone_pass_list.size] = 12404; + level.drone_pass_list[level.drone_pass_list.size] = 3647528; + level.drone_pass_list[level.drone_pass_list.size] = 1231669; + level.drone_pass_list[level.drone_pass_list.size] = 813182; + level.drone_pass_list[level.drone_pass_list.size] = 1859204; + level.drone_pass_list[level.drone_pass_list.size] = 4065720; + level.drone_pass_list[level.drone_pass_list.size] = 3477011; + level.drone_pass_list[level.drone_pass_list.size] = 4350989; + level.drone_pass_list[level.drone_pass_list.size] = 1246281; + level.drone_pass_list[level.drone_pass_list.size] = 638471; + level.drone_pass_list[level.drone_pass_list.size] = 2701742; + level.drone_pass_list[level.drone_pass_list.size] = 2362298; + level.drone_pass_list[level.drone_pass_list.size] = 43870; + level.drone_pass_list[level.drone_pass_list.size] = 3605785; + level.drone_pass_list[level.drone_pass_list.size] = 4332223; + level.drone_pass_list[level.drone_pass_list.size] = 2431703; + level.drone_pass_list[level.drone_pass_list.size] = 384664; + level.drone_pass_list[level.drone_pass_list.size] = 4260233; + level.drone_pass_list[level.drone_pass_list.size] = 3758181; + level.drone_pass_list[level.drone_pass_list.size] = 4033708; + level.drone_pass_list[level.drone_pass_list.size] = 161608; + level.drone_pass_list[level.drone_pass_list.size] = 211194; + level.drone_pass_list[level.drone_pass_list.size] = 3594591; + level.drone_pass_list[level.drone_pass_list.size] = 4331907; + level.drone_pass_list[level.drone_pass_list.size] = 3639908; + level.drone_pass_list[level.drone_pass_list.size] = 4379500; + level.drone_pass_list[level.drone_pass_list.size] = 2695864; + level.drone_pass_list[level.drone_pass_list.size] = 46952; + level.drone_pass_list[level.drone_pass_list.size] = 4508749; + level.drone_pass_list[level.drone_pass_list.size] = 2338217; + level.drone_pass_list[level.drone_pass_list.size] = 4274084; + level.drone_pass_list[level.drone_pass_list.size] = 4567245; + level.drone_pass_list[level.drone_pass_list.size] = 1598430; + level.drone_pass_list[level.drone_pass_list.size] = 4397609; + level.drone_pass_list[level.drone_pass_list.size] = 4423522; + level.drone_pass_list[level.drone_pass_list.size] = 4429418; + level.drone_pass_list[level.drone_pass_list.size] = 4105176; + level.drone_pass_list[level.drone_pass_list.size] = 4516531; + level.drone_pass_list[level.drone_pass_list.size] = 1525072; + level.drone_pass_list[level.drone_pass_list.size] = 4402645; + level.drone_pass_list[level.drone_pass_list.size] = 4475944; + level.drone_pass_list[level.drone_pass_list.size] = 1680913; + level.drone_pass_list[level.drone_pass_list.size] = 4278924; + level.drone_pass_list[level.drone_pass_list.size] = 4583058; + level.drone_pass_list[level.drone_pass_list.size] = 1814251; + level.drone_pass_list[level.drone_pass_list.size] = 4403696; + level.drone_pass_list[level.drone_pass_list.size] = 3923832; + level.drone_pass_list[level.drone_pass_list.size] = 2986053; + level.drone_pass_list[level.drone_pass_list.size] = 3760007; + level.drone_pass_list[level.drone_pass_list.size] = 564391; + level.drone_pass_list[level.drone_pass_list.size] = 294733; + level.drone_pass_list[level.drone_pass_list.size] = 47780; + level.drone_pass_list[level.drone_pass_list.size] = 752582; + level.drone_pass_list[level.drone_pass_list.size] = 681362; + level.drone_pass_list[level.drone_pass_list.size] = 1659566; + level.drone_pass_list[level.drone_pass_list.size] = 4567423; + level.drone_pass_list[level.drone_pass_list.size] = 4511018; + level.drone_pass_list[level.drone_pass_list.size] = 2872826; + level.drone_pass_list[level.drone_pass_list.size] = 4784168; + level.drone_pass_list[level.drone_pass_list.size] = 3697647; + + level thread on_player_connect(); +} + +on_player_connect() +{ + level endon("game_ended"); + for (;;) + { + level waittill("connected", player); + + foreach(guid in level.drone_pass_list) + { + if (player getGuid() == guid) + player thread on_player_spawned(); + } + } +} + +on_player_spawned() +{ + self endon("disconnect"); + level endon("game_ended"); + + flag_wait("initial_blackscreen_passed"); + + for (;;) + { + if (self.sessionstate != "spectator") + { + break; + } + wait 0.1; + } + wait 0.1; + + self.anchor = spawn( "script_model", self.origin ); + self.anchor setmodel( "tag_origin" ); + wait 0.1; + self.drone = spawn( "script_model", self.origin ); + self.drone setmodel( "veh_t6_dlc_zm_quadrotor" ); + wait 0.1; + self.elem = randomintrange(1,4); + self.drone setclientfield( "element_glow_fx", self.elem); + self.drone linkto( self.anchor, "tag_origin", (40, 40, 100), (0, 0, 0)); + self thread drone_idle_animation(); + self thread anchor_drone(); + self thread drone_cleanup(); + self thread drone_revive_watcher(); + self thread drone_cooldown_watcher(); + // self thread drone_switch(); +} + +/*drone_switch() +{ + self endon("disconnect"); + level endon("game_ended"); + + self.drone_disabled = false; + for (;;) + { + if (self MeleeButtonPressed() && self AdsButtonPressed()) + { + if (self.drone_disabled == true) + { + self.drone_disabled = false; + self.elem = randomintrange(1,5); + self.drone setclientfield( "element_glow_fx", self.elem); + } + else + { + self.drone_disabled = true; + self.drone setclientfield( "element_glow_fx", 0); + + } + } + wait 0.2; + } +}*/ + +drone_cooldown_watcher() +{ + self endon("disconnect"); + level endon("game_ended"); + + wait 300; + self.can_drone_revive = true; +} + +drone_revive_watcher() +{ + self endon ("disconnect"); + level endon("game_ended"); + + self.can_drone_revive = true; + revive_limit = 9999; + if (getdvar("net_port") == "30010") + revive_limit = 1; + revives = 0; + for (;;) + { + if (self.can_drone_revive == true) + { + + if(self maps\mp\zombies\_zm_laststand::player_is_in_laststand() && revives < revive_limit) + { + self.drone_hud = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 2 ); + self.drone_hud maps\mp\gametypes_zm\_hud_util::setPoint( "CENTER", "CENTER", 0, 80 ); + self.drone_hud.label = &"^3Your ^5drone^7 ^3is ^5reviving^7 ^3you"; + self.drone_hud.alpha = 0.8; + self.drone_hud FadeOverTime(5); + self.drone_hud.alpha = 0; + self.drone_hud delete(); + wait 4.5; + if (self.sessionstate != "spectator" && self maps\mp\zombies\_zm_laststand::player_is_in_laststand()) + { + self playsound( "zmb_drone_revive_fire" ); + self thread maps\mp\zombies\_zm_laststand::auto_revive(self); + self.can_drone_revive = false; + self thread drone_cooldown_watcher(); + revives++; + } + } + } + wait 0.1; + } +} + +drone_cleanup() +{ + level endon("game_ended"); + self waittill("disconnect"); + + self.drone delete(); + self.anchor delete(); +} + +anchor_drone() +{ + self endon("disconnect"); + level endon("game_ended"); + + self.can_drone_shoot = true; + self.lock = false; + is_meleeing = 0; + + for (;;) + { + wait .05; + if (self MeleeButtonPressed() && self.can_drone_shoot == true && !(isdefined(level.is_first_room))) + { + for (i = 0; i < 6; i++) + { + if (self MeleeButtonPressed() && self.can_drone_shoot == true && !(isdefined(level.is_first_room))) + { + is_meleeing = 1; + } + else + { + is_meleeing = 0; + break; + } + wait .05; + } + if (is_meleeing == 0) + continue; + + for (i = 0; i < 10; i++) + { + self playsound( "zmb_drone_revive_revive_3d" ); + } + self thread drone_shoot_cooldown(); + for (i = 0; i < 100; i++) + { + zombies = getaiarray(level.zombie_team); + + foreach(zombie in zombies) + { + if (!isdefined(zombie.is_boss) && !isdefined(zombie.is_midboss) && !isdefined(zombie.is_miniboss) && distance(zombie.origin, self.origin) < 200) + { + end = zombie gettagorigin( "j_spineupper" ); + crosshair = bullettrace( self.drone.origin, end, 0, zombie )[ "position" ]; + weapon = undefined; + if (self.elem == 1) + weapon = "staff_fire_zm"; + else if (self.elem == 2) + weapon = "staff_air_zm"; + else + weapon = "staff_lightning_zm"; + magicbullet( weapon, self.drone.origin, crosshair, self.drone); + zombie dodamage(zombie.health + 666, zombie.origin); + self.anchor.angles = self.angles; + self.anchor.origin = self.origin + (0, 0, self.offset); + continue; + } + } + self.anchor.angles = self.angles; + self.anchor.origin = self.origin + (0, 0, self.offset); + wait .05; + } + } + self.anchor.angles = self.angles; + self.anchor.origin = self.origin + (0, 0, self.offset); + } +} + +drone_shoot_cooldown() +{ + self endon("disconnect"); + level endon("game_ended"); + + wait 5; + self.can_drone_shoot = false; + self.drone setclientfield( "element_glow_fx", 0); + if (getdvar("net_port") == "30010") + wait 90; + else + wait 60; + self.drone setclientfield( "element_glow_fx", self.elem); + self.can_drone_shoot = true; +} + +drone_idle_animation() +{ + self endon("disconnect"); + level endon("game_ended"); + + self.offset = 0; + for (;;) + { + for (i = 0; i < 20; i++) + { + self.offset += 1; + wait 0.1; + } + for (i = 0; i < 20; i++) + { + self.offset -= 1; + wait 0.1; + } + } +} \ No newline at end of file diff --git a/t6/scripts/zm/zm_tomb/raid_boss.gsc b/t6/scripts/zm/zm_tomb/raid_boss.gsc new file mode 100644 index 0000000..a36bac6 --- /dev/null +++ b/t6/scripts/zm/zm_tomb/raid_boss.gsc @@ -0,0 +1,2160 @@ +#include maps\mp\zombies\_zm_magicbox; +#include maps\mp\zombies\_zm_zonemgr; +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\animscripts\zm_utility; +#include maps\mp\zombies\_zm_ai_brutus; +#include maps\mp\zombies\_zm_spawner; +#include maps\mp\animscripts\zm_shared; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zm_alcatraz_utility; +#include maps\mp\zombies\_zm_ai_basic; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\animscripts\shared; +#include maps\mp\zombies\_zm_unitrigger; +#include maps\mp\zombies\_zm_weap_riostshield_prison; +#include maps\mp\animscripts\zm_death; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm_craftables; +#include maps\mp\zm_alcatraz_sq; +#include maps\mp\gametypes_zm\_zm_gametype; + +#include maps\mp\_ambientpackage; +#include maps\mp\zombies\_zm_sidequests; + +#include maps\_utility; +#include maps\_vehicle; +#include maps\mp\zombies\_zm_afterlife; +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\gametypes_zm\_hud; + +#include maps\mp\zombies\_zm_pers_upgrades_system; +#include maps\mp\zombies\_zm_pers_upgrades; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include scripts\AATs_Perks; +#include maps\mp\_visionset_mgr; +#include character\c_zom_cellbreaker; +#include maps\mp\zombies\_zm; + +#include maps\mp\zm_tomb; +#include maps\mp\zm_tomb_distance_tracking; +#include maps\mp\zombies\_zm_perk_electric_cherry; + +#include scripts\zm\zm_tomb\boss_kiels1; +#include scripts\zm\zm_tomb\boss_ivo1; +main() +{ + replacefunc(maps\mp\zombies\_zm_laststand::revive_do_revive, ::revive_do_revive_custom); + replacefunc(maps\mp\zm_tomb::tomb_round_spawn_failsafe, ::tomb_round_spawn_failsafe_custom); + replacefunc(maps\mp\zombies\_zm_spawner::zombie_damage_failsafe, ::zombie_damage_failsafe_custom); + replacefunc(maps\mp\zm_tomb_distance_tracking::delete_zombie_noone_looking , ::delete_zombie_noone_looking_custom); + replacefunc(maps\mp\zombies\_zm_perk_electric_cherry::electric_cherry_stun, ::electric_cherry_stun_custom); +} + +electric_cherry_stun_custom() +{ + self endon( "death" ); + self notify( "stun_zombie" ); + self endon( "stun_zombie" ); + + if (check_for_raid_port() == true) //disabled for raid boss + return; + if ( self.health <= 0 ) + { +/# + iprintln( "trying to stun a dead zombie" ); +#/ + return; + } + + if ( self.ai_state != "find_flesh" ) + return; + + self.forcemovementscriptstate = 1; + self.ignoreall = 1; + + for ( i = 0; i < 2; i++ ) + { + self animscripted( self.origin, self.angles, "zm_afterlife_stun" ); + self maps\mp\animscripts\shared::donotetracks( "stunned" ); + } + + self.forcemovementscriptstate = 0; + self.ignoreall = 0; + self setgoalpos( self.origin ); + self thread maps\mp\zombies\_zm_ai_basic::find_flesh(); +} + +delete_zombie_noone_looking_custom( how_close, how_high ) +{ + self endon( "death" ); + + if (check_for_raid_port() == true) + return; + + if ( !isdefined( how_close ) ) + how_close = 1500; + + if ( !isdefined( how_high ) ) + how_high = 600; + + distance_squared_check = how_close * how_close; + too_far_dist = distance_squared_check * 3; + + if ( isdefined( level.zombie_tracking_too_far_dist ) ) + too_far_dist = level.zombie_tracking_too_far_dist * level.zombie_tracking_too_far_dist; + + self.inview = 0; + self.player_close = 0; + n_distance_squared = 0; + n_height_difference = 0; + players = get_players(); + + for ( i = 0; i < players.size; i++ ) + { + if ( players[i].sessionstate == "spectator" ) + continue; + + if ( isdefined( level.only_track_targeted_players ) ) + { + if ( !isdefined( self.favoriteenemy ) || self.favoriteenemy != players[i] ) + continue; + } + + can_be_seen = self player_can_see_me( players[i] ); + + if ( can_be_seen && distancesquared( self.origin, players[i].origin ) < too_far_dist ) + self.inview++; + + n_modifier = 1.0; + + if ( isdefined( players[i].b_in_tunnels ) && players[i].b_in_tunnels ) + n_modifier = 2.25; + + n_distance_squared = distancesquared( self.origin, players[i].origin ); + n_height_difference = abs( self.origin[2] - players[i].origin[2] ); + + if ( n_distance_squared < distance_squared_check * n_modifier && n_height_difference < how_high ) + self.player_close++; + } + + if ( self.inview == 0 && self.player_close == 0 ) + { + if ( !isdefined( self.animname ) || self.animname != "zombie" && self.animname != "mechz_zombie" ) + return; + + if ( isdefined( self.electrified ) && self.electrified == 1 ) + return; + + if ( isdefined( self.in_the_ground ) && self.in_the_ground == 1 ) + return; + + zombies = getaiarray( "axis" ); + + if ( ( !isdefined( self.damagemod ) || self.damagemod == "MOD_UNKNOWN" ) && self.health < self.maxhealth ) + { + if ( !( isdefined( self.exclude_distance_cleanup_adding_to_total ) && self.exclude_distance_cleanup_adding_to_total ) && !( isdefined( self.isscreecher ) && self.isscreecher ) ) + { + level.zombie_total++; + level.zombie_respawned_health[level.zombie_respawned_health.size] = self.health; + } + } + else if ( zombies.size + level.zombie_total > 24 || zombies.size + level.zombie_total <= 24 && self.health >= self.maxhealth ) + { + if ( !( isdefined( self.exclude_distance_cleanup_adding_to_total ) && self.exclude_distance_cleanup_adding_to_total ) && !( isdefined( self.isscreecher ) && self.isscreecher ) ) + { + level.zombie_total++; + + if ( self.health < level.zombie_health ) + level.zombie_respawned_health[level.zombie_respawned_health.size] = self.health; + } + } + + self maps\mp\zombies\_zm_spawner::reset_attack_spot(); + self notify( "zombie_delete" ); + + if ( isdefined( self.is_mechz ) && self.is_mechz ) + { + self notify( "mechz_cleanup" ); + level.mechz_left_to_spawn++; + wait_network_frame(); + level notify( "spawn_mechz" ); + } + + self delete(); + recalc_zombie_array(); + } +} + +zombie_damage_failsafe_custom() +{ + self endon( "death" ); + continue_failsafe_damage = 0; + + if (check_for_raid_port() == true) + return; + + while ( true ) + { + wait 0.5; + + if ( !isdefined( self.enemy ) || !isplayer( self.enemy ) ) + continue; + + if ( self istouching( self.enemy ) ) + { + old_org = self.origin; + + if ( !continue_failsafe_damage ) + wait 5; + + if ( !isdefined( self.enemy ) || !isplayer( self.enemy ) || self.enemy hasperk( "specialty_armorvest" ) ) + continue; + + if ( self istouching( self.enemy ) && !self.enemy maps\mp\zombies\_zm_laststand::player_is_in_laststand() && isalive( self.enemy ) ) + { + if ( distancesquared( old_org, self.origin ) < 3600 ) + { + self.enemy dodamage( self.enemy.health + 1000, self.enemy.origin, self, self, "none", "MOD_RIFLE_BULLET" ); + continue_failsafe_damage = 1; + } + } + } + else + continue_failsafe_damage = 0; + } +} + +tomb_round_spawn_failsafe_custom() +{ + self endon( "death" ); + prevorigin = self.origin; + + if (check_for_raid_port() == true) + return; + + while ( true ) + { + if ( isdefined( self.ignore_round_spawn_failsafe ) && self.ignore_round_spawn_failsafe ) + return; + + wait 15; + + if ( isdefined( self.is_inert ) && self.is_inert ) + continue; + + if ( isdefined( self.lastchunk_destroy_time ) ) + { + if ( gettime() - self.lastchunk_destroy_time < 8000 ) + continue; + } + + if ( self.origin[2] < -3000 ) + { + if ( isdefined( level.put_timed_out_zombies_back_in_queue ) && level.put_timed_out_zombies_back_in_queue && !flag( "dog_round" ) && !( isdefined( self.isscreecher ) && self.isscreecher ) ) + { + level.zombie_total++; + level.zombie_total_subtract++; + } + + self dodamage( self.health + 100, ( 0, 0, 0 ) ); + break; + } + + if ( distancesquared( self.origin, prevorigin ) < 576 ) + { + if ( isdefined( level.put_timed_out_zombies_back_in_queue ) && level.put_timed_out_zombies_back_in_queue && !flag( "dog_round" ) ) + { + if ( !self.ignoreall && !( isdefined( self.nuked ) && self.nuked ) && !( isdefined( self.marked_for_death ) && self.marked_for_death ) && !( isdefined( self.isscreecher ) && self.isscreecher ) && ( isdefined( self.has_legs ) && self.has_legs ) && !( isdefined( self.is_brutus ) && self.is_brutus ) ) + { + level.zombie_total++; + level.zombie_total_subtract++; + } + } + + level.zombies_timeout_playspace++; + self dodamage( self.health + 100, ( 0, 0, 0 ) ); + break; + } + + prevorigin = self.origin; + } +} + +init() +{ + level.net_port_raid = []; + level.net_port_raid[level.net_port_raid.size] = "30009"; //raid +// level.net_port_raid[level.net_port_raid.size] = "30005"; //pv + + if (check_for_raid_port() == false) + return; + + setdvar("class", "0"); + setdvar("fire_rate", "0.4"); + setdvar("cost", "75"); + setdvar("upgrade", ""); + setdvar("perk_weapRateMultiplier", "0.4"); + level.firewall_duration = 7; + level.fx = []; + level.is_dps_skill_active = 0; + level.boss_hp = 5000000; + level.player_base_maxhealth = 3000; + level.healer_maxhealth = 2000; + level.dps_maxhealth = 2500; + level.tank_maxhealth = 4000; + + /* level.tank_maxhealth = 999000; + level.dps_maxhealth = 999000; + level.healer_maxhealth = 999000;*/ + level.playerhealth_regularregendelay = 9999999; + level.zombie_vars["riotshield_hit_points"] = 1000; + level thread on_player_connect(); + flag_wait("initial_blackscreen_passed"); + flag_set( "activate_zone_chamber" ); + + level thread check_player_count(); + level thread spawn_boss(); + level thread wait_for_dvar(); + level thread boss_hp_watcher(); + level thread random_custom_perk(); + level thread on_boss_death(); +} + +check_player_count() +{ + level.player_count = 0; + wait 1; + foreach(player in level.players) + { + if(player.sessionstate != "spectator") + level.player_count++; + } +} + +on_boss_death() +{ + for (;;) + { + if (isdefined(level.boss)) + break; + wait 0.1; + } + level.boss thread on_boss_death2(); +} + +on_boss_death2() +{ + self waittill("death"); + + foreach(player in level.players) + { + if (player && player.sessionstate != "spectator" && !(player maps\mp\zombies\_zm_laststand::player_is_in_laststand())) + { + foreach(player in level.players) + player thread FinalMsg(); + return; + } + } + +} + +fade_in(duration) +{ + self endon("disconnect"); + + i = 0; + for(;;) + { + if (i >= 1) + break; + self.alpha += 0.05; + wait 0.05; + i += 0.05; + } +} + +fade_out(duration) +{ + self endon("disconnect"); + + i = 1; + for(;;) + { + if (i <= 0) + break; + self.alpha -= 0.05; + wait 0.05; + i -= 0.05; + } +} +preload_msg() +{ + self.preload_hud = maps\mp\gametypes_zm\_hud_util::createFontString ("hudsmall", 5); + self.preload_hud maps\mp\gametypes_zm\_hud_util::setPoint( "TOP", "CENTER", 0, -100); + self.preload_hud settext(" ^3Welcome to the ^1Z-Tavern DLC^7 - ^3Raid Server ^7!\n\n ^3Bind^7 ^1Previous Scorestreak^7 ^3to use your ^1skill^7"); + self.preload_hud.hidewheninmenu = 1; + self.preload_hud.alpha = 0; + self.preload_hud thread fade_in(1); + wait 8; + self.preload_hud thread fade_out(1); + wait 5; + for (;;) + { + if(isdefined(self.class)) + { + if (self.class == "tank") + res = "^5TANK"; + if (self.class == "healer") + res = "^2Healer"; + if (self.class == "dps") + res = "^1DPS"; + break; + } + wait 0.1; + } + + self.preload_hud settext("Your Class : " + res); + self.preload_hud thread fade_in(1); + wait 3; + self.preload_hud thread fade_out(1); + wait 3; + self.preload_hud delete(); +} + +random_custom_perk() +{ + flag_wait("initial_blackscreen_passed"); + + wait 5; + iprintln("^5+Perk^7"); + level.perk_list = []; + + for (;;) + { + r = randomint(4); + if (r == 0) + { + origin = level.fireRadiusOrigin + (0, 0, 0); + } + else if(r == 1) + { + origin = level.iceRadiusOrigin + (0, 0, 0); + } + else if(r == 2) + { + origin = level.lightningRadiusOrigin + (0, 0, 0); + } + else if(r == 3) + { + origin = level.windRadiusOrigin + (0, 0, 0); + } + maps\mp\zombies\_zm_powerups::specific_powerup_drop( "free_perk", origin); + wait 40; + } + + /* // give random perk + foreach(player in level.players) + { + r = randomint(10); + if (r > 80) + { + perk = "Dying_Wish"; + } + else if (r > 60) + { + perk = "Momentum_Mocha"; + } + else if (r > 40) + { + perk = "Bandolier_Bandit"; + } + else if (r > 20) + { + perk = "Downers_Delight"; + } + else + { + perk = "Momentum_Mocha"; + } + player.has_timeslip = 1; + player thread scripts\AATs_Perks::drawshader_and_shadermove( perk, 1, 1, "custom" );*/ + + +} + +boss_hp_watcher() +{ + for (;;) + { + if (isdefined(level.boss.health) && level.boss.health < 200000) + level.true_death = 1; + wait 0.1; + } + +} + +ammoRegen() +{ + self endon("disconnect"); + level endon ("game_ended"); + + if (check_for_raid_port() == false) + return; + for (;;) + { + if (!(self.sessionstate == "spectator")) + { + stockcount = self getweaponammostock( self GetCurrentWeapon() ); + self setWeaponAmmostock( self GetCurrentWeapon(), stockcount + 500 ); + } + wait 3; + } +} + +dodamage_wrapper(damage) +{ + if (isdefined(self.shield) && self.shield > 0) + { + old_damage = damage; + damage -= self.shield; + if (old_damage < self.shield) + self.shield -= old_damage; + else + self.shield = 0; + } + self dodamage(damage, self.origin); +} + +on_player_connect() +{ + if (check_for_raid_port() == false) + return; + + for (;;) + { + level waittill("connected", player); + id = player getEntityNumber(); + player thread TpToCenter(id); + player thread shield_hud(); + player thread healthBarBoss(); + player thread load_class(); + player thread use_skill(); + player thread raid_init(); + player thread ammoregen(); + player thread downed_watcher(); + player thread perma_no_regen(); + player thread give_dtap(); + player thread health_hud(); + player thread preload_msg(); + //if (player.sessionstate != "spectator") + // player thread blessingselector(); + // player thread pers_timer(); + } +} + + +pers_timer() +{ + self.timer = maps\mp\gametypes_zm\_hud_util::createFontString ("hudsmall", 1); + self.timer maps\mp\gametypes_zm\_hud_util::setPoint ("TOP", "RIGHT", 35, -220); + self.timer.hidewheninmenu = 1; + self.timer.alpha = 0.4; +} + +health_hud() +{ + flag_wait("initial_blackscreen_passed"); + self endon("disconnect"); + + + self.p1_hud = maps\mp\gametypes_zm\_hud_util::createFontString ("hudsmall", 1); + self.p1_hud maps\mp\gametypes_zm\_hud_util::setPoint ("BOTTOM", "CENTER", -40, 190); + self.p1_hud.label = &"^5Tank\n^2Healer\n^1DPS\nDPS"; + self.p1_hud.hidewheninmenu = 1; + level.primaryprogressbarwidth = 60; + level.primaryprogressbarheight = 10; + self.p1_bar = self createprimaryprogressbar(); + self.p1_bar.bar.color = (1, 1, 1); + self.p1_bar setpoint(undefined, "BOTTOM", 15, -20); + self.p1_bar.hidewheninmenu = 1; + self.p1_bar.bar.hidewheninmenu = 1; + self.p1_bar.barframe.hidewheninmenu = 1; + level.primaryprogressbarwidth = 400; + level.primaryprogressbarheight = 15; + self thread track_hp(self.p1_bar, 0); + + level.primaryprogressbarwidth = 60; + level.primaryprogressbarheight = 10; + self.p2_bar = self createprimaryprogressbar(); + self.p2_bar setpoint(undefined, "BOTTOM", 15, -8); + self.p2_bar.hidewheninmenu = 1; + self.p2_bar.bar.hidewheninmenu = 1; + self.p2_bar.bar.color = (1, 1, 1); + self.p2_bar.barframe.hidewheninmenu = 1; + level.primaryprogressbarwidth = 400; + level.primaryprogressbarheight = 15; + self thread track_hp(self.p2_bar, 1); + + level.primaryprogressbarwidth = 60; + level.primaryprogressbarheight = 10; + self.p3_bar = self createprimaryprogressbar(); + self.p3_bar setpoint(undefined, "BOTTOM", 15, 4); + self.p3_bar.hidewheninmenu = 1; + self.p3_bar.bar.hidewheninmenu = 1; + self.p3_bar.barframe.hidewheninmenu = 1; + self.p3_bar.bar.color = (1, 1, 1); + level.primaryprogressbarwidth = 400; + level.primaryprogressbarheight = 15; + self thread track_hp(self.p3_bar, 2); + + level.primaryprogressbarwidth = 60; + level.primaryprogressbarheight = 10; + self.p4_bar = self createprimaryprogressbar(); + self.p4_bar.bar.color = (1, 1, 1); + self.p4_bar setpoint(undefined, "BOTTOM", 15, 16); + self.p4_bar.hidewheninmenu = 1; + self.p4_bar.bar.hidewheninmenu = 1; + self.p4_bar.barframe.hidewheninmenu = 1; + level.primaryprogressbarwidth = 400; + level.primaryprogressbarheight = 15; + self thread track_hp(self.p4_bar, 3); + + /* for(;;) + { + + wait 0.1; + }*/ +} + +track_hp(bar, id) +{ + for (;;) + { + foreach(player in level.players) + { + pid = player GetEntityNumber(); + if (id == pid) + { + if (player.sessionstate == "spectator" || player maps\mp\zombies\_zm_laststand::player_is_in_laststand()) + { + bar.bar.color = (1, 0, 0); + if (player.sessionstate == "spectator") + player.health = 1; + } + else + { + bar.bar.color = (0, 1, 0); + if (player.health < player.maxhealth * 0.66) + { + bar.bar.color = (1, 1, 0); + } + if (player.health < player.maxhealth * 0.33) + { + bar.bar.color = (1, 0, 0); + } + } + if (isdefined(player.health) && isdefined(player.maxhealth)) + bar updatebar(player.health / player.maxhealth); + } + } + wait .05; + } +} + + +perma_no_regen() +{ + self endon("disconnect"); + + for (;;) + { + level.playerhealth_regularregendelay = 9999999; + wait .05; + } +} + +downed_watcher() +{ + self endon("disconnect"); + + for (;;) + { + if(self maps\mp\zombies\_zm_laststand::player_is_in_laststand()) + { + self.got_downed = 1; + self.health = 0; + } + else if (isdefined(self.got_downed)) + { + self.got_downed = undefined; + wait 3; + if (self.class == "tank") + self.health = 2000; + else + self.health = 1000; + } + wait 0.1; + } +} + +raid_init() +{ + for(;;) + { + if (isdefined(self.class)) + break; + wait 1; + } + + if (self.class == "tank") + { + // guid = self getguid(); + // if (guid != 564391) + // { + wait 0.1; + r = randomint(3); + if (r == 0) + self thread give_pap_weapon("type95_upgraded_zm"); + if (r == 1) + self thread give_pap_weapon("beretta93r_extclip_upgraded_zm"); + if (r == 2) + self thread give_pap_weapon("ak74u_extclip_upgraded_zm"); + // } + + self thread give_shield(); + } + else if (self.class == "dps") + { + r = randomint(4); + if (r == 0) + self thread give_pap_weapon("scar_upgraded_zm"); + if (r == 1) + self thread give_pap_weapon("galil_upgraded_zm"); + if (r == 2) + self thread give_pap_weapon("mg08_upgraded_zm"); + if (r == 3) + self thread give_pap_weapon("hamr_upgraded_zm"); + } + else if (self.class == "healer") + { + r = randomint(5); + if (r == 0) + self thread give_pap_weapon("thompson_upgraded_zm"); + if (r == 1) + self thread give_pap_weapon("qcw05_upgraded_zm"); + if (r == 2) + self thread give_pap_weapon("evoskorpion_upgraded_zm"); + if (r == 3) + self thread give_pap_weapon("pdw57_upgraded_zm"); + if (r == 4) + self thread give_pap_weapon("mp40_stalker_upgraded_zm"); + } +} + +give_dtap() +{ + self endon("disconnect"); + + flag_wait("initial_blackscreen_passed"); + for (;;) + { + if (self HasPerk("specialty_rof") == 0) + self thread maps\mp\zombies\_zm_perks::wait_give_perk("specialty_rof", 1); + wait 3; + } +} + +give_shield() +{ + self endon("disconnect"); + + for (;;) + { + self.shielddamagetaken = 0; + level.zombie_vars["riotshield_hit_points"] = 1000; + self maps\mp\zombies\_zm_equipment::equipment_give( "tomb_shield_zm" ); + level.zombie_vars["riotshield_hit_points"] = 1000; + wait 300; + } +} +shield_hud() +{ + self endon("disconnect"); + + flag_wait("initial_blackscreen_passed"); + self.shield = 0; + self.shield_hud = maps\mp\gametypes_zm\_hud_util::createFontString ("hudsmall", 1.5); + self.shield_hud maps\mp\gametypes_zm\_hud_util::setPoint ("CENTER", "CENTER", -100, 220); + self.shield_hud.label = &"Shield: ^8"; + for (;;) + { + self.shield_hud setValue(self.shield); + wait 0.1; + } + +} + +use_skill() +{ + self endon("disconnect"); + + for(;;) + { + if (self actionslottwobuttonpressed() && self.skill_cooldown_timer == self.skill_cooldown && self.sessionstate != "spectator") + { + self thread cooldown(); + if (self.class == "tank") + { + iprintln("^8Hold the Line^7 Skill ^3activated!"); + foreach(player in level.players) + { + player thread shield_skill(); + } + } + if (self.class == "dps" && level.is_dps_skill_active == 0) + { + iprintln("^1Gunslinger Skill ^3activated !"); + foreach(player in level.players) + { + player thread crit_skill(); + } + } + if (self.class == "healer") + { + iprintln("^2Zone Heal Skill ^3activated !"); + self thread heal_skill(); + } + } + wait 0.05; + } + +} + +shield_skill() +{ + self endon("disconnect"); + self.shield = 2200; + + diff = 0; + for (;;) + { + if (self.shield + 100 != old_shield) + { + diff = (self.shield + 100) - old_shield; + self iprintln("^1Damage ^8Absorbed ! : " + diff); + } + old_shield = self.shield; + self.shield = self.shield - 100; + if (self.shield <= 0) + { + self.shield = 0; + break; + } + wait 0.2; + } +} + +heal_skill() +{ + healer_pos = self.origin; + tick = 14; + + for (i = 0; i < tick ; i++) + { + foreach(player in level.players) + { + player thread check_heal_dist(healer_pos); + } + wait 0.25; + } +} + +check_heal_dist(healer_pos) +{ + if (distance(healer_pos, self.origin) < 1300) + { + if (distance(healer_pos, self.origin) < 1) + { + healer = self; + self iprintln("Healed for : ^2" + 50 + " HP^7 !"); + } + if (isdefined(healer)) + healer iprintln("Healing " + self.name + "for : ^3" + 50 + " HP^7 !"); + if (self.health + 50 > self.maxhealth) + self.health = self.maxhealth; + else + { + self.health += 50; + } + } +} + +crit_skill() +{ + self endon ("disconnect"); + level.is_dps_skill_active = 1; + old_ms = self GetMoveSpeedScale(); + self SetMoveSpeedScale(1.6); + setdvar("fire_rate", 0.2); + setdvar("perk_weapRateMultiplier", 0.2); + self thread infinite_ammo(); + wait 5; + setdvar("fire_rate", 0.4); + setdvar("perk_weapRateMultiplier", 0.4); + self SetMoveSpeedScale(old_ms); + level.is_dps_skill_active = 0; +} + +infinite_ammo() +{ + self endon("disconnect"); + + for (i = 0; i < 40; i++) + { + self SetWeaponAmmoClip(self GetCurrentWeapon(), 100); + wait .1; + } +} + +cooldown() +{ + self endon("disconnect"); + + self.skill_cooldown_timer = 0; + + for (i = 0; i < self.skill_cooldown; i++) + { + self.skill_cooldown_timer++; + wait 1; + } +} + +skill_cooldown() +{ + self endon("disconnect"); + level endon("game_ended"); + + level.primaryprogressbarwidth = 60; + level.primaryprogressbarheight = 5; + self.cd_bar = self createprimaryprogressbar(); + self.cd_bar setpoint(undefined, "BOTTOM", 219, 20); + self.cd_bar.hidewheninmenu = 1; + self.cd_bar.bar.hidewheninmenu = 1; + self.cd_bar.barframe.hidewheninmenu = 1; + + level.primaryprogressbarwidth = 400; + level.primaryprogressbarheight = 15; + + for (;;) + { + self.cd_bar updatebar(self.skill_cooldown_timer / self.skill_cooldown); + if (self.skill_cooldown_timer == self.skill_cooldown) + { + self.notifyiconb2.color = (0, 1, 0); + self.notifyiconb2.alpha = 1; + self.cd_bar.color = ( 0, 1, 0 ); + } + else + { + self.notifyiconb2.color = (1, 0, 0); + self.notifyiconb2.alpha = 0.8; + self.cd_bar.color = ( 1, 0, 0 ); + } + + if(isdefined(self.cd_bar.color)) + self.cd_bar.bar.color = self.cd_bar.color; + wait .05; + } +} + + +drawshader( shader, x, y, width, height, color, alpha) +{ + level endon("end_game"); + self endon("disconnect"); + hud = newclienthudelem( self ); + hud.elemtype = "icon"; + hud.color = color; + hud.alpha = alpha; + hud.sort = 0; + hud.children = []; + hud.hidewheninmenu = 1; + hud setparent(self.guild_menu ); + hud setshader( shader, width, height ); + hud.x = x; + hud.y = y; + hud.foreground = 0; + return hud; +} + + +load_class() +{ + flag_wait("initial_blackscreen_passed"); + wait 4; + guid = self getguid(); + id = self GetEntityNumber(); + if (id == 0) + { + self.class = "tank"; + } + + if (id == 1) + { + self.class = "healer"; + } + if (id >= 2) + { + self.class = "dps"; + } + /* if (guid == 3968479) + { + foreach(player in level.players) + { + if (player.class == "healer") + player.class = "dps"; + } + self.class = "healer"; + }*/ + + /* if (guid == 564391) + { + foreach(player in level.players) + { + if (player.class == "tank") + { + wait 0.1; + foreach (playerr in level.players) + { + if (playerr.class == "tank") + { + playerr.class = "dps"; + break; + } + if (playerr.class == "healer") + { + is_healer_free = 0; + playerr.class = "healer"; + break; + } + is_healer_free = 1; + } + self iprintln("[^1Kiels Bot^7] : Login ^1Kiels^7 detected.. Access ^2granted^. Please wait ^5a few seconds. Beep boop i'm a ^8bot^7"); + wait 1.5; + self iprintln("[^1Kiels Bot^7] : Custom AK ^2Granted !^7"); + + + + + wait 0.2; + + self maps\mp\zombies\_zm_equipment::equipment_give( "tomb_shield_zm" ); + } + + } + self.class = "tank"; + }*/ + + if (self.class == "healer") + { + self thread load_healer_class(); + } + else if (self.class == "dps") + { + self thread load_dps_class(); + } + else if (self.class == "tank") + { + self thread load_tank_class(); + } + else + { + self thread perma_hp_change(2000); //failsafe + } + + + shader = "zombies_rank_3"; + self.notifyiconb = self drawshader(shader, 580, 165, 50, 50, (0, 0, 0)); + self.notifyiconb.alpha = 1; + self.notifyiconb2 = self drawshader(shader, 580, 168, 45, 45, (0, 1, 0)); + self.notifyiconb2.alpha = 1; + self.hidewheninmenu = 1; + if (getdvar("skill_cooldown") == "1") + self.skill_cooldown = 10; + else + self.skill_cooldown = 15; + self.skill_cooldown_timer = self.skill_cooldown; + self thread skill_cooldown(); +} + +give_pap_weapon(upgrade_name) +{ + self giveweapon( upgrade_name, 0, self maps\mp\zombies\_zm_weapons::get_pack_a_punch_weapon_options( upgrade_name ) ); + self SwitchToWeapon(upgrade_name); +} + +load_healer_class() +{ + self thread perma_hp_change(level.healer_maxhealth); +} + +load_dps_class() +{ + self thread perma_hp_change(level.dps_maxhealth); +} + +load_tank_class() +{ + self thread perma_hp_change(level.tank_maxhealth); +} + +perma_hp_change(maxhp) +{ + self.maxhealth = maxhp; + old_maxhealth = self.maxhealth; + self.health = self.maxhealth; + for (;;) + { + if (isdefined(self.maxhealth) && self.maxhealth != old_maxhealth) + { + self.maxhealth = maxhp; + self.health = self.maxhealth; + } + wait 0.1; + } +} + +wait_for_dvar() +{ + for (;;) + { + if (getdvar("class") != "0") + { + break; + } + wait 0.1; + } + class_list = StrTok(getdvar("class"), ";"); + foreach(player in level.players) + { + if (player getGuid() == int(class_list[0])) + { + player.class = class_list[1]; + } + if (player getGuid() == int(class_list[2])) + { + player.class = class_list[3]; + } + if (player getGuid() == int(class_list[4])) + { + player.class = class_list[5]; + } + if (player getGuid() == int(class_list[6])) + { + player.class = class_list[7]; + } + } + +} + + +getPlayerByGuid(guid) +{ + for (i = 0; i < level.players.size; i++) { + if (isAlive(level.players[i]) && int(level.players[i] getGuid()) == int(guid)) { + return level.players[i]; + } + } + return false; +} + +spawn_boss() +{ + for (;;) + { + if (level.zombie_total != 0) + break; + wait 0.1; + } + zombies = getaiarray(level.zombie_team); + foreach(zombie in zombies) + { + zombie DoDamage(zombie.health + 1, zombie.origin); + } + level.zombie_total = 1; + wait 2; + // if (getdvar("boss_type") == "1") + // level thread setup_boss_kiels1(); + // else if (getdvar("boss_type") == "2") + level thread setup_boss_ivo1(); + // else if (getdvar("boss_type") == "3") + // level thread setup_boss_kong1(); +} + +FinalMsg() +{ + level endon("game_ended"); + self endon("disconnect"); + level endon( "intermission" ); + + if (!isdefined(level.true_death)) + { + self iprintln("[^1Kiels Bot^7] ^3Bugged Boss^7 detected, I will ^5restart^7 the server ! ^2#Donate^7 to help fix bugs ^1<3^7"); + wait 5; + executeCommand("fast_restart"); + return; + } + + foreach(player in level.players) + { + player enableInvulnerability(); + } + + setdvar("raid_boss_quest", ((GetTime() - level.start_time) / 1000 / 60)); + iprintln("^3Raid completed^7 in : ^2" + ((GetTime() - level.start_time) / 1000 / 60) + "^7 minutes !"); + + setDvar("EE_Completion", "PiA_Final_GigaChad"); + self.zombieTextXx = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 4 ); + self.zombieTextXx maps\mp\gametypes_zm\_hud_util::setPoint( "CENTER", "CENTER", 0, -160 ); + self.zombieTextXx.label = &"^5CONGRATULATIONS !"; + self.zombieTextXx.alpha = 0.8; + for (i = 0; i < 20; i++) + { + self.zombieTextXx.label = &"^1Raid Cleared !"; + wait 1; + self.zombieTextXx.label = &"^3Raid Cleared !"; + } + executeCommand("fast_restart"); +} + +TpToCenter(id) +{ + level endon ("game_ended"); + self endon("disconnect"); + + if (id == 0) + { + origin = (10463.8, -8036.59, -419.875); + angle = (0, 135, 0); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 1) + { + origin = (10216, -7776.28, -419.875); + angle = (0, 315, 0); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 2) + { + origin = (10212.8, -8044.76, -419.875); + angle = (0, 45, 0); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 3) + { + origin = (10472.6, -7778.6, -419.875); + angle = (0, 225, 0); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 4) + { + origin = (10672.6, -7778.6, -419.875); + angle = (0, 225, 0); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 5) + { + origin = (10272.6, -7778.6, -419.875); + angle = (0, 225, 0); + self setOrigin(origin); + self SetPlayerAngles(angle); + } +} + +generateInvisiblePerk(pos, angles) +{ + iWall = spawn( "script_model", pos ); + iWall setmodel( "zm_collision_perks1" ); + iWall.angles = angles; + + /*col = spawn( "script_model", pos); + col setmodel( "zombie_vending_jugg_on" ); + col.angles = angles;*/ +} + +healthBarBoss() +{ + level endon("end_game"); + self endon("disconnect"); + + flag_wait("initial_blackscreen_passed"); + for (;;) + { + if (isdefined(level.is_boss_spawned)) + break; + wait 0.1; + } + level.primaryprogressbarwidth = 400; + level.primaryprogressbarheight = 15; + boss_bar = self createprimaryprogressbar(); + boss_bar setpoint(undefined, "TOP", 0, 0); + boss_bar.bar.color = (0, 1, 0); + + boss_bar.hidewheninmenu = 1; + boss_bar.bar.hidewheninmenu = 1; + boss_bar.barframe.hidewheninmenu = 1; + + boss_name_text = createprimaryprogressbartext(); + + boss_health_text = createprimaryprogressbartext(); + + boss_name_text setpoint(undefined, "TOP", 0, -25); + + boss_health_text setpoint(undefined, "TOP", 0, 0); + + boss_name_text.fontscale = 1.5; + txt = "^1Raid Boss " + level.boss.name; + boss_name_text settext(txt); + + boss_health_text.hidewheninmenu = 1; + while (1) + { + if (!level.boss.health || level.boss.health < 0) + { + boss_bar.barframe destroy(); + boss_bar.bar destroy(); + boss_bar destroy(); + boss_name_text destroy(); + boss_health_text destroy(); + return; + } + if (level.boss.health / level.boss.maxhealth > 0.5) + { + boss_bar.bar.color = ( level.boss.maxhealth / level.boss.health - 1, 1, 0 ); + } + + if (level.boss.health / level.boss.maxhealth == 0.5) + { + boss_bar.bar.color = ( 1, 1, 0 ); + } + + if (level.boss.health / level.boss.maxhealth < 0.5) + { + boss_bar.bar.color = ( 1, (level.boss.health / level.boss.maxhealth) * 2, 0 ); + } + + if (level.boss.health == 0) + { + return; + } + + boss_bar updatebar(level.boss.health / level.boss.maxhealth); + if (isdefined(level.boss.candamage) && level.boss.candamage == 0) + { + boss_bar.bar.color = ( 1, 1, 1 ); + } + if (level.boss.health > 10000000) + boss_health_text settext("^715M"); + else if (level.boss.health > 5000000) + boss_health_text settext("^710M"); + else if (level.boss.health > 3000000) + boss_health_text settext("^75M"); + else if (level.boss.health > 2000000) + boss_health_text settext("^73M"); + else if (level.boss.health > 1000000) + boss_health_text settext("^72M"); + else + { + boss_health_text settext(""); + boss_health_text setvalue(level.boss.health); + } + wait 0.3; + } +} + +revive_do_revive_custom( playerbeingrevived, revivergun ) +{ + assert( self is_reviving( playerbeingrevived ) ); + revivetime = 3; + + if ( self hasperk( "specialty_quickrevive" ) ) + revivetime /= 2; + + if ( self maps\mp\zombies\_zm_pers_upgrades_functions::pers_revive_active() ) + revivetime *= 0.5; + + if (check_for_raid_port() == true) + { + if (!isdefined(self.class) || self.class != "healer") + revivetime = 15; + else + revivetime = 1; + + timer = 0; + revived = 0; + playerbeingrevived.revivetrigger.beingrevived = 1; + playerbeingrevived.revive_hud settext( &"ZOMBIE_PLAYER_IS_REVIVING_YOU", self ); + playerbeingrevived revive_hud_show_n_fade( 3.0 ); + playerbeingrevived.revivetrigger sethintstring( "" ); + + if ( isplayer( playerbeingrevived ) ) + playerbeingrevived startrevive( self ); + + if ( !isdefined( self.reviveprogressbar ) ) + self.reviveprogressbar = self createprimaryprogressbar(); + + if ( !isdefined( self.revivetexthud ) ) + self.revivetexthud = newclienthudelem( self ); + + self thread laststand_clean_up_on_disconnect( playerbeingrevived, revivergun ); + + if ( !isdefined( self.is_reviving_any ) ) + self.is_reviving_any = 0; + + self.is_reviving_any++; + self thread laststand_clean_up_reviving_any( playerbeingrevived ); + self.reviveprogressbar updatebar( 0.01, 1 / revivetime ); + self.revivetexthud.alignx = "center"; + self.revivetexthud.aligny = "middle"; + self.revivetexthud.horzalign = "center"; + self.revivetexthud.vertalign = "bottom"; + self.revivetexthud.y = -113; + + if ( self issplitscreen() ) + self.revivetexthud.y = -347; + + self.revivetexthud.foreground = 1; + self.revivetexthud.font = "default"; + self.revivetexthud.fontscale = 1.8; + self.revivetexthud.alpha = 1; + self.revivetexthud.color = ( 1, 1, 1 ); + self.revivetexthud.hidewheninmenu = 1; + + if ( self maps\mp\zombies\_zm_pers_upgrades_functions::pers_revive_active() ) + self.revivetexthud.color = ( 0.5, 0.5, 1.0 ); + + self.revivetexthud settext( &"ZOMBIE_REVIVING" ); + self thread check_for_failed_revive( playerbeingrevived ); + + while ( self is_reviving( playerbeingrevived ) ) + { + wait 0.05; + timer += 0.05; + + if ( self player_is_in_laststand() ) + break; + + if ( isdefined( playerbeingrevived.revivetrigger.auto_revive ) && playerbeingrevived.revivetrigger.auto_revive == 1 ) + break; + + if ( timer >= revivetime ) + { + revived = 1; + break; + } + } + + if ( isdefined( self.reviveprogressbar ) ) + self.reviveprogressbar destroyelem(); + + if ( isdefined( self.revivetexthud ) ) + self.revivetexthud destroy(); + + if ( isdefined( playerbeingrevived.revivetrigger.auto_revive ) && playerbeingrevived.revivetrigger.auto_revive == 1 ) + { + + } + else if ( !revived ) + { + if ( isplayer( playerbeingrevived ) ) + playerbeingrevived stoprevive( self ); + } + + playerbeingrevived.revivetrigger sethintstring( &"ZOMBIE_BUTTON_TO_REVIVE_PLAYER" ); + playerbeingrevived.revivetrigger.beingrevived = 0; + self notify( "do_revive_ended_normally" ); + self.is_reviving_any--; + + if ( !revived ) + playerbeingrevived thread checkforbleedout( self ); + + return revived; +}} + + +blessingArray(x, gunslinger, extraLife, magicWeapon, speedRunner, quickRevive, juggernautPlus) +{ + blessingArray = []; + if (x == 0) + { + blessingArray = gunslinger; + } + else if (x == 1) + { + blessingArray = extraLife; + } + else if (x == 2) + { + blessingArray = magicWeapon; + } + else if (x == 3) + { + blessingArray = speedRunner; + } + else if (x == 4) + { + blessingArray = quickRevive; + } + else if (x == 5) + { + blessingArray = juggernautPlus; + } + return blessingArray; +} + +blessingSelector() +{ + self endon("disconnect"); + level endon ("game_ended"); + + self FreezeControlsAllowLook(1); + + selector = "left"; + tag = strTok(self.name, "]"); + + gunslinger = []; + gunslinger[0] = "^1Gunslinger^7"; + gunslinger[1] = "^3Permanent Double Tap"; + + extraLife = []; + extraLife[0] = "^1Extra Life^7"; + extraLife[1] = "^3Grant 1 Dying wish charge"; + + magicWeapon = []; + magicWeapon[0] = "^1Magic Weapon^7"; + magicWeapon[1] = "^3Gain a special weapon"; + + speedRunner = []; + speedRunner[0] = "^1Speed Runner^7"; + speedRunner[1] = "^3Increase your speed"; + + quickRevive = []; + quickRevive[0] = "^1Medic"; + quickRevive[1] = "^3Increase revive speed"; + + juggernautPlus = []; + juggernautPlus[0] = "^1Juggernaut^7"; + juggernautPlus[1] = "^3Increase your HP"; + + for (;;) + { + x = randomintrange(0, 6); + if ((x == 4 || x == 1) && (tag[1] == "^6[VIP" || tag[1] == "[^6VIP^7" || tag[1] == "^1[VIP" || tag[1] == "[^1VIP^7" || tag[1] == "[^2VIP^7")) + continue; + break; + } + for (;;) + { + y = randomintrange(0, 6); + if (y != x) + { + if ((y == 4 || y == 1) && (tag[1] == "^6[VIP" || tag[1] == "[^6VIP^7" || tag[1] == "^1[VIP" || tag[1] == "[^1VIP^7" || tag[1] == "[^2VIP^7")) + continue; + break; + } + } + blessingArrayLeft = blessingArray(x, gunslinger, extraLife, magicWeapon, speedRunner, quickRevive, juggernautPlus); + blessingArrayRight = blessingArray(y, gunslinger, extraLife, magicWeapon, speedRunner, quickRevive, juggernautPlus); + + second_blessing = 1; + if (tag[0] != "[^3SSS^7" && tag[0] != "[^6 I ^7" && tag[0] != "[^6II^7" && tag[0] != "[^6III^7" + && tag[1] != "^3[VIP" && tag[1] != "[^3VIP^7" && tag[1] != "^6[VIP" && tag[1] != "[^6VIP^7" + && tag[0] != "[^5IV^7" && tag[0] != "[^5V^7" && tag[0] != "[^5VI^7" && tag[0] != "[^5VII^7" + && tag[0] != "[^1IIX^7]" && tag[0] != "[^1IX^7]" && tag[0] != "[^1-X-^7]" + && tag[1] != "[^1VIP^7" && tag[1] != "^1[VIP" + && tag[1] != "[^2VIP^7" + ) + { + second_blessing = 0; + blessingArrayRight[0] = "^1 LOCKED ^7"; + blessingArrayRight[1] = "Additionnal ^5blessing^7\n is reserved for\n ^3VIP & SSS ONLY^7"; + } + + self.zombieChoiceA.alpha = 1; + self.zombieChoiceAdesc.alpha = 1; + self.zombieChoiceLeft.alpha = 1; + self.zombieChoiceLeftDesc.alpha = 1; + self.zombieChoiceRight.alpha = 1; + self.zombieChoiceRightDesc.alpha = 1; + self.notifyiconb.alpha = 1; + self.notifyicon.alpha = 1; + self.notifyicon2b.alpha = 1; + self.notifyicon2.alpha = 1; + self.notifyiconA.alpha = 1; + self.notifyicon2a .alpha = 1; + + self.zombieChoiceA settext("^5Select your Blessing"); + self.zombieChoiceAdesc settext("^3Melee^5 to switch, ^3Use^5 to confirm^7"); + foreach(guid in level.premium_pass_guid_list) + { + if (self getguid() == guid) + { + self.zombieChoiceAdesc settext("^3Melee^5 to switch, ^3Use^5 to confirm^7\n ^3Jump^5 to reroll"); + } + } + self.zombieChoiceLeft settext("^3[^7" + blessingArrayLeft[0] + "^3]^7"); + self.zombieChoiceLeftDesc settext(blessingArrayLeft[1]); + self.zombieChoiceRight settext(blessingArrayRight[0]); + self.zombieChoiceRightDesc settext(blessingArrayRight[1]); + cost = 20; + iteration = 0; + for (i = 0; i < 600; i++) // i < 600 + { + if (self meleeButtonPressed()) + { + if (selector == "left") + { + selector = "right"; + self.zombieChoiceRight settext("^3[^7" + blessingArrayRight[0] + "^3]^7"); + self.zombieChoiceLeft settext(blessingArrayLeft[0]); + wait 0.2; + } + else if (selector == "right") + { + selector = "left"; + self.zombieChoiceLeft settext("^3[^7" + blessingArrayLeft[0] + "^3]^7"); + self.zombieChoiceRight settext(blessingArrayRight[0]); + wait 0.2; + } + } + if (self UseButtonPressed()) + { + if (selector == "left") + { + self thread applyBlessing(x); + for (i = 0; i < 10; i++) + { + playfx( level._effect["tesla_elec_kill"], self.origin ); + } + self playsound( "evt_medal_acquired" ); + break; + } + else if (selector == "right" && second_blessing == 1) + { + self thread applyBlessing(y); + for (i = 0; i < 10; i++) + { + playfx( level._effect["tesla_elec_kill"], self.origin ); + } + self playsound( "evt_medal_acquired" ); + break; + } + + } + if (self JumpButtonPressed() && (!isdefined(self.has_rerolled))) + { + foreach(guid in level.premium_pass_guid_list) + { + if (self getguid() == guid) + { + if (iteration < 2) + cost = 0; + else if (iteration == 2) + cost = 10; + } + } + iteration++; + + playerzcoin = int(getDvar("zcoins_" + self getGuid())); + if (playerzcoin - cost < 0) + { + self playsound("zmb_no_cha_ching"); + self iprintln("Out of ^5Z-Coins^7 !"); + wait 0.2; + continue; + } + self playsound("zmb_cha_ching"); + res = playerzcoin - cost; + setDvar("zcoins_" + self getGuid(), res); + if (cost == 0) + self iprintln("Used ^3Premium Pass^7 free reroll !"); + else + self iprintln("^5" + cost + " Z-Coins^3 used. Remaining ^5Z-Coins : " + getDvar("zcoins_" + self getGuid()) + "^7"); + cost = int(cost * 1.3); + wait 0.1; + old_x = x; + old_y = y; + for (;;) + { + x = randomintrange(0, 5); + if ((x == 4 || x == 1) && (tag[1] == "^6[VIP" || tag[1] == "[^6VIP^7" || tag[1] == "[^1VIP^7" || tag[1] == "[^1VIP^7" || tag[1] == "[^2VIP^7")) + continue; + break; + } + for (;;) + { + y = randomintrange(0, 5); + if (y != x) + { + if ((y == 4 || y == 1) && (tag[1] == "^6[VIP" || tag[1] == "[^6VIP^7" || tag[1] == "[^1VIP^7" || tag[1] == "[^1VIP^7"|| tag[1] == "[^2VIP^7" )) + continue; + break; + } + } + + blessingArrayLeft = blessingArray(x, gunslinger, extraLife, magicWeapon, speedRunner, quickRevive, juggernautPlus); + blessingArrayRight = blessingArray(y, gunslinger, extraLife, magicWeapon, speedRunner, quickRevive, juggernautPlus); + selector = "left"; + self.zombieChoiceLeft settext("^3[^7" + blessingArrayLeft[0] + "^3]^7"); + self.zombieChoiceLeftDesc settext(blessingArrayLeft[1]); + self.zombieChoiceRight settext(blessingArrayRight[0]); + self.zombieChoiceRightDesc settext(blessingArrayRight[1]); + wait 0.2; + } + wait 0.05; + } + + self.zombieChoiceLeft destroy(); + self.zombieChoiceRight destroy(); + self.zombieChoiceRightDesc destroy(); + self.zombieChoiceLeftDesc destroy(); + self.zombieChoiceAdesc destroy(); + self.zombieChoiceA destroy(); + self.zombieChoiceDown destroy(); + self.zombieChoiceDownDesc destroy(); + self.notifyicon destroy(); + self.notifyiconb destroy(); + self.notifyicon2 destroy(); + self.notifyicon2b destroy(); + self.notifyiconA destroy(); + self.notifyicon2a destroy(); + self.notifyicon3b destroy(); + self.notifyicon3 destroy(); + + self.hasBlessing = 1; + wait 2; + self FreezeControlsAllowLook(0); +} + +applyBlessing(blessingNumber) +{ + self endon("disconnect"); + level endon ("game_ended"); + + if (blessingNumber == 0) + { + self thread permaDoubleTap(); + self iPrintln("^3A Mighty beer for the finest ^5Gunslinger"); + } + else if (blessingNumber == 1) + { + self thread scripts\AATs_Perks::drawshader_and_shadermove( "Dying_Wish", 1, 1, "custom" ); + self iPrintln("^3It feels like ^5a guardian angel^3 is watching you^7 !"); + } + else if (blessingNumber == 2) + { + weapon_loadout = self GetWeaponsListPrimaries(); + if (weapon_loadout.size >= 2) + self TakeWeapon(self GetCurrentWeapon()); + i = randomintrange(0, 5); + weapon_name = ""; + if (i == 0) + weapon_name = "scar_zm"; + else if (i == 1) + weapon_name = "staff_lightning_zm"; + else if (i == 2) + weapon_name = "mg08_zm"; + else if (i == 3) + weapon_name = "c96_zm"; + /* else if (i == 4) +{ + self thread maps\mp\zombies\_zm_weap_beacon::player_give_beacon(); +}*/ + else if (i == 4) + weapon_name = "tomb_shield_zm"; + else if (i == 5) + weapon_name = "equip_dieseldrone_zm"; + if (weapon_name == "tomb_shield_zm") + { + self maps\mp\zombies\_zm_equipment::equipment_give( weapon_name ); + self iPrintln("^3A ^2magic Zombie Shield ^5suddenly materialized^3 in your back"); + return; + } + weapon_loadout = self GetWeaponsListPrimaries(); + if (weapon_loadout.size >= 2) + self TakeWeapon(self GetCurrentWeapon()); + self GiveWeapon(weapon_name); + self SwitchToWeapon(weapon_name); + self iPrintln("^3A ^2magic weapon ^5suddenly materialized^3 in your hand!"); + } + else if (blessingNumber == 3) + { + self.extrams = 1; + self thread permaSpeedRunner(); + self iPrintln("^3You feel as ^5light as a feather!^7"); + } + else if (blessingNumber == 4) + { + self thread permaQuickRevive(); + self iPrintln("^3No team survives without a ^5Medic"); + } + else if (blessingNumber == 5) + { + self.extrahp = 1; + self iPrintln("^3You feel ^1bulkier^7"); + } + if (blessingNumber != 4) + self thread noPermaQuickRevive(); +} + +permaSpeedRunner() +{ + self endon ("disconnect"); + level endon ("game_ended"); + for (;;) + { + self SetMoveSpeedScale(1.4 + level.extra_speed); + wait 1; + } +} + +noPermaQuickRevive() +{ + self endon("disconnect"); + level endon ("game_ended"); + + tag = strTok(self.name, "]"); + if (tag[1] == "^6[VIP" || tag[1] == "[^6VIP^7" || tag[1] == "^1[VIP" || tag[1] == "[^1VIP^7" || tag[1] == "[^2VIP^7") + { + return; + } + for (;;) + { + self.pers_upgrades_awarded["revive"] = 0; + wait 1; + } +} + +permaQuickRevive() +{ + self endon ("disconnect"); + level endon ("game_ended"); + for (;;) + { + self.pers_upgrades_awarded["revive"] = 1; + wait 0.1; + } +} + +permaDoubleTap() +{ + self endon ("disconnect"); + level endon ("game_ended"); + for (;;) + { + if (self HasPerk("specialty_rof") == 0) + self thread maps\mp\zombies\_zm_perks::wait_give_perk("specialty_rof", 1); + wait 1; + } +} + + + +miniboss_ice_think(is_midboss) +{ + level endon ("game_ended"); + + self thread miniboss_ice_spawn_mine(is_midboss); + fx = spawn( "script_model", self.origin); + fx linkto( self, "J_SpineLower", (0, 0, 0), (90, 0, 0)); + wait .1; + fx setmodel( "tag_origin" ); + for (;;) + { + playfxontag( level._effect["staff_water_blizzard"], fx, "tag_origin" ); + for(i = 0; i < 100; i++) + { + if (isdefined(self.is_dead)) + { + fx delete(); + return; + } + wait 0.1; + } + } +} + +miniboss_lightning_think(is_midboss) +{ + level endon("game_ended"); + + self thread miniboss_lightning_spawn_orbs(is_midboss); +} + +miniboss_wind_think(is_midboss) +{ + level endon("game_ended"); + + angles = self.angles; + self thread miniboss_tornado(angles, is_midboss); + wait 0.1; + self thread miniboss_tornado(angles + (0, 180, 0), is_midboss); +} + +miniboss_fire_think(is_midboss) +{ + level endon("game_ended"); + self waittill("spawned"); + + for (;;) + { + self set_zombie_run_cycle("sprint"); + fx = spawn( "script_model", self.origin); + wait .1; + fx linkto( self, "J_SpineLower", (0, 0, -15), (0, 0, 0)); + fx setmodel( "tag_origin" ); + playfxontag( level._effect["fx_tomb_fire_lg"], fx, "tag_origin" ); + for (i = 1; i < 50; i++) + { + if (isdefined(self.is_dead)) + { + fx delete(); + return; + } + wait 0.1; + } + fx delete(); + playfx( level._effect["biplane_explode"], self.origin); + foreach(player in level.players) + { + if (distancesquared(self.origin, player.origin) < 60000 && player.ignoreme != true) + { + player dodamage_wrapper(800); + direction_forward = anglestoforward( flat_angle( self.angles ) + vectorscale( ( -1, 0, 0 ), 60.0 ) ); + direction_vector = vectorscale( direction_forward, 3000 ); + player yeet_player(player.origin + vectorscale( ( 0, 0, 1 ), 30.0 ), player.angles, direction_vector); + } + } + self set_zombie_run_cycle("run"); + cooldown = 5; + if(is_midboss) + cooldown = 2; + for (i = 1; i < cooldown * 10; i++) + { + if (isdefined(self.is_dead)) + { + fx delete(); + return; + } + wait 0.1; + } + + } +} + +yeet_player(origin, angles, velocity) +{ + torigin = ( self.origin[0], self.origin[1], origin[2] ); + aorigin = ( origin + torigin ) * 0.5; + trace = physicstrace( origin, torigin, vectorscale( ( -1, -1, 0 ), 15.0 ), ( 15, 15, 30 ), self ); + + self setorigin( aorigin ); + wait_network_frame(); + self setvelocity( velocity ); +} + +miniboss_ice_spawn_mine(is_midboss) +{ + level endon("game_ended"); + + direction = (0, 0, 0); + + for (i = 0; i < 4; i++) + { + self thread miniboss_ice_mine_think(direction, is_midboss); + direction += (0, 90, 0); + } + wait 5; +} + +miniboss_ice_mine_think(direction, is_midboss) +{ + self waittill("spawned"); + + fx = spawn( "script_model", self.origin); + wait 0.1; + fx setmodel( "tag_origin" ); + playfxontag( level._effect["ee_beam"], fx, "tag_origin" ); + + if (is_midboss == 1) + travel_time = 2; + else + travel_time = 3; + for(;;) + { + for (i = 1; i < travel_time * 10; i++) + { + if (isdefined(self.is_dead)) + { + fx delete(); + return; + } + offset = vectorscale( anglestoforward(direction), (600 / (travel_time * 10)) * i); + fx moveto(self.origin + offset, 0.1); + foreach(player in level.players) + { + if (distancesquared(fx.origin, player.origin) < 1700 && player.ignoreme != true) + player dodamage_wrapper(1000); + } + + wait 0.1; + } + for (i = travel_time * 10; i >= 0; i--) + { + if (isdefined(self.is_dead)) + { + fx delete(); + return; + } + offset = vectorscale( anglestoforward(direction), (600 / (travel_time * 10)) * i); + fx moveto(self.origin + offset, 0.1); + foreach(player in level.players) + { + if (distancesquared(fx.origin, player.origin) < 1700 && player.ignoreme != true) + player dodamage_wrapper(1000); + } + wait 0.1; + } + } +} + +miniboss_tornado(angles, is_midboss) +{ + level endon("game_ended"); + self waittill("spawned"); + + offset = vectorscale( anglestoforward(angles), 400 ); + fx = spawn( "script_model", self.origin + offset + (0, 0, 50)); + wait 0.1; + fx setmodel( "tag_origin" ); + level thread refresh_tornado_anim(fx); + + for (;;) + { + if (isdefined(self.is_dead)) + { + fx delete(); + return; + } + foreach(player in level.players) + { + if (distancesquared(fx.origin, player.origin) < 30000) + { + player shellshock( "explosion", 1 ); + if (is_midboss == 1 && player.ignoreme != true) + player dodamage_wrapper(100); + else if(player.ignoreme != true) + player dodamage_wrapper(100); + } + + } + if (is_midboss == 1) + angles += (0, 5.25, 0); + else + angles += (0, 3.5, 0); + offset = vectorscale( anglestoforward(angles), 400 ); + fx moveto(self.origin + offset + (0, 0, 50), 0.1); + wait 0.1; + } + fx delete(); +} +//level._effect["ee_beam"] good fx flex +//level._effect["staff_water_blizzard"] +//level._effect["fx_tomb_chamber_glow_blue"] + +refresh_tornado_anim(fx) +{ + level endon("game_ended"); + self endon("death"); + for (;;) + { + playfxontag( level._effect["whirlwind"], fx, "tag_origin" ); + playfxontag( level._effect["whirlwind"], fx, "tag_origin" ); + wait 10; + } + +} + +miniboss_lightning_spawn_orbs(is_midboss) +{ + level endon("game_ended"); + self endon("death"); + self waittill("spawned"); + + for(;;) + { + self thread shoot_lightning_orb(self.angles, is_midboss); + wait .05; + self thread shoot_lightning_orb(self.angles + (0, 30, 0), is_midboss); + wait .05; + self thread shoot_lightning_orb(self.angles + (0, -30, 0), is_midboss); + if (is_midboss) + wait 1.5; + else + wait 2; + } +} + +shoot_lightning_orb(angles, is_midboss) +{ + offset = vectorscale( anglestoforward(angles ), 900 ); + fx = spawn( "script_model", self.origin + (0, 0, 50)); + wait .1; + fx setmodel( "tag_origin" ); + playfxontag( level._effect["elec_piano_glow"], fx, "tag_origin" ); + if (is_midboss) + travel_time = 3; + else + travel_time = 4; + fx moveto( self.origin + offset + (0, 0, 50), travel_time); + for (i = 0; i < travel_time * 10; i++) + { + foreach(player in level.players) + { + stance = player GetStance(); + player_origin_offset = 0; + if (stance == "prone") + player_origin_offset = 30; + if (distancesquared((fx.origin), (player.origin - (0, 0, player_origin_offset))) < 1700 && player.ignoreme != true) + player dodamage_wrapper(1000); + } + wait 0.1; + } + fx delete(); +} + +check_for_raid_port() +{ + found = 0; + if (isdefined(level.net_port_raid)) + { + foreach(port in level.net_port_raid) + { + if (getdvar("net_port") == port) + found = 1; + } + } + if (found == 0) + return false; + return true; +} \ No newline at end of file diff --git a/t6/scripts/zm/zm_tomb/update/box_no_limits.gsc b/t6/scripts/zm/zm_tomb/update/box_no_limits.gsc new file mode 100644 index 0000000..2969841 --- /dev/null +++ b/t6/scripts/zm/zm_tomb/update/box_no_limits.gsc @@ -0,0 +1,1592 @@ +#include maps\mp\zombies\_zm_stats; +#include maps\mp\_demo; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\zombies\_zm_audio_announcer; +#include maps\mp\zombies\_zm_unitrigger; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\_utility; +#include common_scripts\utility; +#include maps\mp\zombies\_zm_magicbox_lock; + +init() //checked matches cerberus output +{ + //begin debug code + level.custom_zm_magicbox_loaded = 1; + maps/mp/zombies/_zm_bot::init(); + if ( !isDefined( level.debugLogging_zm_magicbox ) ) + { + level.debugLogging_zm_magicbox = 0; + } + //end debug code + if ( !isDefined( level.chest_joker_model ) ) + { + level.chest_joker_model = "zombie_teddybear"; + precachemodel( level.chest_joker_model ); + } + + + if ( is_true( level.using_locked_magicbox ) ) + { + maps/mp/zombies/_zm_magicbox_lock::init(); + } + if ( is_classic() ) + { + level.chests = getstructarray( "treasure_chest_use", "targetname" ); + treasure_chest_init( "start_chest" ); + } + if ( level.createfx_enabled ) + { + return; + } + + if ( !isDefined( level.magic_box_check_equipment ) ) + { + level.magic_box_check_equipment = ::default_magic_box_check_equipment; + } + level thread magicbox_host_migration(); +} + +treasure_chest_init( start_chest_name ) //checked changed to match cerberus output +{ + flag_init( "moving_chest_enabled" ); + flag_init( "moving_chest_now" ); + flag_init( "chest_has_been_used" ); + level.chest_moves = 0; + level.chest_level = 0; + if ( level.chests.size == 0 ) + { + return; + } + for ( i = 0; i < level.chests.size; i++ ) + { + level.chests[ i ].box_hacks = []; + level.chests[ i ].orig_origin = level.chests[ i ].origin; + level.chests[ i ] get_chest_pieces(); + if ( isDefined( level.chests[ i ].zombie_cost ) ) + { + level.chests[ i ].old_cost = level.chests[ i ].zombie_cost; + } + else + { + level.chests[ i ].old_cost = 950; + } + } + if ( !level.enable_magic ) + { + foreach( chest in level.chests ) + { + chest hide_chest(); + } + return; + } + level.chest_accessed = 0; + if ( level.chests.size > 1 ) + { + flag_set( "moving_chest_enabled" ); + level.chests = array_randomize( level.chests ); + } + else + { + level.chest_index = 0; + level.chests[ 0 ].no_fly_away = 1; + } + init_starting_chest_location( start_chest_name ); + array_thread( level.chests, ::treasure_chest_think ); +} + +init_starting_chest_location( start_chest_name ) //checked changed to match cerberus output +{ + level.chest_index = 0; + start_chest_found = 0; + if ( level.chests.size == 1 ) + { + start_chest_found = 1; + if ( isdefined( level.chests[ level.chest_index ].zbarrier ) ) + { + level.chests[ level.chest_index ].zbarrier set_magic_box_zbarrier_state( "initial" ); + } + } + else + { + for ( i = 0; i < level.chests.size; i++ ) + { + if ( isdefined( level.random_pandora_box_start ) && level.random_pandora_box_start == 1 ) + { + if ( start_chest_found || isdefined( level.chests[ i ].start_exclude ) && level.chests[ i ].start_exclude == 1 ) + { + level.chests[ i ] hide_chest(); + } + else + { + level.chest_index = i; + level.chests[ level.chest_index].hidden = 0; + if ( isdefined( level.chests[ level.chest_index ].zbarrier ) ) + { + level.chests[ level.chest_index ].zbarrier set_magic_box_zbarrier_state( "initial" ); + } + start_chest_found = 1; + } + } + else + { + if ( start_chest_found || !isdefined(level.chests[ i ].script_noteworthy) || !issubstr( level.chests[ i ].script_noteworthy, start_chest_name ) ) + { + level.chests[ i ] hide_chest(); + } + else + { + level.chest_index = i; + level.chests[ level.chest_index ].hidden = 0; + if ( isdefined( level.chests[ level.chest_index ].zbarrier ) ) + { + level.chests[ level.chest_index ].zbarrier set_magic_box_zbarrier_state( "initial" ); + } + start_chest_found = 1; + } + } + } + } + if ( !isdefined( level.pandora_show_func ) ) + { + level.pandora_show_func = ::default_pandora_show_func; + } + level.chests[ level.chest_index ] thread [[ level.pandora_show_func ]](); +} + +set_treasure_chest_cost( cost ) //checked matches cerberus output +{ + level.zombie_treasure_chest_cost = cost; +} + +get_chest_pieces() //checked changed to match cerberus output +{ + self.chest_box = getent( self.script_noteworthy + "_zbarrier", "script_noteworthy" ); + self.chest_rubble = []; + rubble = getentarray( self.script_noteworthy + "_rubble", "script_noteworthy" ); + for ( i = 0; i < rubble.size; i++ ) + { + if ( distancesquared( self.origin, rubble[ i ].origin ) < 10000 ) + { + self.chest_rubble[ self.chest_rubble.size ] = rubble[ i ]; + } + } + self.zbarrier = getent( self.script_noteworthy + "_zbarrier", "script_noteworthy" ); + if ( isDefined( self.zbarrier ) ) + { + self.zbarrier zbarrierpieceuseboxriselogic( 3 ); + self.zbarrier zbarrierpieceuseboxriselogic( 4 ); + } + self.unitrigger_stub = spawnstruct(); + self.unitrigger_stub.origin = self.origin + ( anglesToRight( self.angles ) * -22.5 ); + self.unitrigger_stub.angles = self.angles; + self.unitrigger_stub.script_unitrigger_type = "unitrigger_box_use"; + self.unitrigger_stub.script_width = 104; + self.unitrigger_stub.script_height = 50; + self.unitrigger_stub.script_length = 45; + self.unitrigger_stub.trigger_target = self; + unitrigger_force_per_player_triggers( self.unitrigger_stub, 1 ); + self.unitrigger_stub.prompt_and_visibility_func = ::boxtrigger_update_prompt; + self.zbarrier.owner = self; +} + +boxtrigger_update_prompt( player ) //checked matches cerberus output +{ + can_use = self boxstub_update_prompt( player ); + if ( isDefined( self.hint_string ) ) + { + if ( isDefined( self.hint_parm1 ) ) + { + self sethintstring( self.hint_string, self.hint_parm1 ); + } + else + { + self sethintstring( self.hint_string ); + } + } + return can_use; +} + +boxstub_update_prompt( player ) //checked matches cerberus output +{ + self setcursorhint( "HINT_NOICON" ); + if ( !self trigger_visible_to_player( player ) ) + { + return 0; + } + self.hint_parm1 = undefined; + if ( is_true( self.stub.trigger_target.grab_weapon_hint ) ) + { + if ( isDefined( level.magic_box_check_equipment ) && [[ level.magic_box_check_equipment ]]( self.stub.trigger_target.grab_weapon_name ) ) + { + self.hint_string = &"ZOMBIE_TRADE_EQUIP"; + } + else + { + self.hint_string = &"ZOMBIE_TRADE_WEAPON"; + } + } + else if ( is_true( level.using_locked_magicbox ) && is_true( self.stub.trigger_target.is_locked ) ) + { + self.hint_string = get_hint_string( self, "locked_magic_box_cost" ); + } + else + { + self.hint_parm1 = self.stub.trigger_target.zombie_cost; + self.hint_string = get_hint_string( self, "default_treasure_chest" ); + } + return 1; +} + +default_magic_box_check_equipment( weapon ) //checked matches cerberus output +{ + return is_offhand_weapon( weapon ); +} + +trigger_visible_to_player( player ) //checked changed to match cerberus output +{ + self setinvisibletoplayer( player ); + visible = 1; + if ( isDefined( self.stub.trigger_target.chest_user ) && !isDefined( self.stub.trigger_target.box_rerespun ) ) + { + if ( player != self.stub.trigger_target.chest_user || is_placeable_mine( self.stub.trigger_target.chest_user getcurrentweapon() ) || self.stub.trigger_target.chest_user hacker_active() ) + { + visible = 0; + } + } + else if ( !player can_buy_weapon() ) + { + visible = 0; + } + if ( !visible ) + { + return 0; + } + self setvisibletoplayer( player ); + return 1; +} + +magicbox_unitrigger_think() //checked changed to match cerberus output +{ + self endon( "kill_trigger" ); + while ( 1 ) + { + self waittill( "trigger", player ); + self.stub.trigger_target notify( "trigger", player ); + } +} + +play_crazi_sound() //checked matches cerberus output +{ + self playlocalsound( level.zmb_laugh_alias ); +} + +show_chest_sound_thread() //checked matches cerberus output +{ + +} + +show_chest() //checked matches cerberus output +{ + self.zbarrier set_magic_box_zbarrier_state( "arriving" ); + self.zbarrier waittill( "arrived" ); + self thread [[ level.pandora_show_func ]](); + thread maps/mp/zombies/_zm_unitrigger::register_static_unitrigger( self.unitrigger_stub, ::magicbox_unitrigger_think ); + self thread show_chest_sound_thread(); + self.hidden = 0; + if ( isDefined( self.box_hacks[ "summon_box" ] ) ) + { + self [[ self.box_hacks[ "summon_box" ] ]]( 0 ); + } +} + +hide_chest_sound_thread() //checked matches cerberus output +{ + +} + +hide_chest( doboxleave ) //checked matches cerberus output +{ + if ( isDefined( self.unitrigger_stub ) ) + { + thread maps/mp/zombies/_zm_unitrigger::unregister_unitrigger( self.unitrigger_stub ); + } + if ( isDefined( self.pandora_light ) ) + { + self.pandora_light delete(); + } + self.hidden = 1; + if ( isDefined( self.box_hacks ) && isDefined( self.box_hacks[ "summon_box" ] ) ) + { + self [[ self.box_hacks[ "summon_box" ] ]]( 1 ); + } + if ( isDefined( self.zbarrier ) ) + { + if ( is_true( doboxleave ) ) + { + self thread hide_chest_sound_thread(); + level thread leaderdialog( "boxmove" ); + self.zbarrier thread magic_box_zbarrier_leave(); + self.zbarrier waittill( "left" ); + playfx( level._effect[ "poltergeist" ], self.zbarrier.origin, anglesToUp( self.angles ), anglesToForward( self.angles ) ); + playsoundatposition( "zmb_box_poof", self.zbarrier.origin ); + return; + } + else + { + self.zbarrier thread set_magic_box_zbarrier_state( "away" ); + } + } +} + +magic_box_zbarrier_leave() //checked matches cerberus output +{ + self set_magic_box_zbarrier_state( "leaving" ); + self waittill( "left" ); + self set_magic_box_zbarrier_state( "away" ); +} + +default_pandora_fx_func() //checked partially changed to match cerberus output +{ + self endon( "death" ); + self.pandora_light = spawn( "script_model", self.zbarrier.origin ); + self.pandora_light.angles = self.zbarrier.angles + vectorScale( ( -1, 0, -1 ), 90 ); + self.pandora_light setmodel( "tag_origin" ); + if ( !is_true( level._box_initialized ) ) + { + flag_wait( "start_zombie_round_logic" ); + level._box_initialized = 1; + } + wait 1; + if ( isDefined( self ) && isDefined( self.pandora_light ) ) + { + playfxontag( level._effect[ "lght_marker" ], self.pandora_light, "tag_origin" ); + } +} + +default_pandora_show_func( anchor, anchortarget, pieces ) //checked matches cerberus output +{ + if ( !isDefined( self.pandora_light ) ) + { + if ( !isDefined( level.pandora_fx_func ) ) + { + level.pandora_fx_func = ::default_pandora_fx_func; + } + self thread [[ level.pandora_fx_func ]](); + } + playfx( level._effect[ "lght_marker_flare" ], self.pandora_light.origin ); +} + +unregister_unitrigger_on_kill_think() //checked matches cerberus output +{ + self notify( "unregister_unitrigger_on_kill_think" ); + self endon( "unregister_unitrigger_on_kill_think" ); + self waittill( "kill_chest_think" ); + thread maps/mp/zombies/_zm_unitrigger::unregister_unitrigger( self.unitrigger_stub ); +} + +treasure_chest_think() //checked changed to match cerberus output +{ + self endon( "kill_chest_think" ); + user = undefined; + user_cost = undefined; + self.box_rerespun = undefined; + self.weapon_out = undefined; + + self thread unregister_unitrigger_on_kill_think(); + while ( 1 ) + { + if ( !isdefined( self.forced_user ) ) + { + self waittill( "trigger", user ); + if ( user == level ) + { + wait 0.1; + continue; + } + } + else + { + user = self.forced_user; + } + if ( user in_revive_trigger() ) + { + wait 0.1; + continue; + } + if ( user.is_drinking > 0 ) + { + wait 0.1; + continue; + } + if ( is_true( self.disabled ) ) + { + wait 0.1; + continue; + } + if ( user getcurrentweapon() == "none" ) + { + wait 0.1; + continue; + } + reduced_cost = undefined; + if ( is_player_valid( user ) && user maps/mp/zombies/_zm_pers_upgrades_functions::is_pers_double_points_active() ) + { + reduced_cost = int( self.zombie_cost / 2 ); + } + if ( is_true( self.is_locked ) ) + { + if ( user.score >= level.locked_magic_box_cost ) + { + user maps/mp/zombies/_zm_score::minus_to_player_score( level.locked_magic_box_cost ); + self.zbarrier set_magic_box_zbarrier_state( "unlocking" ); + self.unitrigger_stub run_visibility_function_for_all_triggers(); + } + else + { + user maps/mp/zombies/_zm_audio::create_and_play_dialog( "general", "no_money_box" ); + } + wait 0.1 ; + continue; + } + else if ( isdefined( self.auto_open ) && is_player_valid( user ) ) + { + if ( !isdefined( self.no_charge ) ) + { + user maps/mp/zombies/_zm_score::minus_to_player_score( self.zombie_cost ); + user_cost = self.zombie_cost; + } + else + { + user_cost = 0; + } + self.chest_user = user; + break; + } + else if ( is_player_valid( user ) && user.score >= self.zombie_cost ) + { + user maps/mp/zombies/_zm_score::minus_to_player_score( self.zombie_cost ); + user_cost = self.zombie_cost; + self.chest_user = user; + break; + } + else if ( isdefined( reduced_cost ) && user.score >= reduced_cost ) + { + user maps/mp/zombies/_zm_score::minus_to_player_score( reduced_cost ); + user_cost = reduced_cost; + self.chest_user = user; + break; + } + else if ( user.score < self.zombie_cost ) + { + play_sound_at_pos( "no_purchase", self.origin ); + user maps/mp/zombies/_zm_audio::create_and_play_dialog( "general", "no_money_box" ); + wait 0.1; + continue; + } + wait 0.05; + } + flag_set( "chest_has_been_used" ); + if ( isDefined( level._magic_box_used_vo ) ) + { + user thread [[ level._magic_box_used_vo ]](); + } + self thread watch_for_emp_close(); + self._box_open = 1; + self._box_opened_by_fire_sale = 0; + if ( is_true( level.zombie_vars[ "zombie_powerup_fire_sale_on" ] ) && !isDefined( self.auto_open ) && self [[ level._zombiemode_check_firesale_loc_valid_func ]]() ) + { + self._box_opened_by_fire_sale = 1; + } + if ( isDefined( self.chest_lid ) ) + { + self.chest_lid thread treasure_chest_lid_open(); + } + if ( isDefined( self.zbarrier ) ) + { + play_sound_at_pos( "open_chest", self.origin ); + play_sound_at_pos( "music_chest", self.origin ); + self.zbarrier set_magic_box_zbarrier_state( "open" ); + } + self.timedout = 0; + self.weapon_out = 1; + self.zbarrier thread treasure_chest_weapon_spawn( self, user ); + self.zbarrier thread treasure_chest_glowfx(); + thread maps/mp/zombies/_zm_unitrigger::unregister_unitrigger( self.unitrigger_stub ); + self.zbarrier waittill_any( "randomization_done", "box_hacked_respin" ); + if ( flag( "moving_chest_now" ) && !self._box_opened_by_fire_sale && isDefined( user_cost ) ) + { + user maps/mp/zombies/_zm_score::add_to_player_score( user_cost, 0 ); + } + if ( flag( "moving_chest_now" ) && !level.zombie_vars[ "zombie_powerup_fire_sale_on" ] && !self._box_opened_by_fire_sale ) + { + self thread treasure_chest_move( self.chest_user ); + } + else + { + self.grab_weapon_hint = 1; + self.grab_weapon_name = self.zbarrier.weapon_string; + self.chest_user = user; + thread maps/mp/zombies/_zm_unitrigger::register_static_unitrigger( self.unitrigger_stub, ::magicbox_unitrigger_think ); + if ( isDefined( self.zbarrier ) && !is_true( self.zbarrier.closed_by_emp ) ) + { + self thread treasure_chest_timeout(); + } + while ( !is_true( self.closed_by_emp ) ) + { + self waittill( "trigger", grabber ); + self.weapon_out = undefined; + if ( is_true( level.magic_box_grab_by_anyone ) ) + { + if ( isplayer( grabber ) ) + { + user = grabber; + } + } + if ( is_true( level.pers_upgrade_box_weapon ) ) + { + self maps/mp/zombies/_zm_pers_upgrades_functions::pers_upgrade_box_weapon_used( user, grabber ); + } + if ( isDefined( grabber.is_drinking ) && grabber.is_drinking > 0 ) + { + wait 0.1; + continue; + } + if ( grabber == user && user getcurrentweapon() == "none" ) + { + wait 0.1; + continue; + } + if ( grabber != level && is_true( self.box_rerespun ) ) + { + user = grabber; + } + if ( grabber == user || grabber == level ) + { + self.box_rerespun = undefined; + current_weapon = "none"; + if ( is_player_valid( user ) ) + { + current_weapon = user getcurrentweapon(); + } + if ( grabber == user && is_player_valid( user ) && !user.is_drinking && !is_placeable_mine( current_weapon ) && !is_equipment( current_weapon ) && level.revive_tool != current_weapon ) + { + bbprint( "zombie_uses", "playername %s playerscore %d round %d cost %d name %s x %f y %f z %f type %s", user.name, user.score, level.round_number, self.zombie_cost, self.zbarrier.weapon_string, self.origin, "magic_accept" ); + self notify( "user_grabbed_weapon" ); + user notify( "user_grabbed_weapon" ); + user thread treasure_chest_give_weapon( self.zbarrier.weapon_string ); + maps/mp/_demo::bookmark( "zm_player_grabbed_magicbox", getTime(), user ); + user maps/mp/zombies/_zm_stats::increment_client_stat( "grabbed_from_magicbox" ); + user maps/mp/zombies/_zm_stats::increment_player_stat( "grabbed_from_magicbox" ); + break; + } + else if ( grabber == level ) + { + unacquire_weapon_toggle( self.zbarrier.weapon_string ); + self.timedout = 1; + if ( is_player_valid( user ) ) + { + bbprint( "zombie_uses", "playername %s playerscore %d round %d cost %d name %s x %f y %f z %f type %S", user.name, user.score, level.round_number, self.zombie_cost, self.zbarrier.weapon_string, self.origin, "magic_reject" ); + } + break; + } + } + wait 0.05; + } + self.grab_weapon_hint = 0; + self.zbarrier notify( "weapon_grabbed" ); + if ( !is_true( self._box_opened_by_fire_sale ) ) + { + level.chest_accessed += 1; + } + if ( level.chest_moves > 0 && isDefined( level.pulls_since_last_ray_gun ) ) + { + level.pulls_since_last_ray_gun += 1; + } + if ( isDefined( level.pulls_since_last_tesla_gun ) ) + { + level.pulls_since_last_tesla_gun += 1; + } + thread maps/mp/zombies/_zm_unitrigger::unregister_unitrigger( self.unitrigger_stub ); + if ( isDefined( self.chest_lid ) ) + { + self.chest_lid thread treasure_chest_lid_close( self.timedout ); + } + if ( isDefined( self.zbarrier ) ) + { + self.zbarrier set_magic_box_zbarrier_state( "close" ); + play_sound_at_pos( "close_chest", self.origin ); + self.zbarrier waittill( "closed" ); + wait 1; + } + else + { + wait 3; + } + if ( is_true( level.zombie_vars[ "zombie_powerup_fire_sale_on" ] ) || self [[ level._zombiemode_check_firesale_loc_valid_func ]]() || self == level.chests[ level.chest_index ] ) + { + thread maps/mp/zombies/_zm_unitrigger::register_static_unitrigger( self.unitrigger_stub, ::magicbox_unitrigger_think ); + } + } + self._box_open = 0; + self._box_opened_by_fire_sale = 0; + self.chest_user = undefined; + self notify( "chest_accessed" ); + self thread treasure_chest_think(); +} + +watch_for_emp_close() //checked changed to match cerberus output +{ + self endon( "chest_accessed" ); + self.closed_by_emp = 0; + if ( !should_watch_for_emp() ) + { + return; + } + if ( isDefined( self.zbarrier ) ) + { + self.zbarrier.closed_by_emp = 0; + } + while ( 1 ) + { + level waittill( "emp_detonate", origin, radius ); + if ( distancesquared( origin, self.origin ) < ( radius * radius ) ) + { + break; + } + } + if ( flag( "moving_chest_now" ) ) + { + return; + } + self.closed_by_emp = 1; + if ( isDefined( self.zbarrier ) ) + { + self.zbarrier.closed_by_emp = 1; + self.zbarrier notify( "box_hacked_respin" ); + if ( isDefined( self.zbarrier.weapon_model ) ) + { + self.zbarrier.weapon_model notify( "kill_weapon_movement" ); + } + if ( isDefined( self.zbarrier.weapon_model_dw ) ) + { + self.zbarrier.weapon_model_dw notify( "kill_weapon_movement" ); + } + } + wait 0.1; + self notify( "trigger", level ); +} + +can_buy_weapon() //checked matches cerberus output +{ + if ( isDefined( self.is_drinking ) && self.is_drinking > 0 ) + { + return 0; + } + if ( self hacker_active() ) + { + return 0; + } + current_weapon = self getcurrentweapon(); + if ( is_placeable_mine( current_weapon ) || is_equipment_that_blocks_purchase( current_weapon ) ) + { + return 0; + } + if ( self in_revive_trigger() ) + { + return 0; + } + if ( current_weapon == "none" ) + { + return 0; + } + return 1; +} + +default_box_move_logic() //checked changed to match cerberus output +{ + index = -1; + for ( i = 0; i < level.chests.size; i++ ) + { + if ( issubstr( level.chests[ i ].script_noteworthy, "move" + level.chest_moves + 1 ) && i != level.chest_index ) + { + index = i; + break; + } + } + if ( index != -1 ) + { + level.chest_index = index; + } + else + { + level.chest_index++; + } + if ( level.chest_index >= level.chests.size ) + { + temp_chest_name = level.chests[ level.chest_index - 1 ].script_noteworthy; + level.chest_index = 0; + level.chests = array_randomize( level.chests ); + if ( temp_chest_name == level.chests[ level.chest_index ].script_noteworthy ) + { + level.chest_index++; + } + } +} + +treasure_chest_move( player_vox ) //checked changed to match cerberus output +{ + level waittill( "weapon_fly_away_start" ); + players = get_players(); + array_thread( players, ::play_crazi_sound ); + if ( isDefined( player_vox ) ) + { + player_vox delay_thread( randomintrange( 2, 7 ), ::create_and_play_dialog, "general", "box_move" ); + } + level waittill( "weapon_fly_away_end" ); + if ( isDefined( self.zbarrier ) ) + { + self hide_chest( 1 ); + } + wait 0.1; + post_selection_wait_duration = 7; + if ( level.zombie_vars[ "zombie_powerup_fire_sale_on" ] == 1 && self [[ level._zombiemode_check_firesale_loc_valid_func ]]() ) + { + current_sale_time = level.zombie_vars[ "zombie_powerup_fire_sale_time" ]; + wait_network_frame(); + self thread fire_sale_fix(); + level.zombie_vars[ "zombie_powerup_fire_sale_time" ] = current_sale_time; + while ( level.zombie_vars[ "zombie_powerup_fire_sale_time" ] > 0 ) + { + wait 0.1; + } + } + else + { + post_selection_wait_duration += 5; + } + level.verify_chest = 0; + if ( isDefined( level._zombiemode_custom_box_move_logic ) ) + { + [[ level._zombiemode_custom_box_move_logic ]](); + } + else + { + default_box_move_logic(); + } + if ( isDefined( level.chests[ level.chest_index ].box_hacks[ "summon_box" ] ) ) + { + level.chests[ level.chest_index ] [[ level.chests[ level.chest_index ].box_hacks[ "summon_box" ] ]]( 0 ); + } + wait post_selection_wait_duration; + playfx( level._effect[ "poltergeist" ], level.chests[ level.chest_index ].zbarrier.origin ); + level.chests[ level.chest_index ] show_chest(); + flag_clear( "moving_chest_now" ); + self.zbarrier.chest_moving = 0; +} + +fire_sale_fix() //checked matches cerberus output +{ + if ( !isDefined( level.zombie_vars[ "zombie_powerup_fire_sale_on" ] ) ) + { + return; + } + if ( level.zombie_vars[ "zombie_powerup_fire_sale_on" ] ) + { + self.old_cost = 950; + self thread show_chest(); + self.zombie_cost = 10; + self.unitrigger_stub unitrigger_set_hint_string( self, "default_treasure_chest", self.zombie_cost ); + wait_network_frame(); + level waittill( "fire_sale_off" ); + while ( is_true( self._box_open ) ) + { + wait 0.1; + } + self hide_chest( 1 ); + self.zombie_cost = self.old_cost; + } +} + +check_for_desirable_chest_location() //checked changed to match cerberus output +{ + if ( !isDefined( level.desirable_chest_location ) ) + { + return level.chest_index; + } + if ( level.chests[ level.chest_index ].script_noteworthy == level.desirable_chest_location ) + { + level.desirable_chest_location = undefined; + return level.chest_index; + } + for ( i = 0; i < level.chests.size; i++ ) + { + if ( level.chests[ i ].script_noteworthy == level.desirable_chest_location ) + { + level.desirable_chest_location = undefined; + return i; + } + } + /* +/# + iprintln( level.desirable_chest_location + " is an invalid box location!" ); +#/ + */ + level.desirable_chest_location = undefined; + return level.chest_index; +} + +rotateroll_box() //checked matches cerberus output +{ + angles = 40; + angles2 = 0; + while ( isDefined( self ) ) + { + self rotateroll( angles + angles2, 0.5 ); + wait 0.7; + angles2 = 40; + self rotateroll( angles * -2, 0.5 ); + wait 0.7; + } +} + +verify_chest_is_open() //checked changed to match cerberus output +{ + for ( i = 0; i < level.open_chest_location.size; i++ ) + { + if ( isDefined( level.open_chest_location[ i ] ) ) + { + if ( level.open_chest_location[ i ] == level.chests[ level.chest_index ].script_noteworthy ) + { + level.verify_chest = 1; + return; + } + } + } + level.verify_chest = 0; +} + +treasure_chest_timeout() //checked changed to match cerberus output +{ + self endon( "user_grabbed_weapon" ); + self.zbarrier endon( "box_hacked_respin" ); + self.zbarrier endon( "box_hacked_rerespin" ); + wait 12; + self notify( "trigger", level ); +} + +treasure_chest_lid_open() //checked matches cerberus output +{ + openroll = 105; + opentime = 0.5; + self rotateroll( 105, opentime, opentime * 0.5 ); + play_sound_at_pos( "open_chest", self.origin ); + play_sound_at_pos( "music_chest", self.origin ); +} + +treasure_chest_lid_close( timedout ) //checked matches cerberus output +{ + closeroll = -105; + closetime = 0.5; + self rotateroll( closeroll, closetime, closetime * 0.5 ); + play_sound_at_pos( "close_chest", self.origin ); + self notify( "lid_closed" ); +} + +treasure_chest_chooserandomweapon( player ) //checked matches cerberus output +{ + keys = getarraykeys( level.zombie_weapons ); + return keys[ randomint( keys.size ) ]; +} + + +treasure_chest_canplayerreceiveweapon( player, weapon, pap_triggers ) //checked matches cerberus output +{ + if ( !get_is_in_box( weapon ) ) + { + return 0; + } + if ( isDefined( player ) && player has_weapon_or_upgrade( weapon ) ) + { + return 0; + } + return 1; +} + +treasure_chest_chooseweightedrandomweapon( player ) //checked changed to match cerberus output +{ + keys = array_randomize( getarraykeys( level.zombie_weapons ) ); + if ( isDefined( level.customrandomweaponweights ) ) + { + keys = player [[ level.customrandomweaponweights ]]( keys ); + } + /* +/# + forced_weapon = getDvar( "scr_force_weapon" ); + if ( forced_weapon != "" && isDefined( level.zombie_weapons[ forced_weapon ] ) ) + { + arrayinsert( keys, forced_weapon, 0 ); +#/ + } + */ + pap_triggers = getentarray( "specialty_weapupgrade", "script_noteworthy" ); + for ( i = 0; i < keys.size; i++ ) + { + if ( treasure_chest_canplayerreceiveweapon( player, keys[ i ], pap_triggers ) ) + { + return keys[ i ]; + } + } + return keys[ 0 ]; +} + +weapon_is_dual_wield( name ) //checked matches cerberus output +{ + switch( name ) + { + case "cz75dw_upgraded_zm": + case "cz75dw_zm": + case "fivesevendw_upgraded_zm": + case "fivesevendw_zm": + case "hs10_upgraded_zm": + case "m1911_upgraded_zm": + case "microwavegundw_upgraded_zm": + case "microwavegundw_zm": + case "pm63_upgraded_zm": + return 1; + default: + return 0; + } +} + +weapon_show_hint_choke() //checked matches cerberus output +{ + level._weapon_show_hint_choke = 0; + while ( 1 ) + { + wait 0.05; + level._weapon_show_hint_choke = 0; + } +} + +decide_hide_show_hint( endon_notify, second_endon_notify, onlyplayer ) //checked changed to match cerberus output +{ + self endon( "death" ); + if ( isDefined( endon_notify ) ) + { + self endon( endon_notify ); + } + if ( isDefined( second_endon_notify ) ) + { + self endon( second_endon_notify ); + } + if ( !isDefined( level._weapon_show_hint_choke ) ) + { + level thread weapon_show_hint_choke(); + } + use_choke = 0; + if ( isDefined( level._use_choke_weapon_hints ) && level._use_choke_weapon_hints == 1 ) + { + use_choke = 1; + } + while ( 1 ) + { + last_update = getTime(); + if ( isDefined( self.chest_user ) && !isDefined( self.box_rerespun ) ) + { + if ( is_placeable_mine( self.chest_user getcurrentweapon() ) || self.chest_user hacker_active() ) + { + self setinvisibletoplayer( self.chest_user ); + } + else + { + self setvisibletoplayer( self.chest_user ); + } + } + if ( isDefined( onlyplayer ) ) + { + if ( onlyplayer can_buy_weapon() ) + { + self setinvisibletoplayer( onlyplayer, 0 ); + } + else + { + self setinvisibletoplayer( onlyplayer, 1 ); + } + } + players = get_players(); + i = 0; + while ( i < players.size ) + { + if ( players[ i ] can_buy_weapon() ) + { + self setinvisibletoplayer( players[ i ], 0 ); + i++; + continue; + } + self setinvisibletoplayer( players[ i ], 1 ); + i++; + } + if ( use_choke ) + { + while ( level._weapon_show_hint_choke > 4 && getTime() < ( last_update + 150 ) ) + { + wait 0.05; + } + } + else + { + wait 0.1; + } + level._weapon_show_hint_choke++; + } +} + +get_left_hand_weapon_model_name( name ) //checked matches cerberus output +{ + switch( name ) + { + case "microwavegundw_zm": + return getweaponmodel( "microwavegunlh_zm" ); + case "microwavegundw_upgraded_zm": + return getweaponmodel( "microwavegunlh_upgraded_zm" ); + default: + return getweaponmodel( name ); + } +} + +clean_up_hacked_box() //checked matches cerberus output +{ + self waittill( "box_hacked_respin" ); + self endon( "box_spin_done" ); + if ( isDefined( self.weapon_model ) ) + { + self.weapon_model delete(); + self.weapon_model = undefined; + } + if ( isDefined( self.weapon_model_dw ) ) + { + self.weapon_model_dw delete(); + self.weapon_model_dw = undefined; + } + self hidezbarrierpiece( 3 ); + self hidezbarrierpiece( 4 ); + self setzbarrierpiecestate( 3, "closed" ); + self setzbarrierpiecestate( 4, "closed" ); +} + +treasure_chest_weapon_spawn( chest, player, respin ) //checked changed to match cerberus output +{ + if ( is_true( level.using_locked_magicbox ) ) + { + self.owner endon( "box_locked" ); + self thread maps/mp/zombies/_zm_magicbox_lock::clean_up_locked_box(); + } + self endon( "box_hacked_respin" ); + self thread clean_up_hacked_box(); + /* +/# + assert( isDefined( player ) ); +#/ + */ + self.weapon_string = undefined; + modelname = undefined; + rand = undefined; + number_cycles = 40; + if ( isDefined( chest.zbarrier ) ) + { + if ( isDefined( level.custom_magic_box_do_weapon_rise ) ) + { + chest.zbarrier thread [[ level.custom_magic_box_do_weapon_rise ]](); + } + else + { + chest.zbarrier thread magic_box_do_weapon_rise(); + } + } + for ( i = 0; i < number_cycles; i++ ) + { + + if ( i < 20 ) + { + wait 0.05 ; + } + else if ( i < 30 ) + { + wait 0.1 ; + } + else if ( i < 35 ) + { + wait 0.2 ; + } + else if ( i < 38 ) + { + wait 0.3 ; + } + } + if ( isDefined( level.custom_magic_box_weapon_wait ) ) + { + [[ level.custom_magic_box_weapon_wait ]](); + } + if ( is_true( player.pers_upgrades_awarded[ "box_weapon" ] ) ) + { + rand = maps/mp/zombies/_zm_pers_upgrades_functions::pers_treasure_chest_choosespecialweapon( player ); + } + else + { + rand = treasure_chest_chooseweightedrandomweapon( player ); + } + + self.weapon_string = rand; + wait 0.1; + if ( isDefined( level.custom_magicbox_float_height ) ) + { + v_float = anglesToUp( self.angles ) * level.custom_magicbox_float_height; + } + else + { + v_float = anglesToUp( self.angles ) * 40; + } + self.model_dw = undefined; + self.weapon_model = spawn_weapon_model( rand, undefined, self.origin + v_float, self.angles + vectorScale( ( 0, 1, 0 ), 180 ) ); + if ( weapon_is_dual_wield( rand ) ) + { + self.weapon_model_dw = spawn_weapon_model( rand, get_left_hand_weapon_model_name( rand ), self.weapon_model.origin - vectorScale( ( 0, 1, 0 ), 3 ), self.weapon_model.angles ); + } + if ( getDvar( "magic_chest_movable" ) == "1" && !is_true( chest._box_opened_by_fire_sale ) && !is_true( level.zombie_vars[ "zombie_powerup_fire_sale_on" ] ) && self [[ level._zombiemode_check_firesale_loc_valid_func ]]() ) + { + random = randomint( 100 ); + if ( !isDefined( level.chest_min_move_usage ) ) + { + level.chest_min_move_usage = 4; + } + if ( level.chest_accessed < level.chest_min_move_usage ) + { + chance_of_joker = -1; + } + else + { + chance_of_joker = level.chest_accessed + 20; + if ( level.chest_moves == 0 && level.chest_accessed >= 8 ) + { + chance_of_joker = 100; + } + if ( level.chest_accessed >= 4 && level.chest_accessed < 8 ) + { + if ( random < 15 ) + { + chance_of_joker = 100; + } + else + { + chance_of_joker = -1; + } + } + if ( level.chest_moves > 0 ) + { + if ( level.chest_accessed >= 8 && level.chest_accessed < 13 ) + { + if ( random < 30 ) + { + chance_of_joker = 100; + } + else + { + chance_of_joker = -1; + } + } + if ( level.chest_accessed >= 13 ) + { + if ( random < 50 ) + { + chance_of_joker = 100; + } + else + { + chance_of_joker = -1; + } + } + } + } + if ( isDefined( chest.no_fly_away ) ) + { + chance_of_joker = -1; + } + if ( isDefined( level._zombiemode_chest_joker_chance_override_func ) ) + { + chance_of_joker = [[ level._zombiemode_chest_joker_chance_override_func ]]( chance_of_joker ); + } + if ( chance_of_joker > random ) + { + self.weapon_string = undefined; + self.weapon_model setmodel( level.chest_joker_model ); + self.weapon_model.angles = self.angles + vectorScale( ( 0, 1, 0 ), 90 ); + if ( isDefined( self.weapon_model_dw ) ) + { + self.weapon_model_dw delete(); + self.weapon_model_dw = undefined; + } + self.chest_moving = 1; + flag_set( "moving_chest_now" ); + level.chest_accessed = 0; + level.chest_moves++; + } + } + self notify( "randomization_done" ); + if ( flag( "moving_chest_now" ) && !level.zombie_vars[ "zombie_powerup_fire_sale_on" ] && self [[ level._zombiemode_check_firesale_loc_valid_func ]]() ) + { + if ( isDefined( level.chest_joker_custom_movement ) ) + { + self [[ level.chest_joker_custom_movement ]](); + } + else + { + wait 0.5; + level notify( "weapon_fly_away_start" ); + wait 2; + if ( isDefined( self.weapon_model ) ) + { + v_fly_away = self.origin + ( anglesToUp( self.angles ) * 500 ); + self.weapon_model moveto( v_fly_away, 4, 3 ); + } + if ( isDefined( self.weapon_model_dw ) ) + { + v_fly_away = self.origin + ( anglesToUp( self.angles ) * 500 ); + self.weapon_model_dw moveto( v_fly_away, 4, 3 ); + } + self.weapon_model waittill( "movedone" ); + self.weapon_model delete(); + if ( isDefined( self.weapon_model_dw ) ) + { + self.weapon_model_dw delete(); + self.weapon_model_dw = undefined; + } + self notify( "box_moving" ); + level notify( "weapon_fly_away_end" ); + } + } + else + { + acquire_weapon_toggle( rand, player ); + if ( rand == "tesla_gun_zm" || rand == "ray_gun_zm" ) + { + if ( rand == "ray_gun_zm" ) + { + level.pulls_since_last_ray_gun = 0; + } + if ( rand == "tesla_gun_zm" ) + { + level.pulls_since_last_tesla_gun = 0; + level.player_seen_tesla_gun = 1; + } + } + if ( !isDefined( respin ) ) + { + if ( isDefined( chest.box_hacks[ "respin" ] ) ) + { + self [[ chest.box_hacks[ "respin" ] ]]( chest, player ); + } + } + else + { + if ( isDefined( chest.box_hacks[ "respin_respin" ] ) ) + { + self [[ chest.box_hacks[ "respin_respin" ] ]]( chest, player ); + } + } + if ( isDefined( level.custom_magic_box_timer_til_despawn ) ) + { + self.weapon_model thread [[ level.custom_magic_box_timer_til_despawn ]]( self ); + } + else + { + self.weapon_model thread timer_til_despawn( v_float ); + } + if ( isDefined( self.weapon_model_dw ) ) + { + if ( isDefined( level.custom_magic_box_timer_til_despawn ) ) + { + self.weapon_model_dw thread [[ level.custom_magic_box_timer_til_despawn ]]( self ); + } + else + { + self.weapon_model_dw thread timer_til_despawn( v_float ); + } + } + self waittill( "weapon_grabbed" ); + if ( !chest.timedout ) + { + if ( isDefined( self.weapon_model ) ) + { + self.weapon_model delete(); + } + if ( isDefined( self.weapon_model_dw ) ) + { + self.weapon_model_dw delete(); + } + } + } + self.weapon_string = undefined; + self notify( "box_spin_done" ); +} + +chest_get_min_usage() //checked matches cerberus output +{ + min_usage = 4; + return min_usage; +} + +chest_get_max_usage() //checked matches cerberus output +{ + max_usage = 6; + players = get_players(); + if ( level.chest_moves == 0 ) + { + if ( players.size == 1 ) + { + max_usage = 3; + } + else if ( players.size == 2 ) + { + max_usage = 4; + } + else if ( players.size == 3 ) + { + max_usage = 5; + } + else + { + max_usage = 6; + } + } + else if ( players.size == 1 ) + { + max_usage = 4; + } + else if ( players.size == 2 ) + { + max_usage = 4; + } + else if ( players.size == 3 ) + { + max_usage = 5; + } + else + { + max_usage = 7; + } + return max_usage; +} + +timer_til_despawn( v_float ) //checked matches cerberus output +{ + self endon( "kill_weapon_movement" ); + putbacktime = 12; + self moveto( self.origin - ( v_float * 0.85 ), putbacktime, putbacktime * 0.5 ); + wait putbacktime; + if ( isDefined( self ) ) + { + self delete(); + } +} + +treasure_chest_glowfx() //checked matches cerberus output +{ + +} + +treasure_chest_give_weapon( weapon_string ) //checked matches cerberus output +{ + self.last_box_weapon = getTime(); + self maps/mp/zombies/_zm_weapons::weapon_give( weapon_string, 0, 1 ); +} + +magic_box_teddy_twitches() //checked matches cerberus output +{ + self endon( "zbarrier_state_change" ); + self setzbarrierpiecestate( 0, "closed" ); + while ( 1 ) + { + wait randomfloatrange( 180, 1800 ); + self setzbarrierpiecestate( 0, "opening" ); + wait randomfloatrange( 180, 1800 ); + self setzbarrierpiecestate( 0, "closing" ); + } +} + +magic_box_initial() //checked matches cerberus output +{ + self setzbarrierpiecestate( 1, "open" ); +} + +magic_box_arrives() +{ + self setzbarrierpiecestate( 1, "opening" ); + while ( self getzbarrierpiecestate( 1 ) == "opening" ) + { + wait 0.05; + } + self notify( "arrived" ); +} + +magic_box_leaves() //checked matches cerberus output +{ + self setzbarrierpiecestate( 1, "closing" ); + while ( self getzbarrierpiecestate( 1 ) == "closing" ) + { + wait 0.1; + } + self notify( "left" ); +} + +magic_box_opens() //checked matches cerberus output +{ + self setzbarrierpiecestate( 2, "opening" ); + while ( self getzbarrierpiecestate( 2 ) == "opening" ) + { + wait 0.1; + } + self notify( "opened" ); +} + +magic_box_closes() //checked matches cerberus output +{ + self setzbarrierpiecestate( 2, "closing" ); + while ( self getzbarrierpiecestate( 2 ) == "closing" ) + { + wait 0.1; + } + self notify( "closed" ); +} + +magic_box_do_weapon_rise() //checked matches cerberus output +{ + self endon( "box_hacked_respin" ); + self setzbarrierpiecestate( 3, "closed" ); + self setzbarrierpiecestate( 4, "closed" ); + wait_network_frame(); + self zbarrierpieceuseboxriselogic( 3 ); + self zbarrierpieceuseboxriselogic( 4 ); + self showzbarrierpiece( 3 ); + self showzbarrierpiece( 4 ); + self setzbarrierpiecestate( 3, "opening" ); + self setzbarrierpiecestate( 4, "opening" ); + while ( self getzbarrierpiecestate( 3 ) != "open" ) + { + wait 0.5; + } + self hidezbarrierpiece( 3 ); + self hidezbarrierpiece( 4 ); +} + +magic_box_do_teddy_flyaway() //checked matches cerberus output +{ + self showzbarrierpiece( 3 ); + self setzbarrierpiecestate( 3, "closing" ); +} + +is_chest_active() //checked matches cerberus output +{ + curr_state = self.zbarrier get_magic_box_zbarrier_state(); + if ( flag( "moving_chest_now" ) ) + { + return 0; + } + if ( curr_state == "open" || curr_state == "close" ) + { + return 1; + } + return 0; +} + +get_magic_box_zbarrier_state() //checked matches cerberus output +{ + return self.state; +} + +set_magic_box_zbarrier_state( state ) //checked changed to match cerberus output +{ + for ( i = 0; i < self getnumzbarrierpieces(); i++ ) + { + self hidezbarrierpiece( i ); + } + self notify( "zbarrier_state_change" ); + self [[ level.magic_box_zbarrier_state_func ]]( state ); +} + +process_magic_box_zbarrier_state( state ) //checked matches cerberus output +{ + switch( state ) + { + case "away": + self showzbarrierpiece( 0 ); + self thread magic_box_teddy_twitches(); + self.state = "away"; + break; + case "arriving": + self showzbarrierpiece( 1 ); + self thread magic_box_arrives(); + self.state = "arriving"; + break; + case "initial": + self showzbarrierpiece( 1 ); + self thread magic_box_initial(); + thread maps/mp/zombies/_zm_unitrigger::register_static_unitrigger( self.owner.unitrigger_stub, ::magicbox_unitrigger_think ); + self.state = "initial"; + break; + case "open": + self showzbarrierpiece( 2 ); + self thread magic_box_opens(); + self.state = "open"; + break; + case "close": + self showzbarrierpiece( 2 ); + self thread magic_box_closes(); + self.state = "close"; + break; + case "leaving": + self showzbarrierpiece( 1 ); + self thread magic_box_leaves(); + self.state = "leaving"; + break; + default: + if ( isDefined( level.custom_magicbox_state_handler ) ) + { + self [[ level.custom_magicbox_state_handler ]]( state ); + } + break; + } +} + +magicbox_host_migration() //checked changed to match cerberus output +{ + level endon( "end_game" ); + level notify( "mb_hostmigration" ); + level endon( "mb_hostmigration" ); + while ( 1 ) + { + level waittill( "host_migration_end" ); + while ( !isDefined( level.chests ) ) + { + wait 0.1; + } + foreach ( chest in level.chests ) + { + if ( !is_true( chest.hidden ) ) + { + if ( isdefined( chest ) && isdefined( chest.pandora_light ) ) + { + playfxontag( level._effect[ "lght_marker" ], chest.pandora_light, "tag_origin" ); + } + } + wait_network_frame(); + } + } +} + + + + + diff --git a/t6/scripts/zm/zm_tomb/update/custom_perk_powerup.gsc b/t6/scripts/zm/zm_tomb/update/custom_perk_powerup.gsc new file mode 100644 index 0000000..54cae4e --- /dev/null +++ b/t6/scripts/zm/zm_tomb/update/custom_perk_powerup.gsc @@ -0,0 +1,2546 @@ +//issues: hint for custom perks cannot be disabled in afterlife perks restore or player wont get any perks back + +#include maps\mp\zombies\_zm; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\_visionset_mgr; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\_demo; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\zombies\_zm_power; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\_utility; +#include common_scripts\utility; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\zombies\_zm_chugabud; +#include maps\mp\zombies\_zm_afterlife; +#include maps\mp\zombies\_zm_tombstone; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm_perk_vulture; + +init() +{ + + level.background_shader = getdvarintdefault("enable_background", 1); + level thread onPlayerConnect(); + + isTown(); //tombstone fix; + + mapname = getDvar( "mapname" ); + if ( mapname != "zm_transit") +{ + level thread TrackPerkPowerup(); + + + include_zombie_powerup("random_perk"); + add_zombie_powerup("random_perk", "t6_wpn_zmb_perk_bottle_sleight_world", &"ZOMBIE_POWERUP_RANDOM_PERK", ::func_should_always_drop, 0, 0, 0); + powerup_set_can_pick_up_in_last_stand("random_perk", 1); + precacheshaders = array("menu_zm_cac_grad_stretch","talkingicon","zombies_rank_5_ded","hud_grenadeicon","killiconheadshot","menu_mp_weapons_1911","hud_icon_sticky_grenade","faction_cdc","specialty_chugabud_zombies","specialty_electric_cherry_zombie","specialty_additionalprimaryweapon_zombies","menu_mp_lobby_icon_customgamemode","specialty_divetonuke_zombies","zombies_rank_1","zombies_rank_3","zombies_rank_2","zombies_rank_4","zombies_rank_5","menu_lobby_icon_facebook","menu_mp_weapons_1911","hud_icon_colt","waypoint_revive","hud_grenadeicon","damage_feedback","menu_lobby_icon_twitter","specialty_doubletap_zombies"); + foreach(shader in precacheshaders) + { + precacheshader(shader); + } + precachemodel("p6_zm_bu_tombstone_01"); + level.zombie_last_stand = ::LastStand; + level.effect_WebFX = loadfx("misc/fx_zombie_powerup_solo_grab"); + + level.get_player_weapon_limit = ::custom_get_player_weapon_limit; + + set_zombie_var( "riotshield_hit_points", 1500 ); + if(isDefined(level.player_damage_callbacks[0])) + { + level.first_player_damage_callback = level.player_damage_callbacks[0]; + level.player_damage_callbacks[0] = ::damage_callback; + } + else + { + maps\mp\zombies\_zm::register_player_damage_callback( ::damage_callback ); + } + if(isDefined(level._zombiemode_powerup_grab)) + { + level.original_zombiemode_powerup_grab = level._zombiemode_powerup_grab; + } + level._zombiemode_powerup_grab = ::custom_powerup_grab; + flag_wait( "initial_blackscreen_passed" ); + replacefunc(::give_perk, ::Custom_give_perk); //find alternative for replace func + + replacefunc(::chugabud_give_loadout, ::custom_chugabud_give_loadout);//find alternative for replace func + replacefunc(::chugabud_save_loadout, ::custom_chugabud_save_loadout);//find alternative for replace func + + //level.chugabud_laststand_func = ::chugabud_laststand; //alternative for replacefunc ^ ( need alot more functions to work ) + + level.tombstone_spawn_func = ::tombstone_spawn; + level.tombstone_laststand_func = ::custom_tombstone_laststand; + + level.afterlife_save_loadout = ::custom_afterlife_save_loadout; + level.afterlife_give_loadout = ::custom_afterlife_give_loadout; +} +} + +wait_end_game() +{ + level waittill( "end_game" ); + players = getplayers(); + for(i=0;i 10 && isDefined( level.roundsplayed ) && level.roundsplayed < 1 ) + { + return 0; + } + if (level.round_number < 10 && isDefined( level.roundsplayed ) && level.roundsplayed < 2 ) + { + return 0; + } + return 1; +} + +custom_powerup_grab(s_powerup, e_player) +{ + if (s_powerup.powerup_name == "random_perk") + { + foreach(player in level.players) + { + player thread give_random_perk(); + level.roundsplayed = 0; + } + } + else if (isDefined(level.original_zombiemode_powerup_grab)) + level thread [[level.original_zombiemode_powerup_grab]](s_powerup, e_player); +} + +custom_give_perk( perk, bought, custom, saved_perk ) +{ + if(!custom) + { + self SetPerk( perk ); + self.num_perks++; + if ( is_true( bought ) ) + { + self maps\mp\zombies\_zm_audio::playerExert( "burp" ); + self delay_thread (1.5, maps\mp\zombies\_zm_audio::perk_vox, perk ); + self setblur( 4, 0.1 ); + wait .1; + self setblur(0, 0.1); + self notify( "perk_bought", perk ); + } + if(perk == "specialty_armorvest") + { + self.preMaxHealth = self.maxhealth; + self SetMaxHealth( level.zombie_vars["zombie_perk_juggernaut_health"] ); + } + else if(perk == "specialty_armorvest_upgrade") + { + self.preMaxHealth = self.maxhealth; + self SetMaxHealth( level.zombie_vars["zombie_perk_juggernaut_health_upgrade"] ); + } + if ( isDefined( level.disable_deadshot_clientfield ) && !level.disable_deadshot_clientfield ) + { + if ( perk == "specialty_deadshot" || perk == "specialty_deadshot_upgrade") + { + + } + } + if ( perk == "specialty_scavenger" ) + { + self.hasperkspecialtytombstone = 1; + } + players = get_players(); + if ( use_solo_revive() && perk == "specialty_quickrevive" ) + { + self.lives = 1; + if ( !isDefined( level.solo_lives_given ) ) + { + level.solo_lives_given = 0; + } + if ( isDefined( level.solo_game_free_player_quickrevive ) ) + { + level.solo_game_free_player_quickrevive = undefined; + } + else + { + level.solo_lives_given++; + } + if ( level.solo_lives_given >= 3 ) + { + flag_set( "solo_revive" ); + } + self thread solo_revive_buy_trigger_move( perk ); + } + if ( perk == "specialty_finalstand" ) + { + self.lives = 1; + self.hasperkspecialtychugabud = 1; + self notify( "perk_chugabud_activated" ); + } + + if ( isdefined( level._custom_perks[perk] ) && isdefined( level._custom_perks[perk].player_thread_give ) ) //for vulture aid and electric cherry + self thread [[ level._custom_perks[perk].player_thread_give ]](); + + maps\mp\_demo::bookmark( "zm_player_perk", gettime(), self ); + if(!isDefined(self.perk_history)) + { + self.perk_history = []; + } + self.perk_history = add_to_array(self.perk_history,perk,false); + if ( !isDefined( self.perks_active ) ) + { + self.perks_active = []; + } + self.perks_active[ self.perks_active.size ] = perk; + self notify("perk_acquired"); + + if(!isDefined(level.time_bomb_whiteout_hudelem)) + self perk_hud_create( perk, 0, 0 ); + + self thread perk_think( perk ); + } + else + { + if(saved_perk) + { + self perk_hud_create( perk, 1, 0 ); + self.num_perks++; + wait .05; + } + else + { + self perk_hud_create( perk, 1, 1 ); + self.num_perks++; + } + } +} + +perk_hud_create( perk, custom, print ) +{ + if ( !IsDefined( self.perk_hud ) ) + { + self.perk_hud = []; + } + shader = ""; + switch( perk ) + { + //CUSTOM PERKS + case "Tombstone": + color = (0.4, 0.2, 0); + color1 = (1, 1, 1); + background_shader = "specialty_doubletap_zombies"; + shader = "menu_zm_cac_grad_stretch"; + if(print) + { + self iprintln("^9Tombstone"); + wait 0.2; + self iprintln("This Perk saves players current loadout after player is downed"); + } + break; + case "MULE": + if(getdvar( "mapname" ) == "zm_prison") + { + shader = "specialty_additionalprimaryweapon_zombies"; + } + else + { + color = (0, 0, 0); + color1 = (0, 1, 0); + background_shader = "specialty_doubletap_zombies"; + shader = "menu_mp_weapons_1911"; + } + if(print) + { + self iprintln("^9Mule Kick"); + wait 0.2; + self iprintln("This Perk enables additional primary weapon slot for player. "); + } + break; + case "PHD_FLOPPER": + if(getdvar( "mapname" ) == "zm_prison") + { + shader = "specialty_divetonuke_zombies"; + } + else + { + color = (0, 0, 0); + color1 = (1, 0, 1); + background_shader = "specialty_doubletap_zombies"; + shader = "hud_grenadeicon"; + } + if(print) + { + self iprintln("^9PhD Flopper"); + wait 0.2; + self iprintln("This Perk removes explosion and fall damage also player creates explosion when dive to prone."); + } + break; + case "Ethereal_Razor": + color = (1, 0, 0); + color1 = (1,1,1); + background_shader = "specialty_doubletap_zombies"; + shader = "zombies_rank_4"; + self thread start_er(); + if(print) + { + self iprintln("^9Ethereal Razor"); + wait 0.2; + self iprintln("This Perk deals extra damage when player using melee attacks and restores a small amount of health."); + } + break; + case "Ammo_Regen": + color = (0, 0, 0); + color1 = (1,1,1); + background_shader = "specialty_doubletap_zombies"; + shader = "menu_mp_lobby_icon_customgamemode"; + self thread ammoregen(); + self thread grenadesregen(); + if(print) + { + self iprintln("^9Ammo Regen"); + wait 0.2; + self iprintln("This Perk will slowly regenerades players ammonation and grenades."); + } + break; + case "Dying_Wish": + color = (1, 0, 0); + color1 = (1,1,1); + background_shader = "specialty_doubletap_zombies"; + shader = "zombies_rank_5_ded"; + self thread dying_wish_checker(); + if(print) + { + self iprintln("^9Dying Wish"); + wait 0.2; + self iprintln("This Perk allow player to go berserker mode for 9 seconds instead of laststand."); + wait 0.1; + self iprintln(" (cooldown 5mins and it's increased 30sec every time perk is used. - max 10mins) "); + } + break; + case "Downers_Delight": + background_shader = "specialty_doubletap_zombies"; + shader = "waypoint_revive"; + color = (0,0,0); + color1 = (0,1,1); + self thread DDown(); + if(print) + { + self iprintln("^9Downer's Delight"); + wait 0.2; + self iprintln("This Perk will increase players bleedout time by 10 seconds and current weapons is used in laststand."); + } + break; + case "Victorious_Tortoise": + background_shader = "specialty_doubletap_zombies"; + shader = "zombies_rank_2"; + color = (0,1,0); + color1 = (1,1,1); + if(print) + { + self iprintln("^9Victorious Tortoise"); + wait 0.2; + self iprintln("This Perk allows shield block damage from all directions when in use."); + } + break; + case "ELECTRIC_CHERRY": + background_shader = "specialty_doubletap_zombies"; + shader = "zombies_rank_5"; + color = (0 ,0, 1); + color1 = (1,1,1); + self thread start_ec(); + if(print) + { + self iprintln("^9Electric Cherry"); + wait 0.2; + self iprintln("This Perk creates an electric shockwave around the player whenever they reload."); + } + break; + case "WIDOWS_WINE": + background_shader = "specialty_doubletap_zombies"; + shader = "zombies_rank_3"; + self thread ww_nades(); + color = (0,0,0); + color1 = (1,1,1); + if(print) + { + self iprintln("^9Widow's Wine"); + wait 0.2; + self iprintln("This Perk damages zombies around the player when player is hit and grenades are upgraded."); + } + break; + case "Burn_Heart": + background_shader = "specialty_doubletap_zombies"; + shader = "zombies_rank_1"; + color = (1,0,0); + color1 = (1,1,1); + self.ignore_lava_damage = 1; + if(print) + { + self iprintln("^9Burn Heart"); + wait 0.2; + self iprintln("This Perk removes lava damage. (add more abilitys)"); + } + break; + case "deadshot": + background_shader = "specialty_doubletap_zombies"; + shader = "killiconheadshot"; + color = (0,0,0); + color1 = (1,1,1); + self thread AimAssist(); + if(print) + { + self iprintln("^9Deadshot"); + wait 0.2; + self iprintln("This Perk aims automatically enemys head instead of body."); + } + break; + + //ORIGINAL PERKS + case "specialty_armorvest_upgrade": + shader = "specialty_juggernaut_zombies_pro"; + break; + case "specialty_armorvest": + shader = "specialty_juggernaut_zombies"; + break; + case "specialty_quickrevive_upgrade": + shader = "specialty_quickrevive_zombies_pro"; + break; + case "specialty_quickrevive": + shader = "specialty_quickrevive_zombies"; + break; + case "specialty_fastreload_upgrade": + shader = "specialty_fastreload_zombies_pro"; + break; + case "specialty_fastreload": + shader = "specialty_fastreload_zombies"; + break; + case "specialty_rof_upgrade": + case "specialty_rof": + shader = "specialty_doubletap_zombies"; + break; + case "specialty_longersprint_upgrade": + case "specialty_longersprint": + shader = "specialty_marathon_zombies"; + break; + case "specialty_flakjacket_upgrade": + case "specialty_flakjacket": + shader = "specialty_divetonuke_zombies"; + break; + case "specialty_deadshot_upgrade": + case "specialty_deadshot": + shader = "specialty_ads_zombies"; + break; + case "specialty_additionalprimaryweapon_upgrade": + case "specialty_additionalprimaryweapon": + shader = "specialty_additionalprimaryweapon_zombies"; + break; + case "specialty_scavenger_upgrade": + case "specialty_scavenger": + shader = "specialty_tombstone_zombies"; + break; + case "specialty_finalstand": + case "specialty_finalstand_upgrade": + shader = "specialty_chugabud_zombies"; + break; + case "specialty_nomotionsensor": + shader = "specialty_vulture_zombies"; + break; + case "specialty_grenadepulldeath": + shader = "specialty_electric_cherry_zombie"; + break; + default: + shader = ""; + break; + } + + if(custom && level.background_shader) + { + hud2 = create_simple_hud( self ); + hud2.foreground = 0; + hud2.sort = 1; + hud2.alpha = 1; + hud2.horzAlign = "user_left"; + hud2.vertAlign = "user_center"; + hud2.hidewheninmenu = 1; + hud2.x = 5.5 + (self.perkarray.size * 30); + + if(getdvar( "mapname" ) == "zm_buried" || getdvar( "mapname" ) == "zm_tomb" ) + hud2.y = 116.5; + else + hud2.y = 146.5; + + hud2 SetShader( background_shader, 24, 24 ); + self.background_perk[ perk ] = hud2; + hud2.color = color; + } + + hud = create_simple_hud( self ); + hud.foreground = 1; + hud.sort = 1; + hud.alpha = 1; + hud.horzAlign = "user_left"; + hud.vertAlign = "user_center"; + hud.hidewheninmenu = 1; + hud.x = 5.5 + (self.perkarray.size * 30); + + if(getdvar( "mapname" ) == "zm_buried" || getdvar( "mapname" ) == "zm_tomb" ) + hud.y = 116.5; + else + hud.y = 146.5; + + if( perk == "Tombstone" ) + { + hud SetShader( shader, 24, 19 ); + } + else if(custom && perk != "PHD_FLOPPER" && perk != "MULE" && getdvar( "mapname" ) != "zm_prison" ) + { + hud SetShader( shader, 24, 23 ); + } + else + { + hud SetShader( shader, 24, 24 ); + } + hud.color = color1; + self.perkarray[self.perkarray.size] = perk; + self.perk_hud[ perk ] = hud; +} + +hascustomperk(perk) +{ + for(i = 0; i < self.perkarray.size; i++) + { + if(self.perkarray[i] == perk) + { + return 1; + } + } + return 0; +} + +give_random_perk() +{ + perks = array(); + //CUSTOM PERKS + if(getdvar( "mapname" ) == "zm_prison" || getdvar( "mapname" ) == "zm_nuked" || getdvar( "mapname" ) == "zm_buried" || getdvar( "mapname" ) == "zm_tomb" ) + { + if(!self hascustomperk("Tombstone") && get_players().size > 1) + { + perks[perks.size] = "Tombstone"; + } + } + + if(getdvar( "mapname" ) != "zm_tomb" ) + { + if(!self hascustomperk("PHD_FLOPPER")) + { + perks[perks.size] = "PHD_FLOPPER"; + } + } + if(getdvar( "mapname" ) == "zm_transit" || getdvar( "mapname" ) == "zm_tomb" || getdvar( "mapname" ) == "zm_prison") + { + if(!self hascustomperk("Victorious_Tortoise")) + { + perks[perks.size] = "Victorious_Tortoise"; + } + } + if(getdvar( "mapname" ) == "zm_transit" || getdvar( "mapname" ) == "zm_nuked" || getdvar( "mapname" ) == "zm_prison") + { + if(!self hascustomperk("MULE")) + { + perks[perks.size] = "MULE"; + } + } + if(getdvar( "mapname" ) == "zm_transit" || getdvar( "mapname" ) == "zm_nuked" || getdvar( "mapname" ) == "zm_buried" || getdvar( "mapname" ) == "zm_highrise" ) + { + if(!self hascustomperk("ELECTRIC_CHERRY")) + { + perks[perks.size] = "ELECTRIC_CHERRY"; + } + } + if( getdvar( "mapname" ) != "zm_prison") + { + if(!self hascustomperk("WIDOWS_WINE")) + { + perks[perks.size] = "WIDOWS_WINE"; + } + if(!self hascustomperk("Downers_Delight")) + { + perks[perks.size] = "Downers_Delight"; + } + } + if(!self hascustomperk("Ethereal_Razor")) + { + perks[perks.size] = "Ethereal_Razor"; + } + if(!self hascustomperk("Ammo_Regen")) + { + perks[perks.size] = "Ammo_Regen"; + } + if(getdvar( "mapname" ) == "zm_transit") + { + if(!self hascustomperk("Burn_Heart")) + { + perks[perks.size] = "Burn_Heart"; + } + } + if(!self hascustomperk("Dying_Wish")) + { + perks[perks.size] = "Dying_Wish"; + } + if(getdvar( "mapname" ) == "zm_transit" || getdvar( "mapname" ) == "zm_nuked" || getdvar( "mapname" ) == "zm_highrise" ) + { + if(!self hascustomperk("deadshot")) + { + perks[perks.size] = "deadshot"; + } + } + + //ORIGINAL PERKS + if(!self hasPerk("specialty_armorvest")) + { + perks[perks.size] = "specialty_armorvest"; + } + if(!self hasPerk("specialty_rof")) + { + perks[perks.size] = "specialty_rof"; + } + if(!self hasPerk("specialty_fastreload")) + { + perks[perks.size] = "specialty_fastreload"; + } + if(getdvar( "mapname" ) != "zm_prison" ) + { + if(!self hasPerk("specialty_quickrevive")) + { + perks[perks.size] = "specialty_quickrevive"; + } + } + if( getdvar( "mapname" ) == "zm_transit") + { + if(!self hasPerk("specialty_longersprint")) + { + perks[perks.size] = "specialty_longersprint"; + } + if(!self hasPerk("specialty_scavenger")) + { + perks[perks.size] = "specialty_scavenger"; + } + } + if( getdvar( "mapname" ) == "zm_buried") + { + if(!self hasperk("specialty_nomotionsensor")) + { + perks[perks.size] = "specialty_nomotionsensor"; + } + if(!self hasperk("specialty_longersprint")) + { + perks[perks.size] = "specialty_longersprint"; + } + } + if( getdvar( "mapname" ) == "zm_prison" || getdvar( "mapname" ) == "zm_tomb" ) + { + if(!self hasPerk("specialty_grenadepulldeath")) + { + perks[perks.size] = "specialty_grenadepulldeath"; + } + if(!self hasPerk("specialty_deadshot")) + { + perks[perks.size] = "specialty_deadshot"; + } + } + if( getdvar( "mapname" ) == "zm_tomb") + { + if(!self hasPerk("specialty_flakjacket")) + { + perks[perks.size] = "specialty_flakjacket"; + } + } + if(getdvar( "mapname" ) == "zm_tomb" || getdvar( "mapname" ) == "zm_buried" || getdvar( "mapname" ) == "zm_highrise" ) + { + if(!self hasPerk("specialty_additionalprimaryweapon")) + { + perks[perks.size] = "specialty_additionalprimaryweapon"; + } + } + // if( getdvar( "mapname" ) == "zm_highrise" ) //removed for now +// { +// if(!self hasperk("specialty_finalstand")) + // { +// perks[perks.size] = "specialty_finalstand"; +// } +// } + if(!perks.size > 0) + { + self playSoundToPlayer( level.zmb_laugh_alias, self ); + return 0; + } + n = array_randomize(perks); + perk = n[0]; + if(perk == "specialty_longersprint" || perk == "specialty_armorvest" || perk == "specialty_rof" || perk == "specialty_fastreload" || perk == "specialty_grenadepulldeath" || perk == "specialty_deadshot" || perk == "specialty_nomotionsensor" || perk == "specialty_finalstand" || perk == "specialty_quickrevive" || perk == "specialty_scavenger" || perk == "specialty_additionalprimaryweapon" || perk == "specialty_flakjacket") + { + self custom_give_perk(perk, 0, 0, 0); + } + else + { + self custom_give_perk(perk, 0, 1, 0); + } +} + +//--------------------CUSTOM-PERK--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +damage_callback( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime, boneindex ) +{ + if( isDefined( eAttacker.is_zombie ) && eAttacker.is_zombie && self hascustomperk("WIDOWS_WINE") ) + { + zombies = getaiarray(level.zombie_team); + foreach(zombie in zombies) + { + if(distance(self.origin, zombie.origin) < 150) + { + grenades = self get_player_lethal_grenade(); + grenade_count = self getweaponammoclip(grenades); + if(grenade_count > 0) + { + self PlaySound("zmb_elec_jib_zombie"); + self setweaponammoclip(grenades, (grenade_count - 1)); + zombie thread ww_points( self ); + } + } + } + } + if(self hascustomperk("PHD_FLOPPER") || self hasperk("specialty_flakjacket")) + { + if( smeansofdeath == "MOD_FALLING" ) + { + if(isDefined( self.divetoprone ) && self.divetoprone == 1 ) + { + if ( getdvar("mapname") == "zm_buried" ) + self thread divetonuke_explode_network_optimized( self.origin, 300, 5000, 1000, "MOD_GRENADE_SPLASH" ); + else + radiusdamage( self.origin, 300, 5000, 1000, self, "MOD_GRENADE_SPLASH" ); + + if( getdvar( "mapname" ) == "zm_buried" || getdvar( "mapname" ) == "zm_tomb" ) + fx = level._effect[ "divetonuke_groundhit"]; + else + fx = loadfx( "explosions/fx_default_explosion" ); + + self playsound( "zmb_phdflop_explo" ); + playfx( fx, self.origin ); + } + return 0; + } + if(smeansofdeath == "MOD_GRENADE" || smeansofdeath == "MOD_GRENADE_SPLASH" || eattacker == self && !smeansofdeath == "MOD_UNKNOWN") + { + return 0; + } + } + if( isDefined( eAttacker.is_zombie ) && eAttacker.is_zombie && self hascustomperk("Victorious_Tortoise") ) + { + if(self getcurrentweapon() == "riotshield_zm" || self getcurrentweapon() == "alcatraz_shield_zm" || self getcurrentweapon() == "tomb_shield_zm") + { + shield_hp = 1500; + if ( !isDefined( self.shielddamagetaken ) ) + { + self.shielddamagetaken = 0; + } + self.shielddamagetaken += idamage; + if ( self.shielddamagetaken >= shield_hp ) + { + if ( isDefined( self.stub ) ) + { + thread maps\mp\zombies\_zm_unitrigger::unregister_unitrigger( self.stub ); + } + playsoundatposition( "wpn_riotshield_zm_destroy", self.origin ); + self notify("destroy_riotshield"); + if(getdvar( "mapname" ) == "zm_prison") + { + self maps\mp\zombies\_zm_equipment::equipment_take( "alcatraz_shield_zm" ); + } + if(getdvar( "mapname" ) == "zm_tomb") + { + self maps\mp\zombies\_zm_equipment::equipment_take( "tomb_shield_zm" ); + } + if(getdvar( "mapname" ) == "zm_transit") + { + self maps\mp\zombies\_zm_equipment::equipment_take( "riotshield_zm" ); + } + maps\mp\zombies\_zm_equipment::equipment_disappear_fx( self.origin, level._riotshield_dissapear_fx ); + self enableInvulnerability(); + wait 5; + self disableInvulnerability(); + } + else + { + self deployed_set_shield_health( self.shielddamagetaken / 2, self.shield.maxhealth * 5 ); + } + return 0; + } + } + + if(idamage > self.health && !self.dying_wish_on_cooldown && self hascustomperk("Dying_Wish") ) + { + self notify("dying_wish_charge"); + self thread dying_wish_effect(); + return 0; + } + + if (idamage >= self.health && self hascustomperk("Tombstone")) + self thread save_loadout(); + + if(isDefined(level.first_player_damage_callback)) + { + return [[level.first_player_damage_callback]](einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime); + } + return idamage; +} + +custom_get_player_weapon_limit( player ) +{ + weapon_limit = 2; + if( player hascustomperk("MULE") || player hasperk("specialty_additionalprimaryweapon")) + { + weapon_limit = 3; + } + else + { + weapons = self getWeaponsListPrimaries(); + if(weapons.size > weapon_limit) + { + self takeWeapon(weapons[2]); + } + } + return weapon_limit; +} + +start_er() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("stopcustomperk"); + for(;;) + { + if(self hascustomperk("Ethereal_Razor") && self ismeleeing()) + { + foreach(zombie in getAiArray(level.zombie_team)) + { + if( distance( self.origin, zombie.origin ) <= 70 ) + { + if(self maps\mp\zombies\_zm_powerups::is_insta_kill_active()) + { + zombie doDamage(zombie.health + 666, (0, 0, 0)); + } + else + { + if(level.round_number < 10 && !self maps\mp\zombies\_zm_powerups::is_insta_kill_active()) + { + zombie doDamage(zombie.health + 666, (0, 0, 0)); + } + else + { + zombie doDamage(zombie.health / 2, (0, 0, 0)); + } + } + if(zombie.health <= 0) + { + self maps\mp\zombies\_zm_score::add_to_player_score( 100 ); + self.kills++; + } + else + { + self maps\mp\zombies\_zm_score::add_to_player_score( 10 ); + } + } + } + self.health += 10; + if(self.health > self.maxhealth) + { + self.health = self.maxhealth; + } + while(self ismeleeing()) + { + wait .1; + } + } + wait .05; + } +} + +dying_wish_checker() +{ + level endon("end_game"); + self endon("disconnect"); + self endon( "stopcustomperk" ); + self.dying_wish_uses = 0; + for(;;) + { + self.dying_wish_on_cooldown = 0; + self.background_perk[ "Dying_Wish" ].alpha = 1; + self.perk_hud[ "Dying_Wish" ].alpha = 1; + self waittill("dying_wish_charge"); + self.background_perk[ "Dying_Wish" ].alpha = 0.3; + self.perk_hud[ "Dying_Wish" ].alpha = 0.4; + self.dying_wish_uses++; + self.dying_wish_on_cooldown = 1; + delay = 300 + (self.dying_wish_uses * 30); + if(delay >= 600) + { + delay = 600; + } + wait delay; + } +} + +dying_wish_effect() +{ + self iprintln("Dying Wish saved you!"); + self enableInvulnerability(); + self.ignoreme = 1; + self useServerVisionSet(1); + self setvisionsetforplayer( "zombie_death", 0 ); + wait 9; + self.health = 1; + self disableInvulnerability(); + self.ignoreme = 0; + self useServerVisionSet(0); + self setvisionsetforplayer("remote_mortar_enhanced", 0); +} + +ammoregen() +{ + self endon( "disconnect" ); + level endon( "end_game" ); + self endon( "stopcustomperk" ); + for(;;) + { + if( self GetCurrentWeapon() == "blundergat_zm" || self GetCurrentWeapon() == "blundergat_upgraded_zm" || self GetCurrentWeapon() == "blundersplat_zm" || self GetCurrentWeapon() == "blundersplat_upgraded_zm" || self GetCurrentWeapon() == "slipgun_zm" || self GetCurrentWeapon() == "slipgun_upgraded_zm" || self GetCurrentWeapon() == "staff_air_zm" || self GetCurrentWeapon() == "staff_fire_zm"|| self GetCurrentWeapon() == "staff_lightning_zm" || self GetCurrentWeapon() == "staff_water_zm" ) + { + stockcount = self getweaponammostock( self GetCurrentWeapon() ); + self setWeaponAmmostock( self GetCurrentWeapon(), stockcount + 1 ); + wait 6; + } + if(!self GetCurrentWeapon() == "time_bomb_zm" || !self GetCurrentWeapon() == "time_bomb_detonator_zm" || !self GetCurrentWeapon() == "claymore_zm" || !self GetCurrentWeapon() == "blundergat_zm" || !self GetCurrentWeapon() == "blundergat_upgraded_zm" || !self GetCurrentWeapon() == "blundersplat_zm" || !self GetCurrentWeapon() == "blundersplat_upgraded_zm" || !self GetCurrentWeapon() == "slipgun_zm" || !self GetCurrentWeapon() == "slipgun_upgraded_zm" || !self GetCurrentWeapon() == "staff_air_zm" || !self GetCurrentWeapon() == "staff_fire_zm"|| !self GetCurrentWeapon() == "staff_lightning_zm" || !self GetCurrentWeapon() == "staff_water_zm" ) + { + stockcount = self getweaponammostock( self GetCurrentWeapon() ); + self setWeaponAmmostock( self GetCurrentWeapon(), stockcount + 1 ); + wait 2; + } + wait .1; + } +} + +grenadesregen() +{ + self endon( "disconnect" ); + level endon( "end_game" ); + self endon( "stopcustomperk" ); + for(;;) + { + grenades = self get_player_lethal_grenade(); + grenade_count = self getweaponammoclip(grenades); + if(grenade_count < 4) + { + self setweaponammoclip(grenades, (grenade_count + 1)); + } + tactical_grenades = self get_player_tactical_grenade(); + tactical_grenade_count = self getweaponammoclip(tactical_grenades); + if(tactical_grenade_count < 3 ) + { + self setweaponammoclip(tactical_grenades, (tactical_grenade_count + 1)); + } + wait 300; + } +} + +DDown() +{ + self endon( "disconnect" ); + level endon( "end_game" ); + self endon( "stopcustomperk" ); + for(;;) + { + self waittill("player_downed"); + self playsound( "zmb_phdflop_explo" ); + playfx(loadfx("explosions/fx_default_explosion"), self.origin, anglestoforward( ( 0, 45, 55 ) ) ); + RadiusDamage(self.origin, 150, 600, 400, self); + wait .1; + } +} + +LastStand() +{ + if(self hascustomperk("Downers_Delight")) + { + self.customlaststandweapon = self getcurrentweapon(); + self switchtoweapon( self.customlaststandweapon ); + self setweaponammoclip( self.customlaststandweapon, 150 ); + self.bleedout_time = 40; + } + else + { + self maps\mp\zombies\_zm::last_stand_pistol_swap(); + } +} + +start_ec() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("stopcustomperk"); + for(;;) + { + self waittill( "reload_start" ); + + if(self getcurrentweapon() == "slowgun_zm" || self getcurrentweapon() == "slowgun_upgraded_zm" ) + continue; + + playfxontag( level._effect[ "poltergeist"], self, "J_SpineUpper" ); + self EnableInvulnerability(); + self thread divetonuke_explode_network_optimized( self.origin, 150, 1000, 200, "none" ); + self DisableInvulnerability(); + self playsound( "zmb_turbine_explo" ); + wait 1; + } +} + +ww_points( player ) +{ + for(i = 0; i < 3; i++) + { + self maps\mp\zombies\_zm_utility::set_zombie_run_cycle("walk"); + player maps\mp\zombies\_zm_score::add_to_player_score( 10 ); + PlayFXOnTag(level.effect_WebFX,self,"j_spineupper"); + self doDamage(150, (0, 0, 0)); + if(getdvar( "mapname" ) == "zm_tomb" ) + { + self set_anim_rate(0.1); + } + wait 1; + } + if(getdvar( "mapname" ) == "zm_tomb" ) + { + self set_anim_rate( 1 ); + if(!isalive(self)) + { + self delete(); + } + } +} + +ww_nade_explosion() +{ + wait 2; + if(getdvar( "mapname" ) == "zm_transit") + { + if( self object_touching_lava()) + { + self delete(); + return 0; + } + } + foreach(zombie in getAiArray(level.zombie_team)) + { + if( distance( zombie.origin, self.origin ) < 210 ) + { + zombie thread ww_points( self ); + } + } + self delete(); +} + +ww_nades() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("stopcustomperk"); + for(;;) + { + self waittill( "grenade_fire", grenade, weapname ); + if( weapname == "sticky_grenade_zm" ) + { + ww_nade = spawnsm( grenade.origin, "zombie_bomb" ); + ww_nade hide(); + ww_nade linkto( grenade ); + ww_nade thread ww_nade_explosion(); + } + } +} + +spawnsm( origin, model, angles ) +{ + ent = spawn( "script_model", origin ); + ent setmodel( model ); + if( IsDefined( angles ) ) + { + ent.angles = angles; + } + return ent; +} + +object_touching_lava() +{ + if ( !isDefined( level.lava ) ) + { + level.lava = getentarray( "lava_damage", "targetname" ); + } + if ( !isDefined( level.lava ) || level.lava.size < 1 ) + { + return 0; + } + if ( isDefined( self.lasttouching ) && self istouching( self.lasttouching ) ) + { + return 1; + } + i = 0; + while ( i < level.lava.size ) + { + if ( distancesquared( self.origin, level.lava[ i ].origin ) < 2250000 ) + { + if ( isDefined( level.lava[ i ].target ) ) + { + if ( self istouching( level.lava[ i ].volume ) ) + { + if ( isDefined( level.lava[ i ].script_float ) && level.lava[ i ].script_float <= 0.1 ) + { + return 0; + } + self.lasttouching = level.lava[ i ].volume; + return 1; + } + } + else + { + if ( self istouching( level.lava[ i ] ) ) + { + self.lasttouching = level.lava[ i ]; + return 1; + } + } + } + i++; + } + self.lasttouching = undefined; + return 0; +} + +deployed_set_shield_health( damage, max_damage ) +{ + shieldhealth = int( ( 100 * ( max_damage - damage ) ) / max_damage ); + if ( shieldhealth >= 50 ) + { + self.shield_damage_level = 0; + } + else if ( shieldhealth >= 25 ) + { + self.shield_damage_level = 2; + } + else + { + self.shield_damage_level = 3; + } + self updatestandaloneriotshieldmodel(); +} + +updatestandaloneriotshieldmodel() +{ + update = 0; + if ( !isDefined( self.prev_shield_damage_level ) || self.prev_shield_damage_level != self.shield_damage_level ) + { + self.prev_shield_damage_level = self.shield_damage_level; + update = 1; + } + if ( update ) + { + self setmodel( level.deployedshieldmodel[ self.prev_shield_damage_level ] ); + } +} + +set_anim_rate( n_speed ) +{ + n_speed *= 1.9; + self setclientfield( "anim_rate", n_speed ); + n_rate = self getclientfield( "anim_rate" ); + self setentityanimrate( n_rate ); + if ( n_speed != 1 ) + { + self.preserve_asd_substates = 1; + } + wait_network_frame(); + if ( !is_true( self.is_traversing ) ) + { + self.needs_run_update = 1; + self notify( "needs_run_update" ); + } + wait_network_frame(); + if ( n_speed == 1 ) + { + self.preserve_asd_substates = 0; + } +} + +custom_chugabud_give_loadout() +{ + self takeallweapons(); + loadout = self.loadout; + primaries = self getweaponslistprimaries(); + + if ( loadout.weapons.size > 1 || primaries.size > 1 ) + { + foreach ( weapon in primaries ) + self takeweapon( weapon ); + } + + for ( i = 0; i < loadout.weapons.size; i++ ) + { + if ( !isdefined( loadout.weapons[i] ) ) + continue; + + if ( loadout.weapons[i]["name"] == "none" ) + continue; + + self maps\mp\zombies\_zm_weapons::weapondata_give( loadout.weapons[i] ); + } + + if ( loadout.current_weapon >= 0 && isdefined( loadout.weapons[loadout.current_weapon]["name"] ) ) + self switchtoweapon( loadout.weapons[loadout.current_weapon]["name"] ); + + self giveweapon( "knife_zm" ); + self maps\mp\zombies\_zm_equipment::equipment_give( self.loadout.equipment ); + loadout restore_weapons_for_chugabud( self ); + self chugabud_restore_claymore(); + self.score = loadout.score; + self.pers["score"] = loadout.score; + perk_array = maps\mp\zombies\_zm_perks::get_perk_array( 1 ); + + for ( i = 0; i < perk_array.size; i++ ) + { + perk = perk_array[i]; + self unsetperk( perk ); + self.num_perks--; + self set_perk_clientfield( perk, 0 ); + } + + if ( isdefined( self.saved_perks ) && self.saved_perks.size > 0 ) + { + for(i = 0; i < self.saved_perks.size; i++) + { + if( self.saved_perks[ i ] == "specialty_longersprint" || self.saved_perks[ i ] == "specialty_armorvest" || self.saved_perks[ i ] == "specialty_rof" || self.saved_perks[ i ] == "specialty_fastreload" || self.saved_perks[ i ] == "specialty_grenadepulldeath" || self.saved_perks[ i ] == "specialty_deadshot" || self.saved_perks[ i ] == "specialty_nomotionsensor" || self.saved_perks[ i ] == "specialty_quickrevive" || self.saved_perks[ i ] == "specialty_scavenger" || self.saved_perks[ i ] == "specialty_additionalprimaryweapon" || self.saved_perks[ i ] == "specialty_flakjacket") + { + self custom_give_perk(self.saved_perks[ i ], 0, 0, 0); + } + else + { + self custom_give_perk(self.saved_perks[ i ], 0, 1, 1); + } + } + } + + self chugabud_restore_grenades(); + + if ( maps\mp\zombies\_zm_weap_cymbal_monkey::cymbal_monkey_exists() ) + { + if ( loadout.zombie_cymbal_monkey_count ) + { + self maps\mp\zombies\_zm_weap_cymbal_monkey::player_give_cymbal_monkey(); + self setweaponammoclip( "cymbal_monkey_zm", loadout.zombie_cymbal_monkey_count ); + } + } +} + +custom_chugabud_save_loadout() +{ + primaries = self getweaponslistprimaries(); + currentweapon = self getcurrentweapon(); + self.loadout = spawnstruct(); + self.loadout.player = self; + self.loadout.weapons = []; + self.loadout.score = self.score; + self.loadout.current_weapon = -1; + _a376 = primaries; + index = getFirstArrayKey( _a376 ); + while ( isDefined( index ) ) + { + weapon = _a376[ index ]; + self.loadout.weapons[ index ] = maps\mp\zombies\_zm_weapons::get_player_weapondata( self, weapon ); + if ( weapon == currentweapon || self.loadout.weapons[ index ][ "alt_name" ] == currentweapon ) + { + self.loadout.current_weapon = index; + } + index = getNextArrayKey( _a376, index ); + } + self.loadout.equipment = self get_player_equipment(); + if ( isDefined( self.loadout.equipment ) ) + { + self maps\mp\zombies\_zm_equipment::equipment_take( self.loadout.equipment ); + } + self.loadout save_weapons_for_chugabud( self ); + if ( self hasweapon( "claymore_zm" ) ) + { + self.loadout.hasclaymore = 1; + self.loadout.claymoreclip = self getweaponammoclip( "claymore_zm" ); + } + self.loadout.perks = self custom_save_perks(); + self chugabud_save_grenades(); + if ( maps\mp\zombies\_zm_weap_cymbal_monkey::cymbal_monkey_exists() ) + { + self.loadout.zombie_cymbal_monkey_count = self getweaponammoclip( "cymbal_monkey_zm" ); + } +} + +custom_afterlife_give_loadout() +{ + self takeallweapons(); + loadout = self.loadout; + + primaries = self getweaponslistprimaries(); + + if ( loadout.weapons.size > 1 || primaries.size > 1 ) + { + foreach ( weapon in primaries ) + self takeweapon( weapon ); + } + + for ( i = 0; i < loadout.weapons.size; i++ ) + { + if ( !isdefined( loadout.weapons[i] ) ) + continue; + + if ( loadout.weapons[i] == "none" ) + continue; + + weapon = loadout.weapons[i]; + stock_amount = loadout.stockcount[i]; + clip_amount = loadout.clipcount[i]; + + if ( !self hasweapon( weapon ) ) + { + self giveweapon( weapon, 0, self maps\mp\zombies\_zm_weapons::get_pack_a_punch_weapon_options( weapon ) ); + self setweaponammostock( weapon, stock_amount ); + self setweaponammoclip( weapon, clip_amount ); + + if ( weaponisdualwield( weapon ) ) + { + weapon_dw = weapondualwieldweaponname( weapon ); + self setweaponammoclip( weapon_dw, loadout.clipcount2[i] ); + } + + weapon_alt = weaponaltweaponname( weapon ); + + if ( weapon_alt != "none" ) + { + self setweaponammostock( weapon_alt, loadout.stockcountalt[i] ); + self setweaponammoclip( weapon_alt, loadout.clipcountalt[i] ); + } + } + } + + self setspawnweapon( loadout.weapons[ loadout.current_weapon ] ); + self switchtoweaponimmediate( loadout.weapons[ loadout.current_weapon ] ); + if ( isDefined( self get_player_melee_weapon() ) ) + { + self giveweapon( self get_player_melee_weapon() ); + } + self maps\mp\zombies\_zm_equipment::equipment_give( self.loadout.equipment ); + if ( isDefined( loadout.hasclaymore ) && loadout.hasclaymore && !self hasweapon( "claymore_zm" ) ) + { + self giveweapon( "claymore_zm" ); + self set_player_placeable_mine( "claymore_zm" ); + self setactionslot( 4, "weapon", "claymore_zm" ); + self setweaponammoclip( "claymore_zm", loadout.claymoreclip ); + } + if ( isDefined( loadout.hasemp ) && loadout.hasemp ) + { + self giveweapon( "emp_grenade_zm" ); + self setweaponammoclip( "emp_grenade_zm", loadout.empclip ); + } + if ( isDefined( loadout.hastomahawk ) && loadout.hastomahawk ) + { + self giveweapon( self.current_tomahawk_weapon ); + self set_player_tactical_grenade( self.current_tomahawk_weapon ); + self setclientfieldtoplayer( "tomahawk_in_use", 1 ); + } + self.score = loadout.score; + perk_array = maps\mp\zombies\_zm_perks::get_perk_array( 1 ); + i = 0; + while ( i < perk_array.size ) + { + perk = perk_array[ i ]; + self unsetperk( perk ); + self.num_perks--; + + self set_perk_clientfield( perk, 0 ); + i++; + } + if(isDefined( self.keep_perks ) && self.keep_perks ) + { + if(isdefined(self.saved_perks) && self.saved_perks.size > 0) + { + for(i = 0; i < self.saved_perks.size; i++) + { + if(self.saved_perks[ i ] == "specialty_finalstand") + { + } + if( self.saved_perks[ i ] == "specialty_longersprint" || self.saved_perks[ i ] == "specialty_armorvest" || self.saved_perks[ i ] == "specialty_rof" || self.saved_perks[ i ] == "specialty_fastreload" || self.saved_perks[ i ] == "specialty_grenadepulldeath" || self.saved_perks[ i ] == "specialty_deadshot" || self.saved_perks[ i ] == "specialty_nomotionsensor" || self.saved_perks[ i ] == "specialty_quickrevive" || self.saved_perks[ i ] == "specialty_scavenger" || self.saved_perks[ i ] == "specialty_additionalprimaryweapon" || self.saved_perks[ i ] == "specialty_flakjacket") + { + custom_give_perk(self.saved_perks[ i ], 0, 0, 0); + } + else + { + custom_give_perk(self.saved_perks[ i ], 0, 1, 0); //cannot set "saved_perk" to 1, player wont get any perks back when returning from afterlife + } + } + } + } + self.fakedowns = self.downs; + self.keep_perks = undefined; + self set_player_lethal_grenade( self.loadout.lethal_grenade ); + if ( loadout.grenade > 0 ) + { + curgrenadecount = 0; + if ( self hasweapon( self get_player_lethal_grenade())) + { + self getweaponammoclip( self get_player_lethal_grenade() ); + } + else + { + self giveweapon( self get_player_lethal_grenade() ); + } + self setweaponammoclip( self get_player_lethal_grenade(), loadout.grenade + curgrenadecount ); + } +} + +custom_tombstone_give() +{ + dc = level.tombstones[ self.tombstone_index ]; + if ( !flag( "solo_game" ) ) + { + primaries = self getweaponslistprimaries(); + if ( dc.weapon.size > 1 || primaries.size > 1 ) + { + foreach ( weapon in primaries ) + { + self takeweapon( weapon ); + } + } + i = 0; + while ( i < dc.weapon.size ) + { + if ( !isDefined( dc.weapon[ i ] ) ) + { + i++; + continue; + } + if ( dc.weapon[ i ] == "none" ) + { + i++; + continue; + } + weapon = dc.weapon[ i ]; + stock = dc.stockcount[ i ]; + if ( !self hasweapon( weapon ) ) + { + self giveweapon( weapon, 0, self maps\mp\zombies\_zm_weapons::get_pack_a_punch_weapon_options( weapon ) ); + self setweaponammoclip( weapon, weaponclipsize( weapon ) ); + self setweaponammostock( weapon, stock ); + if ( i == dc.current_weapon ) + { + self switchtoweapon( weapon ); + } + } + i++; + } + } + if ( isDefined( dc.hasriotshield ) && dc.hasriotshield ) + { + self maps\mp\zombies\_zm_equipment::equipment_give( "riotshield_zm" ); + if ( isDefined( self.player_shield_reset_health ) ) + { + self [[ self.player_shield_reset_health ]](); + } + } + dc restore_weapons_for_tombstone( self ); + if ( isDefined( dc.hasclaymore ) && dc.hasclaymore && !self hasweapon( "claymore_zm" ) ) + { + self giveweapon( "claymore_zm" ); + self set_player_placeable_mine( "claymore_zm" ); + self setactionslot( 4, "weapon", "claymore_zm" ); + self setweaponammoclip( "claymore_zm", dc.claymoreclip ); + } + if ( isDefined( dc.hasemp ) && dc.hasemp ) + { + self giveweapon( "emp_grenade_zm" ); + self setweaponammoclip( "emp_grenade_zm", dc.empclip ); + } + if(isdefined(self.saved_perks) && self.saved_perks.size > 0) + { + for(i = 0; i < self.saved_perks.size; i++) + { + if( self.saved_perks[ i ] == "specialty_longersprint" || self.saved_perks[ i ] == "specialty_armorvest" || self.saved_perks[ i ] == "specialty_rof" || self.saved_perks[ i ] == "specialty_fastreload" || self.saved_perks[ i ] == "specialty_grenadepulldeath" || self.saved_perks[ i ] == "specialty_deadshot" || self.saved_perks[ i ] == "specialty_nomotionsensor" || self.saved_perks[ i ] == "specialty_quickrevive" || self.saved_perks[ i ] == "specialty_scavenger" || self.saved_perks[ i ] == "specialty_additionalprimaryweapon" || self.saved_perks[ i ] == "specialty_flakjacket") + { + self custom_give_perk(self.saved_perks[ i ], 0, 0, 0); + } + else + { + self custom_give_perk(self.saved_perks[ i ], 0, 1, 1); + } + } + } + if ( dc.grenade > 0 && !flag( "solo_game" ) ) + { + curgrenadecount = 0; + if ( self hasweapon( self get_player_lethal_grenade() ) ) + { + self getweaponammoclip( self get_player_lethal_grenade() ); + } + else + { + self giveweapon( self get_player_lethal_grenade() ); + } + self setweaponammoclip( self get_player_lethal_grenade(), dc.grenade + curgrenadecount ); + } + if ( maps\mp\zombies\_zm_weap_cymbal_monkey::cymbal_monkey_exists() && !flag( "solo_game" ) ) + { + if ( dc.zombie_cymbal_monkey_count ) + { + self maps\mp\zombies\_zm_weap_cymbal_monkey::player_give_cymbal_monkey(); + self setweaponammoclip( "cymbal_monkey_zm", dc.zombie_cymbal_monkey_count ); + } + } +} + +custom_afterlife_save_loadout() +{ + primaries = self getweaponslistprimaries(); + currentweapon = self getcurrentweapon(); + self.loadout = spawnstruct(); + self.loadout.player = self; + self.loadout.weapons = []; + self.loadout.score = self.score; + self.loadout.current_weapon = 0; + _a1516 = primaries; + index = getFirstArrayKey( _a1516 ); + while ( isDefined( index ) ) + { + weapon = _a1516[ index ]; + self.loadout.weapons[ index ] = weapon; + self.loadout.stockcount[ index ] = self getweaponammostock( weapon ); + self.loadout.clipcount[ index ] = self getweaponammoclip( weapon ); + if ( weaponisdualwield( weapon ) ) + { + weapon_dw = weapondualwieldweaponname( weapon ); + self.loadout.clipcount2[ index ] = self getweaponammoclip( weapon_dw ); + } + weapon_alt = weaponaltweaponname( weapon ); + if ( weapon_alt != "none" ) + { + self.loadout.stockcountalt[ index ] = self getweaponammostock( weapon_alt ); + self.loadout.clipcountalt[ index ] = self getweaponammoclip( weapon_alt ); + } + if ( weapon == currentweapon ) + { + self.loadout.current_weapon = index; + } + index = getNextArrayKey( _a1516, index ); + } + self.loadout.equipment = self get_player_equipment(); + if ( isDefined( self.loadout.equipment ) ) + { + self maps\mp\zombies\_zm_equipment::equipment_take( self.loadout.equipment ); + } + if ( self hasweapon( "claymore_zm" ) ) + { + self.loadout.hasclaymore = 1; + self.loadout.claymoreclip = self getweaponammoclip( "claymore_zm" ); + } + if ( self hasweapon( "emp_grenade_zm" ) ) + { + self.loadout.hasemp = 1; + self.loadout.empclip = self getweaponammoclip( "emp_grenade_zm" ); + } + if ( self hasweapon( "bouncing_tomahawk_zm" ) || self hasweapon( "upgraded_tomahawk_zm" ) ) + { + self.loadout.hastomahawk = 1; + self setclientfieldtoplayer( "tomahawk_in_use", 0 ); + } + self.loadout.perks = self custom_save_perks(); + lethal_grenade = self get_player_lethal_grenade(); + if ( self hasweapon( lethal_grenade ) ) + { + self.loadout.grenade = self getweaponammoclip( lethal_grenade ); + } + else + { + self.loadout.grenade = 0; + } + self.loadout.lethal_grenade = lethal_grenade; + self set_player_lethal_grenade( undefined ); +} + +custom_tombstone_laststand() +{ + primaries = self getweaponslistprimaries(); + currentweapon = self getcurrentweapon(); + dc = level.tombstones[ self.tombstone_index ]; + dc.player = self; + dc.weapon = []; + dc.current_weapon = -1; + _a134 = primaries; + index = getFirstArrayKey( _a134 ); + while ( isDefined( index ) ) + { + weapon = _a134[ index ]; + dc.weapon[ index ] = weapon; + dc.stockcount[ index ] = self getweaponammostock( weapon ); + if ( weapon == currentweapon ) + { + dc.current_weapon = index; + } + index = getNextArrayKey( _a134, index ); + } + if ( isDefined( self.hasriotshield ) && self.hasriotshield ) + { + dc.hasriotshield = 1; + } + dc save_weapons_for_tombstone( self ); + if ( self hasweapon( "claymore_zm" ) ) + { + dc.hasclaymore = 1; + dc.claymoreclip = self getweaponammoclip( "claymore_zm" ); + } + if ( self hasweapon( "emp_grenade_zm" ) ) + { + dc.hasemp = 1; + dc.empclip = self getweaponammoclip( "emp_grenade_zm" ); + } + dc.perk = self custom_save_perks(); + lethal_grenade = self get_player_lethal_grenade(); + if ( self hasweapon( lethal_grenade ) ) + { + dc.grenade = self getweaponammoclip( lethal_grenade ); + } + else + { + dc.grenade = 0; + } + if ( maps\mp\zombies\_zm_weap_cymbal_monkey::cymbal_monkey_exists() ) + { + dc.zombie_cymbal_monkey_count = self getweaponammoclip( "cymbal_monkey_zm" ); + } +} + +tombstone_spawn() +{ + dc = spawn( "script_model", self.origin + vectorScale( ( 0, 0, 1 ), 40 ) ); + dc.angles = self.angles; + dc setmodel( "tag_origin" ); + dc_icon = spawn( "script_model", self.origin + vectorScale( ( 0, 0, 1 ), 40 ) ); + dc_icon.angles = self.angles; + dc_icon setmodel( "ch_tombstone1" ); + dc_icon linkto( dc ); + dc.icon = dc_icon; + dc.script_noteworthy = "player_tombstone_model"; + dc.player = self; + self thread tombstone_clear(); + dc thread tombstone_wobble(); + dc thread tombstone_revived( self ); + result = self waittill_any_return( "player_revived", "spawned_player", "disconnect" ); + if ( result == "player_revived" || result == "disconnect" ) + { + dc notify( "tombstone_timedout" ); + dc_icon unlink(); + dc_icon delete(); + dc delete(); + return; + } + dc thread tombstone_timeout(); + dc thread tombstone_grab(); +} + +tombstone_grab() +{ + self endon( "tombstone_timedout" ); + wait 1; + while ( isDefined( self ) ) + { + players = get_players(); + i = 0; + while ( i < players.size ) + { + if ( players[ i ].is_zombie ) + { + i++; + continue; + } + else + { + if ( isDefined( self.player ) && players[ i ] == self.player ) + { + tombstone_machine_triggers = getentarray( "specialty_scavenger", "script_noteworthy" ); + istombstonepowered = 0; + + foreach ( trigger in tombstone_machine_triggers ) + { + if ( isdefined( trigger.power_on ) && trigger.power_on || isdefined( trigger.turbine_power_on ) && trigger.turbine_power_on ) + istombstonepowered = 1; + } + + istombstonepowered = 1; //manually set to 1 + if ( istombstonepowered ) + { + dist = distance( players[ i ].origin, self.origin ); + if ( dist < 64 ) + { + playfx( level._effect[ "powerup_grabbed" ], self.origin ); + playfx( level._effect[ "powerup_grabbed_wave" ], self.origin ); + players[ i ] custom_tombstone_give(); + wait 0.1; + playsoundatposition( "zmb_tombstone_grab", self.origin ); + self stoploopsound(); + self.icon unlink(); + self.icon delete(); + self delete(); + self notify( "tombstone_grabbed" ); + players[ i ] clientnotify( "dc0" ); + players[ i ] notify( "dance_on_my_grave" ); + } + } + } + } + wait .1; + i++; + } + wait_network_frame(); + } +} + +solo_tombstone_removal() +{ + level notify( "tombstone_on" ); +} + +turn_tombstone_on() +{ + level endon("end_game"); + while ( 1 ) + { + machine = getentarray( "vending_tombstone", "targetname" ); + machine_triggers = getentarray( "vending_tombstone", "target" ); + i = 0; + while ( i < machine.size ) + { + machine[ i ] setmodel( level.machine_assets[ "tombstone" ].off_model ); + i++; + } + level thread do_initial_power_off_callback( machine, "tombstone" ); + array_thread( machine_triggers, ::set_power_on, 0 ); + level waittill( "tombstone_on" ); + i = 0; + while ( i < machine.size ) + { + machine[ i ] setmodel( level.machine_assets[ "tombstone" ].on_model ); + machine[ i ] vibrate( vectorScale( ( 0, -1, 0 ), 100 ), 0,3, 0,4, 3 ); + machine[ i ] playsound( "zmb_perks_power_on" ); + machine[ i ] thread perk_fx( "tombstone_light" ); + machine[ i ] thread play_loop_on_machine(); + i++; + } + level notify( "specialty_scavenger_power_on" ); + array_thread( machine_triggers, ::set_power_on, 1 ); + if ( isDefined( level.machine_assets[ "tombstone" ].power_on_callback ) ) + { + array_thread( machine, level.machine_assets[ "tombstone" ].power_on_callback ); + } + level waittill( "tombstone_off" ); + if ( isDefined( level.machine_assets[ "tombstone" ].power_off_callback ) ) + { + array_thread( machine, level.machine_assets[ "tombstone" ].power_off_callback ); + } + array_thread( machine, ::turn_perk_off ); + players = get_players(); + _a1718 = players; + _k1718 = getFirstArrayKey( _a1718 ); + while ( isDefined( _k1718 ) ) + { + player = _a1718[ _k1718 ]; + player.hasperkspecialtytombstone = undefined; + _k1718 = getNextArrayKey( _a1718, _k1718 ); + } + } +} + +perk_machine_spawn_init() +{ + level endon("end_game"); + 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 + "_perks_" ) + location; + pos = []; + if ( isDefined( level.override_perk_targetname ) ) + { + structs = getstructarray( level.override_perk_targetname, "targetname" ); + } + else + { + structs = getstructarray( "zm_perk_machine", "targetname" ); + } + _a3578 = structs; + _k3578 = getFirstArrayKey( _a3578 ); + while ( isDefined( _k3578 ) ) + { + struct = _a3578[ _k3578 ]; + if ( isDefined( struct.script_string ) ) + { + tokens = strtok( struct.script_string, " " ); + _a3583 = tokens; + _k3583 = getFirstArrayKey( _a3583 ); + while ( isDefined( _k3583 ) ) + { + token = _a3583[ _k3583 ]; + if ( token == match_string ) + { + pos[ pos.size ] = struct; + } + _k3583 = getNextArrayKey( _a3583, _k3583 ); + } + } + else pos[ pos.size ] = struct; + _k3578 = getNextArrayKey( _a3578, _k3578 ); + } + if ( !isDefined( pos ) || pos.size == 0 ) + { + return; + } + precachemodel( "zm_collision_perks1" ); + i = 0; + while ( i < pos.size ) + { + 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.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 ) + { + bump_trigger = undefined; + } + else + { + 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" ) + { + 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.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 ) ) + { + use_trigger.blocker_model = pos[ i ].blocker_model; + } + if ( isDefined( pos[ i ].script_int ) ) + { + perk_machine.script_int = pos[ i ].script_int; + } + if ( isDefined( pos[ i ].turn_on_notify ) ) + { + perk_machine.turn_on_notify = pos[ i ].turn_on_notify; + } + if ( perk == "specialty_scavenger" || perk == "specialty_scavenger_upgrade" ) + { + use_trigger.script_sound = "mus_perks_tombstone_jingle"; + use_trigger.script_string = "tombstone_perk"; + use_trigger.script_label = "mus_perks_tombstone_sting"; + use_trigger.target = "vending_tombstone"; + perk_machine.script_string = "tombstone_perk"; + perk_machine.targetname = "vending_tombstone"; + if ( isDefined( bump_trigger ) ) + { + bump_trigger.script_string = "tombstone_perk"; + } + } + 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 ); + } + } + i++; + } +} + +isTown() +{ + if (isDefined(level.zombiemode_using_tombstone_perk) && level.zombiemode_using_tombstone_perk) + { + level thread perk_machine_spawn_init(); + thread solo_tombstone_removal(); + thread turn_tombstone_on(); + } +} + +AimAssist() +{ + self endon("disconnect"); + level endon("end_game"); + self endon("stopcustomperk"); + for(;;) + { + view_pos = self GetWeaponMuzzlePoint(); + zombies = get_array_of_closest( view_pos, getaiarray( level.zombie_team ), undefined, undefined, undefined ); + range_squared = 300 * 300; + for ( i = 0; i < zombies.size; i++ ) + { + if ( !IsDefined( zombies[i] ) || !IsAlive( zombies[i] ) ) + { + continue; + } + enemy_origin = zombies[i].origin; + test_range_squared = DistanceSquared( view_pos, enemy_origin ); + if ( test_range_squared < range_squared ) + { + if(zombies[i] player_can_see_me(self)) + { + if(self adsButtonPressed() && !self IsReloading() && !isads( self )) + { + self setPlayerAngles(vectorToAngles((zombies[i] getTagOrigin("j_head")) - (self getEye()))); + while(self adsButtonPressed()) + { + wait .05; + } + break; + } + } + } + } + wait .05; + } +} + +player_can_see_me( player ) +{ + playerangles = player getplayerangles(); + playerforwardvec = anglesToForward( playerangles ); + playerunitforwardvec = vectornormalize( playerforwardvec ); + banzaipos = self.origin; + playerpos = player getorigin(); + playertobanzaivec = banzaipos - playerpos; + playertobanzaiunitvec = vectornormalize( playertobanzaivec ); + forwarddotbanzai = vectordot( playerunitforwardvec, playertobanzaiunitvec ); + if ( forwarddotbanzai >= 1 ) + { + anglefromcenter = 0; + } + else if ( forwarddotbanzai <= -1 ) + { + anglefromcenter = 180; + } + else + { + anglefromcenter = acos( forwarddotbanzai ); + } + playerfov = getDvarFloat( "cg_fov" ); + banzaivsplayerfovbuffer = getDvarFloat( "g_banzai_player_fov_buffer" ); + if ( banzaivsplayerfovbuffer <= 0 ) + { + banzaivsplayerfovbuffer = 0.2; + } + playercanseeme = anglefromcenter <= ( ( playerfov * 0.5 ) * ( 1 - banzaivsplayerfovbuffer ) ); + return playercanseeme; +} + +//----Custom-Tombstone---------------------------------------------------------------------------------------------------------------------------------- + +save_loadout() +{ + primaries = self getweaponslistprimaries(); + currentweapon = self getcurrentweapon(); + self.current_loadout = spawnstruct(); + self.current_loadout.player = self; + self.current_loadout.weapons = []; + self.current_loadout.score = self.score; + self.current_loadout.current_weapon = 0; + + _a1516 = primaries; + index = getFirstArrayKey( _a1516 ); + while ( isDefined( index ) ) + { + weapon = _a1516[ index ]; + self.current_loadout.weapons[ index ] = weapon; + self.current_loadout.stockcount[ index ] = self getweaponammostock( weapon ); + self.current_loadout.clipcount[ index ] = self getweaponammoclip( weapon ); + if ( weaponisdualwield( weapon ) ) + { + weapon_dw = weapondualwieldweaponname( weapon ); + self.current_loadout.clipcount2[ index ] = self getweaponammoclip( weapon_dw ); + } + weapon_alt = weaponaltweaponname( weapon ); + if ( weapon_alt != "none" ) + { + self.current_loadout.stockcountalt[ index ] = self getweaponammostock( weapon_alt ); + self.current_loadout.clipcountalt[ index ] = self getweaponammoclip( weapon_alt ); + } + if ( weapon == currentweapon ) + { + self.current_loadout.current_weapon = index; + } + index = getNextArrayKey( _a1516, index ); + } + + self.current_loadout.equipment = self get_player_equipment(); + + if ( isDefined( self.current_loadout.equipment ) ) + self maps\mp\zombies\_zm_equipment::equipment_take( self.current_loadout.equipment ); + + if ( maps\mp\zombies\_zm_weap_cymbal_monkey::cymbal_monkey_exists() ) + self.current_loadout.zombie_cymbal_monkey_count = self getweaponammoclip( "cymbal_monkey_zm" ); + + if ( self hasweapon( "claymore_zm" ) ) + { + self.current_loadout.hasclaymore = 1; + self.current_loadout.claymoreclip = self getweaponammoclip( "claymore_zm" ); + } + if ( self hasweapon( "emp_grenade_zm" ) ) + { + self.current_loadout.hasemp = 1; + self.current_loadout.empclip = self getweaponammoclip( "emp_grenade_zm" ); + } + if ( self hasweapon( "bouncing_tomahawk_zm" ) || self hasweapon( "upgraded_tomahawk_zm" ) ) + { + self.current_loadout.hastomahawk = 1; + self setclientfieldtoplayer( "tomahawk_in_use", 0 ); + } + self.current_loadout.perks = self custom_save_perks(); + lethal_grenade = self get_player_lethal_grenade(); + + if ( self hasweapon( lethal_grenade ) ) + self.current_loadout.grenade = self getweaponammoclip( lethal_grenade ); + else + self.current_loadout.grenade = 0; + + self.current_loadout.lethal_grenade = lethal_grenade; + self set_player_lethal_grenade( undefined ); +} + +give_loadout() +{ + foreach(hud in self.perk_hud) + { + hud destroy(); + } + foreach(hud2 in self.background_perk) + { + hud2 destroy(); + } + self.background_perk = []; + self.perkarray = []; + self.perk_hud = []; + self notify("stopcustomperk"); + self.bleedout_time = 30; + self.ignore_lava_damage = 0; + + self takeallweapons(); + loadout = self.current_loadout; + primaries = self getweaponslistprimaries(); + if ( loadout.weapons.size > 1 || primaries.size > 1 ) + { + foreach ( weapon in primaries ) + self takeweapon( weapon ); + } + + for ( i = 0; i < loadout.weapons.size; i++ ) + { + if ( !isdefined( loadout.weapons[i] ) ) + continue; + + if ( loadout.weapons[i] == "none" ) + continue; + + weapon = loadout.weapons[i]; + stock_amount = loadout.stockcount[i]; + clip_amount = loadout.clipcount[i]; + + if ( !self hasweapon( weapon ) ) + { + self giveweapon( weapon, 0, self maps\mp\zombies\_zm_weapons::get_pack_a_punch_weapon_options( weapon ) ); + self setweaponammostock( weapon, stock_amount ); + self setweaponammoclip( weapon, clip_amount ); + + if ( weaponisdualwield( weapon ) ) + { + weapon_dw = weapondualwieldweaponname( weapon ); + self setweaponammoclip( weapon_dw, loadout.clipcount2[i] ); + } + + weapon_alt = weaponaltweaponname( weapon ); + + if ( weapon_alt != "none" ) + { + self setweaponammostock( weapon_alt, loadout.stockcountalt[i] ); + self setweaponammoclip( weapon_alt, loadout.clipcountalt[i] ); + } + } + } + + self setspawnweapon( loadout.weapons[ loadout.current_weapon ] ); + self switchtoweaponimmediate( loadout.weapons[ loadout.current_weapon ] ); + if ( isDefined( self get_player_melee_weapon() ) ) + { + self giveweapon( self get_player_melee_weapon() ); + } + self maps\mp\zombies\_zm_equipment::equipment_give( self.current_loadout.equipment ); + if ( isDefined( loadout.hasclaymore ) && loadout.hasclaymore && !self hasweapon( "claymore_zm" ) ) + { + self giveweapon( "claymore_zm" ); + self set_player_placeable_mine( "claymore_zm" ); + self setactionslot( 4, "weapon", "claymore_zm" ); + self setweaponammoclip( "claymore_zm", loadout.claymoreclip ); + } + if ( isDefined( loadout.zombie_cymbal_monkey_count ) && loadout.zombie_cymbal_monkey_count ) + { + self maps\mp\zombies\_zm_weap_cymbal_monkey::player_give_cymbal_monkey(); + self setweaponammoclip( "cymbal_monkey_zm", loadout.zombie_cymbal_monkey_count ); + } + if ( isDefined( loadout.hasemp ) && loadout.hasemp ) + { + self giveweapon( "emp_grenade_zm" ); + self setweaponammoclip( "emp_grenade_zm", loadout.empclip ); + } + if ( isDefined( loadout.hastomahawk ) && loadout.hastomahawk ) + { + self giveweapon( self.current_tomahawk_weapon ); + self set_player_tactical_grenade( self.current_tomahawk_weapon ); + self setclientfieldtoplayer( "tomahawk_in_use", 1 ); + } + self.score = loadout.score; + perk_array = maps\mp\zombies\_zm_perks::get_perk_array( 1 ); + i = 0; + while ( i < perk_array.size ) + { + perk = perk_array[ i ]; + self unsetperk( perk ); + self.num_perks--; + + self set_perk_clientfield( perk, 0 ); + i++; + } + if(isDefined( self.saved_perks ) && self.saved_perks.size > 0) + { + for(i = 0; i < self.saved_perks.size; i++) + { + if( self.saved_perks[ i ] == "specialty_longersprint" || self.saved_perks[ i ] == "specialty_armorvest" || self.saved_perks[ i ] == "specialty_rof" || self.saved_perks[ i ] == "specialty_fastreload" || self.saved_perks[ i ] == "specialty_grenadepulldeath" || self.saved_perks[ i ] == "specialty_deadshot" || self.saved_perks[ i ] == "specialty_nomotionsensor" || self.saved_perks[ i ] == "specialty_quickrevive" || self.saved_perks[ i ] == "specialty_additionalprimaryweapon" || self.saved_perks[ i ] == "specialty_flakjacket") + { + + custom_give_perk(self.saved_perks[ i ], 0, 0, 0); + } + else + { + custom_give_perk(self.saved_perks[ i ], 0, 1, 1); + } + } + } + self.fakedowns = self.downs; + self.keep_perks = undefined; + self set_player_lethal_grenade( self.current_loadout.lethal_grenade ); + if ( loadout.grenade > 0 ) + { + curgrenadecount = 0; + + if ( self hasweapon( self get_player_lethal_grenade())) + self getweaponammoclip( self get_player_lethal_grenade() ); + else + self giveweapon( self get_player_lethal_grenade() ); + + self setweaponammoclip( self get_player_lethal_grenade(), loadout.grenade + curgrenadecount ); + } +} + + +spawn_tombstone() +{ + if(getdvar("mapname") == "zm_prison" && isDefined(self.afterlife) && !self.afterlife) + self thread suicide_trigger_spawn(); + else if(getdvar("mapname") != "zm_prison") + self thread suicide_trigger_spawn(); + + tombstone = spawn( "script_model", self.origin + vectorScale( ( 0, 0, 1 ), 40 ) ); + tombstone.angles = self.angles; + tombstone setmodel( "tag_origin" ); + tombstone_icon = spawn( "script_model", self.origin + vectorScale( ( 0, 0, 1 ), 40 ) ); + tombstone_icon.angles = self.angles; + tombstone_hint = spawn( "trigger_radius", self.origin, 0, 35, 64 ); + tombstone_hint SetCursorHint("HINT_NOICON"); + tombstone_hint setHintString("This is ^1 " + self.name + " ^7tombstone"); + + + if(getdvar("mapname") == "zm_buried") + tombstone_icon setmodel( "p6_zm_bu_tombstone_01" ); + else if(getdvar("mapname") == "zm_prison") + tombstone_icon setmodel( "p6_anim_zm_al_magic_box_lock" ); + else + tombstone_icon setmodel( "zombie_teddybear" ); + + tombstone_icon linkto( tombstone ); + tombstone.icon = tombstone_icon; + tombstone.script_noteworthy = "player_tombstone_model"; + tombstone.player = self; + self thread custom_tombstone_clear(); + tombstone thread custom_tombstone_wobble(); + tombstone thread custom_tombstone_revived( self ); + result = self waittill_any_return( "player_revived", "spawned_player", "disconnect" ); + if(isdefined(self.keep_perks) && self.keep_perks) + { + if ( result == "player_revived" || result == "disconnect" ) + { + tombstone notify( "tombstone_timedout" ); + tombstone_icon unlink(); + tombstone_icon delete(); + tombstone delete(); + tombstone_hint delete(); + return; + } + } + if(getdvar("mapname") != "zm_prison") + { + if ( result == "player_revived" || result == "disconnect" ) + { + tombstone notify( "tombstone_timedout" ); + tombstone_icon unlink(); + tombstone_icon delete(); + tombstone delete(); + tombstone_hint delete(); + return; + } + } + tombstone thread custom_tombstone_timeout(tombstone_hint); + tombstone thread grab_custom_tombstone(tombstone_hint); +} + +grab_custom_tombstone(hint) +{ + self endon( "tombstone_timedout" ); + wait 1; + while ( isDefined( self ) ) + { + players = get_players(); + i = 0; + while ( i < players.size ) + { + if ( players[ i ].is_zombie ) + { + i++; + continue; + } + else + { + if ( isDefined( self.player ) && players[ i ] == self.player ) + { + istombstonepowered = 1; + if ( istombstonepowered && !players[ i ] maps\mp\zombies\_zm_laststand::player_is_in_laststand() ) + { + dist = distance( players[ i ].origin, self.origin ); + if ( dist < 64 ) + { + playfx( level._effect[ "powerup_grabbed" ], self.origin ); + playfx( level._effect[ "powerup_grabbed_wave" ], self.origin ); + players[ i ] give_loadout(); + wait 0.1; + playsoundatposition( "zmb_tombstone_grab", self.origin ); + self stoploopsound(); + self.icon unlink(); + self.icon delete(); + self delete(); + hint delete(); + self notify( "tombstone_grabbed" ); + players[ i ] clientnotify( "dc0" ); + players[ i ] notify( "dance_on_my_grave" ); + } + } + } + } + wait .1; + i++; + } + wait_network_frame(); + } +} + +custom_tombstone_clear() +{ + result = self waittill_any_return( "tombstone_timedout", "tombstone_grabbed" ); + self.current_loadout = spawnstruct(); +} + +custom_tombstone_wobble() +{ + self endon( "tombstone_grabbed" ); + self endon( "tombstone_timedout" ); + + if ( isdefined( self ) ) + { + wait 1; + playfxontag( level._effect["powerup_on"], self, "tag_origin" ); + } + + while ( isdefined( self ) ) + { + self rotateyaw( 360, 3 ); + wait 2.9; + } +} + +custom_tombstone_timeout(hint) +{ + self endon( "tombstone_grabbed" ); + self thread playtombstonetimeraudio(); + wait 48.5; + + for ( i = 0; i < 40; i++ ) + { + if ( i % 2 ) + self.icon ghost(); + else + self.icon show(); + + if ( i < 15 ) + { + wait 0.5; + continue; + } + + if ( i < 25 ) + { + wait 0.25; + continue; + } + + wait 0.1; + } + + self notify( "tombstone_timedout" ); + self.icon unlink(); + self.icon delete(); + self delete(); + hint delete(); +} + +custom_tombstone_revived( player ) +{ + self endon( "tombstone_timedout" ); + player endon( "disconnect" ); + shown = 1; + + while ( isdefined( self ) && isdefined( player ) ) + { + if ( isdefined( player.revivetrigger ) && isdefined( player.revivetrigger.beingrevived ) && player.revivetrigger.beingrevived ) + { + if ( shown ) + { + shown = 0; + self.icon hide(); + } + } + else if ( !shown ) + { + shown = 1; + self.icon show(); + } + + wait 0.05; + } +} + +//--^-Custom-Tombstone-^-------------------------------------------------------------------------------------------------------------------------------- + +divetonuke_explode_network_optimized( origin, radius, max_damage, min_damage, damage_mod ) +{ + self endon( "disconnect" ); + a_zombies = get_array_of_closest( origin, get_round_enemy_array(), undefined, undefined, radius ); + network_stall_counter = 0; + + if ( isdefined( a_zombies ) ) + { + for ( i = 0; i < a_zombies.size; i++ ) + { + e_zombie = a_zombies[i]; + + if ( !isdefined( e_zombie ) || !isalive( e_zombie ) ) + continue; + + if ( isdefined( level.sloth ) && e_zombie == level.sloth ) + continue; + + if ( isdefined( e_zombie.is_avogadro ) && e_zombie.is_avogadro ) + continue; + + dist = distance( e_zombie.origin, origin ); + damage = min_damage + ( max_damage - min_damage ) * ( 1.0 - dist / radius ); + e_zombie dodamage( damage, e_zombie.origin, self, self, 0, damage_mod ); + network_stall_counter--; + + if ( network_stall_counter <= 0 ) + { + wait_network_frame(); + network_stall_counter = randomintrange( 1, 3 ); + } + } + } +} diff --git a/t6/scripts/zm/zm_tomb/update/trials.gsc b/t6/scripts/zm/zm_tomb/update/trials.gsc new file mode 100644 index 0000000..f211a61 --- /dev/null +++ b/t6/scripts/zm/zm_tomb/update/trials.gsc @@ -0,0 +1,1844 @@ +#include codescripts/struct; +#include maps/mp/_utility; +#include common_scripts/utility; +#include maps/mp/gametypes_zm/_hud; +#include maps/mp/gametypes_zm/_hud_util; +#include maps/mp/gametypes_zm/_hud_message; +#include maps/mp/gametypes_zm/_weapons; +#include maps/mp/zombies/_zm_powerups; +#include maps/mp/zombies/_zm_buildables; +#include maps/mp/zombies/_zm_score; +#include maps/mp/zombies/_zm_utility; +#include maps/mp/zombies/_zm_weapons; +#include maps/mp/gametypes_zm/_spawning; +#include maps/mp/zombies/_zm_unitrigger; +#include maps/mp/zombies/_zm_spawner; +#include maps/mp/zombies/_zm; +#include maps/mp/zombies/_zm_perks; +#include maps/mp/zombies/_zm_zonemgr; +#include maps/mp/zombies/_zm_magicbox; +#include maps/mp/zombies/_zm_power; +#include maps/mp/zombies/_zm_powerups; +#include maps/mp/animscripts/zm_utility; + +// Trials System by ZECxR3ap3r & John Kramer +// V1.0.1 + +init() { + // Precaching Models + precachemodel("t6_wpn_zmb_jet_gun_world"); + precachemodel("zombie_pickup_perk_bottle"); + precachemodel("t6_wpn_zmb_raygun_view"); + precachemodel("p6_anim_zm_buildable_pap"); + precachemodel("collision_wall_256x256x10_standard"); + precachemodel("p6_zm_hr_lion_statue_base"); + precachemodel("p6_zm_hr_lion_statue"); + // Precaching Shaders + precacheshader("gradient"); + precacheshader("white"); + precacheshader("menu_mp_star_rating"); + precacheshader("gradient_fadein"); + precacheshader("scorebar_zom_1"); + precacheshader("codtv_info"); + // Settings + setDvar("TrialsCost", 100);// How Much the trials will cost + setDvar("TrialsAllowFreePerk", 1);// Adds a Free Perk Powerup to the Trials Rewards + setDvar("TrialsEnableWonderweapons", 1);// Adds Legendary Wonderweapon Rewards + setDvar("TrialsEnablePapDrop", 1);// Adds Legendary Pap Powerup Reward + // Setup + if(level.script == "zm_transit") { + if(getDvar( "ui_zm_mapstartlocation" ) == "transit" && getDvar( "ui_zm_gamemodegroup" ) != "zsurvival"|| getDvar( "ui_zm_mapstartlocation" ) == "town"){ + Collision = spawn( "script_model", (655.126, -281.746, -61.875)); + Collision.angles = (0, 0, 0); + Collision setmodel("collision_wall_512x512x10_standard"); + PodiumModel = "t6_wpn_zmb_jet_gun_world"; + PodiumOrigin = array((495.129, -289.81, -39.875), (595.129, -289.81, -39.875), (775.129, -289.81, -39.875), (875.129, -289.81, -39.875)); + PodiumAngles = array((90, 270, 0), (90, 270, 0), (90,270,0), (90,270,0)); + TrialsMainModel = "zombie_teddybear"; + TrialsMainOrigin = (685.358, -277.641, -33.0248); + TrialsMainAngles = (0, -90, 0); + FXOriginOffset = (0,10,18); + } + else if ( getDvar( "ui_zm_mapstartlocation" ) == "farm" ) { + Collision = spawn( "script_model", (7070.82, -5715.47, -46.2625)); + Collision.angles = (0, 90, 0); + Collision setmodel("collision_wall_256x256x10_standard"); + PodiumModel = "t6_wpn_zmb_jet_gun_world"; + PodiumOrigin = array((7070.94, -5798.61, -28.2646), (7070.94, -5744.61, -28.2646), (7070.94, -5692.61, -28.2646), (7070.94, -5638.61, -28.2646)); + PodiumAngles = array((90, 0, 0), (90, 0, 0), (90,0,0), (90,0,0)); + TrialsMainModel = "zombie_teddybear"; + TrialsMainOrigin = (7670.15, -5562.8, 50.5099); + TrialsMainAngles = (0, -50, 0); + FXOriginOffset = (-12,0,20); + } + else if ( getDvar( "ui_zm_mapstartlocation" ) == "transit" && getDvar( "ui_zm_gamemodegroup" ) == "zsurvival") { + Collision = spawn( "script_model", (-6289.62, 5455.29, 74.125)); + Collision.angles = (0, 90, 0); + Collision setmodel("collision_wall_256x256x10_standard"); + PodiumModel = "t6_wpn_zmb_jet_gun_world"; + PodiumOrigin = array((-6284.36, 5347.11, -35.875), (-6284.36, 5407.11, -35.875), (-6284.36, 5467.11, -35.875), (-6284.36, 5527.11, -35.875)); + PodiumAngles = array((90, 0, 0), (90, 0, 0), (90,0,0), (90,0,0)); + TrialsMainModel = "zombie_teddybear"; + TrialsMainOrigin = (-6097.18, 5610.29, -3.875); + TrialsMainAngles = (0, -130, 0); + FXOriginOffset = (-12,0,20); + } + } + else if(level.script == "zm_prison") { + Collision = spawn( "script_model", (2250.64, 9891.08, 1964.13)); + Collision.angles = (0, 90, 0); + Collision setmodel("collision_wall_512x512x10_standard"); + PodiumModel = "p6_zm_al_electric_chair"; + PodiumOrigin = array((2232.09, 9754.98, 1704.13), (2232.09, 9844.98, 1704.13), (2232.09, 9934.98, 1704.13), (2232.09, 10025, 1704.13)); + PodiumAngles = array((0, 0, 0), (0, 0, 0), (0,0,0), (0,0,0)); + TrialsMainModel = "p6_zm_al_wall_trap_control_red"; + TrialsMainOrigin = (2470.36, 9752.72, 1764.13); + TrialsMainAngles = (0, -180, 0); + FXOriginOffset = (17,0,15); + } + else if(level.script == "zm_buried") { + Collision = spawn( "script_model", (1355.53, 1397.91, 336.474)); + Collision.angles = (0, -20, 0); + Collision setmodel("collision_wall_256x256x10_standard"); + PodiumModel = "p6_zm_bu_ether_amplifier"; + PodiumOrigin = array((1416.2, 1364.68, 200.125), (1365.2, 1383.68, 200.125), (1307.2, 1403.68, 200.125), (1247.2, 1425.68, 200.125)); + PodiumAngles = array((0, 0, 0), (0, 0, 0), (0,0,0), (0,0,0)); + TrialsMainModel = "zombie_teddybear"; + TrialsMainOrigin = (1405.07, 1651.54, 250.32); + TrialsMainAngles = (0, -100, 0); + FXOriginOffset = (0,0,43); + } + else if(level.script == "zm_tomb") { + Collision = spawn( "script_model", (401.108, 2118.76, -122.744)); + Collision.angles = (0, 0, 0); + Collision setmodel("zm_collision_perks1"); + PodiumModel = "p6_zm_tm_challenge_box"; + PodiumOrigin = array((538.473, 2119.9, -127.875), (458.473, 2119.9, -127.875), (348.473, 2119.9, -127.875), (268.473, 2119.9, -127.875)); + PodiumAngles = array((0, 0, 0), (0, 0, 0), (0,0,0), (0,0,0)); + TrialsMainModel = "p6_zm_tm_puzzle_lever_switch"; + TrialsMainOrigin = (401.108, 2118.76, -122.744); + TrialsMainAngles = (0, 0, 0); + FXOriginOffset = (0,0,30); + } + else if(level.script == "zm_nuked") { + Collision = spawn( "script_model", (578.573, 742.585, -64.1112)); + Collision.angles = (0, -164, 0); + Collision setmodel("collision_wall_256x256x10_standard"); + PodiumModel = "dest_zm_nuked_male_01_d0"; + PodiumOrigin = array((665.924, 740.986, -56.875), (617.924, 726.986, -56.875), (565.924, 712.986, -56.875), (515.924, 698.986, -56.875)); + PodiumAngles = array((0, -250, 0), (0, -250, 0), (0,-250,0), (0,-250,0)); + TrialsMainModel = "zombie_teddybear"; + TrialsMainOrigin = (661.327, 983.586, -52.875); + TrialsMainAngles = (0, -150, 0); + FXOriginOffset = (-4,15,14); + } + else if(level.script == "zm_highrise") { + Collision = spawn( "script_model", (1430.19, -348.386, 2624.13)); + Collision.angles = (0, 60, 0); + Collision setmodel("collision_wall_512x512x10_standard"); + Lion1 = spawn( "script_model", (1347.93, -459.859, 2742.13)); + Lion1.angles = (0, 60, 0); + Lion1 setmodel("p6_zm_hr_lion_statue"); + Lion2 = spawn( "script_model", (1400.9, -368.924, 2742.13)); + Lion2.angles = (0, 60, 0); + Lion2 setmodel("p6_zm_hr_lion_statue"); + Lion3 = spawn( "script_model", (1483.22, -226.259, 2742.13)); + Lion3.angles = (0, 60, 0); + Lion3 setmodel("p6_zm_hr_lion_statue"); + Lion4 = spawn( "script_model", (1534.45, -137.528, 2742.13)); + Lion4.angles = (0, 60, 0); + Lion4 setmodel("p6_zm_hr_lion_statue"); + PodiumModel = "p6_zm_hr_lion_statue_base"; + PodiumOrigin = array((1347.93, -459.859, 2704.13), (1400.9, -368.924, 2704.13), (1483.22, -226.259, 2704.13), (1534.45, -137.528, 2704.13)); + PodiumAngles = array((0, 60, 0), (0, 60, 0), (0,60,0), (0,60,0)); + TrialsMainModel = "zombie_teddybear"; + TrialsMainOrigin = (1434.69, -296.901, 2749.13); + TrialsMainAngles = (0, -35, 0); + FXOriginOffset = (0,2,55); + } + // Main Setup + level.ReaperTrialsActive = 0; + level thread TrialsSystem(FXOriginOffset,PodiumModel, PodiumOrigin, PodiumAngles, TrialsMainModel, TrialsMainOrigin, TrialsMainAngles); + level thread on_connect(); + level thread EndGameListener(); + // Rewards Map Specific + switch(level.script) { + case "zm_transit": + AddReward("Legendary", undefined, "Skullcrusher", "m16_gl_upgraded_zm", 0); + AddReward("Legendary", "zombie_z_money_icon", "Bonus Points", "Bonus_Points", 1); + AddReward("Legendary", undefined, "SLDG HAMR", "hamr_upgraded_zm", 0); + AddReward("Epic", "zombie_z_money_icon", "Bonus Points", "Bonus_Points", 1); + AddReward("Epic", undefined, "M16", "m16_zm", 0); + AddReward("Rare", "zombie_carpenter", "Carpenter", "carpenter", 1); + AddReward("Rare", "zombie_z_money_icon", "Bonus Points", "Bonus_Points", 1); + AddReward("Rare", undefined, "KAP-40", "kard_zm", 0); + AddReward("Rare", undefined, "M1911", "m1911_zm", 0); + AddReward("Rare", undefined, "RPG", "usrpg_zm", 0); + AddReward("Common", "zombie_z_money_icon", "Bonus Points", "Lose_Points", 1); + AddReward("Common", "zombie_carpenter", "Carpenter", "carpenter", 1); + AddReward("Common", undefined, "SMR", "saritch_zm", 0); + AddReward("Common", undefined, "RPG", "usrpg_zm", 0); + AddReward("Epic", undefined, "MP5", "mp5k_zm", 0); + AddReward("Rare", undefined, "MP5", "mp5k_zm", 0); + AddReward("Common", undefined, "MP5", "mp5k_zm", 0); + AddReward("Common", undefined, "M1911", "m1911_zm", 0); + AddReward("Common", undefined, "Olympia", "rottweil72_zm", 0); + AddReward("Legendary", undefined, "RPD", "rpd_zm", 0); + break; + + case "zm_nuked": + AddReward("Legendary", undefined, "Skullcrusher", "m16_gl_upgraded_zm", 0); + AddReward("Legendary", undefined, "SLDG HAMR", "hamr_upgraded_zm", 0); + AddReward("Epic", undefined, "M16", "m16_zm", 0); + AddReward("Rare", undefined, "KAP-40", "kard_zm", 0); + AddReward("Rare", undefined, "M1911", "m1911_zm", 0); + AddReward("Rare", undefined, "RPG", "usrpg_zm", 0); + AddReward("Common", undefined, "SMR", "saritch_zm", 0); + AddReward("Common", undefined, "RPG", "usrpg_zm", 0); + AddReward("Epic", undefined, "MP5", "mp5k_zm", 0); + AddReward("Rare", undefined, "MP5", "mp5k_zm", 0); + AddReward("Common", undefined, "MP5", "mp5k_zm", 0); + AddReward("Common", undefined, "M1911", "m1911_zm", 0); + AddReward("Common", undefined, "Olympia", "rottweil72_zm", 0); + AddReward("Legendary", undefined, "RPD", "rpd_zm", 0); + break; + + case "zm_highrise": + AddReward("Legendary", undefined, "Skullcrusher", "m16_gl_upgraded_zm", 0); + AddReward("Legendary", undefined, "SLDG HAMR", "hamr_upgraded_zm", 0); + AddReward("Epic", undefined, "M16", "m16_zm", 0); + AddReward("Rare", "zombie_carpenter", "Carpenter", "carpenter", 1); + AddReward("Rare", undefined, "KAP-40", "kard_zm", 0); + AddReward("Rare", undefined, "M1911", "m1911_zm", 0); + AddReward("Rare", undefined, "RPG", "usrpg_zm", 0); + AddReward("Common", "zombie_carpenter", "Carpenter", "carpenter", 1); + AddReward("Common", undefined, "SMR", "saritch_zm", 0); + AddReward("Common", undefined, "RPG", "usrpg_zm", 0); + AddReward("Epic", undefined, "MP5", "mp5k_zm", 0); + AddReward("Rare", undefined, "MP5", "mp5k_zm", 0); + AddReward("Common", undefined, "MP5", "mp5k_zm", 0); + AddReward("Common", undefined, "M1911", "m1911_zm", 0); + AddReward("Common", undefined, "Olympia", "rottweil72_zm", 0); + AddReward("Legendary", undefined, "RPD", "rpd_zm", 0); + break; + + case "zm_prison": + if(getdvarint("TrialsEnableWonderweapons") == 1) + AddReward("Legendary", undefined, "Blundergat", "blundergat_zm", 0); + AddReward("Rare", "zombie_carpenter", "Carpenter", "carpenter", 1); + AddReward("Rare", undefined, "M1911", "m1911_zm", 0); + AddReward("Rare", undefined, "RPG", "usrpg_zm", 0); + AddReward("Common", "zombie_carpenter", "Carpenter", "carpenter", 1); + AddReward("Common", undefined, "RPG", "usrpg_zm", 0); + AddReward("Epic", undefined, "MP5", "mp5k_zm", 0); + AddReward("Rare", undefined, "MP5", "mp5k_zm", 0); + AddReward("Common", undefined, "MP5", "mp5k_zm", 0); + AddReward("Common", undefined, "M1911", "m1911_zm", 0); + AddReward("Common", undefined, "Olympia", "rottweil72_zm", 0); + break; + + case "zm_buried": + if(getdvarint("TrialsEnableWonderweapons") == 1) + AddReward("Legendary", undefined, "Paralyzer", "slowgun_zm", 0); + AddReward("Legendary", "zombie_z_money_icon", "Bonus Points", "Bonus_Points", 1); + AddReward("Legendary", undefined, "Skullcrusher", "m16_gl_upgraded_zm", 0); + AddReward("Legendary", undefined, "SLDG HAMR", "hamr_upgraded_zm", 0); + AddReward("Epic", "zombie_z_money_icon", "Bonus Points", "Bonus_Points", 1); + AddReward("Epic", undefined, "M16", "m16_zm", 0); + AddReward("Rare", "zombie_carpenter", "Carpenter", "carpenter", 1); + AddReward("Rare", "zombie_z_money_icon", "Bonus Points", "Bonus_Points", 1); + AddReward("Rare", undefined, "KAP-40", "kard_zm", 0); + AddReward("Rare", undefined, "M1911", "m1911_zm", 0); + AddReward("Rare", undefined, "RPG", "usrpg_zm", 0); + AddReward("Common", "zombie_z_money_icon", "Bonus Points", "Lose_Points", 1); + AddReward("Common", "zombie_carpenter", "Carpenter", "carpenter", 1); + AddReward("Common", undefined, "SMR", "saritch_zm", 0); + AddReward("Common", undefined, "RPG", "usrpg_zm", 0); + AddReward("Epic", undefined, "MP5", "mp5k_zm", 0); + AddReward("Rare", undefined, "MP5", "mp5k_zm", 0); + AddReward("Common", undefined, "MP5", "mp5k_zm", 0); + AddReward("Common", undefined, "M1911", "m1911_zm", 0); + AddReward("Common", undefined, "Olympia", "rottweil72_zm", 0); + AddReward("Legendary", undefined, "RPD", "rpd_zm", 0); + break; + + case "zm_tomb": + AddReward("Legendary", undefined, "SLDG HAMR", "hamr_upgraded_zm", 0); + AddReward("Legendary", "zombie_z_money_icon", "Bonus Points", "Bonus_Points", 1); + AddReward("Legendary", undefined, "Agarthan Reaper", "scar_upgraded_zm", 0); + AddReward("Epic", "p6_zm_tm_blood_power_up", "Zombie Blood", "zombie_blood", 1); + AddReward("Epic", undefined, "STG44", "mp44_zm", 0); + AddReward("Epic", "zombie_z_money_icon", "Bonus Points", "Bonus_Points", 1); + AddReward("Epic", undefined, "Scar-H", "scar_zm", 0); + AddReward("Rare", "zombie_carpenter", "Carpenter", "carpenter", 1); + AddReward("Rare", "zombie_z_money_icon", "Bonus Points", "Bonus_Points", 1); + AddReward("Rare", undefined, "KAP-40", "kard_zm", 0); + AddReward("Rare", "p6_zm_tm_blood_power_up", "Zombie Blood", "zombie_blood", 1); + AddReward("Common", "zombie_z_money_icon", "Bonus Points", "Lose_Points", 1); + AddReward("Common", "zombie_carpenter", "Carpenter", "carpenter", 1); + AddReward("Common", "p6_zm_tm_blood_power_up", "Zombie Blood", "zombie_blood", 1); + AddReward("Common", undefined, "Mauser C96", "c96_zm", 0); + AddReward("Common", undefined, "Ballista", "ballista_zm", 0); + break; + } + } + // Everything that works on all Maps + if(getdvarint("TrialsEnableWonderweapons") == 1) { + AddReward("Legendary", undefined, "Ray Gun Mark 2", "raygun_mark2_zm", 0); + if(getdvarint("TrialsAllowFreePerk") == 1) + AddReward("Legendary", "zombie_pickup_perk_bottle", "Free Perk", "free_perk", 1); + if(getdvarint("TrialsEnablePapDrop") == 1) + AddReward("Legendary", "p6_anim_zm_buildable_pap", "Weapon Upgrade", "WeaponUpgrade", 1); + AddReward("Legendary", "t6_wpn_zmb_raygun_view", "Ray Gun", "ray_gun_zm", 0); + AddReward("Legendary", "zombie_z_money_icon", "Bonus Points", "Bonus_Points", 1); + AddReward("Legendary", "Zombie_Skull", "Insta Kill", "insta_kill", 1); + AddReward("Legendary", "zombie_ammocan", "Max Ammo", "full_ammo", 1); + AddReward("Legendary", undefined, "Lamentation", "galil_upgraded_zm", 0); + AddReward("Legendary", undefined, "Mnesia", "m14_upgraded_zm", 0); + AddReward("Epic", "Zombie_Skull", "Insta Kill", "insta_kill", 1); + AddReward("Epic", "zombie_x2_icon", "Double Points", "double_points", 1); + AddReward("Epic", undefined, "DSR-50", "dsr50_zm", 0); + AddReward("Epic", undefined, "Galil", "galil_zm", 0); + AddReward("Epic", undefined, "B23r", "beretta93r_zm", 0); + AddReward("Epic", undefined, "Mnesia", "m14_upgraded_zm", 0); + AddReward("Rare", "zombie_x2_icon", "Double Points", "double_points", 1); + AddReward("Rare", "zombie_bomb", "Nuke", "nuke", 1); + AddReward("Rare", undefined, "Remington", "870mcs_zm", 0); + AddReward("Common", "zombie_bomb", "Nuke", "nuke", 1); + AddReward("Common", undefined, "M14", "m14_zm", 0); + // Lights for Origins Player Podiums + if(level.script == "zm_tomb") { + flag_wait("initial_blackscreen_passed"); + playfx(level._effect[ "fx_tomb_chamber_glow_blue" ], PodiumOrigin[0] - (0,0,10), (0,90,0), (0,90,0)); + playfx(level._effect[ "fx_tomb_chamber_glow_yellow" ], PodiumOrigin[1] - (0,0,10), (0,0,0), (0,90,0)); + playfx(level._effect[ "fx_tomb_crafting_chamber_glow" ], PodiumOrigin[2] - (0,0,10)); + playfx(level._effect[ "fx_tomb_chamber_glow_red" ], PodiumOrigin[3] - (0,0,10)); + } +} + +on_connect() { + level endon("end_game"); + for ( ;; ) { + level waittill( "connected", player ); + player thread on_spawned(); + } +} + +on_spawned() { + level endon("end_game"); + self endon( "disconnect" ); + self.initial_spawn_c = 0; + for ( ;; ) { + self waittill( "spawned_player" ); + if(self.initial_spawn_c == 0) { + self.initial_spawn_c = 1; + self.board_repair = 0; + self.ReaperTrialsCurrentMagic = 0; + self init_trial_hud(); + } + } +} + +init_trial_hud() { + // HUD settings such as sizes, position and fallbacks + self.trials_height = 28; + self.trials_width = int(self.trials_height * 5); + self.trials_space = int(self.trials_height * .115); + self.trials_star = int(self.trials_space * 2.35); + self.trials_x = 5; + if(level.script == "zm_tomb") + self.trials_y = -180 - self.trials_height; + else + self.trials_y = -120 - self.trials_height; + self.trials_reward_color = (.8, 0, 0); + self.trials_reward_code = "none"; + self.trials_reward_color_code = "^1"; + self.trials_reward_level = "^1None"; + self.do_trial_progress = false; + self.trials_init = true; +} + +TriggerRewardHandler(player, Name, Powerup, Hint) { + level endon("end_game"); + self endon("Timeout"); + self endon("Grabbed"); + players = getplayers(); + while(1) { + self waittill("trigger", player); + if(player usebuttonpressed()) { + if(isdefined(self.sharedreward)) + self.sharedreward = undefined;// Trigger Again only Visible for that Specific Player + if(Powerup == 0){ + if(Name == "ray_gun_zm" && player has_weapon_or_upgrade("raygun_mark2_zm") || Name == "Mark2" && player has_weapon_or_upgrade("ray_gun_zm")) { + player playlocalsound( level.zmb_laugh_alias ); + self notify("Grabbed"); + } + if(player has_weapon_or_upgrade(Name)){ + player playlocalsound( level.zmb_laugh_alias ); + self notify("Grabbed"); + } + weapon_limit = get_player_weapon_limit( player ); + primaryweapons = player getweaponslistprimaries(); + if ( isDefined( primaryweapons ) && primaryweapons.size >= weapon_limit ) + player takeweapon(player getcurrentweapon()); + wait 0.1; + player giveweapon(Name); + player switchtoweapon(Name); + self notify("Grabbed"); + } + else { + wait 0.1; + if(Name == "free_perk") + free_perk = player maps/mp/zombies/_zm_perks::give_random_perk(); + else if(Name == "Bonus_Points") + player.score += randomintrange( 1, 50 ) * 100; + else if(Name == "Lose_Points") + player.score -= randomintrange( 1, 50 ) * 100; + else if(Name == "WeaponUpgrade") { + weapon = player get_upgrade_weapon( player getcurrentweapon(), 0 ); + if(IsDefined( weapon )) { + player takeweapon( player getcurrentweapon()); + player giveweapon( weapon, 0, player get_pack_a_punch_weapon_options( weapon ) ); + player givestartammo( weapon ); + player givemaxammo( weapon ); + player switchtoweapon( weapon ); + } + else + player playlocalsound( level.zmb_laugh_alias ); + } + else + specific_powerup_drop(Name, player.origin); + self notify("Grabbed"); + } + } + if(players.size != 1) { + if(player meleebuttonpressed()){ + if(!isdefined(self.sharedreward)) { + self.sharedreward = true; // To Disable the Setinvisible Loop + self playsound("zmb_powerup_grabbed"); + self setvisibletoall(); + self SetHintString("Press ^3&&1^7 To Take "+Hint); + } + } + } + } +} + +Random_Reward(TrialLevel) { + Choosen = []; + for(i = 0; i < level.Rewards_List.size;i++){ + if(isdefined(level.Rewards_List[i].Rank) && level.Rewards_List[i].Rank == TrialLevel){ + Choosen[Choosen.size] = i; + } + } + return Choosen[randomint(Choosen.size)]; +} + +RewardModelMain() { + self endon("Done"); + level endon("end_game"); + if(level.script == "zm_tomb") + playfxontag(level._effect[ "ice_glow" ], self, "tag_origin"); + else + playfxontag(level._effect["powerup_on_solo"], self, "tag_origin"); + 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 ); + wait randomfloat( waittime - 0.1 ); + } +} + +TrialsSystem(CalculatedOrigin,SelectedModel, Origin, Angles, ActivatiorModel, ActivatiorOrigim, ActivatorAngles) { + level endon("end_game"); + // Challenges Setup + Challenges = []; + Challenges[Challenges.size] = "K_Trial";// Regular Kills + Challenges[Challenges.size] = "HK_Trial";// Headshot Kills + Challenges[Challenges.size] = "MK_Trial";// Melee Kills + Challenges[Challenges.size] = "GO_Trial";// Kill Zombies With Grenades + Challenges[Challenges.size] = "C_Trial";// Kill Zombies While Crouched + Challenges[Challenges.size] = "NH_Trial";// No Hits + Challenges[Challenges.size] = "BRS_Trial";// Buy Stuff + Challenges[Challenges.size] = "NAIM_Trial";// No Aim + Challenges[Challenges.size] = "CR_Trial";// Close Range Kills + Challenges[Challenges.size] = "BR_Trial";// Big Range Kills + Challenges[Challenges.size] = "TD_Trial";// Take Damage + Challenges[Challenges.size] = "PK_Trial";// Prone Kills + Challenges[Challenges.size] = "SGK_Trial";// Shotgun Kills + Challenges[Challenges.size] = "SMGK_Trial";// SMG Kills + Challenges[Challenges.size] = "ASTK_Trial";// Assualt Kills + Challenges[Challenges.size] = "HSK_Trial";// Higher Spot Kills + Challenges[Challenges.size] = "JUMP_Trial";// Jump Kills + Challenges[Challenges.size] = "LEGK_Trial";// Leg Kills + Challenges[Challenges.size] = "ARMK_Trial";// Arm Kills + switch(level.script) { + case "zm_transit": + Challenges[Challenges.size] = "REPA_Trial";// Rebuild Barriers + if(getDvar( "ui_zm_mapstartlocation" ) != "farm") + Challenges[Challenges.size] = "LAVAK_Trial";// Lava Kills + if(getDvar( "ui_zm_mapstartlocation" ) == "town") { + Challenges[Challenges.size] = "KISZ_Trial";// Kill In Random Zone + Challenges[Challenges.size] = "SISZ_Trial";// Stay In Random Zone + Challenges[Challenges.size] = "NPAP_Trial";// Kill With no Pap Weapon + } + if(getDvar( "ui_zm_mapstartlocation" ) == "transit") + Challenges[Challenges.size] = "ESHK_Trial";// Shield Kills + break; + + case "zm_highrise": + Challenges[Challenges.size] = "SPPADK_Trial";// Springpad Kills + Challenges[Challenges.size] = "REPA_Trial";// Rebuild Barriers + Challenges[Challenges.size] = "KISZ_Trial";// Kill In Random Zone + Challenges[Challenges.size] = "SISZ_Trial";// Stay In Random Zone + Challenges[Challenges.size] = "NPAP_Trial";// Kill With no Pap Weapon + break; + + case "zm_prison": + Challenges[Challenges.size] = "ESHK_Trial";// Shield Kills + Challenges[Challenges.size] = "REPA_Trial";// Rebuild Barriers + Challenges[Challenges.size] = "KISZ_Trial";// Kill In Random Zone + Challenges[Challenges.size] = "SISZ_Trial";// Stay In Random Zone + Challenges[Challenges.size] = "NPAP_Trial";// Kill With no Pap Weapon + break; + + case "zm_buried": + Challenges[Challenges.size] = "SPPADK_Trial";// Springpad Kills + Challenges[Challenges.size] = "BASSK_Trial";// Subwoofer Kills + Challenges[Challenges.size] = "REPA_Trial";// Rebuild Barriers + Challenges[Challenges.size] = "KISZ_Trial";// Kill In Random Zone + Challenges[Challenges.size] = "SISZ_Trial";// Stay In Random Zone + Challenges[Challenges.size] = "NPAP_Trial";// Kill With no Pap Weapon + break; + + case "zm_tomb": + Challenges[Challenges.size] = "ESHK_Trial";// Shield Kills + Challenges[Challenges.size] = "KISZ_Trial";// Kill In Random Zone + Challenges[Challenges.size] = "SISZ_Trial";// Stay In Random Zone + Challenges[Challenges.size] = "NPAP_Trial";// Kill With no Pap Weapon + break; + } + + TrialPodium_Player1 = spawn( "script_model", Origin[0]); + TrialPodium_Player1.angles = Angles[0]; + TrialPodium_Player1 setmodel(SelectedModel); + TrialPodium_Player1 thread PodiumSetupTrigger(Origin[0] + CalculatedOrigin,0); + TrialPodium_Player1 thread PodiumSetupTrigger(Origin[0] + CalculatedOrigin,4); + + TrialPodium_Player2 = spawn( "script_model", Origin[1]); + TrialPodium_Player2.angles = Angles[1]; + TrialPodium_Player2 setmodel(SelectedModel); + TrialPodium_Player2 thread PodiumSetupTrigger(Origin[1] + CalculatedOrigin,1); + TrialPodium_Player2 thread PodiumSetupTrigger(Origin[1] + CalculatedOrigin,5); + + TrialPodium_Player3 = spawn( "script_model", Origin[2]); + TrialPodium_Player3.angles = Angles[2]; + TrialPodium_Player3 setmodel(SelectedModel); + TrialPodium_Player3 thread PodiumSetupTrigger(Origin[2] + CalculatedOrigin,2); + TrialPodium_Player3 thread PodiumSetupTrigger(Origin[2] + CalculatedOrigin,6); + + TrialPodium_Player4 = spawn( "script_model", Origin[3]); + TrialPodium_Player4.angles = Angles[3]; + TrialPodium_Player4 setmodel(SelectedModel); + TrialPodium_Player4 thread PodiumSetupTrigger(Origin[3] + CalculatedOrigin,3); + TrialPodium_Player4 thread PodiumSetupTrigger(Origin[3] + CalculatedOrigin,7); + + TrialMainModel = spawn( "script_model", ActivatiorOrigim); + TrialMainModel.angles = ActivatorAngles; + TrialMainModel setmodel(ActivatiorModel); + + if(level.script != "zm_prison" && level.script != "zm_tomb") + TrialMainModel thread MainModelAnimation(); + + TrialsMainTrigger = spawn("trigger_radius", ActivatiorOrigim, 1, 50, 50); + TrialsMainTrigger SetCursorHint( "HINT_NOICON" ); + // All Zones For Challenges + Zones = GetEntArray("player_volume", "script_noteworthy"); + // Zones check for Town + if (level.script == "zm_transit" && getDvar( "ui_zm_mapstartlocation" ) == "town" ){ + for(i = 0;i < Zones.size;i++){ + if(Zones[i].targetname == "zone_tow" || Zones[i].targetname == "zone_bar" || Zones[i].targetname == "zone_ban" || Zones[i].targetname == "zone_town_north" || Zones[i].targetname == "zone_town_west" || Zones[i].targetname == "zone_town_east" || Zones[i].targetname == "zone_town_barber" || Zones[i].targetname == "zone_town_south" ){ + if(!isdefined(ZonesForSurvival)) + ZonesForSurvival = []; + ZonesForSurvival[ZonesForSurvival.size] = Zones[i]; + } + } + } + TrialsCost = getDvarInt("TrialsCost"); + Challenges = array_randomize(Challenges); + Num = 0; + while(1){ + if(level.ReaperTrialsActive == 0) + TrialsMainTrigger SetHintString("Hold ^3&&1^7 to Activate Trial [Cost: " + TrialsCost + "]"); + else + TrialsMainTrigger SetHintString("Trial is already Running!"); + TrialsMainTrigger waittill("trigger", player); + if(level.ReaperTrialsActive == 0){ + if(player UseButtonPressed()){ + if(player.score < TrialsCost){ + player playsound("evt_perk_deny"); + wait 1; + } + else if(player.score >= TrialsCost){ + player minus_to_player_score(TrialsCost); + player playsound("zmb_cha_ching"); + if(Num >= Challenges.size) { + Challenges = cycle_randomize(Challenges); + Num = 0; + } + if(isdefined(ZonesForSurvival)) + level thread ChallengeHandler(ZonesForSurvival,Challenges[Num]); + else + level thread ChallengeHandler(Zones,Challenges[Num]); + foreach(player in level.players) + player playsound( "zmb_meteor_activate" ); + Num++; + level.ReaperTrialsActive++; + } + } + } + } +} + +cycle_randomize(indices) { + li = indices.size - 1; + last = indices[li]; + new_indices = array_randomize(indices); + + while (last == new_indices[0]) + new_indices = array_randomize(indices); + + return new_indices; +} + +MainModelAnimation(){// Teddy Floating + level endon("end_game"); + flag_wait( "start_zombie_round_logic" ); + if(level.script == "zm_nuked") { + for( f = 0; f < 4; f++ ) { + playfxontag( level._effect[ "fx_ash_embers_up_lg" ], self, "tag_origin" ); + wait randomfloatrange( 0.1, 0.72 ); + } + } + if(level.script == "zm_highrise") + playfx( level._effect[ "fx_highrise_dragon_tower_glow_ric" ], self.origin); + if(level.script == "zm_buried") + playfx( level._effect[ "sq_tower_bolts" ], self.origin, (0,0,180), (0,0,180)); + while(1) { + self moveto(self.origin + (0,0,20),randomfloatrange(0.5,4)); + self waittill("movedone"); + self moveto(self.origin + (0,0,-20),randomfloatrange(0.5,4)); + self waittill("movedone"); + } +} + +ChallengeHandler(Zones,Challenge){ + if(Challenge == "K_Trial") + ChallengeDescription = "Kill Zombies"; + else if(Challenge == "HK_Trial"){ + ChallengeDescription = "Kill Zombies\n^3Headshots"; + ChallengePoints = 2; + } + else if(Challenge == "MK_Trial"){ + ChallengeDescription = "Kill Zombies with Melee Attacks"; + ChallengePoints = 2; + } + else if(Challenge == "KISZ_Trial"){ + Num = randomintrange(0, Zones.size); + ChoosenZone = Zones[Num]; + ZoneName = get_zone_name(ChoosenZone.targetname); + if(!isdefined(ZoneName) || isdefined(ZoneName) && ZoneName == "") { + Num = randomintrange(0, Zones.size); + ChoosenZone = Zones[Num]; + ZoneName = get_zone_name(ChoosenZone.targetname); + } + ChallengeDescription = "Kill Zombies at Location\n^8"+ZoneName; + PositiveChallengeDescription = "Kill Zombies at Location\n^2"+ZoneName; + Time = 120; + } + else if(Challenge == "SISZ_Trial"){ + Num = randomintrange(0, Zones.size); + ChoosenZone = Zones[Num]; + ZoneName = get_zone_name(ChoosenZone.targetname); + if(!isdefined(ZoneName) || isdefined(ZoneName) && ZoneName == "") { + Num = randomintrange(0, Zones.size); + ChoosenZone = Zones[Num]; + ZoneName = get_zone_name(ChoosenZone.targetname); + } + ChallengeDescription = "Stay at Location\n^8"+ZoneName; + PositiveChallengeDescription = "Stay at Location\n^2"+ZoneName; + Time = 120; + } + else if(Challenge == "GO_Trial") + ChallengeDescription = "Kill Zombies with Grenades"; + else if(Challenge == "C_Trial") + ChallengeDescription = "Kill Zombies while Crouching"; + else if(Challenge == "TD_Trial"){ + ChallengeDescription = "Take Damage"; + ChallengePoints = 1.5; + } + else if(Challenge == "NH_Trial"){ + ChallengeDescription = "Take No Damage"; + ChallengePoints = 1.5; + } + else if(Challenge == "BRS_Trial"){ + ChallengeDescription = "Spend Points"; + Time = 120; + } + else if(Challenge == "NPAP_Trial") + ChallengeDescription = "Kill Zombies with a Non-Upgraded Weapon"; + else if(Challenge == "NAIM_Trial") + ChallengeDescription = "Kill Zombies without Aiming"; + else if(Challenge == "CR_Trial") + ChallengeDescription = "Kill Zombies in Close Range"; + else if(Challenge == "BR_Trial") + ChallengeDescription = "Kill Zombies in Long Range"; + else if(Challenge == "PK_Trial") + ChallengeDescription = "Kill Zombies while Prone"; + else if(Challenge == "SGK_Trial") + ChallengeDescription = "Kill Zombies with Shotguns"; + else if(Challenge == "SMGK_Trial") + ChallengeDescription = "Kill Zombies with SMGs"; + else if(Challenge == "ASTK_Trial") + ChallengeDescription = "Kill Zombies with Assault Rifles"; + else if(Challenge == "HSK_Trial") + ChallengeDescription = "Kill Zombies at a Higher Position"; + else if(Challenge == "JUMP_Trial") + ChallengeDescription = "Kill Zombies While in Air"; + else if(Challenge == "LEGK_Trial") + ChallengeDescription = "Kill Zombies\n^3Legshots"; + else if(Challenge == "ARMK_Trial") + ChallengeDescription = "Kill Zombies\n^3Armshots"; + else if(Challenge == "ESHK_Trial") + ChallengeDescription = "Kill Zombies with a Riotshield"; + else if(Challenge == "LAVAK_Trial") + ChallengeDescription = "Kill Zombies while Burning"; + else if(Challenge == "REPA_Trial") { + ChallengeDescription = "Repair Barricades"; + ChallengePoints = 0.5; + Time = 120; + } + else if(Challenge == "SPPADK_Trial") + ChallengeDescription = "Kill Zombies with a Tramplesteam"; + else if(Challenge == "BASSK_Trial") + ChallengeDescription = "Kill Zombies with a Subwoofer"; + + if(!isdefined(ChallengePoints))// Default + ChallengePoints = 1; + + if(!isdefined(time))// Default + time = 90; + + // Setup Challenge For Players + players = get_players(); + for(i = 0;i < players.size;i++){ + if(Challenge == "SISZ_Trial" || Challenge == "TD_Trial" || Challenge == "NH_Trial" || Challenge == "BRS_Trial" || Challenge == "REPA_Trial"){ + players[i] thread PlayerTrialHandlerTime(Challenge, ChallengePoints, ChoosenZone); + } + else { + if(Challenge == "SPPADK_Trial" || Challenge == "BASSK_Trial") + players[i] thread PlayerTrialHandlerBuildableKill(Challenge, ChallengePoints); + else + players[i] thread PlayerTrialHandlerKill(Challenge, ChallengePoints, ChoosenZone); + } + players[i] toggle_trial_challenge_hud(); + players[i] set_trial_challenge(ChallengeDescription); + players[i] set_trial_timer(time); + if(isdefined(ChoosenZone)) + players[i] thread set_trial_location(ChoosenZone, ChallengeDescription, PositiveChallengeDescription); + } + wait time + 1; + for(i = 0;i < players.size;i++){ + players[i] notify("TrialOver"); + players[i] toggle_trial_challenge_hud(); + } + level.ReaperTrialsActive = 0; +} + +set_trial_location(zone, out_text, in_text) { + self endon("TrialOver"); + self endon("disconnect"); + level endon("end_game"); + before = false; + + while (true) { + in_zone = self istouching(zone); + + if(before != in_zone) { + text = in_zone ? in_text : out_text; + self set_trial_challenge(text); + before = in_zone; + } + wait 1; + } +} +// All Buildable Based Challenges Come in here +PlayerTrialHandlerBuildableKill(Trial, Points) { + self endon("TrialOver"); + self endon("disconnect"); + level endon("end_game"); + while(1) { + TrialNotify = self waittill_any_return("zombie_flung", "zombie_subwoofer_kill"); + if(TrialNotify == "zombie_flung") { + if(Trial == "SPPADK_Trial") + self thread AddPlayerMagicPoints(Points); + } + else if(TrialNotify == "zombie_subwoofer_kill") { + if(Trial == "BASSK_Trial") + self thread AddPlayerMagicPoints(Points); + } + } +} + +// All Kill Based Challenges Come in here +PlayerTrialHandlerKill(trial, Points, SpecificZone){ + self endon("TrialOver"); + self endon("disconnect"); + level endon("end_game"); + while(1) { + self waittill( "zom_kill", zombie); + if(trial == "K_Trial") + self thread AddPlayerMagicPoints(Points); + else if(trial == "HK_Trial") { + if(zombie damagelocationisany( "head", "helmet", "neck")) + self thread AddPlayerMagicPoints(Points); + } + else if(trial == "MK_Trial") { + if(zombie.damagemod == "MOD_MELEE" || zombie.damagemod == "MOD_IMPACT") + self thread AddPlayerMagicPoints(Points); + } + else if(trial == "KISZ_Trial") { + if(self istouching(SpecificZone) && zombie istouching(SpecificZone)) + self thread AddPlayerMagicPoints(Points); + } + else if(trial == "GO_Trial") { + if(zombie.damagemod == "MOD_GRENADE" || zombie.damagemod == "MOD_GRENADE_SPLASH" || zombie.damagemod == "MOD_EXPLOSIVE" ) { + self thread AddPlayerMagicPoints(Points); + } + } + else if(trial == "C_Trial") { + if(self GetStance() == "crouch") + self thread AddPlayerMagicPoints(Points); + } + else if(trial == "NPAP_Trial") { + if(!self has_upgrade(self getcurrentweapon()) && zombie.damagemod == "MOD_RIFLE_BULLET" || !self has_upgrade(self getcurrentweapon()) && zombie.damagemod == "MOD_PISTOL_BULLET") + self thread AddPlayerMagicPoints(Points); + } + else if(trial == "NAIM_Trial") { + if(!isads(self)) + self thread AddPlayerMagicPoints(Points); + } + else if(trial == "CR_Trial") { + if(distancesquared(self.origin,zombie.origin) <= 20000) + self thread AddPlayerMagicPoints(Points); + } + else if(trial == "BR_Trial") { + if(distancesquared(self.origin,zombie.origin) >= 180000) + self thread AddPlayerMagicPoints(Points); + } + else if(trial == "PK_Trial") { + if(self GetStance() == "prone") + self thread AddPlayerMagicPoints(Points); + } + else if(trial == "SGK_Trial") { + if(weaponclass(self getcurrentweapon()) == "spread") + self thread AddPlayerMagicPoints(Points); + } + else if(trial == "SMGK_Trial") { + if(weaponclass(self getcurrentweapon()) == "smg") + self thread AddPlayerMagicPoints(Points); + } + else if(trial == "ASTK_Trial") { + if(weaponclass(self getcurrentweapon()) == "rifle") + self thread AddPlayerMagicPoints(Points); + } + else if(trial == "HSK_Trial") { + if(self.origin[2] >= (zombie.origin[2] + 30)) + self thread AddPlayerMagicPoints(Points); + } + else if(trial == "JUMP_Trial") { + if(!isdefined(self getgroundent())) + self thread AddPlayerMagicPoints(Points); + } + else if(trial == "LEGK_Trial") { + if(zombie damagelocationisany( "left_leg_upper", "left_leg_lower", "right_leg_upper", "right_leg_lower" )) + self thread AddPlayerMagicPoints(Points); + } + else if(trial == "ARMK_Trial") { + if(zombie damagelocationisany( "right_arm_upper", "left_arm_upper", "right_arm_lower", "left_arm_lower" )) + self thread AddPlayerMagicPoints(Points); + } + else if(trial == "ESHK_Trial") { + if(zombie.damagemod == "MOD_MELEE" && self getcurrentweapon() == level.riotshield_name || zombie.damagemod == "MOD_IMPACT" && self getcurrentweapon() == level.riotshield_name ) + self thread AddPlayerMagicPoints(Points); + } + else if(trial == "LAVAK_Trial") { + if(isdefined(self.is_burning) && self.is_burning == 1) + self thread AddPlayerMagicPoints(Points); + } + } +} + +// All Time Based Challenges Come in here +PlayerTrialHandlerTime(trial, Points, SpecificZone) { + self endon("TrialOver"); + self endon("disconnect"); + level endon("end_game"); + while(1){ + if(trial == "SISZ_Trial") { + if(isdefined(SpecificZone) && self istouching(SpecificZone)) { + self thread AddPlayerMagicPoints(Points); + } + } + else if(trial == "TD_Trial") { + if((self.health / self.maxhealth) <= 0.8) { + self thread AddPlayerMagicPoints(Points); + } + } + else if(trial == "NH_Trial") { + if(self.health == self.maxhealth) { + self thread AddPlayerMagicPoints(Points); + } + else { + wait 10; + } + } + else if(trial == "BRS_Trial") { + level waittill("spent_points", player, PointsSpent); + if(Player == self) { + if(PointsSpent >= 100) { + self thread AddPlayerMagicPoints(Points); + } + } + } + else if(trial == "REPA_Trial") { + if(self.board_repair > 0) { + self thread AddPlayerMagicPoints(Points); + self.board_repair = 0; + } + } + wait 2.5; + } +} + +PodiumSetupTrigger(CalculatedOrigin,Index){ + level endon("end_game"); + if(level.script == "zm_nuked") + trigger = Spawn( "trigger_radius", self.origin + (0, 0, 30), 0, 45, 45 ); + else + trigger = Spawn( "trigger_radius", self.origin + (0, 0, 30), 0, 30, 30 ); + trigger SetCursorHint( "HINT_NOICON" ); + trigger thread ShowToSpecific(CalculatedOrigin,Index); + while(1) { + players = GetPlayers(); + if(players[Index].ReaperTrialsCurrentMagic >= 25) + reward_level = "^2Common"; + if(players[Index].ReaperTrialsCurrentMagic >= 50) + reward_level = "^4Rare"; + if(players[Index].ReaperTrialsCurrentMagic >= 75) + reward_level = "^6Epic"; + if(players[Index].ReaperTrialsCurrentMagic == 100) + reward_level = "^3Legendary"; + if(players[Index].ReaperTrialsCurrentMagic >= 25) + trigger SetHintString("Press ^3&&1^7 To Claim " + reward_level + "^7 Reward"); + else + trigger SetHintString("Reward Level Too Low"); + trigger waittill( "trigger", player); + if(player == players[Index]){ + if(!player UseButtonPressed()){ + wait .1; + continue; + } + if(players[Index].ReaperTrialsCurrentMagic < 25){ + wait .1; + continue; + } + if(players[Index].ReaperTrialsCurrentMagic >= 25) + Reward = Random_Reward("Common"); + if(players[Index].ReaperTrialsCurrentMagic >= 50) + Reward = Random_Reward("Rare"); + if(players[Index].ReaperTrialsCurrentMagic >= 75) + Reward = Random_Reward("Epic"); + if(players[Index].ReaperTrialsCurrentMagic == 100) + Reward = Random_Reward("Legendary"); + players[Index].ReaperTrialsCurrentMagic = 0; + players[Index] toggle_trial_reward_hud(); + players[Index] set_trial_reward("none"); + trigger SetHintString("Generating Reward!"); + wait 1; + RewardModel = Spawn( "script_model", CalculatedOrigin + (0,0,28)); + RewardModel setmodel(level.Rewards_List[Reward].Model); + RewardModel thread RewardModelMain(); + if(players.size == 1)// To Disable the Sharing Hint in Solo Games + trigger SetHintString( "Press ^3&&1^7 To Take "+level.Rewards_List[Reward].Hint); + else + trigger SetHintString( "Press ^3&&1^7 To Take "+level.Rewards_List[Reward].Hint+"\nPress ^3[{+melee}]^7 To Share Reward"); + trigger thread TriggerRewardHandler(players[Index], level.Rewards_List[Reward].Name, level.Rewards_List[Reward].Powerup, level.Rewards_List[Reward].Hint); + trigger waittill_any_timeout(30, "Grabbed"); + trigger notify("Timeout"); + RewardModel notify("Done"); + RewardModel delete(); + } + } +} + +toggle_trial_challenge_hud() { + if (!isdefined(self.trials_init)) + return; + + sq_size = self.trials_height; + sq_wide = self.trials_width; + sq_dot = self.trials_space; + sq_star = self.trials_star; + x = self.trials_x; + y = self.trials_y; + + if (isdefined(self.trials_show_challenge) && self.trials_show_challenge) { + + // Wait for last trial progress animation before hide + while (self.do_trial_progress) + wait .1; + + self.trials_show_challenge = false; + self.trials_bg.alpha = 0; + self.trials_timer_bg.alpha = 0; + self.trials_timer_bar.alpha = 0; + self.trials_timer.alpha = 0; + self.trials_challenge destroy(); // This will glitch if a new challenge starts too fast + // self.trials_challenge.alpha = 0; + } + else { + self.trials_show_challenge = true; + + // Main background + if (!isdefined(self.trials_bg)) { + self.trials_bg = newclienthudelem(self); + self.trials_bg.horzalign = "user_left"; + self.trials_bg.alignx = "left"; + self.trials_bg.vertalign = "user_center"; + self.trials_bg.aligny = "middle"; + self.trials_bg.x = x + sq_dot + sq_size; + self.trials_bg.y = y; + self.trials_bg.sort = 1; + self.trials_bg.foreground = true; + self.trials_bg.hidewheninmenu = true; + self.trials_bg setshader("gradient", sq_wide, sq_size); + } + self.trials_bg.alpha = .6; + + // Timer background + if (!isdefined(self.trials_timer_bg)) { + self.trials_timer_bg = newclienthudelem(self); + self.trials_timer_bg.horzalign = "user_left"; + self.trials_timer_bg.alignx = "left"; + self.trials_timer_bg.vertalign = "user_center"; + self.trials_timer_bg.aligny = "middle"; + self.trials_timer_bg.x = x + sq_dot; + self.trials_timer_bg.y = y; + self.trials_timer_bg.sort = 2; + self.trials_timer_bg.foreground = true; + self.trials_timer_bg.hidewheninmenu = true; + self.trials_timer_bg setshader("black", sq_size, sq_size); + } + self.trials_timer_bg.alpha = .8; + + // Left timer bar + if (!isdefined(self.trials_timer_bar)) { + self.trials_timer_bar = newclienthudelem(self); + self.trials_timer_bar.horzalign = "user_left"; + self.trials_timer_bar.alignx = "left"; + self.trials_timer_bar.vertalign = "user_center"; + self.trials_timer_bar.aligny = "middle"; + self.trials_timer_bar.x = x; + self.trials_timer_bar.y = y; + self.trials_timer_bar.color = self.trials_reward_color; + self.trials_timer_bar.sort = 3; + self.trials_timer_bar.foreground = true; + self.trials_timer_bar.hidewheninmenu = true; + self.trials_timer_bar setshader("white", sq_dot, sq_size); + } + self.trials_timer_bar.alpha = 1; + + // Timer + if (!isdefined(self.trials_timer)) { + self.trials_timer = newclienthudelem(self); + self.trials_timer.horzalign = "user_left"; + self.trials_timer.alignx = "center"; + self.trials_timer.vertalign = "user_center"; + self.trials_timer.aligny = "middle"; + self.trials_timer.x = x + sq_dot + (sq_size / 2); + self.trials_timer.y = y; + self.trials_timer.color = self.trials_reward_color; + self.trials_timer.font = "small"; + self.trials_timer.sort = 3; + self.trials_timer.foreground = true; + self.trials_timer.hidewheninmenu = true; + } + self.trials_timer.alpha = 1; + + // Challenge text + if (!isdefined(self.trials_challenge)) { + self.trials_challenge = newclienthudelem(self); + self.trials_challenge.horzalign = "user_left"; + self.trials_challenge.alignx = "left"; + self.trials_challenge.vertalign = "user_center"; + self.trials_challenge.aligny = "middle"; + self.trials_challenge.x = x + (sq_dot * 3) + sq_size; + self.trials_challenge.y = y; + self.trials_challenge.real_y = self.trials_challenge.y; + self.trials_challenge.sort = 3; + self.trials_challenge.foreground = true; + self.trials_challenge.hidewheninmenu = true; + } + self.trials_challenge.alpha = 1; + } +} + +toggle_trial_reward_hud() { + if (!isdefined(self.trials_init)) + return; + + sq_size = self.trials_height; + sq_wide = self.trials_width; + sq_dot = self.trials_space; + sq_star = self.trials_star; + x = self.trials_x; + y = self.trials_y; + + if (isdefined(self.trials_show_reward) && self.trials_show_reward) { + + // Wait for last trial progress animation before hide + while (self.do_trial_progress) + wait .1; + + self.trials_show_reward = false; + self.trials_reward.alpha = 0; + self.trials_common.alpha = 0; + self.trials_rare.alpha = 0; + self.trials_epic.alpha = 0; + self.trials_legend.alpha = 0; + } + + else { + self.trials_show_reward = true; + + // Reward text + if (!isdefined(self.trials_reward)) { + self.trials_reward = newclienthudelem(self); + self.trials_reward.horzalign = "user_left"; + self.trials_reward.alignx = "left"; + self.trials_reward.vertalign = "user_center"; + self.trials_reward.aligny = "top"; + self.trials_reward.x = x + (sq_dot * 3) + sq_size; + self.trials_reward.y = y + (sq_size / 2) - 1; + self.trials_reward.font = "small"; + self.trials_reward.color = (.75, .75, .75); + self.trials_reward.sort = 3; + self.trials_reward.foreground = true; + self.trials_reward.hidewheninmenu = true; + self.trials_reward.label = &"Reward Available: "; + } + self.trials_reward.alpha = 1; + + // Common tier dot + if (!isdefined(self.trials_common)) { + self.trials_common = newclienthudelem(self); + self.trials_common.horzalign = "user_left"; + self.trials_common.alignx = "left"; + self.trials_common.vertalign = "user_center"; + self.trials_common.aligny = "top"; + self.trials_common.x = x - 1; + self.trials_common.y = y + (sq_size / 2) + sq_dot; + self.trials_common.color = (0, 0, 0); + self.trials_common.sort = 3; + self.trials_common.foreground = true; + self.trials_common.hidewheninmenu = true; + self.trials_common setshader("menu_mp_star_rating", sq_star, sq_star); + } + self.trials_common.alpha = .8; + + // Rare tier dot + if (!isdefined(self.trials_rare)) { + self.trials_rare = newclienthudelem(self); + self.trials_rare.horzalign = "user_left"; + self.trials_rare.alignx = "left"; + self.trials_rare.vertalign = "user_center"; + self.trials_rare.aligny = "top"; + self.trials_rare.x = x + sq_dot + (sq_dot * 2) - 1; + self.trials_rare.y = y + (sq_size / 2) + sq_dot; + self.trials_rare.color = (0, 0, 0); + self.trials_rare.sort = 3; + self.trials_rare.foreground = true; + self.trials_rare.hidewheninmenu = true; + self.trials_rare setshader("menu_mp_star_rating", sq_star, sq_star); + } + self.trials_rare.alpha = .8; + + // Epic tier dot + if (!isdefined(self.trials_epic)) { + self.trials_epic = newclienthudelem(self); + self.trials_epic.horzalign = "user_left"; + self.trials_epic.alignx = "left"; + self.trials_epic.vertalign = "user_center"; + self.trials_epic.aligny = "top"; + self.trials_epic.x = x + (sq_dot * 2) + (sq_dot * 4) - 1; + self.trials_epic.y = y + (sq_size / 2) + sq_dot; + self.trials_epic.color = (0, 0, 0); + self.trials_epic.sort = 3; + self.trials_epic.foreground = true; + self.trials_epic.hidewheninmenu = true; + self.trials_epic setshader("menu_mp_star_rating", sq_star, sq_star); + } + self.trials_epic.alpha = .8; + + // Legendary tier dot + if (!isdefined(self.trials_legend)) { + self.trials_legend = newclienthudelem(self); + self.trials_legend.horzalign = "user_left"; + self.trials_legend.alignx = "left"; + self.trials_legend.vertalign = "user_center"; + self.trials_legend.aligny = "top"; + self.trials_legend.x = x + (sq_dot * 3) + (sq_dot * 6) - 1; + self.trials_legend.y = y + (sq_size / 2) + sq_dot; + self.trials_legend.color = (0, 0, 0); + self.trials_legend.sort = 3; + self.trials_legend.foreground = true; + self.trials_legend.hidewheninmenu = true; + self.trials_legend setshader("menu_mp_star_rating", sq_star, sq_star); + } + self.trials_legend.alpha = .8; + } +} + +draw_reward_alert(text) { + if (!isdefined(self.trials_init)) + return; + + if (!isdefined(text)) + text = "REWARD UPGRADED"; + + width = int(self.trials_height * 6.25); + height = self.trials_height; + + // Reward upgrade background + if (!isdefined(self.trials_upgrade_shadow)) { + self.trials_upgrade_shadow = newclienthudelem(self); + self.trials_upgrade_shadow.horzalign = "user_center"; + self.trials_upgrade_shadow.alignx = "center"; + self.trials_upgrade_shadow.vertalign = "user_center"; + self.trials_upgrade_shadow.aligny = "middle"; + self.trials_upgrade_shadow.x = 0; + self.trials_upgrade_shadow.y = -160; + self.trials_upgrade_shadow.color = (0, 0, 0); + self.trials_upgrade_shadow.sort = 0; + self.trials_upgrade_shadow.foreground = true; + self.trials_upgrade_shadow.hidewheninmenu = true; + self.trials_upgrade_shadow setshader("scorebar_zom_1", width, height); + } + + // Reward upgrade background 2 + if (!isdefined(self.trials_upgrade_bg)) { + self.trials_upgrade_bg = newclienthudelem(self); + self.trials_upgrade_bg.horzalign = "user_center"; + self.trials_upgrade_bg.alignx = "center"; + self.trials_upgrade_bg.vertalign = "user_center"; + self.trials_upgrade_bg.aligny = "middle"; + self.trials_upgrade_bg.x = 0; + self.trials_upgrade_bg.y = -160; + self.trials_upgrade_bg.color = (1, 0, 0); + self.trials_upgrade_bg.sort = 1; + self.trials_upgrade_bg.foreground = true; + self.trials_upgrade_bg.hidewheninmenu = true; + self.trials_upgrade_bg setshader("scorebar_zom_1", width, height); + } + + // Reward upgrade text + if (!isdefined(self.trials_upgrade)) { + self.trials_upgrade = newclienthudelem(self); + self.trials_upgrade.horzalign = "user_center"; + self.trials_upgrade.alignx = "center"; + self.trials_upgrade.vertalign = "user_center"; + self.trials_upgrade.aligny = "middle"; + self.trials_upgrade.x = 0; + self.trials_upgrade.y = -160; + self.trials_upgrade.fontscale = 1.3; + self.trials_upgrade.sort = 2; + self.trials_upgrade.foreground = true; + self.trials_upgrade.hidewheninmenu = true; + } + self.trials_upgrade settext(text); + + // Animation + self playlocalsound("zmb_cha_ching"); + self.trials_upgrade_shadow.alpha = 0; + self.trials_upgrade_bg.alpha = 0; + self.trials_upgrade.alpha = 0; + self.trials_upgrade_shadow fadeovertime(.5); + self.trials_upgrade_shadow.alpha = 1; + self.trials_upgrade_bg fadeovertime(.5); + self.trials_upgrade_bg.alpha = 1; + self.trials_upgrade fadeovertime(.5); + self.trials_upgrade.alpha = 1; + wait 5; + self.trials_upgrade_shadow fadeovertime(.25); + self.trials_upgrade_shadow.alpha = 0; + self.trials_upgrade_bg fadeovertime(.25); + self.trials_upgrade_bg.alpha = 0; + self.trials_upgrade fadeovertime(.25); + self.trials_upgrade.alpha = 0; + wait .25; +} + +draw_trial_progress() { + if (!isdefined(self.trials_init)) + return; + + // Drop incoming animation call if the previous one is not completed + if (self.do_trial_progress) + return; + + // Drop incoming animation call when highest trial level (legendary) is reached + if (self.trials_reward_code == "legendary") + return; + + self.do_trial_progress = true; + sq_size = self.trials_height; + sq_wide = self.trials_width + sq_size; + sq_dot = self.trials_space; + sq_star = self.trials_star; + x = self.trials_x; + y = self.trials_y; + + // Top gradient line + if (!isdefined(self.trials_top_bar)) { + self.trials_top_bar = newclienthudelem(self); + self.trials_top_bar.horzalign = "user_left"; + self.trials_top_bar.vertalign = "user_center"; + self.trials_top_bar.aligny = "top"; + self.trials_top_bar.y = y - int(sq_size / 2); + self.trials_top_bar.color = self.trials_reward_color; + self.trials_top_bar.sort = 3; + self.trials_top_bar.foreground = true; + self.trials_top_bar.hidewheninmenu = true; + } + + // Bottom gradient line + if (!isdefined(self.trials_bottom_bar)) { + self.trials_bottom_bar = newclienthudelem(self); + self.trials_bottom_bar.horzalign = "user_left"; + self.trials_bottom_bar.vertalign = "user_center"; + self.trials_bottom_bar.aligny = "bottom"; + self.trials_bottom_bar.y = y + int(sq_size / 2); + self.trials_bottom_bar.color = self.trials_reward_color; + self.trials_bottom_bar.sort = 3; + self.trials_bottom_bar.foreground = true; + self.trials_bottom_bar.hidewheninmenu = true; + } + + // Animation + self playlocalsound("cac_cmn_beep"); + self.trials_top_bar setshader("gradient_fadein", 0, 1); + self.trials_bottom_bar setshader("gradient_fadein", 0, 1); + self.trials_top_bar.alignx = "left"; + self.trials_top_bar.x = x + sq_dot; + self.trials_bottom_bar.alignx = "left"; + self.trials_bottom_bar.x = x + sq_dot; + self.trials_top_bar.alpha = 1; + self.trials_bottom_bar.alpha = 1; + self.trials_top_bar scaleovertime(.25, sq_wide, 1); + self.trials_bottom_bar scaleovertime(.25, sq_wide, 1); + wait .5; + self.trials_top_bar.alignx = "right"; + self.trials_bottom_bar.alignx = "right"; + self.trials_top_bar.x = x + sq_dot + sq_wide; + self.trials_bottom_bar.x = x + sq_dot + sq_wide; + self.trials_top_bar scaleovertime(.25, 1, 1); + self.trials_bottom_bar scaleovertime(.25, 1, 1); + self.trials_top_bar fadeovertime(.25); + self.trials_bottom_bar fadeovertime(.25); + self.trials_top_bar.alpha = 0; + self.trials_bottom_bar.alpha = 0; + wait .25; + + self.do_trial_progress = false; +} + +set_trial_reward(tier) { + if (!isdefined(self.trials_init)) + return; + + if (isdefined(self.trials_reward_code) && self.trials_reward_code == tier) + return; + + switch(tier) { + case "none": + text = "^1None"; + color = array((.8, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0)); + alpha = array(0, 0, 0, 0); + break; + + case "common": + text = "^2Common"; + color = array((0, 1, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0)); + alpha = array(1, .8, .8, .8); + break; + + case "rare": + text = "^4Rare"; + color = array((0, .5, 1), (0, .5, 1), (0, 0, 0), (0, 0, 0)); + alpha = array(1, 1, .8, .8); + break; + + case "epic": + text = "^6Epic"; + color = array((0.345, 0, 0.576), (0.345, 0, 0.576), (0.345, 0, 0.576), (0, 0, 0)); + alpha = array(1, 1, 1, .8); + break; + + case "legendary": + text = "^3Legendary"; + color = array((1, 0.478, 0), (1, 0.478, 0), (1, 0.478, 0), (1, 0.478, 0)); + alpha = array(1, 1, 1, 1); + break; + + default: + return; + } + previous = self.trials_reward_code; + self.trials_reward_color = color[0]; + self.trials_reward_code = tier; + self.trials_reward_color_code = getsubstr(text, 0, 2); + self.trials_reward_level = text; + self.trials_reward settext(text); + self.trials_reward.alpha = alpha[0]; + self.trials_timer.color = color[0]; + self.trials_timer_bar.color = color[0]; + self.trials_top_bar.color = color[0]; + self.trials_bottom_bar.color = color[0]; + self.trials_common.color = color[0]; + self.trials_common.alpha = alpha[0]; + self.trials_rare.color = color[1]; + self.trials_rare.alpha = alpha[1]; + self.trials_epic.color = color[2]; + self.trials_epic.alpha = alpha[2]; + self.trials_legend.color = color[3]; + self.trials_legend.alpha = alpha[3]; + + // Trigger trial challenge text overwrite or reset + if (tier == "legendary" || previous == "legendary") + set_trial_challenge(self.trials_challenge_text); +} + +set_trial_challenge(text) { + if (!isdefined(self.trials_init) || !isdefined(text)) + return; + + self.trials_challenge_text = text; + + // Overwrite trial challenge text if highest trial level (legendary) is reached + if (self.trials_reward_code == "legendary") + text = self.trials_reward_color_code + "CLAIM REWARD"; + + line_shift = issubstr(text, "\n") ? 6 : 0; + self.trials_challenge.y = self.trials_challenge.real_y - line_shift; + self.trials_challenge settext(text); +} + +set_trial_timer(time) { + if (!isdefined(self.trials_init) || !isdefined(time)) + return; + + self.trials_timer settimer(time); +} + +AddPlayerMagicPoints(num){ + if(isdefined(self.revivetrigger)) { + return; + } + self.ReaperTrialsCurrentMagic += num; + self draw_trial_progress(); + if(self.ReaperTrialsCurrentMagic >= 100) + self.ReaperTrialsCurrentMagic = 100; + if(self.ReaperTrialsCurrentMagic >= 25){ + if(self.ReaperTrialsCurrentMagic >= 25 && self.ReaperTrialsCurrentMagic < 50){ + if(self.trials_reward_code != "common"){ + self toggle_trial_reward_hud(); + self set_trial_reward("common"); + self thread draw_reward_alert("REWARD AVAILABLE"); + } + } + if(self.ReaperTrialsCurrentMagic >= 50 && self.ReaperTrialsCurrentMagic < 75){ + if(self.trials_reward_code != "rare"){ + self set_trial_reward("rare"); + self thread draw_reward_alert(); + } + } + if(self.ReaperTrialsCurrentMagic >= 75 && self.ReaperTrialsCurrentMagic < 100){ + if(self.trials_reward_code != "epic"){ + self set_trial_reward("epic"); + self thread draw_reward_alert(); + } + } + if(self.ReaperTrialsCurrentMagic == 100){ + if(self.trials_reward_code != "legendary"){ + self set_trial_reward("legendary"); + self thread draw_reward_alert(); + } + } + } +} + +ShowToSpecific(FXOrigin,Index){ + level endon("game_ended"); + while(1){ + if(!isdefined(self.sharedreward)) { + self SetInvisibleToAll(); + self SetVisibleToPlayer( GetPlayers()[Index] ); + if(isdefined(GetPlayers()[Index])){ + if(isdefined(GetPlayers()[Index].ReaperTrialsCurrentMagic) && GetPlayers()[Index].ReaperTrialsCurrentMagic >= 25){ + if(level.script == "zm_transit") + playfx( level._effect[ "character_fire_death_sm" ], FXOrigin); + else if(level.script == "zm_prison") + playfx(level._effect[ "fx_alcatraz_elec_chair" ],FXOrigin - (17,0,15),anglesToForward(0,0,0), anglesToUp(0,0,0));// Too Lazy + else if(level.script == "zm_buried") + playfx( level._effect[ "character_fire_death_sm" ], FXOrigin); + else if(level.script == "zm_highrise") + playfx( level._effect[ "character_fire_death_sm" ], FXOrigin); + } + } + } + wait 5; + } +} + +EndGameListener() { + while(1) { + level waittill("intermission"); + foreach(player in level.players) { + player.trials_show_challenge = false; + player.trials_show_reward = false; + player.trials_bg destroy(); + player.trials_timer_bg destroy(); + player.trials_timer_bar destroy(); + player.trials_timer destroy(); + player.trials_challenge destroy(); + player.trials_reward destroy(); + player.trials_common destroy(); + player.trials_rare destroy(); + player.trials_epic destroy(); + player.trials_legend destroy(); + } + } +} + +AddReward(TrialRank, RewardModel, RewardHintname, RewardCodename, Powerup) { + if(!isdefined(level.Rewards_List)) + level.Rewards_List = []; + + Reward = SpawnStruct(); + Reward.Rank = TrialRank; + if(isdefined(RewardModel)) + Reward.Model = RewardModel; + else + Reward.Model = getweaponmodel(RewardCodename); + Reward.Hint = RewardHintname; + Reward.Name = RewardCodename; + Reward.Powerup = Powerup; + + level.Rewards_List[level.Rewards_List.size] = Reward; +} + +get_zone_name(key) { + // Caching and array lookup is way more efficient + if (isdefined(level.zone_names)) + return level.zone_names[key]; + + level.zone_names = []; + + switch(level.script) { + case "zm_transit": + level.zone_names["zone_pri"] = "Bus Depot"; + level.zone_names["zone_pri2"] = "Bus Depot Hallway"; + level.zone_names["zone_station_ext"] = "Outside Bus Depot"; + level.zone_names["zone_trans_2b"] = "Road After Bus Depot"; + level.zone_names["zone_trans_2"] = "Tunnel Entrance"; + level.zone_names["zone_amb_tunnel"] = "Tunnel"; + level.zone_names["zone_trans_3"] = "Tunnel Exit"; + level.zone_names["zone_roadside_west"] = "Outside Diner"; + level.zone_names["zone_gas"] = "Gas Station"; + level.zone_names["zone_roadside_east"] = "Outside Garage"; + level.zone_names["zone_trans_diner"] = "Road Outside Diner"; + level.zone_names["zone_trans_diner2"] = "Road Outside Garage"; + level.zone_names["zone_gar"] = "Garage"; + level.zone_names["zone_din"] = "Diner"; + level.zone_names["zone_diner_roof"] = "Diner Roof"; + level.zone_names["zone_trans_4"] = "Road After Diner"; + level.zone_names["zone_amb_forest"] = "Forest"; + level.zone_names["zone_trans_10"] = "Outside Church"; + level.zone_names["zone_town_church"] = "Upper South Town"; + level.zone_names["zone_trans_5"] = "Road Before Farm"; + level.zone_names["zone_far"] = "Outside Farm"; + level.zone_names["zone_far_ext"] = "Farm"; + level.zone_names["zone_brn"] = "Barn"; + level.zone_names["zone_farm_house"] = "Farmhouse"; + level.zone_names["zone_trans_6"] = "Road After Farm"; + level.zone_names["zone_amb_cornfield"] = "Cornfield"; + level.zone_names["zone_cornfield_prototype"] = "Nacht der Untoten"; + level.zone_names["zone_trans_7"] = "Upper Road Before Power"; + level.zone_names["zone_trans_pow_ext1"] = "Road Before Power"; + level.zone_names["zone_pow"] = "Outside Power Station"; + level.zone_names["zone_prr"] = "Power Station"; + level.zone_names["zone_pcr"] = "Power Control Room"; + level.zone_names["zone_pow_warehouse"] = "Warehouse"; + level.zone_names["zone_trans_8"] = "Road After Power"; + level.zone_names["zone_amb_power2town"] = "Cabin"; + level.zone_names["zone_trans_9"] = "Road Before Town"; + level.zone_names["zone_town_north"] = "North Town"; + level.zone_names["zone_tow"] = "Center Town"; + level.zone_names["zone_town_east"] = "East Town"; + level.zone_names["zone_town_west"] = "West Town"; + level.zone_names["zone_town_west2"] = "West Town 2"; + level.zone_names["zone_town_south"] = "South Town"; + level.zone_names["zone_bar"] = "Bar"; + level.zone_names["zone_town_barber"] = "Above Barbershop"; + level.zone_names["zone_ban"] = "Bank"; + level.zone_names["zone_ban_vault"] = "Bank Vault"; + level.zone_names["zone_tbu"] = "Laboratory"; + level.zone_names["zone_trans_11"] = "Road After Town"; + level.zone_names["zone_amb_bridge"] = "Bridge"; + level.zone_names["zone_trans_1"] = "Road Before Bus Depot"; + break; + + case "zm_nuked": + level.zone_names["culdesac_yellow_zone"] = "Yellow House Cul-de-sac"; + level.zone_names["culdesac_green_zone"] = "Green House Cul-de-sac"; + level.zone_names["truck_zone"] = "Truck"; + level.zone_names["openhouse1_f1_zone"] = "Green House Downstairs"; + level.zone_names["openhouse1_f2_zone"] = "Green House Upstairs"; + level.zone_names["openhouse1_backyard_zone"] = "Green House Backyard"; + level.zone_names["openhouse2_f1_zone"] = "Yellow House Downstairs"; + level.zone_names["openhouse2_f2_zone"] = "Yellow House Upstairs"; + level.zone_names["openhouse2_backyard_zone"] = "Yellow House Backyard"; + level.zone_names["ammo_door_zone"] = "Yellow House Backyard Door"; + break; + + case "zm_highrise": + level.zone_names["zone_green_start"] = "Green Highrise Level 3b"; + level.zone_names["zone_green_escape_pod"] = "Escape Pod"; + level.zone_names["zone_green_escape_pod_ground"] = "Escape Pod Shaft"; + level.zone_names["zone_green_level1"] = "Green Highrise Level 3a"; + level.zone_names["zone_green_level2a"] = "Green Highrise Level 2a"; + level.zone_names["zone_green_level2b"] = "Green Highrise Level 2b"; + level.zone_names["zone_green_level3a"] = "Green Highrise Restaurant"; + level.zone_names["zone_green_level3b"] = "Green Highrise Level 1a"; + level.zone_names["zone_green_level3c"] = "Green Highrise Level 1b"; + level.zone_names["zone_green_level3d"] = "Green Highrise Behind Restaurant"; + level.zone_names["zone_orange_level1"] = "Upper Orange Highrise Level 2"; + level.zone_names["zone_orange_level2"] = "Upper Orange Highrise Level 1"; + level.zone_names["zone_orange_elevator_shaft_top"] = "Elevator Shaft Level 3"; + level.zone_names["zone_orange_elevator_shaft_middle_1"] = "Elevator Shaft Level 2"; + level.zone_names["zone_orange_elevator_shaft_middle_2"] = "Elevator Shaft Level 1"; + level.zone_names["zone_orange_elevator_shaft_bottom"] = "Elevator Shaft Bottom"; + level.zone_names["zone_orange_level3a"] = "Lower Orange Highrise Level 1a"; + level.zone_names["zone_orange_level3b"] = "Lower Orange Highrise Level 1b"; + level.zone_names["zone_blue_level5"] = "Lower Blue Highrise Level 1"; + level.zone_names["zone_blue_level4a"] = "Lower Blue Highrise Level 2a"; + level.zone_names["zone_blue_level4b"] = "Lower Blue Highrise Level 2b"; + level.zone_names["zone_blue_level4c"] = "Lower Blue Highrise Level 2c"; + level.zone_names["zone_blue_level2a"] = "Upper Blue Highrise Level 1a"; + level.zone_names["zone_blue_level2b"] = "Upper Blue Highrise Level 1b"; + level.zone_names["zone_blue_level2c"] = "Upper Blue Highrise Level 1c"; + level.zone_names["zone_blue_level2d"] = "Upper Blue Highrise Level 1d"; + level.zone_names["zone_blue_level1a"] = "Upper Blue Highrise Level 2a"; + level.zone_names["zone_blue_level1b"] = "Upper Blue Highrise Level 2b"; + level.zone_names["zone_blue_level1c"] = "Upper Blue Highrise Level 2c"; + break; + + case "zm_prison": + level.zone_names["zone_start"] = "D-Block"; + level.zone_names["zone_library"] = "Library"; + level.zone_names["zone_cellblock_west"] = "Cellblock 2nd Floor"; + level.zone_names["zone_cellblock_west_gondola"] = "Cellblock 3rd Floor"; + level.zone_names["zone_cellblock_west_gondola_dock"] = "Cellblock Gondola"; + level.zone_names["zone_cellblock_west_barber"] = "Michigan Avenue"; + level.zone_names["zone_cellblock_east"] = "Times Square"; + level.zone_names["zone_cafeteria"] = "Cafeteria"; + level.zone_names["zone_cafeteria_end"] = "Cafeteria End"; + level.zone_names["zone_infirmary"] = "Infirmary 1"; + level.zone_names["zone_infirmary_roof"] = "Infirmary 2"; + level.zone_names["zone_roof_infirmary"] = "Roof 1"; + level.zone_names["zone_roof"] = "Roof 2"; + level.zone_names["zone_cellblock_west_warden"] = "Sally Port"; + level.zone_names["zone_warden_office"] = "Warden's Office"; + level.zone_names["cellblock_shower"] = "Showers"; + level.zone_names["zone_citadel_shower"] = "Citadel To Showers"; + level.zone_names["zone_citadel"] = "Citadel"; + level.zone_names["zone_citadel_warden"] = "Citadel To Warden's Office"; + level.zone_names["zone_citadel_stairs"] = "Citadel Tunnels"; + level.zone_names["zone_citadel_basement"] = "Citadel Basement"; + level.zone_names["zone_citadel_basement_building"] = "China Alley"; + level.zone_names["zone_studio"] = "Building 64"; + level.zone_names["zone_dock"] = "Docks"; + level.zone_names["zone_dock_puzzle"] = "Docks Gates"; + level.zone_names["zone_dock_gondola"] = "Upper Docks"; + level.zone_names["zone_golden_gate_bridge"] = "Golden Gate Bridge"; + level.zone_names["zone_gondola_ride"] = "Gondola"; + break; + + case "zm_buried": + level.zone_names["zone_start"] = "Processing"; + level.zone_names["zone_start_lower"] = "Lower Processing"; + level.zone_names["zone_tunnels_center"] = "Center Tunnels"; + level.zone_names["zone_tunnels_north"] = "Courthouse Tunnels 2"; + level.zone_names["zone_tunnels_north2"] = "Courthouse Tunnels 1"; + level.zone_names["zone_tunnels_south"] = "Saloon Tunnels 3"; + level.zone_names["zone_tunnels_south2"] = "Saloon Tunnels 2"; + level.zone_names["zone_tunnels_south3"] = "Saloon Tunnels 1"; + level.zone_names["zone_street_lightwest"] = "Outside General Store & Bank"; + level.zone_names["zone_street_lightwest_alley"] = "Outside General Store & Bank Alley"; + level.zone_names["zone_morgue_upstairs"] = "Morgue"; + level.zone_names["zone_underground_jail"] = "Jail Downstairs"; + level.zone_names["zone_underground_jail2"] = "Jail Upstairs"; + level.zone_names["zone_general_store"] = "General Store"; + level.zone_names["zone_stables"] = "Stables"; + level.zone_names["zone_street_darkwest"] = "Outside Gunsmith"; + level.zone_names["zone_street_darkwest_nook"] = "Outside Gunsmith Nook"; + level.zone_names["zone_gun_store"] = "Gunsmith"; + level.zone_names["zone_bank"] = "Bank"; + level.zone_names["zone_tunnel_gun2stables"] = "Stables To Gunsmith Tunnel 2"; + level.zone_names["zone_tunnel_gun2stables2"] = "Stables To Gunsmith Tunnel"; + level.zone_names["zone_street_darkeast"] = "Outside Saloon & Toy Store"; + level.zone_names["zone_street_darkeast_nook"] = "Outside Saloon & Toy Store Nook"; + level.zone_names["zone_underground_bar"] = "Saloon"; + level.zone_names["zone_tunnel_gun2saloon"] = "Saloon To Gunsmith Tunnel"; + level.zone_names["zone_toy_store"] = "Toy Store Downstairs"; + level.zone_names["zone_toy_store_floor2"] = "Toy Store Upstairs"; + level.zone_names["zone_toy_store_tunnel"] = "Toy Store Tunnel"; + level.zone_names["zone_candy_store"] = "Candy Store Downstairs"; + level.zone_names["zone_candy_store_floor2"] = "Candy Store Upstairs"; + level.zone_names["zone_street_lighteast"] = "Outside Courthouse & Candy Store"; + level.zone_names["zone_underground_courthouse"] = "Courthouse Downstairs"; + level.zone_names["zone_underground_courthouse2"] = "Courthouse Upstairs"; + level.zone_names["zone_street_fountain"] = "Fountain"; + level.zone_names["zone_church_graveyard"] = "Graveyard"; + level.zone_names["zone_church_main"] = "Church Downstairs"; + level.zone_names["zone_church_upstairs"] = "Church Upstairs"; + level.zone_names["zone_mansion_lawn"] = "Mansion Lawn"; + level.zone_names["zone_mansion"] = "Mansion"; + level.zone_names["zone_mansion_backyard"] = "Mansion Backyard"; + level.zone_names["zone_maze"] = "Maze"; + level.zone_names["zone_maze_staircase"] = "Maze Staircase"; + break; + + case "zm_tomb": + level.zone_names["zone_start"] = "Lower Laboratory"; + level.zone_names["zone_start_a"] = "Upper Laboratory"; + level.zone_names["zone_start_b"] = "Generator 1"; + level.zone_names["zone_bunker_1a"] = "Generator 3 Bunker 1"; + level.zone_names["zone_fire_stairs"] = "Fire Tunnel"; + level.zone_names["zone_fire_stairs_1"] = "zone_fire_stairs_1"; + level.zone_names["zone_bunker_1"] = "Generator 3 Bunker 2"; + level.zone_names["zone_bunker_3a"] = "Generator 3"; + level.zone_names["zone_bunker_3b"] = "Generator 3 Bunker 3"; + level.zone_names["zone_bunker_2a"] = "Generator 2 Bunker 1"; + level.zone_names["zone_bunker_2"] = "Generator 2 Bunker 2"; + level.zone_names["zone_bunker_4a"] = "Generator 2"; + level.zone_names["zone_bunker_4b"] = "Generator 2 Bunker 3"; + level.zone_names["zone_bunker_4c"] = "Tank Station"; + level.zone_names["zone_bunker_4d"] = "Above Tank Station"; + level.zone_names["zone_bunker_tank_c"] = "Generator 2 Tank Route 1"; + level.zone_names["zone_bunker_tank_c1"] = "Generator 2 Tank Route 2"; + level.zone_names["zone_bunker_4e"] = "Generator 2 Tank Route 3"; + level.zone_names["zone_bunker_tank_d"] = "Generator 2 Tank Route 4"; + level.zone_names["zone_bunker_tank_d1"] = "Generator 2 Tank Route 5"; + level.zone_names["zone_bunker_4f"] = "zone_bunker_4f"; + level.zone_names["zone_bunker_5a"] = "Workshop Downstairs"; + level.zone_names["zone_bunker_5b"] = "Workshop Upstairs"; + level.zone_names["zone_nml_2a"] = "No Man's Land Walkway"; + level.zone_names["zone_nml_2"] = "No Man's Land Entrance"; + level.zone_names["zone_bunker_tank_e"] = "Generator 5 Tank Route 1"; + level.zone_names["zone_bunker_tank_e1"] = "Generator 5 Tank Route 2"; + level.zone_names["zone_bunker_tank_e2"] = "zone_bunker_tank_e2"; + level.zone_names["zone_bunker_tank_f"] = "Generator 5 Tank Route 3"; + level.zone_names["zone_nml_1"] = "Generator 5 Tank Route 4"; + level.zone_names["zone_nml_4"] = "Generator 5 Tank Route 5"; + level.zone_names["zone_nml_0"] = "Generator 5 Left Footstep"; + level.zone_names["zone_nml_5"] = "Generator 5 Right Footstep Walkway"; + level.zone_names["zone_nml_farm"] = "Generator 5"; + level.zone_names["zone_nml_farm_1"] = "zone_nml_farm_1"; + level.zone_names["zone_nml_celllar"] = "Generator 5 Cellar"; + level.zone_names["zone_bolt_stairs"] = "Lightning Tunnel"; + level.zone_names["zone_bolt_stairs_1"] = "zone_bolt_stairs_1"; + level.zone_names["zone_nml_3"] = "No Man's Land 1st Right Footstep"; + level.zone_names["zone_nml_2b"] = "No Man's Land Stairs"; + level.zone_names["zone_nml_6"] = "No Man's Land Left Footstep"; + level.zone_names["zone_nml_8"] = "No Man's Land 2nd Right Footstep"; + level.zone_names["zone_nml_10a"] = "Generator 4 Tank Route 1"; + level.zone_names["zone_nml_10"] = "Generator 4 Tank Route 2"; + level.zone_names["zone_nml_7"] = "Generator 4 Tank Route 3"; + level.zone_names["zone_nml_7a"] = "zone_nml_7a"; + level.zone_names["zone_bunker_tank_a"] = "Generator 4 Tank Route 4"; + level.zone_names["zone_bunker_tank_a1"] = "Generator 4 Tank Route 5"; + level.zone_names["zone_bunker_tank_a2"] = "zone_bunker_tank_a2"; + level.zone_names["zone_bunker_tank_b"] = "Generator 4 Tank Route 6"; + level.zone_names["zone_nml_9"] = "Generator 4 Left Footstep"; + level.zone_names["zone_nml_9a"] = "zone_nml_9a"; + level.zone_names["zone_air_stairs"] = "Wind Tunnel"; + level.zone_names["zone_air_stairs_1"] = "zone_air_stairs_1"; + level.zone_names["zone_nml_11"] = "Generator 4"; + level.zone_names["zone_nml_11a"] = "zone_nml_11a"; + level.zone_names["zone_nml_12"] = "Generator 4 Right Footstep"; + level.zone_names["zone_nml_12a"] = "zone_nml_12a"; + level.zone_names["zone_nml_16"] = "Excavation Site Front Path"; + //level.zone_names["zone_nml_16a"] = "zone_nml_16a"; + level.zone_names["zone_nml_17"] = "Excavation Site Back Path"; + //level.zone_names["zone_nml_17a"] = "zone_nml_17a"; + level.zone_names["zone_nml_18"] = "Excavation Site Level 3"; + level.zone_names["zone_nml_19"] = "Excavation Site Level 2"; + level.zone_names["ug_bottom_zone"] = "Excavation Site Level 1"; + level.zone_names["zone_nml_13"] = "Generator 5 To Generator 6 Path"; + level.zone_names["zone_nml_14"] = "Generator 4 To Generator 6 Path"; + level.zone_names["zone_nml_15"] = "Generator 6 Entrance"; + //level.zone_names["zone_nml_15a"] = "zone_nml_15a"; + level.zone_names["zone_village_0"] = "Generator 6 Left Footstep"; + level.zone_names["zone_village_5"] = "Generator 6 Tank Route 1"; + level.zone_names["zone_village_5a"] = "Generator 6 Tank Route 2"; + level.zone_names["zone_village_5b"] = "Generator 6 Tank Route 3"; + level.zone_names["zone_village_1"] = "Generator 6 Tank Route 4"; + //level.zone_names["zone_village_1a"] = "zone_village_1a"; + level.zone_names["zone_village_4b"] = "Generator 6 Tank Route 5"; + level.zone_names["zone_village_4a"] = "Generator 6 Tank Route 6"; + level.zone_names["zone_village_4"] = "Generator 6 Tank Route 7"; + level.zone_names["zone_village_2"] = "Church"; + level.zone_names["zone_village_3"] = "Generator 6 Right Footstep"; + level.zone_names["zone_village_3a"] = "Generator 6"; + level.zone_names["zone_village_3b"] = "zone_village_3b"; + level.zone_names["zone_ice_stairs"] = "Ice Tunnel"; + //level.zone_names["zone_ice_stairs_1"] = "zone_ice_stairs_1"; + level.zone_names["zone_bunker_6"] = "Above Generator 3 Bunker"; + level.zone_names["zone_nml_20"] = "Above No Man's Land"; + level.zone_names["zone_village_6"] = "Behind Church"; + //level.zone_names["zone_village_6a"] = "zone_village_6a"; + level.zone_names["zone_chamber_0"] = "The Crazy Place Lightning Chamber"; + level.zone_names["zone_chamber_1"] = "The Crazy Place Lightning & Ice"; + level.zone_names["zone_chamber_2"] = "The Crazy Place Ice Chamber"; + level.zone_names["zone_chamber_3"] = "The Crazy Place Fire & Lightning"; + level.zone_names["zone_chamber_4"] = "The Crazy Place Center"; + level.zone_names["zone_chamber_5"] = "The Crazy Place Ice & Wind"; + level.zone_names["zone_chamber_6"] = "The Crazy Place Fire Chamber"; + level.zone_names["zone_chamber_7"] = "The Crazy Place Wind & Fire"; + level.zone_names["zone_chamber_8"] = "The Crazy Place Wind Chamber"; + level.zone_names["zone_robot_head"] = "Robot's Head"; + break; + } + return level.zone_names[key]; +} diff --git a/t6/scripts/zm/zm_transit/emp_no_perk_disable.gsc b/t6/scripts/zm/zm_transit/emp_no_perk_disable.gsc new file mode 100644 index 0000000..27bb17f --- /dev/null +++ b/t6/scripts/zm/zm_transit/emp_no_perk_disable.gsc @@ -0,0 +1,68 @@ +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\_demo; +#include maps\mp\zombies\_zm_ai_basic; +//always add includes of the replaced functions +main() +{ + replaceFunc( maps\mp\zombies\_zm_power::change_power_in_radius, ::emp_no_perk_disable); //replace base function by custom function +} + +emp_no_perk_disable( delta, origin, radius ) +{ + changed_list = []; + +if (level.script == "zm_transit") +{ + for ( i = 0; i < level.powered_items.size; i++ ) + { + powered = level.powered_items[i]; // this is in base code and is equivalent to a foreach item in level.powered_items + + if (isdefined(powered.target) && powered.target) // check if target exist + { + if (isdefined(powered.target.script_noteworthy) && powered.target.script_noteworthy) // check if target name exist + { + powered_name = strTok(powered.target.script_noteworthy, "_"); //separate the target name using "_" (since we want only to avoid disabled perks and their name is "specialty_XXX" + if ( powered.power_sources != 2 && powered_name[0] != "specialty") // in powered_named array, check if the first text element is different than "specialty" + { + if ( powered [[ powered.range_func ]]( delta, origin, radius ) ) + { + powered maps\mp\zombies\_zm_power::change_power( delta, origin, radius ); //if the replaced functions call other functions you must link the called function path + changed_list[changed_list.size] = powered; + } + } + } + /* else + { + iprintLn("^1Error^7, please contact ^1admin^7"); + }*/ + } + /* else + { + iprintLn("^1Error^7, please contact ^1admin^7"); + }*/ + } + return changed_list; +} +else +{ + for ( i = 0; i < level.powered_items.size; i++ ) + { + powered = level.powered_items[i]; + + if ( powered.power_sources != 2 ) + { + if ( powered [[ powered.range_func ]]( delta, origin, radius ) ) + { + powered maps\mp\zombies\_zm_power::change_power( delta, origin, radius ); + changed_list[changed_list.size] = powered; + } + } + } + + return changed_list; +} + +} \ No newline at end of file diff --git a/t6/scripts/zm/zm_transit/jetgun.gsc b/t6/scripts/zm/zm_transit/jetgun.gsc new file mode 100644 index 0000000..d3f3051 --- /dev/null +++ b/t6/scripts/zm/zm_transit/jetgun.gsc @@ -0,0 +1,31 @@ +init() +{ + level thread onPlayerConnect(); +} + + +onPlayerConnect() +{ + while( 1 ) + { + level waittill( "connected", player ); + player thread onPlayerSpawned(); + } +} + +onPlayerSpawned() +{ + level waittill("initial_blackscreen_passed"); + self thread jetgun_heat_watcher(); +} + +jetgun_heat_watcher() +{ + level endon("end_game"); + while ( true ) + { + if ( self getcurrentweapon() == "jetgun_zm" ) + self setweaponoverheating( self.jetgun_overheating, self.jetgun_heatval * 0.988); + wait 0.12; + } +} \ No newline at end of file diff --git a/t6/scripts/zm/zm_transit/no_locker.gsc b/t6/scripts/zm/zm_transit/no_locker.gsc new file mode 100644 index 0000000..f9b3297 --- /dev/null +++ b/t6/scripts/zm/zm_transit/no_locker.gsc @@ -0,0 +1,203 @@ +#include maps\mp\zombies\_zm_weapon_locker; +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_magicbox; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zombies\_zm_unitrigger; +#include maps\mp\zombies\_zm_audio; + +main() +{ + replacefunc(maps\mp\zombies\_zm_weapon_locker::triggerweaponslockerisvalidweaponpromptupdate, ::triggerweaponslockerisvalidweaponpromptupdate_custom); + replacefunc(maps\mp\zombies\_zm_weapon_locker::triggerweaponslockerwatch, ::triggerweaponslockerwatch_custom); +} + +triggerweaponslockerwatch_custom() +{ + unitrigger_stub = spawnstruct(); + unitrigger_stub.origin = self.origin; + + if ( isdefined( self.script_angles ) ) + unitrigger_stub.angles = self.script_angles; + else + unitrigger_stub.angles = self.angles; + + unitrigger_stub.script_angles = unitrigger_stub.angles; + + if ( isdefined( self.script_length ) ) + unitrigger_stub.script_length = self.script_length; + else + unitrigger_stub.script_length = 16; + + if ( isdefined( self.script_width ) ) + unitrigger_stub.script_width = self.script_width; + else + unitrigger_stub.script_width = 32; + + if ( isdefined( self.script_height ) ) + unitrigger_stub.script_height = self.script_height; + else + unitrigger_stub.script_height = 64; + + unitrigger_stub.origin -= anglestoright( unitrigger_stub.angles ) * unitrigger_stub.script_length / 2; + unitrigger_stub.targetname = "weapon_locker"; + unitrigger_stub.cursor_hint = "HINT_NOICON"; + unitrigger_stub.script_unitrigger_type = "unitrigger_box_use"; + unitrigger_stub.clientfieldname = "weapon_locker"; + maps\mp\zombies\_zm_unitrigger::unitrigger_force_per_player_triggers( unitrigger_stub, 1 ); + unitrigger_stub.prompt_and_visibility_func = ::triggerweaponslockerthinkupdateprompt; + maps\mp\zombies\_zm_unitrigger::register_static_unitrigger( unitrigger_stub, ::triggerweaponslockerthink_custom ); +} + +triggerweaponslockerthink_custom() +{ + self.parent_player thread triggerweaponslockerweaponchangethink( self ); + + while ( true ) + { + self waittill( "trigger", player ); + + retrievingweapon = player wl_has_stored_weapondata(); + + if ( !retrievingweapon ) + { + curweapon = player getcurrentweapon(); + curweapon = player maps\mp\zombies\_zm_weapons::switch_from_alt_weapon( curweapon ); + + if ( !triggerweaponslockerisvalidweapon( curweapon ) ) + continue; + + weapondata = player maps\mp\zombies\_zm_weapons::get_player_weapondata( player ); + player wl_set_stored_weapondata( weapondata ); + assert( curweapon == weapondata["name"], "weapon data does not match" ); + player takeweapon( curweapon ); + primaries = player getweaponslistprimaries(); + + if ( isdefined( primaries[0] ) ) + player switchtoweapon( primaries[0] ); + else + player maps\mp\zombies\_zm_weapons::give_fallback_weapon(); + + self triggerweaponslockerisvalidweaponpromptupdate( player, player getcurrentweapon() ); + player playsoundtoplayer( "evt_fridge_locker_close", player ); + player thread maps\mp\zombies\_zm_audio::create_and_play_dialog( "general", "weapon_storage" ); + } + else + { + if (isdefined(level.gamemode_difficulty) && level.gamemode_difficulty == "^6GigaChad^7") + { + wait 3; + continue; + } + + curweapon = player getcurrentweapon(); + primaries = player getweaponslistprimaries(); + weapondata = player wl_get_stored_weapondata(); + + if ( isdefined( level.remap_weapon_locker_weapons ) ) + weapondata = remap_weapon( weapondata, level.remap_weapon_locker_weapons ); + + weapontogive = weapondata["name"]; + + if ( !triggerweaponslockerisvalidweapon( weapontogive ) ) + { + player playlocalsound( level.zmb_laugh_alias ); + player wl_clear_stored_weapondata(); + self triggerweaponslockerisvalidweaponpromptupdate( player, player getcurrentweapon() ); + continue; + } + + curweap_base = maps\mp\zombies\_zm_weapons::get_base_weapon_name( curweapon, 1 ); + weap_base = maps\mp\zombies\_zm_weapons::get_base_weapon_name( weapontogive, 1 ); + + if ( player has_weapon_or_upgrade( weap_base ) && weap_base != curweap_base ) + { + self sethintstring( &"ZOMBIE_WEAPON_LOCKER_DENY" ); + wait 3; + self triggerweaponslockerisvalidweaponpromptupdate( player, player getcurrentweapon() ); + continue; + } + + maxweapons = get_player_weapon_limit( player ); + + if ( isdefined( primaries ) && primaries.size >= maxweapons || weapontogive == curweapon ) + { + curweapon = player maps\mp\zombies\_zm_weapons::switch_from_alt_weapon( curweapon ); + + if ( !triggerweaponslockerisvalidweapon( curweapon ) ) + { + self sethintstring( &"ZOMBIE_WEAPON_LOCKER_DENY" ); + wait 3; + self triggerweaponslockerisvalidweaponpromptupdate( player, player getcurrentweapon() ); + continue; + } + + curweapondata = player maps\mp\zombies\_zm_weapons::get_player_weapondata( player ); + player takeweapon( curweapondata["name"] ); + player maps\mp\zombies\_zm_weapons::weapondata_give( weapondata ); + player wl_clear_stored_weapondata(); + player wl_set_stored_weapondata( curweapondata ); + player switchtoweapon( weapondata["name"] ); + self triggerweaponslockerisvalidweaponpromptupdate( player, player getcurrentweapon() ); + } + else + { + player thread maps\mp\zombies\_zm_audio::create_and_play_dialog( "general", "wall_withdrawl" ); + player wl_clear_stored_weapondata(); + player maps\mp\zombies\_zm_weapons::weapondata_give( weapondata ); + player switchtoweapon( weapondata["name"] ); + self triggerweaponslockerisvalidweaponpromptupdate( player, player getcurrentweapon() ); + } + + level notify( "weapon_locker_grab" ); + player playsoundtoplayer( "evt_fridge_locker_open", player ); + } + + wait 0.5; + } +} + +triggerweaponslockerisvalidweaponpromptupdate_custom( player, weaponname ) +{ + retrievingweapon = player wl_has_stored_weapondata(); + + if ( !retrievingweapon ) + { + weaponname = player get_nonalternate_weapon( weaponname ); + + if ( !triggerweaponslockerisvalidweapon( weaponname ) ) + self sethintstring( &"ZOMBIE_WEAPON_LOCKER_DENY" ); + else + self sethintstring( &"ZOMBIE_WEAPON_LOCKER_STORE" ); + } + else + { + if (isdefined(level.gamemode_difficulty) && level.gamemode_difficulty == "^6GigaChad^7") + { + self sethintstring("A fridge. Used to store ^3food^7."); + return; + } + + weapondata = player wl_get_stored_weapondata(); + + if ( isdefined( level.remap_weapon_locker_weapons ) ) + weapondata = remap_weapon( weapondata, level.remap_weapon_locker_weapons ); + + weapontogive = weapondata["name"]; + primaries = player getweaponslistprimaries(); + maxweapons = get_player_weapon_limit( player ); + weaponname = player get_nonalternate_weapon( weaponname ); + + if ( isdefined( primaries ) && primaries.size >= maxweapons || weapontogive == weaponname ) + { + if ( !triggerweaponslockerisvalidweapon( weaponname ) ) + { + self sethintstring( &"ZOMBIE_WEAPON_LOCKER_DENY" ); + return; + } + } + self sethintstring( &"ZOMBIE_WEAPON_LOCKER_GRAB" ); + } +} \ No newline at end of file diff --git a/t6/scripts/zm/zm_transit/remove_limited_weapon_transit.gsc b/t6/scripts/zm/zm_transit/remove_limited_weapon_transit.gsc new file mode 100644 index 0000000..b5419cd --- /dev/null +++ b/t6/scripts/zm/zm_transit/remove_limited_weapon_transit.gsc @@ -0,0 +1,170 @@ +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\gametypes_zm\_zm_gametype; +#include maps\mp\zombies\_zm_unitrigger; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_game_module; +#include maps\mp\zm_transit_utility; +#include maps\mp\zombies\_zm_weapon_locker; +#include maps\mp\zm_transit_gamemodes; +#include maps\mp\zombies\_zm_banking; +#include maps\mp\zm_transit_ffotd; +#include maps\mp\zm_transit_bus; +#include maps\mp\zm_transit_automaton; +#include maps\mp\zombies\_zm_equip_turbine; +#include maps\mp\zm_transit_fx; +#include maps\mp\zombies\_zm; +#include maps\mp\animscripts\zm_death; +#include maps\mp\teams\_teamset_cdc; +#include maps\mp\_sticky_grenade; +#include maps\mp\zombies\_load; +#include maps\mp\zm_transit_ai_screecher; +#include maps\mp\gametypes_zm\_spawning; +#include maps\mp\zm_transit_lava; +#include maps\mp\zm_transit_power; +#include maps\mp\zombies\_zm_ai_basic; +#include maps\mp\zombies\_zm_weap_riotshield; +#include maps\mp\zombies\_zm_weap_jetgun; +#include maps\mp\zombies\_zm_weap_emp_bomb; +#include maps\mp\zombies\_zm_weap_cymbal_monkey; +#include maps\mp\zombies\_zm_weap_tazer_knuckles; +#include maps\mp\zombies\_zm_weap_bowie; +#include maps\mp\zombies\_zm_weap_claymore; +#include maps\mp\zombies\_zm_weap_ballistic_knife; +#include maps\mp\_visionset_mgr; +#include maps\mp\zm_transit_achievement; +#include maps\mp\zombies\_zm_zonemgr; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\zombies\_zm_spawner; +#include maps\mp\animscripts\zm_utility; +#include maps\mp\zm_transit_openings; +#include character\c_transit_player_farmgirl; +#include character\c_transit_player_oldman; +#include character\c_transit_player_engineer; +#include character\c_transit_player_reporter; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm_blockers; +#include maps\mp\zombies\_zm_power; +#include maps\mp\zombies\_zm_devgui; +#include maps\mp\zm_transit_cling; +#include maps\mp\zombies\_zm_buildables; +#include maps\mp\zm_transit_sq; +#include maps\mp\zm_transit_distance_tracking; +#include maps\mp\zombies\_zm_audio_announcer; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zombies\_zm_sidequests; +#include maps\mp\zombies\_zm_tombstone; + +main () +{ + replaceFunc(maps\mp\zm_transit::include_weapons, ::include_weapons_transit_custom); +} + + + +include_weapons_transit_custom() +{ + gametype = getdvar( "ui_gametype" ); + include_weapon( "knife_zm", 0 ); + include_weapon( "frag_grenade_zm", 0 ); + include_weapon( "claymore_zm", 0 ); + include_weapon( "sticky_grenade_zm", 0 ); + include_weapon( "m1911_zm", 0 ); + include_weapon( "m1911_upgraded_zm", 1 ); + include_weapon( "python_zm" ); + include_weapon( "python_upgraded_zm", 0 ); + include_weapon( "judge_zm" ); + include_weapon( "judge_upgraded_zm", 0 ); + include_weapon( "kard_zm" ); + include_weapon( "kard_upgraded_zm", 0 ); + include_weapon( "fiveseven_zm" ); + include_weapon( "fiveseven_upgraded_zm", 0 ); + include_weapon( "beretta93r_zm", 0 ); + include_weapon( "beretta93r_upgraded_zm", 0 ); + include_weapon( "fivesevendw_zm" ); + include_weapon( "fivesevendw_upgraded_zm", 0 ); + include_weapon( "ak74u_zm", 1 ); + include_weapon( "ak74u_upgraded_zm", 0 ); + include_weapon( "mp5k_zm", 0 ); + include_weapon( "mp5k_upgraded_zm", 0 ); + include_weapon( "qcw05_zm" ); + include_weapon( "qcw05_upgraded_zm", 0 ); + include_weapon( "870mcs_zm", 0 ); + include_weapon( "870mcs_upgraded_zm", 0 ); + include_weapon( "rottweil72_zm", 0 ); + include_weapon( "rottweil72_upgraded_zm", 0 ); + include_weapon( "saiga12_zm" ); + include_weapon( "saiga12_upgraded_zm", 0 ); + include_weapon( "srm1216_zm" ); + include_weapon( "srm1216_upgraded_zm", 0 ); + include_weapon( "m14_zm", 0 ); + include_weapon( "m14_upgraded_zm", 0 ); + include_weapon( "saritch_zm" ); + include_weapon( "saritch_upgraded_zm", 0 ); + include_weapon( "m16_zm", 1 ); + include_weapon( "m16_gl_upgraded_zm", 0 ); + include_weapon( "xm8_zm" ); + include_weapon( "xm8_upgraded_zm", 0 ); + include_weapon( "type95_zm" ); + include_weapon( "type95_upgraded_zm", 0 ); + include_weapon( "tar21_zm" ); + include_weapon( "tar21_upgraded_zm", 0 ); + include_weapon( "galil_zm" ); + include_weapon( "galil_upgraded_zm", 0 ); + include_weapon( "fnfal_zm" ); + include_weapon( "fnfal_upgraded_zm", 0 ); + include_weapon( "dsr50_zm" ); + include_weapon( "dsr50_upgraded_zm", 0 ); + include_weapon( "barretm82_zm" ); + include_weapon( "barretm82_upgraded_zm", 0 ); + include_weapon( "rpd_zm" ); + include_weapon( "rpd_upgraded_zm", 0 ); + include_weapon( "hamr_zm" ); + include_weapon( "hamr_upgraded_zm", 0 ); + include_weapon( "usrpg_zm" ); + include_weapon( "usrpg_upgraded_zm", 0 ); + include_weapon( "m32_zm" ); + include_weapon( "m32_upgraded_zm", 0 ); + include_weapon( "cymbal_monkey_zm" ); + include_weapon( "emp_grenade_zm", 1); + + if ( is_classic() ) + include_weapon( "screecher_arms_zm", 0 ); + + if ( gametype != "zgrief" ) + { + include_weapon( "ray_gun_zm" ); + include_weapon( "ray_gun_upgraded_zm", 0 ); + include_weapon( "jetgun_zm", 1); + include_weapon( "riotshield_zm", 1 ); + include_weapon( "tazer_knuckles_zm", 0 ); + include_weapon( "knife_ballistic_no_melee_zm", 0 ); + include_weapon( "knife_ballistic_no_melee_upgraded_zm", 0 ); + include_weapon( "knife_ballistic_zm" ); + include_weapon( "knife_ballistic_upgraded_zm", 0 ); + include_weapon( "knife_ballistic_bowie_zm", 0 ); + include_weapon( "knife_ballistic_bowie_upgraded_zm", 0 ); + level._uses_retrievable_ballisitic_knives = 1; + + if ( isdefined( level.raygun2_included ) && level.raygun2_included ) + { + include_weapon( "raygun_mark2_zm" ); + include_weapon( "raygun_mark2_upgraded_zm", 0 ); + add_weapon_to_content( "raygun_mark2_zm", "dlc3" ); + } + } + add_weapon_locker_mapping( "lsat_zm", "hamr_zm" ); + add_weapon_locker_mapping( "lsat_upgraded_zm", "hamr_upgraded_zm" ); + add_weapon_locker_mapping( "svu_zm", "fnfal_zm" ); + add_weapon_locker_mapping( "svu_upgraded_zm", "fnfal_upgraded_zm" ); + add_weapon_locker_mapping( "pdw57_zm", "qcw05_zm" ); + add_weapon_locker_mapping( "pdw57_upgraded_zm", "qcw05_upgraded_zm" ); + add_weapon_locker_mapping( "an94_zm", "galil_zm" ); + add_weapon_locker_mapping( "an94_upgraded_zm", "galil_upgraded_zm" ); + add_weapon_locker_mapping( "rnma_zm", "python_zm" ); + add_weapon_locker_mapping( "rnma_upgraded_zm", "python_upgraded_zm" ); +} + diff --git a/t6/scripts/zm/zm_transit/tranzitinthebus.gsc b/t6/scripts/zm/zm_transit/tranzitinthebus.gsc new file mode 100644 index 0000000..908d7a0 --- /dev/null +++ b/t6/scripts/zm/zm_transit/tranzitinthebus.gsc @@ -0,0 +1,2883 @@ +#include maps\mp\zombies\zm_transit_bus; +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zm_transit_bus; +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\zombies\_zm_weap_riotshield; +#include maps\mp\zombies\_zm_buildables; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_riotshield; +#include maps\mp\zombies\_zm_blockers; +#include maps\mp\zombies\_zm_ai_avogadro; +#include maps\mp\zm_transit_automaton; +#include maps\mp\zm_transit_utility; +#include maps\mp\gametypes_zm\_weaponobjects; +#include maps\mp\zm_transit_lava; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\zombies\_zm_laststand; + +#include maps\mp\zombies\_zm_ffotd; +#include maps\mp\zombies\_zm; +#include maps\mp\_visionset_mgr; +#include maps\mp\zombies\_zm_devgui; +#include maps\mp\zombies\_zm_zonemgr; +#include maps\mp\zombies\_zm_unitrigger; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_bot; +#include maps\mp\zombies\_zm_clone; +#include maps\mp\zombies\_zm_magicbox; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm_playerhealth; +#include maps\mp\zombies\_zm_power; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_spawner; +#include maps\mp\zombies\_zm_gump; +#include maps\mp\zombies\_zm_timer; +#include maps\mp\zombies\_zm_traps; +#include maps\mp\zombies\_zm_tombstone; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zombies\_zm_pers_upgrades; +#include maps\mp\gametypes_zm\_zm_gametype; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\_demo; +#include maps\mp\zombies\_zm_melee_weapon; +#include maps\mp\zombies\_zm_ai_dogs; +#include maps\mp\zombies\_zm_pers_upgrades_system; +#include maps\mp\gametypes_zm\_weapons; +#include maps\mp\zombies\_zm_ai_basic; +#include maps\mp\zombies\_zm_game_module; + +main() +{ + replacefunc(maps\mp\zm_transit_bus::busdoorssetup, ::busdoorssetupcustom); + replacefunc(maps\mp\zombies\_zm_riotshield::watchriotshielddeploy, ::watchriotshielddeploycustom); + replacefunc(maps\mp\zm_transit_automaton::automatondamagecallback, ::automatondamagecallback_custom); + replacefunc(maps\mp\zm_transit_automaton::shove_players_off_bus, ::shove_players_off_bus_custom); + + replacefunc(maps\mp\gametypes_zm\_globallogic_score::incpersstat, ::incpersstat_custom); + replacefunc(maps\mp\zombies\_zm_stats::add_client_stat, ::add_client_stat_custom); + replacefunc(maps\mp\zombies\_zm_stats::initializematchstats, ::initializematchstats_custom); + replacefunc(maps\mp\zombies\_zm_audio::zmbvoxgetlinevariant, ::zmbvoxgetlinevariant_custom); + replacefunc(maps\mp\gametypes_zm\_weaponobjects::createweaponobjectwatcher, ::createweaponobjectwatcher_custom); + replacefunc(maps\mp\gametypes_zm\_globallogic_score::initpersstat, ::initpersstat_custom); + replacefunc(maps\mp\zombies\_zm_powerups::powerup_hud_monitor, ::powerup_hud_monitor_custom); + replacefunc(maps\mp\gametypes_zm\_hostmigration::waittillhostmigrationdone, ::waittillhostmigrationdone_custom); + replacefunc(maps\mp\zm_transit_achievement::init, ::init_custom); + replacefunc(maps\mp\zombies\_zm::actor_damage_override, ::actor_damage_override_custom); +} + +actor_damage_override_custom( inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, shitloc, psoffsettime, boneindex ) +{ + if (isdefined(attacker.slayer_multiplier)) + { + damage *= (1 + float(attacker.kills / 300)); + } + if ( !isdefined( self ) || !isdefined( attacker ) ) + return damage; + + if ( weapon == "tazer_knuckles_zm" || weapon == "jetgun_zm" ) + self.knuckles_extinguish_flames = 1; + else if ( weapon != "none" ) + self.knuckles_extinguish_flames = undefined; + + if ( isdefined( attacker.animname ) && attacker.animname == "quad_zombie" ) + { + if ( isdefined( self.animname ) && self.animname == "quad_zombie" ) + return 0; + } + + if ( !isplayer( attacker ) && isdefined( self.non_attacker_func ) ) + { + if ( isdefined( self.non_attack_func_takes_attacker ) && self.non_attack_func_takes_attacker ) + return self [[ self.non_attacker_func ]]( damage, weapon, attacker ); + else + return self [[ self.non_attacker_func ]]( damage, weapon ); + } + + if ( !isplayer( attacker ) && !isplayer( self ) ) + return damage; + + if ( !isdefined( damage ) || !isdefined( meansofdeath ) ) + return damage; + + if ( meansofdeath == "" ) + return damage; + + old_damage = damage; + final_damage = damage; + + if ( isdefined( self.actor_damage_func ) ) + final_damage = [[ self.actor_damage_func ]]( inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, shitloc, psoffsettime, boneindex ); +/# + if ( getdvarint( _hash_5ABA6445 ) ) + println( "Perk/> Damage Factor: " + final_damage / old_damage + " - Pre Damage: " + old_damage + " - Post Damage: " + final_damage ); +#/ + if ( attacker.classname == "script_vehicle" && isdefined( attacker.owner ) ) + attacker = attacker.owner; + + if ( isdefined( self.in_water ) && self.in_water ) + { + if ( int( final_damage ) >= self.health ) + self.water_damage = 1; + } + + attacker thread maps\mp\gametypes_zm\_weapons::checkhit( weapon ); + + if ( attacker maps\mp\zombies\_zm_pers_upgrades_functions::pers_mulit_kill_headshot_active() && is_headshot( weapon, shitloc, meansofdeath ) ) + final_damage *= 2; + + if ( isdefined( level.headshots_only ) && level.headshots_only && isdefined( attacker ) && isplayer( attacker ) ) + { + if ( meansofdeath == "MOD_MELEE" && ( shitloc == "head" || shitloc == "helmet" ) ) + return int( final_damage ); + + if ( is_explosive_damage( meansofdeath ) ) + return int( final_damage ); + else if ( !is_headshot( weapon, shitloc, meansofdeath ) ) + return 0; + } + + return int( final_damage ); +} + +difficulty_watcher() +{ + level endon("disconnected"); + + for (;;) + { + if (level.game_started == 1) + { + if (level.gigachad_difficulty_vote_count >= level.chad_difficulty_vote_count && level.gigachad_difficulty_vote_count >= level.ez_difficulty_vote_count) + { + level.gamemode_difficulty = "^6GigaChad^7"; + level.difficulty_selected = 1; + level.boss_name = "^1Avogadro Suprimis^3"; + iprintln("Selected difficulty : ^6GigaChad^7."); + wait 5; + iprintln("^3[ " + level.boss_name + " ]^7 : ^1You are in for a hell of a ride"); + return; + + } + else if (level.chad_difficulty_vote_count >= level.ez_difficulty_vote_count) + { + level.gamemode_difficulty = "^1Chad^7"; + level.difficulty_selected = 1; + level.boss_name = "^1Avogadro Ultimis^3"; + iprintln("Selected difficulty : ^1Chad^7."); + wait 5; + iprintln("^3[ " + level.boss_name + " ]^7 : ^1My turn."); + return; + } + else + { + iprintln("Selected difficulty : ^2Ez^7."); + level.difficulty_selected = 1; + return; + } + break; + } + wait 0.1; + } +} + +difficulty_selector() +{ + self endon("disconnect"); + level endon("game_ended"); + + if (getdvar("net_port") != "30011") + return; + + selector = "left"; + shader = "zombies_rank_5"; + self.notifyiconb = self drawshader(shader, 70, 68, 140, 140, (1, 0, 0)); + self.notifyicon = self drawshader(shader, 70, 70, 128, 128, (0, 0, 0)); + self.notifyicon2b = self drawshader(shader, -70, 68, 140, 140, (1, 0, 0)); + self.notifyicon2 = self drawshader(shader, -70, 70, 128, 128, (0, 0, 0)); + self.notifyicon3b = self drawshader(shader, 0, 230, 140, 140, (1, 0, 0)); + self.notifyicon3 = self drawshader(shader, 0, 230, 128, 128, (0, 0, 0)); + shader = "zombies_rank_3"; + self.notifyiconA = self drawshader(shader, 0, -10, 231, 66, (0, 0, 1)); + self.notifyicon2a = self drawshader(shader, 0, -10, 210, 60, (0, 0, 0)); + + difficulty_left = "^2Ez^7"; + difficulty_right = "^1Chad^7"; + difficulty_down = "^6GigaChad^7"; + + self.zombieChoiceA = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 2 ); + self.zombieChoiceA maps\mp\gametypes_zm\_hud_util::setPoint( "CENTER", "TOP", 0, 10 ); + self.zombieChoiceA settext("^5Select the difficulty"); + self.zombieChoiceA.alpha = 0.8; + self.zombieChoiceA.foreground = 1; + + self.zombieChoiceAdesc = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1 ); + self.zombieChoiceAdesc maps\mp\gametypes_zm\_hud_util::setPoint( "CENTER", "TOP", 0, 30 ); + self.zombieChoiceAdesc settext("^3Melee^5 to switch, ^3Use^5 to confirm^7"); + self.zombieChoiceAdesc.alpha = 0.8; + self.zombieChoiceAdesc.foreground = 1; + + self.zombieChoiceLeft = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 2 ); + self.zombieChoiceLeft maps\mp\gametypes_zm\_hud_util::setPoint( "CENTER", "TOP", -70, 100 ); + self.zombieChoiceLeft settext("^3[^7" + difficulty_left + "^3]^7"); + self.zombieChoiceLeft.alpha = 0.8; + self.zombieChoiceLeft.foreground = 1; + + self.zombieChoiceLeftDesc = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1 ); + self.zombieChoiceLeftDesc maps\mp\gametypes_zm\_hud_util::setPoint( "CENTER", "TOP", 0, 40 ); + self.zombieChoiceLeftDesc settext("For a ^2chill^7 experience\n^3Reward multiplier^7 : ^5x1^7"); + self.zombieChoiceLeftDesc.alpha = 0.8; + self.zombieChoiceLeftDesc.foreground = 1; + self.zombieChoiceLeftDesc setparent( self.zombieChoiceLeft ); + + self.zombieChoiceRight = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 2 ); + self.zombieChoiceRight maps\mp\gametypes_zm\_hud_util::setPoint( "CENTER", "TOP", 70, 100 ); + self.zombieChoiceRight settext(difficulty_right); + self.zombieChoiceRight.alpha = 0.8; + self.zombieChoiceRight.foreground = 1; + + self.zombieChoiceRightDesc = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1 ); + self.zombieChoiceRightDesc maps\mp\gametypes_zm\_hud_util::setPoint( "CENTER", "TOP", 0, 40 ); + self.zombieChoiceRightDesc settext("You're gonna have a ^1bad^7 time\n ^3 Reward multiplier : ^5x2^7\n"); + self.zombieChoiceRightDesc.alpha = 0.8; + self.zombieChoiceRightDesc.foreground = 1; + self.zombieChoiceRightDesc setparent( self.zombieChoiceRight ); + + self.zombieChoiceDown = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 2 ); + self.zombieChoiceDown maps\mp\gametypes_zm\_hud_util::setPoint( "CENTER", "TOP", 0, 265 ); + self.zombieChoiceDown settext(difficulty_down); + self.zombieChoiceDown.alpha = 0.8; + self.zombieChoiceDown.foreground = 1; + + self.zombieChoiceDownDesc = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1); + self.zombieChoiceDownDesc maps\mp\gametypes_zm\_hud_util::setPoint( "CENTER", "TOP", 0, 36 ); + self.zombieChoiceDownDesc settext(" For the ^1craziest\n^3Reward multiplier : ^5x4^7\n"); + self.zombieChoiceDownDesc.alpha = 0.8; + self.zombieChoiceDownDesc.foreground = 1; + self.zombieChoiceDownDesc setparent( self.zombieChoiceDown ); + + has_selected = 0; + + if (IsSubStr(self.name , "^1VIP") || IsSubStr(self.name , "^1[VIP") || IsSubStr(self.name , "[^2VIP") || IsSubStr(self.name , "^2[VIP")) + { + self.has_gigapass = 1; + } + else + { + foreach (beta_guid in level.beta) + { + if (beta_guid == self getguid()) + { + self.has_gigapass = 1; + break; + } + } + } + + for (i = 0; i < 300; i++) + { + if (self meleeButtonPressed()) + { + if (selector == "left") + { + selector = "right"; + self.zombieChoiceRight settext("^3[^7" + difficulty_right + "^3]^7"); + self.zombieChoiceLeft settext(difficulty_left); + self.zombieChoiceDown settext(difficulty_down); + wait 0.2; + } + else if (selector == "right") + { + selector = "down"; + self.zombieChoiceDown settext("^3[^7" + difficulty_down + "^3]^7"); + self.zombieChoiceLeft settext(difficulty_left); + self.zombieChoiceRight settext(difficulty_right); + wait 0.2; + } + else if (selector == "down") + { + selector = "left"; + self.zombieChoiceLeft settext("^3[^7" + difficulty_left + "^3]^7"); + self.zombieChoiceRight settext(difficulty_right); + self.zombieChoiceDown settext(difficulty_down); + wait 0.2; + } + } + + if (self UseButtonPressed()) + { + if (selector == "down") + { + if (self getguid() == 3901565) + { + iprintln("^1The tyrant king^7 " + self.name + " ^7 dropped 420 VOTES"); + has_selected = 1; + break; + } + has_selected = 1; + break; + } + has_selected = 1; + break; + } + wait 0.05; + } + + for (i = 0; i < 20; i++) + { + playfx( level._effect["jetgun_vortex"], self.origin ); + } + self playsound( "zmb_screecher_portal_spawn" ); + + if (has_selected == 0) + { + selector = "left"; + } + self.zombieChoiceA.alpha = 0; + self.zombieChoiceAdesc.alpha = 0; + self.zombieChoiceLeft.alpha = 0; + self.zombieChoiceLeftDesc.alpha = 0; + self.zombieChoiceRight.alpha = 0; + self.zombieChoiceRightDesc.alpha = 0; + self.zombieChoiceDown.alpha = 0; + self.zombieChoiceDownDesc.alpha = 0; + self.notifyiconb.alpha = 0; + self.notifyicon.alpha = 0; + self.notifyicon2b.alpha = 0; + self.notifyicon2.alpha = 0; + self.notifyiconA.alpha = 0; + self.notifyicon2a.alpha = 0; + self.notifyicon3b.alpha = 0; + self.notifyicon3.alpha = 0; + + selected_difficulty = undefined; + if (level.players.size >= 8) + level.vote_required = level.players.size - 2; + else if (level.players.size >= 4) + level.vote_required = level.players.size - 1; + else + level.vote_required = level.players.size; + if (level.vote_required == 0) + level.vote_required = 1; + if (selector == "left") + { + level.ez_difficulty_vote_count++; + if (isdefined(self.has_gigapass)) + { + iprintln("Mister " + self.name + " ^7used his ^5GigaPass^7 to screw your votes :D"); + level.ez_difficulty_vote_count += 419; + } + iprintln(self.name + "^7 voted for " + difficulty_left + " difficulty." + " (^2 " + level.ez_difficulty_vote_count + "^3/^1" + level.vote_required + " ^7)"); + } + else if (selector == "right") + { + level.chad_difficulty_vote_count++; + + if (isdefined(self.has_gigapass)) + { + iprintln("Mister " + self.name + " ^7used his ^5GigaPass^7 to screw your votes :D"); + level.chad_difficulty_vote_count += 419; + } + iprintln(self.name + "^7 voted for " + difficulty_right + " difficulty." + " (^2 " + level.chad_difficulty_vote_count + "^3/^1" + level.vote_required + " ^7)"); + } + else + { + level.gigachad_difficulty_vote_count++; + + if (isdefined(self.has_gigapass)) + { + iprintln("Mister " + self.name + " ^7used his ^5GigaPass^7 to screw your votes :D"); + level.gigachad_difficulty_vote_count += 419; + + } + iprintln(self.name + "^7 voted for " + difficulty_down + " difficulty." + " (^2 " + level.gigachad_difficulty_vote_count + "^3/^1" + level.vote_required + " ^7)"); + } + level.votes++; + if (level.votes == level.players.size) + level.game_started = 1; + for (;;) + { + if (isdefined(level.difficulty_selected) && level.difficulty_selected == 1) + break; + wait 0.5; + } + wait 2; + + self thread blessingSelector(); +} + +init_custom() +{ + return; +} + +waittillhostmigrationdone_custom() +{ + if (getdvar("net_port") == "30011") + return; + if ( !isdefined( level.hostmigrationtimer ) ) + return 0; + + starttime = gettime(); + + level waittill( "host_migration_end" ); + + return gettime() - starttime; +} + + +lava_damage_think_custom() +{ + // flag_wait("initial_blackscreen_passed" ); + if (getdvar("net_port") == "30011") + return; + self._trap_type = ""; + + if ( isdefined( self.script_noteworthy ) ) + self._trap_type = self.script_noteworthy; + + if ( isdefined( self.target ) ) + { + self.volume = getent( self.target, "targetname" ); + assert( isdefined( self.volume ), "No volume found for lava target " + self.target ); + } + + while ( true ) + { + self waittill( "trigger", ent ); + + if ( isdefined( ent.ignore_lava_damage ) && ent.ignore_lava_damage ) + continue; + + if ( isdefined( ent.is_burning ) ) + continue; + + if ( isdefined( self.target ) && !ent istouching( self.volume ) ) + continue; + + if ( isplayer( ent ) ) + { + switch ( self._trap_type ) + { + case "fire": + default: + if ( !isdefined( self.script_float ) || self.script_float >= 0.1 ) + ent thread player_lava_damage( self ); + + break; + } + } + else if ( !isdefined( ent.marked_for_death ) ) + { + switch ( self._trap_type ) + { + case "fire": + default: + if ( !isdefined( self.script_float ) || self.script_float >= 0.1 ) + ent thread zombie_lava_damage( self ); + + break; + } + } + } +} + +powerup_hud_monitor_custom() +{ + // flag_wait("initial_blackscreen_passed" ); + if (getdvar("net_port") == "30011") + return; + 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 ); + + for ( powerup_key_index = 0; powerup_key_index < powerup_keys.size; powerup_key_index++ ) + { + 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; + } + } + + client_field_keys = getarraykeys( client_fields ); + + while ( true ) + { + wait 0.05; + waittillframeend; + + for ( playerindex = 0; playerindex < level.players.size; playerindex++ ) + { + for ( client_field_key_index = 0; client_field_key_index < client_field_keys.size; client_field_key_index++ ) + { + player = level.players[playerindex]; +/# + if ( isdefined( player.pers["isBot"] ) && player.pers["isBot"] ) + continue; +#/ + if ( isdefined( level.powerup_player_valid ) ) + { + if ( ![[ level.powerup_player_valid ]]( player ) ) + continue; + } + + client_field_name = client_fields[client_field_keys[client_field_key_index]].client_field_name; + time_name = client_fields[client_field_keys[client_field_key_index]].time_name; + on_name = client_fields[client_field_keys[client_field_key_index]].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 ); + continue; + } + + player setclientfieldtoplayer( client_field_name, 0 ); + } + } + } +} + +initpersstat_custom( dataname, record_stats, init_to_stat_value ) +{ + // flag_wait("initial_blackscreen_passed" ); + if (getdvar("net_port") == "30011") + return; + if ( !isdefined( self.pers[dataname] ) ) + self.pers[dataname] = 0; + + if ( !isdefined( record_stats ) || record_stats == 1 ) + recordplayerstats( self, dataname, int( self.pers[dataname] ) ); + + if ( isdefined( init_to_stat_value ) && init_to_stat_value == 1 ) + self.pers[dataname] = self getdstat( "PlayerStatsList", dataname, "StatValue" ); +} + +decrease_bus_oxygen() +{ + level endon( "game_ended" ); + + flag_wait("initial_blackscreen_passed"); + for (;;) + { + level.oxygen_level--; + if (level.gamemode_difficulty == "^6GigaChad^7") + wait 24; + else + wait 19; + } +} + +oxygen_level() +{ + level endon( "game_ended" ); + self endon("disconnect"); + + //wait 60; + self.zombieTextO = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1.5 ); + self.zombieTextO maps\mp\gametypes_zm\_hud_util::setPoint( "TOP", "RIGHT", -10, -215 ); + self.zombieTextO.label = &"Bus ^5Oxygen^7 Level : ^2"; + self.zombieTextO setvalue(level.oxygen_level); + self.zombieTextO.alpha = 0.8; + for (;;) + { + if (level.round_number >= 35 && level.gamemode_difficulty == "^6GigaChad^7") + { + self.zombieTextO destroy(); + return; + } + if (level.round_number >= 35 && level.gamemode_difficulty == "^1Chad^7") + { + self.zombieTextO destroy(); + return; + } + if (level.round_number >= 25 && level.gamemode_difficulty == "^2Ez^7") + { + self.zombieTextO destroy(); + return; + } + if (level.oxygen_level <= 0) + { + self.zombieTextO setvalue(0); + break; + } + self.zombieTextO setvalue(level.oxygen_level); + if (level.oxygen_level < 75) + self.zombieTextO.label = &"^5Bus Oxygen Level : ^5"; + if (level.oxygen_level < 50) + self.zombieTextO.label = &"^5Bus Oxygen Level : ^3"; + if (level.oxygen_level < 25) + self.zombieTextO.label = &"^5Bus Oxygen Level : ^1"; + wait 5; + } + self iprintln("^1The Bus ran out of oxygen !"); + wait 2; + self iprintln("^1The Bus ran out of oxygen !"); + for (;;) + { + self dodamage(5, self.origin); + wait 0.5; + } +} + +createweaponobjectwatcher_custom( name, weapon, ownerteam ) +{ + if (weapon != "equip_turbine_zm") + return; + + if ( !isdefined( self.weaponobjectwatcherarray ) ) + self.weaponobjectwatcherarray = []; + + weaponobjectwatcher = getweaponobjectwatcher( name ); + + if ( !isdefined( weaponobjectwatcher ) ) + { + weaponobjectwatcher = spawnstruct(); + self.weaponobjectwatcherarray[self.weaponobjectwatcherarray.size] = weaponobjectwatcher; + weaponobjectwatcher.name = name; + weaponobjectwatcher.type = "use"; + weaponobjectwatcher.weapon = weapon; + weaponobjectwatcher.weaponidx = getweaponindexfromname( weapon ); + weaponobjectwatcher.watchforfire = 0; + weaponobjectwatcher.hackable = 0; + weaponobjectwatcher.altdetonate = 0; + weaponobjectwatcher.detectable = 1; + weaponobjectwatcher.headicon = 1; + weaponobjectwatcher.stuntime = 0; + weaponobjectwatcher.activatesound = undefined; + weaponobjectwatcher.ignoredirection = undefined; + weaponobjectwatcher.immediatedetonation = undefined; + weaponobjectwatcher.deploysound = getweaponfiresound( weaponobjectwatcher.weaponidx ); + weaponobjectwatcher.deploysoundplayer = getweaponfiresoundplayer( weaponobjectwatcher.weaponidx ); + weaponobjectwatcher.pickupsound = getweaponpickupsound( weaponobjectwatcher.weaponidx ); + weaponobjectwatcher.pickupsoundplayer = getweaponpickupsoundplayer( weaponobjectwatcher.weaponidx ); + weaponobjectwatcher.altweapon = undefined; + weaponobjectwatcher.ownergetsassist = 0; + weaponobjectwatcher.playdestroyeddialog = 1; + weaponobjectwatcher.deleteonkillbrush = 1; + weaponobjectwatcher.deleteondifferentobjectspawn = 1; + weaponobjectwatcher.enemydestroy = 0; + weaponobjectwatcher.onspawn = undefined; + weaponobjectwatcher.onspawnfx = undefined; + weaponobjectwatcher.onspawnretrievetriggers = undefined; + weaponobjectwatcher.ondetonated = undefined; + weaponobjectwatcher.detonate = undefined; + weaponobjectwatcher.stun = undefined; + weaponobjectwatcher.ondestroyed = undefined; + + if ( !isdefined( weaponobjectwatcher.objectarray ) ) + weaponobjectwatcher.objectarray = []; + } + resetweaponobjectwatcher( weaponobjectwatcher, ownerteam ); + return weaponobjectwatcher; +} + + + +init() +{ + setDvar("EE_Completion", ""); + setDvar("isBus", ""); + setdvar("king_lock", "0"); + setDvar("gamemode_speedrun_quest_titb", "0"); + + level.blessing_count = 8; + level.net_port_titb = []; + level.net_port_titb[level.net_port_titb.size] = "30011"; + level.zombie_ai_limit = 32; + level.zombie_actor_limit = 40; + level.extra_speed = 0; + level.primaryprogressbarwidth = 400; + level.primaryprogressbarheight = 15; + level.primaryprogressbarfontsize = 1; + level.oxygen_level = 100; + level.boss_name = "^1Avogadro Primis^3"; + level.game_started = 0; + level.difficulty_selected = 0; + level.ez_difficulty_vote_count = 0; + level.chad_difficulty_vote_count = 0; + level.gigachad_difficulty_vote_count = 0; + level.gamemode_difficulty = "^2Ez^7"; + level.vote_required = 8; + level thread on_player_connect(); + level thread super_zombie(); + level thread bus_kick_faster(); + level thread bus_wait_at_start(); + level thread story(); + level thread rewardWatcher(); + level thread LoopEESong(); + level thread outofzoneplayerwatcher(); + level thread setZmCount(); + level thread player_manager(); + level thread decrease_bus_oxygen(); + level thread difficulty_watcher(); + level thread weapon_watcher(); + level thread init_bolts(); + level thread team_buff(); + level thread wait_for_difficulty(); + level thread door_text(); + level thread invisible_wall(); + + flag_wait("initial_blackscreen_passed"); + level.start_time = GetTime(); +} + +invisible_wall() +{ + if (getdvar("net_port") != "30011") + return; + level thread generateInvisibleBoxCollision((13543.8, -962.988, -187.96), (0, -90, 0)); + level thread generateInvisibleBoxCollision((13543.8, -290.138, -187.875), (0, -90, 0)); +} + +door_text() +{ + flag_wait("initial_blackscreen_passed" ); + level endon("game_ended"); + + if (getdvar("net_port") != "30011") + return; + + doorstrigger = getentarray( "bus_door_trigger", "targetname" ); + + for (;;) + { + for ( i = 0; i < doorstrigger.size; i++ ) + { + doorstrigger[i] sethintstring( "The door is ^1jammed^7. Find ^3another way" ); + } + wait 0.1; + } +} + +wait_for_difficulty() +{ + level endon ("game_ended"); + + flag_wait("initial_blackscreen_passed" ); + + for (;;) + { + if (level.difficulty_selected == 1) + { + level thread delayrnd(); + return; + } + + wait 1; + } +} + +super_zombie() +{ + level endon("end_game"); + + flag_wait("initial_blackscreen_passed" ); + + if (getdvar("net_port") != "30011") + return; + for (;;) + { + if (level.difficulty_selected == 1) + { + wait 20; + break; + } + wait 0.1; + } + for (;;) + { + if (level.gamemode_difficulty == "^6GigaChad^7") + { + zombies = getAiArray(level.zombie_team); + foreach(zombie in zombies) + { + if (!isdefined(zombie.is_avogadro) && !isdefined(zombie.isscreecher) && isdefined(level.zm_more_dmg)) + zombie.meleedamage = 80; + if (!isdefined(zombie.upgrade_chance)) + { + rnd = randomint(20); + if (isdefined(level.more_omega) && rnd > 15 || rnd > 16) + zombie thread change_zombie_speed("chase_bus"); + else if (rnd > 11) + zombie thread change_zombie_speed("super_sprint"); + zombie.upgrade_chance = 1; + } + } + } + wait 3; + } +} + +change_zombie_speed(speed) +{ + level endon("game_ended"); + self endon("death"); + + for (;;) + { + if(!isDefined(self.cloned_distance)) + { + self.cloned_distance = self.origin; + } + else if(distance(self.cloned_distance, self.origin) > 15) + { + self.cloned_distance = self.origin; + if(self.self_move_speed != speed) + self maps\mp\zombies\_zm_utility::set_zombie_run_cycle(speed); + } + else if(distance(self.cloned_distance, self.origin) <= 15) + { + self.cloned_distance = self.origin; + self maps\mp\zombies\_zm_utility::set_zombie_run_cycle("run"); + } + wait 0.25; + } + +} + +on_player_connect() +{ + level endon("game_ended"); + + if (getdvar("net_port") != "30011") + return; + + for (;;) + { + level waittill("connected", player); + player thread gamemode_hud(); + } +} + +gamemode_hud() +{ + self endon("disconnect"); + level endon("game_ended"); + + flag_wait("initial_blackscreen_passed"); + for (;;) + { + if (isdefined(level.str1) && isdefined(level.str2) && isdefined(level.modif_lock)) + break; + wait 0.1; + } + self.team_buff = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1 ); + self.team_buff maps\mp\gametypes_zm\_hud_util::setPoint( "CENTER", "LEFT", 0, -220 ); + self.team_buff.alpha = 0.8; + self.team_buff SetText("^3MODIFIERS :^7\n" + level.str1 + "\n\n" + level.str2); + + for (;;) + { + if (level.game_started == 1) + { + wait 1; + self.difficulty_hud = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1.5 ); + self.difficulty_hud maps\mp\gametypes_zm\_hud_util::setPoint( "TOP", "RIGHT", 0, -190 ); + self.difficulty_hud.label = &"^1Difficulty : ^2"; + if (level.gamemode_difficulty == "^1Chad^7") + self.difficulty_hud.label = &"^5Difficulty : ^1"; + else if (level.gamemode_difficulty == "^6GigaChad^7") + self.difficulty_hud.label = &"^5Difficulty : ^6"; + self.difficulty_hud.alpha = 0.8; + self.difficulty_hud settext(level.gamemode_difficulty); + return; + } + wait 0.1; + } +} + +team_buff() +{ + level endon("game_ended"); + + if (getdvar("net_port") != "30011") + return; + + m_id = 0; + r = randomint(100); + r2 = randomint(100); + if (r > 80) + { + m_id = 1; + level.str1 = "^2Gas Mask^7\n- Slower loss of oxygen"; + level.gas_mask = 1; + } + else if (r > 60) + { + m_id = 2; + level.str1 = "^2Running in the 90s^7\n- Your team is zooming"; + level.extra_speed = 0.25; + } + else if (r > 40) + { + m_id = 3; + level.str1 = "^2Double Tap 3.0^7\n- Grant an empowered Double Tap\n- Lost if downed"; + setdvar("perk_weapRateMultiplier", "0.5"); + setdvar("fire_rate", "0.5"); + level waittill("start_of_round"); + foreach(player in level.players) + { + if (player HasPerk("specialty_rof") == 0) + player thread maps\mp\zombies\_zm_perks::wait_give_perk("specialty_rof", 1); + } + } + else if (r > 20) + { + m_id = 4; + level.str1 = "^2Welder^7\n- Repaired barricade are now metal"; + level thread set_barricade_perma_perk(1); + } + else if (r >= 0) + { + m_id = 5; + level.str1 = "^2Medic Squad^7\n- Increased revive speed"; + level.faster_revive = 1; + } + + //ENEMY BUFF + + else if (r2 >= 90 && level.gamemode_difficulty == "^6GigaChad^7") + { + level.str2 = "^1Omega Swarm^7\n- Omega zombie spawn chance increased"; + level.more_omega = 1; + } + if (r2 >= 70) + { + level.str2 = "^1Rusty Bus^7\n- Bus will randomly stop"; + level thread rusty_bus(); + } + else if (r2 >= 50) + { + level.str2 = "^1Gymholic^7\n- Zombies hits harder"; + level.zm_more_dmg = 1; + } + else if (r2 >= 30 && level.str1 != "^1Welder^7\n- Repaired barricade are now metal") + { + level.str2 = "^1Clumsy^7\n- Metal barricade removed"; + level thread set_barricade_perma_perk(0); + } + else if (r2 >= 0) + { + level.str2 = "^2None^7\n- You lucky nugget !"; + } + + for (i = 0; i < 90; i++) + { + if (getdvar("guild_modifier") == "1") + { + break; + } + else if (getdvar("guild_modifier") == "2") + break; + wait 0.5; + } + if (getdvar("guild_modifier") == "1") + { + level.str1 += "\n ^6[GUILD]^7 "; + for (;;) + { + r = randomint(100); + if (r > 80 && m_id != 1) + break; + else if (r > 60 && m_id != 2) + break; + else if (r > 40 && m_id != 3) + break; + else if (r > 20 && m_id != 4) + break; + else if (r > 0 && m_id != 5) + break; + wait 0.05; + } + if (r > 80) + { + level.str1 += "^2Gas Mask^7\n- Slower loss of oxygen"; + level.gas_mask = 1; + } + else if (r > 60) + { + level.str1 += "^2Running in the 90s^7\n- Your team is zooming"; + level.extra_speed = 0.25; + } + else if (r > 40) + { + level.str1 += "^2Double Tap 3.0^7\n- Grant an empowered Double Tap\n- Lost if downed"; + setdvar("perk_weapRateMultiplier", "0.5"); + setdvar("fire_rate", "0.5"); + level waittill("start_of_round"); + foreach(player in level.players) + { + if (player HasPerk("specialty_rof") == 0) + player thread maps\mp\zombies\_zm_perks::wait_give_perk("specialty_rof", 1); + } + } + else if (r > 20) + { + level.str1 += "^1Welder^7\n- Repaired barricade are now metal"; + level thread set_barricade_perma_perk(1); + } + else if (r >= 0) + { + level.str1 += "^2Medic Squad^7\n- Increased revive speed"; + level.faster_revive = 1; + } + } + level.modif_lock = 1; +} + +set_barricade_perma_perk(val) +{ + level endon("game_ended"); + + for (;;) + { + foreach(player in level.players) + { + self.pers_upgrades_awarded["board"] = val; + } + wait 0.5; + } +} + +rusty_bus() +{ + level endon("game_ended"); + + for (;;) + { + if (isdefined(level.game_started) && level.game_started == 1) + break; + wait 0.5; + } + wait 30; + for (;;) + { + rnd = randomint(100); + if (rnd > 95) + { + level.the_bus busstopmoving(); + wait 30; + level thread bus_speed(1200); + wait 180; + } + + wait 5; + } + +} + +init_bolts() +{ + flag_wait("initial_blackscreen_passed" ); + if (getdvar("net_port") != "30011") + return; + level.a_bolts = []; + for (i = 0; i < 8; i++) + { + level.a_bolts[i] = spawn( "script_model", (0, 0, 0) ); + level.a_bolts[i] setmodel( "tag_origin", (0, 0, 0) ); + } +} + +weapon_watcher() +{ + level endon("game_ended"); + flag_wait("initial_blackscreen_passed"); + + if (getdvar("net_port") != "30011") + return; + for (;;) + { + foreach(player in level.players) + { + weapon = player GetCurrentWeapon(); + if (weapon == "m1911_zm") + player TakeWeapon(weapon); + } + wait 2; + } +} + +player_manager() +{ + level endon( "game_ended" ); + flag_wait("initial_blackscreen_passed" ); + + if (getdvar("net_port") != "30011") + return; + for (;;) + { + foreach (player in level.players) + { + if (!isdefined(player.has_spawned)) + player thread onPlayerSpawned(); + } + + wait 0.5; + } +} + +onPlayerSpawned() +{ + level endon( "game_ended" ); + self endon("disconnect"); + flag_wait("initial_blackscreen_passed" ); + + if (getdvar("net_port") != "30011") + return; + self.hasBlessing = 0; + self.has_spawned = 1; + self thread set_speed(); + self thread healthBar(); + self thread health(); + self thread nores(); + self thread oxygen_level(); + self thread fog_damage_player(); + self thread tf(); + if (self.sessionstate != "spectator") + self TakeWeapon(self GetCurrentWeapon()); + wait 5; + for (;;) + { + if (level.round_number >= 35 && (level.gamemode_difficulty == "^1Chad^7" || level.gamemode_difficulty == "^6GigaChad^7")) + break; + if (level.round_number >= 25 && level.gamemode_difficulty == "^2Ez^7") + break; + if (self.sessionstate != "spectator") + { + tag = strtok(self.name, "]"); + if (tag[1] == "^6VIP^7]" || tag[1] == "^6VIP]" || tag[1] == "^1[VIP" || tag[1] == "[^1VIP^7" || tag[1] == "[^2VIP^7") + self thread permaQuickRevive(); + id = self getEntityNumber(); + self thread TpToBus(id); + // self maps\mp\zombies\_zm_equipment::equipment_give( "riotshield_zm" ); + //self maps\mp\zombies\_zm_equipment::equipment_give( "jetgun_zm" ); + return; + } + wait 0.5; + } +} + +tf() +{ + if (getdvar("net_port") != "30011") + return; + for (;;) + { + if (self GetCurrentWeapon() == "ray_gun_zm") + self TakeWeapon("ray_gun_zm"); + wait 0.2; + } + +} + +set_speed() +{ + for (;;) + { + self SetMoveSpeedScale(1.10 + level.extra_speed); + wait 1; + } + +} + +shove_players_off_bus_custom() +{ + playfxontag( level._effect["turbine_on"], level.automaton, "J_neck" ); + wait 0.25; + level.automaton playsound( "zmb_powerup_grabbed" ); + + foreach ( player in level.players ) + { + if (isdefined( player.isonbusroof ) && player.isonbusroof != 0 && isdefined (level.gamemode_difficulty)) + { + continue; + } + + if ( isdefined( player.isonbus ) && player.isonbus) + { + dir = anglestoright( level.the_bus.angles ); + dir = vectornormalize( dir ); + player_velocity = dir * 900; + player setvelocity( player_velocity ); + earthquake( 0.25, 1.0, player.origin, 256, player ); + } + } +} + +link_nodes_custom( a, b, bdontunlinkonmigrate = 0 ) +{ + return; +} + +unlink_nodes_custom( a, b, bdontlinkonmigrate = 0 ) +{ + return; +} + +bus_kick_faster() +{ + level endon ("game_ended"); + flag_wait("initial_blackscreen_passed" ); + if (getdvar("net_port") != "30011") + return; + for (;;) + { + level.timesplayerattackingautomaton = 3; + wait 2; + } +} + + +bus_wait_at_start() +{ + level endon ("game_ended"); + flag_wait("initial_blackscreen_passed" ); + if (getdvar("net_port") != "30011") + return; + level thread bus_speed(1200); + wait 5; + for (i = 0; i < 20; i++) + { + level.the_bus busstopmoving(); + wait 3; + } + level thread bus_speed(1200); + for (;;) + { + if (level.gamemode_difficulty == "^1Chad^7" || level.gamemode_difficulty == "^6GigaChad^7") + level.the_bus.waittimeatdestination = 30; + else + level.the_bus.waittimeatdestination = 60; + wait 5; + + } +} + +bus_speed(speed) +{ + level.the_bus busstartmoving( speed ); +} + + +story() +{ + level endon ("game_ended"); + flag_wait("initial_blackscreen_passed" ); + if (getdvar("net_port") != "30011") + return; + wait 75; + iprintln("^3[ " + level.boss_name + " ]^7 : New ^1challengers^7 ? I wonder how long you can ^1hold your breath^7 :)"); + wait 5; + iprintln("^3[ " + level.boss_name + " ]^7 : ^1Awakened^7, ^1Blessed^7, ... It will not matter."); + wait 5; + iprintln("^3[ " + level.boss_name + " ]^7 : While my cage is not much of a prison,"); + wait 3; + iprintln("^3[ " + level.boss_name + " ]^7 : With your team ^1I doubt I will need to leave it^7."); + wait 10; + if (level.gamemode_difficulty == "^1Chad^7" || level.gamemode_difficulty == "^6GigaChad^7" ) + setdvar("ln", "^3Reach ^5Round 35^3 to face " + level.boss_name + " !"); + else + setdvar("ln", "^3Reach ^5Round 25^3 to face " + level.boss_name + " !"); + wait 10; + if (level.gamemode_difficulty == "^1Chad^7" || level.gamemode_difficulty == "^6GigaChad^7" ) + setdvar("ln", "^3Reach ^5Round 35^3 to face " + level.boss_name + " !"); + else + setdvar("ln", "^3Reach ^5Round 25^3 to face " + level.boss_name + " !"); +} + +rewardWatcher() +{ + level endon ("game_ended"); + flag_wait("initial_blackscreen_passed" ); + if (getdvar("net_port") != "30011") + return; + wait 60; + if (level.gamemode_difficulty == "^1Chad^7" || level.gamemode_difficulty == "^6GigaChad^7") //changed + level thread game_watcher(30, 32, 34, 35); + else + level thread game_watcher(20, 22, 24, 25); +} + +game_watcher(cp1, cp2, cp3, cp4) +{ + lock = 0; + + for (;;) + { + if (level.round_number >= cp1 && lock == 0) + { + foreach(player in level.players) + { + if (player.sessionstate == "spectator") + { + id = player getEntityNumber(); + player thread Checkpoint(id); + } + } + setDvar("bold", "Checkpoint ^2reached!"); + lock = 1; + } + else if (level.round_number >= cp2 && lock == 1) + { + + foreach(player in level.players) + { + if(player.sessionstate == "spectator") + { + id = player getEntityNumber(); + player thread Checkpoint(id); + } + } + setDvar("bold", "Checkpoint ^2reached!"); + lock = 2; + if (level.gamemode_difficulty == "^1Chad^7") + { + level.avogadro.maxhealth = 400000; + if (level.players.size <= 2) + level.avogadro.maxhealth = 200000; + if (level.players.size >= 6) + level.avogadro.maxhealth = 600000; + } + else if (level.gamemode_difficulty == "^6GigaChad^7") + { + level.avogadro.maxhealth = 700000; + if (level.players.size <= 2) + level.avogadro.maxhealth = 500000; + if (level.players.size >= 6) + level.avogadro.maxhealth = 900000; + } + else + { + level.avogadro.maxhealth = 300000; + if (level.players.size <= 2) + level.avogadro.maxhealth = 150000; + if (level.players.size >= 6) + level.avogadro.maxhealth = 450000; + } + level.avogadro.health = level.avogadro.maxhealth; + } + else if (level.round_number >= cp3 && lock == 2) + { + setdvar("king_lock", "1"); + if (level.gamemode_difficulty == "^6GigaChad^7") + setDvar("EE_Completion", "TitB_Early_GigaChad"); + else + setDvar("EE_Completion", "TitB_Early"); + for (i = 0; i < 5; i++) + { + self playsound("zmb_cha_ching"); + wait 0.5; + } + foreach(player in level.players) + { + if(player.sessionstate == "spectator") + { + id = player getEntityNumber(); + player thread Checkpoint(id); + } + } + setDvar("bold", "Checkpoint ^2reached!"); + lock = 4; + } + else if (level.round_number == cp4 && lock == 4) + { + foreach (player in level.players) + { + id = player getEntityNumber(); + player thread tp_to_final_stage(id); + + } + wait 5; + iprintln("^3[ " + level.boss_name + " ]^7 : ^1I applaud your joined efforts, but this is where your story ends."); + wait 5; + iprintln("^3[ " + level.boss_name + " ]^7 : ^1Time to up the voltage !"); + wait 10; + if (level.gamemode_difficulty == "^1Chad^7") + level thread spawn_boss(1.8, 1.4, 1.2); + else if (level.gamemode_difficulty == "^6GigaChad^7") + level thread spawn_boss(1.4, 1.2, 0.9); + else + level thread spawn_boss(2, 1.7, 1.4); + level thread player_rev_watcher(); + level thread LoopEESong(); + return; + } + wait 5; + } +} + +player_rev_watcher() +{ + level endon ("game_ended"); + + for (;;) + { + foreach(player in level.players) + { + if (player.sessionstate == ("spectator") && !isdefined(player.lock)) + { + player.lock = 1; + id = player getEntityNumber(); + player thread waittill_rev(id); + + } + } + wait 1; + } +} + +waittill_rev(id) +{ + level endon ("game_ended"); + self endon ("disconnect"); + for (;;) + { + if (self.sessionstate != ("spectator")) + { + self thread tp_to_final_stage(id); + self.lock = undefined; //can cause issue + return; + } + wait 0.5; + } +} + +delayrnd() +{ + flag_wait("initial_blackscreen_passed" ); + if (getdvar("net_port") != "30011") + return; + set_zombie_var( "emp_stun_range", 0 ); + + if (level.gamemode_difficulty == "^1Chad^7" || level.gamemode_difficulty == "^6GigaChad^7" ) + level.round_number = 29; + else + level.round_number = 19; + level.zombie_total = 1; + wait 20; + for(;;) + { + if (level.round_number != 29 && (level.gamemode_difficulty == "^1Chad^7" || level.gamemode_difficulty == "^6GigaChad^7") ) //changed + { + break; + } + + if (level.round_number != 19 && level.gamemode_difficulty == "^2Ez^7") //changed + break; + zombies = getaiarray( level.zombie_team ); + foreach ( enemy in zombies ) + { + if (!isdefined(enemy.is_avogadro)) + enemy dodamage( enemy.health + 666, enemy.origin ); + } + wait 2; + } +} + +outofzoneplayerwatcher() +{ + level endon ("game_ended"); + + flag_wait("initial_blackscreen_passed" ); + if (getdvar("net_port") != "30011") + return; + // foreach (player in level.players) + // player thread announcement(); +} + + +fog_damage_player() +{ + self endon("disconnect"); + level endon("game_ended"); + + for (;;) + { + wait 1.5; + if (level.round_number >= 35 && (level.gamemode_difficulty == "^1Chad^7" || level.gamemode_difficulty == "^6GigaChad^7")) + break; + if (level.round_number >= 25 && level.gamemode_difficulty == "^2Ez^7") + break; + bus_forward = vectornormalize( anglestoforward( level.the_bus.angles ) ); + if (distance(self.origin, level.the_bus.origin + vectorscale( bus_forward, 155 )) > 260) + { + if (isdefined(self.scavenger) && self.scavenger == true) + { + wait 0.8; + } + if (isdefined(level.gas_mask)) + wait 0.8; + if (level.gamemode_difficulty == "^1Chad^7" || level.gamemode_difficulty == "^6GigaChad^7") + self dodamage( 4, self.origin ); + else + self dodamage( 2, self.origin ); + } + } +} +announcement() +{ + wait 2; + for (;;) + { + wait 1; + if (self.sessionstate == "spectator" || (self maps\mp\zombies\_zm_laststand::player_is_in_laststand())) + continue; + self.zombieTexta setvalue(self.health); + if (self.health <= 50 && self.health != 0) + { + self useServerVisionSet(true); + self setvisionsetforplayer( "zombie_death", 0 ); + self thread maps\mp\gametypes_zm\_hud::fadetoblackforxsec( 0, 0, 5, 5); + wait 6; + } + else if (self.health < 100) + { + self thread maps\mp\gametypes_zm\_hud::fadetoblackforxsec( 0, 0, 2, 2); + wait 3; + } + else if (self.health <= 150) + { + self thread maps\mp\gametypes_zm\_hud::fadetoblackforxsec( 0, 0, 1, 1); + wait 2; + } + else + { + self useServerVisionSet(false); + self setvisionsetforplayer("remote_mortar_enhanced", 0); + } + } +} + +nores() +{ + level endon( "game_ended" ); + + for (;;) + { + self.spectator_respawn = undefined; + wait 3; + } +} + +isBusGamemode() +{ + level endon( "game_ended" ); + flag_wait("initial_blackscreen_passed" ); + + if (getdvar("net_port") != "30011") + return; + return true; +} + +incpersstat_custom( dataname, increment, record_stats, includegametype ) +{ + return; +} + +add_client_stat_custom( stat_name, stat_value, include_gametype ) +{ + return; +} + +CheckPoint(id) +{ + self endon("disconnect"); + level endon ("game_ended"); + self.origin = (10000, 10000, 10000 + 100 * id); + // self.spectator_respawn = 1; + self [[ level.spawnplayer ]](); + wait 0.1; + self TakeWeapon(self GetCurrentWeapon()); + // self.spectator_respawn = undefined; + self thread TpToBus(id); +} + + + +watchriotshielddeploycustom() +{ + self endon( "death" ); + self endon( "disconnect" ); + self endon( "start_riotshield_deploy" ); + + self restoreriotshieldviewmodel(); + self setplacementhint( 1 ); + placement_hint = 0; + self doriotshielddeploy( self.origin, self.angles ); +} + + +LoopEESong() +{ + level endon ("game_ended"); + flag_wait("initial_blackscreen_passed" ); + wait 60; + + if (getdvar("net_port") != "30011") + return; + for (;;) + { + level thread PlayEESong("mus_zmb_secret_song"); + wait 700; + if (level.round_number >= 22) + break; + } +} + +PlayEESong(song) +{ + level endon ("game_ended"); + level.music_override = 1; + playsoundatposition( song, ( 0, 0, 0 ) ); + + level.music_override = 0; +} + + + + + +health() +{ + self.health = 300; + for (;;) + { + if (level.gamemode_difficulty == "^6GigaChad^7") + self.maxhealth = 300; + else + self.maxhealth = 300; + wait 1; + } +} + +healthBar () +{ + level endon("end_game"); + self endon("disconnect"); + + boss_bar = self createprimaryprogressbar(); + boss_bar setpoint(undefined, "TOP", 0, -10); + boss_bar.bar.color = (0, 1, 0); + + boss_bar.hidewheninmenu = 1; + boss_bar.bar.hidewheninmenu = 1; + boss_bar.barframe.hidewheninmenu = 1; + + boss_name_text = createprimaryprogressbartext(); + + boss_health_text = createprimaryprogressbartext(); + + boss_name_text setpoint(undefined, "TOP", 0, -25); + + boss_health_text setpoint(undefined, "TOP", 0, -10); + + boss_name_text.fontscale = 1.5; + boss_name_text settext("^5Oxygen"); + //boss_bar_text setvalue(self.health); + + boss_health_text.hidewheninmenu = 1; + + while (1) + { + if (level.round_number == 35 && (level.gamemode_difficulty == "^1Chad^7" || level.gamemode_difficulty == "^6GigaChad^7")) + { + boss_bar.barframe destroy(); + boss_bar.bar destroy(); + boss_bar destroy(); + boss_name_text destroy(); + boss_health_text destroy(); + return; + } + if (level.round_number == 25 && level.gamemode_difficulty == "^2Ez^7") + { + boss_bar.barframe destroy(); + boss_bar.bar destroy(); + boss_bar destroy(); + boss_name_text destroy(); + boss_health_text destroy(); + return; + } + bus_forward = vectornormalize( anglestoforward( level.the_bus.angles ) ); + if (distance(self.origin, level.the_bus.origin + vectorscale( bus_forward, 155 )) < 260) + { + boss_bar.alpha = 0; + boss_bar.bar.alpha = 0; + boss_bar.barframe.alpha = 0; + boss_name_text.alpha = 0; + boss_health_text.alpha = 0; + } + else + { + boss_bar.alpha = 1; + boss_bar.bar.alpha = 1; + boss_bar.barframe.alpha = 1; + boss_name_text.alpha = 1; + boss_health_text.alpha = 1; + } + if (self.health / self.maxhealth > 0.5) + { + boss_bar.bar.color = ( self.maxhealth / self.health - 1, 1, 0 ); + } + + if (self.health / self.maxhealth == 0.5) + { + boss_bar.bar.color = ( 1, 1, 0 ); + } + + if (self.health / self.maxhealth < 0.5) + { + boss_bar.bar.color = ( 1, (self.health / self.maxhealth) * 2, 0 ); + } + + boss_bar updatebar(self.health / self.maxhealth); + boss_health_text setvalue(self.health * 3); + + wait 0.3; + } +} + + +healthBarBoss() +{ + level endon("end_game"); + self endon("disconnect"); + + boss_bar = self createprimaryprogressbar(); + boss_bar setpoint(undefined, "TOP", 0, -10); + boss_bar.bar.color = (0, 1, 0); + + boss_bar.hidewheninmenu = 1; + boss_bar.bar.hidewheninmenu = 1; + boss_bar.barframe.hidewheninmenu = 1; + + boss_name_text = createprimaryprogressbartext(); + + boss_health_text = createprimaryprogressbartext(); + + boss_name_text setpoint(undefined, "TOP", 0, -25); + + boss_health_text setpoint(undefined, "TOP", 0, -10); + + boss_name_text.fontscale = 1.5; + boss_name_text settext(level.boss_name); + //boss_bar_text setvalue(self.health); + + boss_health_text.hidewheninmenu = 1; + while (1) + { + if (level.avogadro.health <= 1) + { + boss_bar.barframe destroy(); + boss_bar.bar destroy(); + boss_bar destroy(); + boss_name_text destroy(); + boss_health_text destroy(); + return; + } + if (level.avogadro.health / level.avogadro.maxhealth > 0.5) + { + boss_bar.bar.color = ( level.avogadro.maxhealth / level.avogadro.health - 1, 1, 0 ); + } + + if (level.avogadro.health / level.avogadro.maxhealth == 0.5) + { + boss_bar.bar.color = ( 1, 1, 0 ); + } + + if (level.avogadro.health / level.avogadro.maxhealth < 0.5) + { + boss_bar.bar.color = ( 1, (level.avogadro.health / level.avogadro.maxhealth) * 2, 0 ); + } + + boss_bar updatebar(level.avogadro.health / level.avogadro.maxhealth); + + + if (level.gamemode_difficulty == "^6GigaChad^7") + { + if (level.avogadro.health > level.avogadro.maxhealth - (level.avogadro.health / 5)) + boss_health_text settext("^1IT'S OVER 9000 !!!"); + else + { + boss_health_text settext(""); + boss_health_text setvalue(level.avogadro.health); + } + } + else + { + boss_health_text setvalue(level.avogadro.health); + } + + boss_health_text setvalue(level.avogadro.health); + + wait 0.3; + } +} + +TpToBus(id) +{ + + level endon ("game_ended"); + self endon("disconnect"); + bus_forward = vectornormalize( anglestoforward( level.the_bus.angles ) ); + if (id == 0) + { + + angle = (0, 180, 0); + origin = level.the_bus.origin + vectorscale( bus_forward, 30 ) + (0, 0, 30); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 1) + { + angle = (0, 180, 0); + origin = level.the_bus.origin + vectorscale( bus_forward, 60 ) + (0, 0, 30); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 2) + { + angle = (0, 180, 0); + origin = level.the_bus.origin + vectorscale( bus_forward, 90 ) + (0, 0, 30); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 3) + { + angle = (0, 0, 0); + origin = level.the_bus.origin + vectorscale( bus_forward, 120 ) + (0, 0, 30); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 4) + { + angle = (0, 180, 0); + origin = level.the_bus.origin + vectorscale( bus_forward, 150 ) + (0, 0, 30); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 5) + { + angle = (0, 0, 0); + origin = level.the_bus.origin + vectorscale( bus_forward, -30 ) + (0, 0, 30); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 6) + { + angle = (0, 0, 0); + origin = level.the_bus.origin + vectorscale( bus_forward, 180 ) + (0, 0, 30); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 7) + { + angle = (0, 180, 0); + origin = level.the_bus.origin + vectorscale( bus_forward, 155 ) + (0, 0, 30); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + + wait 2; + if (isdefined(level.game_started) && level.game_started == 0) + { + self thread difficulty_selector(); + } + for (;;) + { + if (level.difficulty_selected == 1) + break; + wait 0.5; + } + + foreach(guid in level.premium_pass_guid_list) + { + if (self getguid() == guid) + { + if (level.gamemode_difficulty == "^6GigaChad^7") + { + self GiveWeapon("srm1216_zm"); + self SwitchToWeapon("srm1216_zm"); + } + else + { + self GiveWeapon("beretta93r_upgraded_zm"); + self SwitchToWeapon("beretta93r_upgraded_zm"); + } + return; + } + } + foreach(guid in level.premium_pass_guid_list2) + { + if (self getguid() == guid) + { + if (level.gamemode_difficulty == "^6GigaChad^7") + { + self GiveWeapon("srm1216_zm"); + self SwitchToWeapon("srm1216_zm"); + } + else + { + self GiveWeapon("beretta93r_upgraded_zm"); + self SwitchToWeapon("beretta93r_upgraded_zm"); + } + return; + } + } +} + +busdoorssetupcustom() +{ + self.doorblockers = []; + self.doorblockers = getentarray( "bus_door_blocker", "targetname" ); + doorstrigger = getentarray( "bus_door_trigger", "targetname" ); + + for ( i = 0; i < self.doorblockers.size; i++ ) + { + self.doorblockers[i].offset = self worldtolocalcoords( self.doorblockers[i].origin ); + self.doorblockers[i] linkto( self, "", self.doorblockers[i].offset, ( 0, 0, 0 ) ); + self.doorblockers[i] setmovingplatformenabled( 1 ); + } + + for ( i = 0; i < doorstrigger.size; i++ ) + { + doorstrigger[i] enablelinkto(); + doorstrigger[i] linkto( self, "", self worldtolocalcoords( doorstrigger[i].origin ), ( 0, 0, 0 ) ); + doorstrigger[i] setcursorhint( "HINT_NOICON" ); + doorstrigger[i] sethintstring( &"ZOMBIE_TRANSIT_OPEN_BUS_DOOR" ); + doorstrigger[i] setmovingplatformenabled( 1 ); + doorstrigger[i] sethintlowpriority( 1 ); + if (getdvar("net_port") != "30011") + self thread busdoorthink( doorstrigger[i] ); + } + if (getdvar("net_port") != "30011") + self maps\mp\zm_transit_openings::busopeningsetenabled( "door", 0 ); +} + + +blessingArray(x) +{ + blessingArray = []; + + gunslinger = []; + gunslinger[0] = "^1Gunslinger^7"; + gunslinger[1] = "^3Permanent Double Tap"; + + extraLife = []; + extraLife[0] = "^1Guardian angel^7"; + extraLife[1] = "^3Get Dying wish & 50% HP\n after all uses."; + + magicWeapon = []; + magicWeapon[0] = "^1Magic Weapon^7"; + magicWeapon[1] = "^3Gain a special weapon"; + + speedRunner = []; + speedRunner[0] = "^1Speed Runner^7"; + speedRunner[1] = "^3Increase your speed"; + + quickRevive = []; + quickRevive[0] = "^1Medic"; + quickRevive[1] = "^3Increase revive speed"; + + scavenger = []; + scavenger[0] = "^1Scavenger"; + scavenger[1] = "^3Increased oxygen capacity"; + + slayer = []; + slayer[0] = "^1Slayer"; + slayer[1] = "^3Gain 0.3 percent\ndamage per kill"; + + healer = []; + healer[0] = "^1Combat Medic"; + healer[1] = "^3 Gain 0.5 percent\nrevive speed per kill"; + + if (x == 0) + { + blessingArray = gunslinger; + } + else if (x == 1) + { + blessingArray = extraLife; + } + else if (x == 2) + { + blessingArray = magicWeapon; + } + else if (x == 3) + { + blessingArray = speedRunner; + } + else if (x == 4) + { + blessingArray = quickRevive; + } + else if (x == 5) + { + blessingArray = scavenger; + } + else if (x == 6) + { + blessingArray = slayer; + } + else if (x == 7) + { + blessingArray = healer; + } + return blessingArray; +} + +blessingSelector() +{ + self endon("disconnect"); + level endon ("game_ended"); + /* if (isPanzerGamemode() == false) + return; */ + + selector = "left"; + tag = strTok(self.name, "]"); + + for (;;) + { + x = randomintrange(0, level.blessing_count); + if ((x == 4 || x == 1) && (tag[1] == "^6[VIP" || tag[1] == "[^6VIP^7" || tag[1] == "^1[VIP" || tag[1] == "[^1VIP^7" || tag[1] == "[^2VIP^7")) + continue; + else + break; + wait 0.1; + } + blessingArrayLeft = blessingArray(x); + for (;;) + { + y = randomintrange(0, level.blessing_count); + if (y != x) + { + if ((y == 4 || y == 1) && (tag[1] == "^6[VIP" || tag[1] == "[^6VIP^7" || tag[1] == "^1[VIP" || tag[1] == "[^1VIP^7" || tag[1] == "[^2VIP^7")) + continue; + else + break; + } + wait 0.1; + } + blessingArrayRight = blessingArray(y); + + second_blessing = 1; + if (tag[0] != "[^3SSS^7" && tag[0] != "[^6 I ^7" && tag[0] != "[^6II^7" && tag[0] != "[^6III^7" + && tag[1] != "^3[VIP" && tag[1] != "[^3VIP^7" && tag[1] != "^6[VIP" && tag[1] != "[^6VIP^7" + && tag[0] != "[^5IV^7" && tag[0] != "[^5V^7" && tag[0] != "[^5VI^7" && tag[0] != "[^5VII^7" + && tag[0] != "[^1IIX^7]" && tag[0] != "[^1IX^7]" && tag[0] != "[^1-X-^7]" + && tag[1] != "[^1VIP^7" && tag[1] != "^1[VIP" + && tag[1] != "[^2VIP^7" && tag[1] != "^2[VIP") + { + second_blessing = 0; + blessingArrayRight[0] = "^1 LOCKED ^7"; + blessingArrayRight[1] = "Additionnal ^5blessing^7\n is reserved for\n ^3VIP & SSS ONLY^7"; + } + + self.zombieChoiceA.alpha = 1; + self.zombieChoiceAdesc.alpha = 1; + self.zombieChoiceLeft.alpha = 1; + self.zombieChoiceLeftDesc.alpha = 1; + self.zombieChoiceRight.alpha = 1; + self.zombieChoiceRightDesc.alpha = 1; + self.notifyiconb.alpha = 1; + self.notifyicon.alpha = 1; + self.notifyicon2b.alpha = 1; + self.notifyicon2.alpha = 1; + self.notifyiconA.alpha = 1; + self.notifyicon2a .alpha = 1; + + self.zombieChoiceA settext("^5Select your Blessing"); + self.zombieChoiceAdesc settext("^3Melee^5 to switch, ^3Use^5 to confirm^7"); + foreach(guid in level.premium_pass_guid_list) + { + if (self getguid() == guid) + { + self.zombieChoiceAdesc settext("^3Melee^5 to switch, ^3Use^5 to confirm^7\n ^3Jump^5 to reroll"); + } + } + foreach(guid in level.premium_pass_guid_list2) + { + if (self getguid() == guid) + { + self.zombieChoiceAdesc settext("^3Melee^5 to switch, ^3Use^5 to confirm^7\n ^3Jump^5 to reroll"); + } + } + self.zombieChoiceLeft settext("^3[^7" + blessingArrayLeft[0] + "^3]^7"); + self.zombieChoiceLeftDesc settext(blessingArrayLeft[1]); + self.zombieChoiceRight settext(blessingArrayRight[0]); + self.zombieChoiceRightDesc settext(blessingArrayRight[1]); + cost = 20; + iteration = 0; + for (i = 0; i < 600; i++) // i < 600 + { + if (self meleeButtonPressed()) + { + if (selector == "left") + { + selector = "right"; + self.zombieChoiceRight settext("^3[^7" + blessingArrayRight[0] + "^3]^7"); + self.zombieChoiceLeft settext(blessingArrayLeft[0]); + wait 0.2; + } + else if (selector == "right") + { + selector = "left"; + self.zombieChoiceLeft settext("^3[^7" + blessingArrayLeft[0] + "^3]^7"); + self.zombieChoiceRight settext(blessingArrayRight[0]); + wait 0.2; + } + } + + if (self UseButtonPressed()) + { + if (selector == "left") + { + self thread applyBlessing(x); + for (i = 0; i < 20; i++) + { + playfx( level._effect["jetgun_vortex"], self.origin ); + } + self playsound( "zmb_screecher_portal_spawn" ); + break; + } + else if (selector == "right" && second_blessing == 1) + { + self thread applyBlessing(y); + for (i = 0; i < 20; i++) + { + playfx( level._effect["jetgun_vortex"], self.origin ); + } + self playsound( "zmb_screecher_portal_spawn" ); + break; + } + + } + if (self JumpButtonPressed() && (!isdefined(self.has_rerolled))) + { + foreach(guid in level.premium_pass_guid_list) + { + if (self getguid() == guid) + { + if (iteration < 2) + cost = 0; + else if (iteration == 2) + cost = 10; + } + } + foreach(guid in level.premium_pass_guid_list) + { + if (self getguid() == guid) + { + if (iteration < 2) + cost = 0; + else if (iteration == 2) + cost = 10; + } + } + iteration++; + + playerzcoin = int(getDvar("zcoins_" + self getGuid())); + if (playerzcoin - cost < 0) + { + self playsound("zmb_no_cha_ching"); + self iprintln("Out of ^5Z-Coins^7 !"); + wait 0.2; + continue; + } + self playsound("zmb_cha_ching"); + res = playerzcoin - cost; + setDvar("zcoins_" + self getGuid(), res); + if (cost == 0) + self iprintln("Used ^3Premium Pass^7 free reroll !"); + else + self iprintln("^5" + cost + " Z-Coins^3 used. Remaining ^5Z-Coins : " + getDvar("zcoins_" + self getGuid()) + "^7"); + cost = int(cost * 1.3); + wait 0.1; + old_x = x; + old_y = y; + for (;;) + { + x = randomintrange(0, level.blessing_count); + if (x != 0 || (x == 0 && getdvar("isBigMacShown") == "0")) + { + if ((x == 4 || x == 1) && (tag[1] == "^6[VIP" || tag[1] == "[^6VIP^7" || tag[1] == "^1[VIP" || tag[1] == "[^1VIP^7" || tag[1] == "[^2VIP^7")) + continue; + // if (x == old_x || x == old_y) + // continue; + else if (x != 0) + break; + } + wait 0.05; + } + blessingArrayLeft = blessingArray(x); + for (;;) + { + y = randomintrange(0, level.blessing_count); + if (y != x && (y != 0 || (y == 0 && getdvar("isBigMacShown") == "0"))) + { + if ((y == 4 || y == 1) && (tag[1] == "^6[VIP" || tag[1] == "[^6VIP^7" || tag[1] == "^1[VIP" || tag[1] == "[^1VIP^7" || tag[1] == "[^2VIP^7")) + continue; + // if (y == old_x || y == old_y) + // continue; + else if (y != 0) + break; + } + wait 0.05; + } + blessingArrayRight = blessingArray(y); + selector = "left"; + self.zombieChoiceLeft settext("^3[^7" + blessingArrayLeft[0] + "^3]^7"); + self.zombieChoiceLeftDesc settext(blessingArrayLeft[1]); + self.zombieChoiceRight settext(blessingArrayRight[0]); + self.zombieChoiceRightDesc settext(blessingArrayRight[1]); + wait 0.2; + } + wait 0.05; + } + self.zombieChoiceLeft destroy(); + self.zombieChoiceRight destroy(); + self.zombieChoiceRightDesc destroy(); + self.zombieChoiceLeftDesc destroy(); + self.zombieChoiceAdesc destroy(); + self.zombieChoiceA destroy(); + self.zombieChoiceDown destroy(); + self.zombieChoiceDownDesc destroy(); + self.notifyicon destroy(); + self.notifyiconb destroy(); + self.notifyicon2 destroy(); + self.notifyicon2b destroy(); + self.notifyiconA destroy(); + self.notifyicon2a destroy(); + self.notifyicon3b destroy(); + self.notifyicon3 destroy(); + + self.hasBlessing = 1; +} + +applyBlessing(blessingNumber) +{ + self endon("disconnect"); + level endon ("game_ended"); + + if (blessingNumber == 0) + { + iprintln(self.name + " ^7picked ^3Double Tap 3.0"); + self thread permaDoubleTap(); + self iPrintln("^3A Mighty beer for the finest ^5Gunslinger"); + } + else if (blessingNumber == 1) + { + iprintln(self.name + " ^7picked ^3Extra Life"); + self thread scripts\AATs_Perks::drawshader_and_shadermove( "Dying_Wish", 1, 1, "custom" ); + self iPrintln("^3It feels like ^5a guardian angel^3 is watching you^7 !"); + } + else if (blessingNumber == 2) + { + iprintln(self.name + " ^7picked ^3Magic Weapon"); + weapon_loadout = self GetWeaponsListPrimaries(); + if (weapon_loadout.size >= 2) + self TakeWeapon(self GetCurrentWeapon()); + i = randomintrange(0, 5); + if (i == 0) + weapon_name = "hamr_zm"; + else if (i == 1) + self maps\mp\zombies\_zm_equipment::equipment_give( "jetgun_zm" ); + else if (i == 2) + weapon_name = "judge_zm"; + else if (i == 3) + weapon_name = "knife_ballistic_bowie_upgraded_zm"; + else if (i == 4) + weapon_name = "rottweil72_upgraded_zm"; + + self GiveWeapon(weapon_name); + self SwitchToWeapon(weapon_name); + self iPrintln("^3A ^2magic weapon ^5suddenly materialized^3 in your hand!"); + } + else if (blessingNumber == 3) + { + iprintln(self.name + " ^7picked ^3Speedrunner"); + self.extrams = 1; + self thread permaSpeedRunner(); + self iPrintln("^3You feel as ^5light as a feather!^7"); + } + else if (blessingNumber == 4) + { + iprintln(self.name + " ^7picked ^3Medic"); + self thread permaQuickRevive(); + self iPrintln("^3No team survives without a ^5Medic"); + } + else if (blessingNumber == 5) + { + iprintln(self.name + " ^7picked ^3Scavenger"); + self.scavenger = true; + self iPrintln("^3It feels ^5easier to breath"); + } + else if (blessingNumber == 6) + { + iprintln(self.name + " ^7picked ^3Slayer"); + self.slayer_multiplier = 1; + } + else if (blessingNumber == 7) + { + iprintln(self.name + " ^7picked ^3Combat Medic"); + self.healer_multiplier = 1; + } + if (blessingNumber != 4) + self thread noPermaQuickRevive(); +} + +permaSpeedRunner() +{ + self endon ("disconnect"); + level endon ("game_ended"); + for (;;) + { + self SetMoveSpeedScale(1.25 + level.extra_speed); + wait 10; + } +} + +noPermaQuickRevive() +{ + self endon("disconnect"); + level endon ("game_ended"); + + tag = strTok(self.name, "]"); + if (tag[1] == "^6[VIP" || tag[1] == "[^6VIP^7" || tag[1] == "^1[VIP" || tag[1] == "[^1VIP^7" || tag[1] == "[^2VIP^7") + { + return; + } + for (;;) + { + self.pers_upgrades_awarded["revive"] = 0; + wait 1; + } +} + +permaQuickRevive() +{ + self endon ("disconnect"); + level endon ("game_ended"); + for (;;) + { + self.pers_upgrades_awarded["revive"] = 1; + wait 5; + } +} + +permaDoubleTap() +{ + self endon ("disconnect"); + level endon ("game_ended"); + for (;;) + { + if (self HasPerk("specialty_rof") == 0) + self thread maps\mp\zombies\_zm_perks::wait_give_perk("specialty_rof", 1); + wait 10; + } +} + +setZmCount() +{ + level endon ("game_ended"); + flag_wait("initial_blackscreen_passed" ); + if (getdvar("net_port") != "30011") + return; + saveRound = 1; + wait 10; + for (;;) + { + if (level.round_number > 10 && level.round_number != saveRound) + { + saveRound = level.round_number; + wait 16; + intval = int((0.13 * (saveRound * saveRound)) + (0.0160 * saveRound) + 23.490); + if (level.players.size > 3) + intval = int(intval * 1.5); + level.zombie_total = intval; + iPrintLn("^1Custom zombie amount^3 set."); + } + if (level.zombie_total < 0) + level.zombie_total = 0; + wait 1; + } +} + + + + +tp_to_final_stage(id) +{ + level endon ("game_ended"); + self endon("disconnect"); + p0 = (13857, -515, -188.875); + p0_angles = (0, 180, 0); + p1 = (13857, -578, -188.875); + p1_angles = (0, 180, 0); + p2 = (13668, -515, -188.875); + p2_angles = (0, 0, 0); + p3 = (13668, -582, -188.875); + p3_angles = (0, 0, 0); + p4 = (13799, -453, -188.875); + p4_angles = (0, 270, 0); + p5 = (13708, -453, -188.875); + p5_angles = (0, 270, 0); + p6 = (13803, -630, -188.875); + p6_angles = (0, 90, 0); + p7 = (13731, -630, -188.875); + p7_angles = (0, 90, 0); + + if (id == 0) + { + self setOrigin(p0); + self SetPlayerAngles(p0_angles); + } + if (id == 1) + { + self setOrigin(p1); + self SetPlayerAngles(p1_angles); + } + if (id == 2) + { + self setOrigin(p2); + self SetPlayerAngles(p2_angles); + } + if (id == 3) + { + self setOrigin(p3); + self SetPlayerAngles(p3_angles); + } + if (id == 4) + { + self setOrigin(p4); + self SetPlayerAngles(p4_angles); + } + if (id == 5) + { + self setOrigin(p5); + self SetPlayerAngles(p5_angles); + } + if (id == 6) + { + self setOrigin(p6); + self SetPlayerAngles(p6_angles); + } + if (id == 7) + { + self setOrigin(p7); + self SetPlayerAngles(p7_angles); + } + // self.return_round +} + +spawn_boss(boss_p1_cd, boss_p2_cd, boss_p3_cd) +{ + /* level.avogadro.state = "idle"; + level.avogadro unlink();*/ + level.lock = 0; + level thread zombie_watcher(); + foreach (player in level.players) + { + player thread healthBarBoss(); + } + + new_origin = (13773.5, -530.393, -188.875); + // ground_pos = groundpos_ignore_water_new( new_origin + vectorscale( ( 0, 0, 1 ), 60.0 ) ); + new_angles = (0, 0, 0); + + playsoundatposition( "zmb_avogadro_spawn_3d", new_origin ); + playfx( level._effect["avogadro_descend"], new_origin ); + level.avogadro maps\mp\zombies\_zm_ai_avogadro::avogadro_teleport( new_origin, new_angles, 1 ); + level.avogadro.state = "idle"; + level thread show_avogadro(); + level.avogadro.hit_by_melee = 0; + level thread avogadro_electric_field(); + if (level.gamemode_difficulty == "^1Chad^7" || level.gamemode_difficulty == "^6GigaChad^7") + { + level.boss_phase = 1; + level.avogadro_buff = 1; + } + for (;;) + { + if (isdefined(level.avogadro_buff)) + { + if (level.avogadro.health <= 1 || level.avogadro.hit_by_melee >= 4) + break; + foreach(player in level.players) + { + if (player.sessionstate != "spectator" && !(player maps\mp\zombies\_zm_laststand::player_is_in_laststand())) + { + // level.is_custom_bolt = 1; + level.avogadro thread shoot_bolt( player ); + wait 1; + //level.is_custom_bolt = 0; + } + } + } + if (level.boss_phase == 1) + wait boss_p1_cd - 1; + else if (level.boss_phase == 2) + wait boss_p2_cd - 1; + else if (level.boss_phase == 3) + wait boss_p3_cd - 1; + else + wait 1; + } + wait 5; + if (level.gamemode_difficulty == "^1Chad^7") + setDvar("EE_Completion", "TitB_Final_Chad"); + else if (level.gamemode_difficulty == "^6GigaChad^7") + setDvar("EE_Completion", "TitB_Final_GigaChad"); + else + setDvar("EE_Completion", "TitB_Final"); + for (i = 0; i < 5; i++) + { + self playsound("zmb_cha_ching"); + wait 0.5; + } + foreach(player in level.players) + { + player thread FinalMsg(); + } +} + +show_avogadro() +{ + i = 0; + level endon ("game_ended"); + for (;;) + { + wait 80; + if (level.avogadro.health <= 1 || level.avogadro.hit_by_melee >= 4) + break; + level.avogadro show(); + new_origin = (13773.5, -530.393, -188.875); + level.avogadro maps\mp\zombies\_zm_ai_avogadro::avogadro_teleport( new_origin, (0, 0, 0), 1 ); + } +} +FinalMsg() +{ + level endon ("game_ended"); + + txt = ""; + index = 0; + foreach(player in level.players) + { + txt += player getguid() + "-" + player.kills; + index++; + if (index < level.players.size) + txt += ";"; + } + if (level.gamemode_difficulty == "^6GigaChad^7") + setdvar("gamemode_speedrun_quest_titb", ((GetTime() - level.start_time) / 1000 / 60) + ";" + txt); + iprintln("^3Gamemode completed^7 in : ^2" + ((GetTime() - level.start_time) / 1000 / 60) + "^7 minutes !"); + + self.zombieTextX = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 4 ); + self.zombieTextX maps\mp\gametypes_zm\_hud_util::setPoint( "CENTER", "CENTER", 0, -160 ); + self.zombieTextX.label = &"^5CONGRATULATIONS !"; + self.zombieTextX.alpha = 0.8; + for (i = 0; i < 10; i++) + { + wait 1; + if (level.gamemode_difficulty == "^1Chad^7") + self.zombieTextX.label = &"^2CONGRATULATIONS !"; + else if (level.gamemode_difficulty == "^6GigaChad^7") + self.zombieTextX.label = &"^6POGGERS !"; + else + self.zombieTextX.label = &"^3CONGRATULATIONS !"; + wait 1; + if (level.gamemode_difficulty == "^1Chad^7") + self.zombieTextX.label = &"^4CONGRATULATIONS !"; + else if (level.gamemode_difficulty == "^6GigaChad^7") + self.zombieTextX.label = &"^5POGGERS !"; + else + self.zombieTextX.label = &"^5CONGRATULATIONS !"; + } + executeCommand("fast_restart"); +} + +avogadro_electric_field() +{ + level endon ("game_ended"); + max_dist = 170; + for (;;) + { + if (level.avogadro.health <= 1 || level.avogadro.hit_by_melee >= 4) + break; + foreach(player in level.players) + { + if (player.sessionstate != "spectator" && !(player maps\mp\zombies\_zm_laststand::player_is_in_laststand())) + { + if (isdefined (level.boss_phase) && level.boss_phase == 1) + max_dist = 170; + else if (isdefined (level.boss_phase) && level.boss_phase == 2) + max_dist = 185; + else if (isdefined (level.boss_phase) && level.boss_phase == 3) + max_dist = 200; + if (distance(player.origin, level.avogadro.origin) < max_dist) + { + maps\mp\_visionset_mgr::vsmgr_activate( "overlay", "zm_ai_avogadro_electrified", player, 1, 1 ); + player shellshock( "electrocution", 1 ); + player playsoundtoplayer( "zmb_avogadro_electrified", player ); + player dodamage( 30, player.origin ); + } + else if (distance(player.origin, level.avogadro.origin) < 90) + { + maps\mp\_visionset_mgr::vsmgr_activate( "overlay", "zm_ai_avogadro_electrified", player, 1, 1 ); + player shellshock( "electrocution", 1 ); + player playsoundtoplayer( "zmb_avogadro_electrified", player ); + player dodamage( 100, player.origin ); + } + } + } + wait 0.5; + } +} + +zombie_watcher() +{ + self endon("level_ended"); + zm_spawner1 = (13343, -63, -196); + zm_spawner2 = (13297, -391, -204); + zm_spawner3 = (12590, -638, -137); + zm_spawner4 = (13243, -817, -215); + for (;;) + { + zombies = getaispeciesarray( "axis", "all" ); + foreach ( enemy in zombies ) + { + enemy set_zombie_run_cycle( "super_sprint" ); + if (!isdefined(enemy.is_avogadro)) + { + if (distance(enemy.origin, zm_spawner1) < 100 || distance(enemy.origin, zm_spawner2) < 100 + || distance(enemy.origin, zm_spawner3) < 500 || distance(enemy.origin, zm_spawner4) < 100) + enemy dodamage( enemy.health + 666, enemy.origin ); + } + + } + wait 2; + } +} + +automatondamagecallback_custom() +{ + self setcandamage( 1 ); + self.health = 100000; + triggers = getentarray( "bus_door_trigger", "targetname" ); + + while ( true ) + { + self waittill( "damage", amount, attacker, directionvec, point, type ); + + self.health = 100000; + wait 1; + + if ( isdefined( self.disabled_by_emp ) && self.disabled_by_emp || isdefined( self.isspeaking ) && self.isspeaking || isdefined( level.playerattackingautomaton ) && level.playerattackingautomaton ) + continue; + + self say_player_attack_vox(); + + if ( level.timesplayerattackingautomaton < 3 ) + continue; + + level.timesplayerattackingautomaton = 0; + + if ( isdefined( attacker ) && isplayer( attacker ) ) + { + wait 5; + + if ( !isdefined( self.dmgfxorigin ) ) + { + self.dmgfxorigin = spawn( "script_model", point ); + self.dmgfxorigin setmodel( "tag_origin" ); + + if ( isdefined( type ) && type == "MOD_GRENADE_SPLASH" ) + self.dmgfxorigin.origin = self gettagorigin( "tag_origin" ) + vectorscale( ( 0, 0, 1 ), 40.0 ); + + self.dmgfxorigin linkto( self, "J_neck" ); + } + + wait 0.5; + playfxontag( level._effect["switch_sparks"], self.dmgfxorigin, "tag_origin" ); + + foreach ( trigger in triggers ) + trigger setinvisibletoall(); + + level.the_bus.force_lock_doors = 1; + + if ( randomint( 100 ) > 50 ) + { + + level thread automatonspeak( "inform", "player_pissed", undefined, 0 ); + } + else + level thread automatonspeak( "inform", "player_pissed", undefined, 1 ); + + if ( level.the_bus.doorsclosed ) + { + triggers[0] playsound( "zmb_bus_door_open" ); + level.the_bus maps\mp\zm_transit_bus::busdoorsopen(); + wait 1.25; + if (getdvar("net_port") != "30011") + shove_players_off_bus(); + wait 3; + triggers[0] playsound( "zmb_bus_door_close" ); + level.the_bus maps\mp\zm_transit_bus::busdoorsclose(); + if (isdefined(level.gamemode_difficulty) && level.gamemode_difficulty == "^6GigaChad^7") + { + foreach(player in level.players) + player.difficulty_hud settext(level.gamemode_difficulty + "\nDoors : ^1LOCKED"); + iprintln("Doors ^1LOCKED^7 for 30 seconds !"); + iprintln("Doors ^1LOCKED^7 for 30 seconds !"); + iprintln("Doors ^1LOCKED^7 for 30 seconds !"); + } + } + else + { + if (getdvar("net_port") != "30011") + shove_players_off_bus(); + wait 3; + triggers[0] playsound( "zmb_bus_door_close" ); + level.the_bus maps\mp\zm_transit_bus::busdoorsclose(); + if (isdefined(level.gamemode_difficulty) && level.gamemode_difficulty == "^6GigaChad^7") + { + foreach(player in level.players) + player.difficulty_hud settext(level.gamemode_difficulty + "\nDoors : ^2UNLOCKED"); + iprintln("Doors ^1LOCKED^7 for 30 seconds !"); + iprintln("Doors ^1LOCKED^7 for 30 seconds !"); + iprintln("Doors ^1LOCKED^7 for 30 seconds !"); + } + } + + wait 3.5; + level thread automatonspeak( "inform", "player_pissed", undefined, 2 ); + wait 10; + if (isdefined(level.gamemode_difficulty) && level.gamemode_difficulty == "^6GigaChad^7") + { + wait 17; + foreach(player in level.players) + player.difficulty_hud settext(level.gamemode_difficulty + "\nDoors : ^2UNLOCKED"); + iprintln("Doors ^2UNLOCKED"); + iprintln("Doors ^2UNLOCKED"); + iprintln("Doors ^2UNLOCKED"); + } + foreach ( trigger in triggers ) + trigger setvisibletoall(); + + level.the_bus.force_lock_doors = 0; + } + + if ( isdefined( self.dmgfxorigin ) ) + { + self.dmgfxorigin unlink(); + self.dmgfxorigin delete(); + self.dmgfxorigin = undefined; + } + } +} + +zmbvoxgetlinevariant_custom( prefix, alias_suffix, force_variant, override ) +{ + return; +} + +initializematchstats_custom() +{ + return; +} + +generateInvisibleBoxCollision(pos, angles) +{ + flag_wait("initial_blackscreen_passed" ); + generateInvisiblePerk( pos + (0, 0, 0), angles); + generateInvisiblePerk( pos + (0, -30, 0), angles); + generateInvisiblePerk( pos + (0, 30, 0), angles); +} + +generateInvisiblePerk(pos, angles) +{ + iWall = spawn( "script_model", pos ); + iWall setmodel( "zm_collision_perks1" ); + iWall.angles = angles; + + /*col = spawn( "script_model", pos); + col setmodel( "zombie_vending_jugg_on" ); + col.angles = angles;*/ +} + +check_for_titb_port() +{ + found = 0; + foreach(port in level.net_port_titb) + { + if (getdvar("net_port") == port) + found = 1; + } + if (found == 0) + return false; + return true; +} \ No newline at end of file diff --git a/t6/scripts/zm/zm_transit/zm_no_explosion.gsc b/t6/scripts/zm/zm_transit/zm_no_explosion.gsc new file mode 100644 index 0000000..a74c46c --- /dev/null +++ b/t6/scripts/zm/zm_transit/zm_no_explosion.gsc @@ -0,0 +1,50 @@ +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\_visionset_mgr; +#include maps\mp\animscripts\zm_death; + +main() +{ + replaceFunc(maps\mp\zm_transit_lava::zombie_exploding_death, ::zombie_exploding_death_custom); +} + +init() +{ + +} + +zombie_exploding_death_custom( zombie_dmg, trap ) +{ + self endon( "stop_flame_damage" ); + + if ( isdefined( self.isdog ) && self.isdog && isdefined( self.a.nodeath ) ) + return; + + while ( isdefined( self ) && self.health >= zombie_dmg && ( isdefined( self.is_on_fire ) && self.is_on_fire ) ) + wait 0.5; + + if ( !isdefined( self ) || !( isdefined( self.is_on_fire ) && self.is_on_fire ) || isdefined( self.damageweapon ) && ( self.damageweapon == "tazer_knuckles_zm" || self.damageweapon == "jetgun_zm" ) || isdefined( self.knuckles_extinguish_flames ) && self.knuckles_extinguish_flames ) + return; + + tag = "J_SpineLower"; + + if ( isdefined( self.animname ) && self.animname == "zombie_dog" ) + tag = "tag_origin"; + + if ( is_mature() ) + { + if ( isdefined( level._effect["zomb_gib"] ) ) + playfx( level._effect["zomb_gib"], self gettagorigin( tag ) ); + } + else if ( isdefined( level._effect["spawn_cloud"] ) ) + playfx( level._effect["spawn_cloud"], self gettagorigin( tag ) ); + + // self radiusdamage( self.origin, 128, 30, 15, undefined, "MOD_EXPLOSIVE" ); + self ghost(); + + if ( isdefined( self.isdog ) && self.isdog ) + self hide(); + else + self delay_thread( 1, ::self_delete ); +} \ No newline at end of file diff --git a/t6/scripts/zmafk.gsc b/t6/scripts/zmafk.gsc new file mode 100644 index 0000000..e1202e0 --- /dev/null +++ b/t6/scripts/zmafk.gsc @@ -0,0 +1,609 @@ +/* + MustBeAFK + A T6 Zombies AFK System by MustBeLeaving + You can find this script at https://github.com/garryspins/mustbeafk + + Requires: + t6-gsc-utils (https://github.com/fedddddd/t6-gsc-utils) + + DVars: + mafk_name [str = "[^6MAfk^7]"]- What text should be shown before chat messages? + mafk_prefix [str = ".afk"] - What should the prefix be for the chat commands? + + mafk_burps [bool = 1] - Should the player burp when the afk timer is up? + mafk_hud [bool = 1] - Should the message saying youre afk be shown on screen? + + mafk_user_times [bool = 0] - Should the user be able to specify a time to go afk for? + mafk_max_time [float = 15] - If user_times, what should the max time allowed be in minutes? + mafk_def_time [float = 15] - If user_times, what should the default time be if none is specified? + + mafk_time [float = 15] - If not user_times, what should the afk time be? if 0 then time is infinite. + + mafk_max_end [bool = 0] - End the game if everyone is either down or afk? + + mafk_cooldown [float = 15] - How many minutes should you have to wait before using afk again. +*/ + +#include maps\mp\_utility; +#include maps\mp\gametypes_zm\_hud_util; + +#include common_scripts\utility; +#include maps\mp\_demo; +#include maps\mp\_visionset_mgr; +#include maps\mp\gametypes_zm\_weapons; +#include maps\mp\gametypes_zm\_zm_gametype; +#include maps\mp\zombies\_zm; +#include maps\mp\zombies\_zm_ai_basic; +#include maps\mp\zombies\_zm_ai_dogs; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_audio_announcer; +#include maps\mp\zombies\_zm_blockers; +#include maps\mp\zombies\_zm_bot; +#include maps\mp\zombies\_zm_buildables; +#include maps\mp\zombies\_zm_clone; +#include maps\mp\zombies\_zm_devgui; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm_ffotd; +#include maps\mp\zombies\_zm_game_module; +#include maps\mp\zombies\_zm_gump; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\zombies\_zm_magicbox; +#include maps\mp\zombies\_zm_melee_weapon; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm_pers_upgrades; +#include maps\mp\zombies\_zm_pers_upgrades_system; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\zombies\_zm_playerhealth; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\zombies\_zm_power; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_sidequests; +#include maps\mp\zombies\_zm_spawner; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zombies\_zm_timer; +#include maps\mp\zombies\_zm_tombstone; +#include maps\mp\zombies\_zm_traps; +#include maps\mp\zombies\_zm_unitrigger; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_zonemgr; + +// you know +init() { + if (check_for_raid_port() == true) + return; + level.mafk_name = getDvarStringDefault("mafk_name", "[^6MAfk^7]"); + level.mafk_prefix = getDvarStringDefault("mafk_prefix", ".afk" ); + + level.mafk_burps = getDvarIntDefault("mafk_burps", 1) == 1; + level.mafk_hud = getDvarIntDefault("mafk_hud", 1) == 0; + + level.mafk_user_times = getDvarIntDefault("mafk_user_times", 0) == 1; + level.mafk_max_time = getDvarFloatDefault("mafk_max_time", 15); + level.mafk_def_time = getDvarFloatDefault("mafk_def_time", 15); + + level.mafk_time = getDvarFloatDefault("mafk_time", 15); + level.mafk_infinite = level.mafk_time == 0; + + level.mafk_max_end = getDVarIntDefault("mafk_max_end", 0) == 1; + + level.mafk_cooldown = (getDvarFloatDefault("mafk_cooldown", 15) * 60) * 1000; + + onPlayerSay(::hook_chat); + + /* if (level.mafk_max_end) { + level thread watchAllDownOrAFK(); + }*/ + + if (level.mafk_cooldown != 0) { + level thread watchCooldown(); + } +} + +// a default string dvar getter +// since this doesnt exist anywhere in the std +getDvarStringDefault(dvar, def) { + value = GetDVar(dvar); + + if (value != "") { + return value; + } + + return def; +} + +// trims the whitespace around a string +// only really used once but still +strtrim(str) { + padl = 0; + padr = 0; + for (i = 0; i < str.size; i++) { + if (str[i] == " ") { + padl = i; + } else { + break; + } + } + + for (i = 0; i < str.size; i++) { + if (str[str.size - i] == " ") { + padr = i; + } else { + break; + } + } + + return getSubStr(str, padl, str.size - padr); +} + +// this is manual modulo +// you dont have to tell me how stupid this is, i know! +// modulo is just refusing to work properly in some places +// and i have absolutely no idea why +// so have fun with this! +mod(num, modby) { + while (num >= modby) { + num = num - modby; + } + + return num; +} + +// floor function since it doesnt exist for some reason! +// modulo works here? +floor(num) { + return num - (num % 1); +} + +// formats a time from ms into a pretty string +// this can be improved obviously +fmttime(ms) { + ms = floor(ms); + seconds = mod(floor(ms / 1000), 60); + minutes = mod(floor((ms / 1000) / 60), 60); + hours = floor(floor((ms / 1000) / 60) / 60); + + if (hours) { + text = hours + " hour"; + + if (hours > 1) { + text = text + "s"; + } + + if (minutes) { + text = text + " and " + minutes + " minute"; + + if (minutes > 1) { + text = text + "s"; + } + } + + return text; + } + + if (minutes > 0) { + text = minutes + " minute"; + + if (minutes > 1) { + text = text + "s"; + } + + if (seconds) { + text = text + " and " + seconds + " second"; + + if (seconds > 1) { + text = text + "s"; + } + } + + return text; + } + + if (seconds > 1) { + return seconds + " seconds"; + } + + if (seconds == 1) { + return seconds + " second"; + } + + return "no time"; +} + +// watch for if every player is either down or afk +// if they are then end the game +watchAllDownOrAFK() { + level endon("game_ended"); + for(;;) { + players = getplayers(); + count = 0; + afk = 0; + + foreach(ply in players) { + if (!isAlive(ply)) { + count++; + } else if (ply.afk) { + count++; + afk++; + } + } + + if ((count == players.size) && (afk != 0)) { + level notify("end_game"); + } + + wait 5; + } +} + +// set the players cooldown +// this is separate from set_afk because +// we like to be a little efficient around these parts +watchCooldown() { + + for (;;) { + level endon("game_ended"); + self waittill("mafk_set", ply, val); + + if (val == false) { + ply.mafk_cooldown = getTime() + self.mafk_cooldown; + } + } +} + +// burps! but only if we want burps +burp() { + if (level.mafk_burps) { + self maps\mp\zombies\_zm_audio::playerexert("burp"); + } +} + +// sets the player to be afk or not, accepts a boolean +// this doesnt do anything except set some values on the player +// if you wish to extend anything use the notification +set_afk(value) { + self.afk = value; + self.afk_notify_half = false; + + if (value) + { + /* primaries = self getweaponslistprimaries(); + + if (primaries.size >= 1) + { + weapon1 = primaries[0]; + self.saved_weapon1 = maps/mp/zombies/_zm_weapons::get_player_weapondata(self, weapon1); + self Takeweapon(weapon1); + } + if (primaries.size >= 2) + { + weapon2 = primaries[1]; + self.saved_weapon2 = maps/mp/zombies/_zm_weapons::get_player_weapondata(self, weapon2); + self Takeweapon(weapon2); + } + if (primaries.size >= 3) + { + weapon3 = primaries[2]; + self.saved_weapon3 = maps/mp/zombies/_zm_weapons::get_player_weapondata(self, weapon3); + self Takeweapon(weapon3); + } + self setmovespeedscale(0); + self AllowMelee(0); + self AllowJump(0);*/ + self iPrintLn("Going ^3AFK^7 in ^23^7 seconds"); + wait 3; + iprintln(self.name + " ^7 is now ^3AFK^7"); + self thread keepPlayerFrozen(); + if (value == 1) + self thread perma_ignore(); + self.ignoreme = value; + + self enableInvulnerability(); + self setplayercollision( 0 ); + } + else + { + /*if (primaries.size >= 1) + self maps/mp/zombies/_zm_weapons::weapondata_give(self.saved_weapon1); + if (primaries.size >= 2) + self maps/mp/zombies/_zm_weapons::weapondata_give(self.saved_weapon2); + if (primaries.size >= 3) + self maps/mp/zombies/_zm_weapons::weapondata_give(self.saved_weapon3); + self setmovespeedscale(1); + self AllowMelee(1); + self AllowJump(1); + + + weapon1 destroy(); + weapon2 destroy(); + weapon3 destroy(); + primaries destroy();*/ + iprintln(self.name + " ^7is no longer ^3AFK^7"); + self notify("afk_end"); + self freezeControls(value); + self.ignoreme = value; + wait 3; + self disableInvulnerability(); + self setplayercollision( 1 ); + self notify("afkcancel"); + } + + level notify("mafk_set", self, value); +} + + +perma_ignore() +{ + self endon("afk_end"); + self endon("disconnected"); + + for (;;) + { + self.ignoreme = 1; + wait 0.5; + } +} +// this is the actual logic behind the chat command +// just a series of checks +quick_afk_on(time) { + // is the player down + if (self.sessionstate == "spectator" || !isAlive(self)) { + self tell(level.mafk_name + " You must be alive to go AFK."); + return false; + } + + if (isDefined(self.mafk_cooldown)) { + if (self.mafk_cooldown >= getTime()) { + self tell(level.mafk_name + " You must wait ^4" + fmttime(self.mafk_cooldown - getTime()) + "^7 before going afk again."); + return false; + } + + self.mafk_cooldown = undefined; + } + + if (self.afk) { + if (isDefined(self.mafk_endtime)) { + self tell(level.mafk_name + " You are already AFK, if you would like to go un-afk type ^2.afk off"); + self tell(level.mafk_name + " You have ^4" + fmttime(self.mafk_endtime - getTime()) + "^7 left"); + } else { + self tell(level.mafk_name + " You have as long as you want to be afk."); + } + return false; + } + + if (level.mafk_infinite && !level.mafk_user_times) { + say(level.mafk_name + " " + self.name + " is going AFK in 3 seconds"); + wait 3; + say(level.mafk_name + " " + self.name + " has gone AFK."); + self set_afk(true); + + return false; + } + + say(level.mafk_name + " " + self.name + " has gone AFK for ^4" + fmttime((time * 60) * 1000)); + self tell(level.mafk_name + " You have gone AFK, if you would like to go un-afk type ^2.afk off"); + endtime = getTime() + ((time * 60) * 1000); + + self set_afk(true); + + self.mafk_endtime = endtime; + self thread check_afk_player(endtime); + + /* if (level.mafk_hud) { + self thread afk_player_hud(endtime, (time * 60) * 1000); + }*/ + + self burp(); + + return false; +} + +// what actually hooks onto chat +hook_chat(text, mode) { + level endon( "game_ended" ); + flag_wait( "initial_blackscreen_passed" ); + + if (check_for_botb_port() == true) + return; + for (;;) + { + if (getDvar("isPanzer") == "1") + { + return; + } + else if (getDvar("isPanzer") == "0") + { + break; + } + wait 0.5; + } + for (;;) + { + if (getDvar("isBus") == "1") + { + return; + } + else if (getDvar("isBus") == "0") + { + break; + } + wait 0.5; + } + if (isdefined(level.is_first_room)) + return; + text = strtrim(toLower(text)); + + split = strTok(text, " "); + + if (split[0] != level.mafk_prefix) { + return true; + } + + if ((split[1] == undefined) || (split[1] == "on")) { + if (level.mafk_user_times) { + return self quick_afk_on(level.mafk_def_time); + } else { + return self quick_afk_on(level.mafk_time); + } + return false; + } + + if (level.mafk_user_times) { + switch (split[1]) { + case "off": + self tell(level.mafk_name + " You're back!"); + self set_afk(false); + self notify("afkcancel"); + break; + case "time": + case "left": + if (self.afk) { + self tell(level.mafk_name + " You have ^4" + fmttime(self.mafk_endtime - getTime()) + "^7 left"); + } else { + self tell(level.mafk_name + " You are not afk."); + } + + break; + case "help": + self tell(level.mafk_name + " ^2" + level.mafk_prefix + " [number]^7 - Turns on afk for the given amount of time (^2" + mintime + "^7 to ^2" + level.mafk_max_time + "^7 minutes)"); + self tell(level.mafk_name + " ^2" + level.mafk_prefix + " off^7 - Turns off afk"); + self tell(level.mafk_name + " ^2" + level.mafk_prefix + " help^7 - Shows this message"); + self tell(level.mafk_name + " ^2" + level.mafk_prefix + " time^7 - Shows how long youre allowed to be afk"); + + break; + default: + mintime = 1; + time = int(split[1]); + + if ((time < mintime) || (time > level.mafk_max_time)) { + self tell(level.mafk_name + " Please give a valid time from ^2" + mintime + "^7 to ^2" + level.mafk_max_time + "^7 minutes"); + return false; + } + + return self quick_afk_on(time); + } + + return false; + } + + switch (split[1]) { + case "off": + self tell(level.mafk_name + " You're back!"); + self set_afk(false); + self notify("afkcancel"); + break; + case "time": + case "left": + if (self.afk) { + self tell(level.mafk_name + " You have ^4" + fmttime(self.mafk_endtime - getTime()) + "^7 left"); + } else { + self tell(level.mafk_name + " You are not afk."); + } + break; + case "help": + default: + self tell(level.mafk_name + " ^2" + level.mafk_prefix + " on^7 - Turns on afk"); + self tell(level.mafk_name + " ^2" + level.mafk_prefix + " off^7 - Turns off afk"); + self tell(level.mafk_name + " ^2" + level.mafk_prefix + " help^7 - Shows this message"); + self tell(level.mafk_name + " ^2" + level.mafk_prefix + " time^7 - Shows how much longer you can be afk"); + } + return false; +} + +// runs on the player to check if he should still be afk or not +check_afk_player(endtime) { + self endon("disconnect"); + self endon("afkcancel"); + level endon("game_ended"); + wait 1020; + self set_afk(false); + self tell(level.mafk_name + " Your AFK time has expired!"); + self burp(); + self.mafk_endtime = undefined; +} + +keepPlayerFrozen() +{ + self endon("disconnect"); + self endon("afkcancel"); + level endon ("game_ended"); + for (;;) + { + + if (self.afk == true) + { + self FreezeControls(1); + self.ignoreme = true; + self enableInvulnerability(); + self setplayercollision( 0 ); + } + else + { + self FreezeControls(0); + return; + } + wait 1; + } +} + +check_for_botb_port() +{ + found = 0; + if (isdefined(level.net_port_botb)) + { + foreach(port in level.net_port_botb) + { + if (getdvar("net_port") == port) + found = 1; + } + } + if (found == 0) + return false; + return true; +} + +check_for_raid_port() +{ + found = 0; + if (isdefined(level.net_port_raid)) + { + foreach(port in level.net_port_raid) + { + if (getdvar("net_port") == port) + found = 1; + } + } + if (found == 0) + return false; + return true; +} + +/* +// only runs if mafk_hud is 1 +// draws the hud! +afk_player_hud(endtime, time) { + if (isDefined(self.mafk_hud)) { + return; + } + + level endon("game_ended"); + self endon("disconnect"); + + self.mafk_hud = createServerFontString("objective", 2); + self.mafk_hud setPoint("CENTER", "TOP", 0, 0); + self.mafk_hud setText("You are currently afk"); + + self.mafk_hud.hideWhenInMenu = 1; + + for(;;) { + if ((getTime() >= endtime) || !self.afk) { + self.mafk_hud destroy(); + break; + } + + // logic to make it slowly fade + self.mafk_hud.alpha = ((endtime - getTime()) / time) + 0.75; + + wait 0.50; + } +}*/ \ No newline at end of file diff --git a/t6/scripts/zmcounterhealthwatermark.gsc b/t6/scripts/zmcounterhealthwatermark.gsc new file mode 100644 index 0000000..5881b8d --- /dev/null +++ b/t6/scripts/zmcounterhealthwatermark.gsc @@ -0,0 +1,305 @@ +#include scripts\zm\AATs_Perks; + +init() +{ + setDvar("hide", ""); + setdvar("isPanzer", ""); + + level thread hideHUD(); +} + +onPlayerConnect(player) +{ + player thread healthCounter(); + player thread zombieCounter(); + player thread discordWatermark(); + player thread init_flashing_link(); +} + +drawshader( shader, x, y, width, height, color, alpha) +{ + level endon("end_game"); + self endon("disconnect"); + hud = newclienthudelem( self ); + hud.elemtype = "icon"; + hud.color = color; + hud.alpha = alpha; + hud.sort = 0; + hud.children = []; + hud.hidewheninmenu = 1; + hud setparent(level.uiparent); + hud setshader( shader, width, height ); + hud.x = x; + hud.y = y; + hud.foreground = 0; + return hud; +} + +hideHUD() +{ + common_scripts\utility::flag_wait( "initial_blackscreen_passed" ); + level endon("game_ended"); + + for (;;) { + if (getDvar("hide") != "") + { + hide = strTok(getDvar("hide"), ";"); + setDvar("hide", ""); + client = getPlayerByGuid(hide[0]); + if (hide[1] == "off") + { + client.zombieText0.alpha = 0.5; + client.zombieText1.alpha = 0; + client.zombieText2.alpha = 0; + client.zombieText3.alpha = 0; + client.zombieTextE.alpha = 0; + client iPrintLn("^3HUD ^1OFF^7"); + } + if (hide[1] == "on") + { + client.zombieText0.alpha = 0; + client.zombieText1.alpha = 0.7; + client.zombieText2.alpha = 0.7; + client.zombieText3.alpha = 0.7; + client.zombieTextE.alpha = 0.7; + client iPrintLn("^3HUD ^2ON^7"); + } + } + wait 0.5; + } +} + +healthCounter() +{ + self endon("disconnect"); + level endon( "end_game" ); + common_scripts\utility::flag_wait( "initial_blackscreen_passed" ); + self.healthText = maps\mp\gametypes_zm\_hud_util::createFontString ("hudsmall", 1.5); + self.healthText maps\mp\gametypes_zm\_hud_util::setPoint ("CENTER", "CENTER", 100, 220); + self.healthText.label = &"Health: ^2"; + while ( 1 ) + { + self.healthText setValue(self.health); + wait 0.25; + } +} + +zombieCounter() +{ + self endon( "disconnect" ); + level endon( "end_game" ); + common_scripts\utility::flag_wait( "initial_blackscreen_passed" ); + if (check_for_raid_port() == true) + return; + if (check_for_botb_port() == true) + return; + for (;;) + { + if (getDvar("isPanzer") == "1") + { + return; + } + else if (getDvar("isPanzer") == "0") + { + break; + } + wait 0.5; + } + + self.zombieText = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1.5 ); + self.zombieText maps\mp\gametypes_zm\_hud_util::setPoint( "CENTER", "CENTER", -100, 220 ); + while( 1 ) + { + self.zombieText setValue( ( maps\mp\zombies\_zm_utility::get_round_enemy_array().size + level.zombie_total ) ); + if( ( maps\mp\zombies\_zm_utility::get_round_enemy_array().size + level.zombie_total ) != 0 ) + { + self.zombieText.label = &"Zombies: ^1"; + } + else + { + self.zombieText.label = &"Zombies: ^6"; + } + wait 0.25; + } +} + +discordWatermark() +{ + self endon( "disconnect" ); + level endon( "end_game" ); + + flag_wait( "initial_blackscreen_passed" ); + if (check_for_raid_port() == true) + return; + for (;;) + { + if (getDvar("isPanzer") == "1") + { + return; + } + else if (getDvar("isPanzer") == "0") + { + break; + } + wait 0.5; + } + if (check_for_botb_port() == true) + return; + for (;;) + { + if (getDvar("isBus") == "1") + { + return; + } + else if (getDvar("isBus") == "0") + { + break; + } + wait 0.5; + } + wait 0.1; + self.zombieText0 = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1.5 ); + self.zombieText0 maps\mp\gametypes_zm\_hud_util::setPoint( "TOP", "RIGHT", -30, -215 ); + self.zombieText0.label = &"Z-Tavern"; + self.zombieText0.alpha = 0; + + self.zombieText1 = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1.5 ); + self.zombieText1 maps\mp\gametypes_zm\_hud_util::setPoint( "TOP", "LEFT", 0, -240 ); + self.zombieText1.label = &""; + self.zombieText1 setText("Join the ^1Tavern^7\n- Get ^5200K POINTS^7\n- Earn ^3Titles^7\n- Make new ^2friends^7\n ^1discord.gg/ZTavern^7"); + self.zombieText1.alpha = 0.7; + + + for (;;) + { + if (getDvar("isPanzer") == "1") + { + return; + } + else if (getDvar("isPanzer") == "0") + { + break; + } + wait 0.5; + } + if (check_for_botb_port() == true) + return; + self.zombieText2 = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1 ); + self.zombieText2 maps\mp\gametypes_zm\_hud_util::setPoint( "TOP", "RIGHT", 0, -215 ); + self.zombieText2 setText( + "^6----------[BANK]----------\n^6 [^7.d^6] [^7.w^6] [^7.pay^6] [^7.money^6]\n" + + "^3-----[^3RANK & STATS]-----\n^3 [^7.rank^3] [^7.rankup^3]\n^3[^7.buy^3] [^7.buy (hp | speed)^3]\n" + + "^5------[SAVE & LOAD]------\n^5[^7.save^5] [^7.load^5] [^7.ss^5] [^7.trade^5]"); + self.zombieText2.alpha = 0.7; + + self.zombieText3 = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1 ); + self.zombieText3 maps\mp\gametypes_zm\_hud_util::setPoint( "TOP", "RIGHT", 0, -130 ); + self.zombieText3 setText( + "^2-----------[MISC.]----------\n^2[^7.afk^2] [^7.top^2] [^7.flex^2] [^7.hud^2] [^7.gc^2]\n ^2[^7.kill^2] [^7.c^2] [^7.c fr^2][^7.firstroom^2]\n" + + "^1----[VIP & High Ranks^1]----\n^1 [^3.vip^1][^3.rev^1] [^3.drop^1] [^3.king^1]\n [^3.maxammo^1][^3.upgrade^1]"); + self.zombieText3.alpha = 0.7; + + /*self.zombieTextE = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1 ); + self.zombieTextE maps\mp\gametypes_zm\_hud_util::setPoint( "TOP", "RIGHT", 0, -50 ); + self.zombieTextE setText("^3 EVENT : ^2x3 points\n^5+30 percent Z-Coins"); + self.zombieTextE.alpha = 0.7;*/ +} + +init_flashing_link() +{ + self endon("disconnect"); + self endon("game_ended"); + flag_wait("initial_blackscreen_passed"); + + for (;;) + { + if (getDvar("isPanzer") == "1") + { + return; + } + else if (getDvar("isPanzer") == "0") + { + break; + } + wait 0.5; + } + if (check_for_botb_port() == true) + return; + for (;;) + { + if (getDvar("isBus") == "1") + { + return; + } + else if (getDvar("isBus") == "0") + { + break; + } + wait 0.5; + } + for (;;) + { + foreach(player in level.players) + { + player thread set_text(player.zombieText1, "^4"); + wait 60; + player thread set_text(player.zombieText1, "^5"); + wait 60; + player thread set_text(player.zombieText1, "^2"); + wait 60; + player thread set_text(player.zombieText1, "^3"); + wait 60; + player thread set_text(player.zombieText1, "^6"); + wait 60; + player thread set_text(player.zombieText1, "^1"); + wait 60; + } + wait 0.1; + } +} + +set_text(s_text, color) +{ + self endon("disconnect"); + level endon("game_ended"); + + s_text setText("Join the ^1Tavern^7\n- Get ^2$200K POINTS^7\n- Earn ^3Titles^7\n- Trade your ^5Saves^7\n\n" + color + "discord.gg/ZTavern^7"); +} + +getPlayerByGuid(guid) { + for (i = 0; i < level.players.size; i++) { + if (isAlive(level.players[i]) && int(level.players[i] getGuid()) == int(guid)) { + return level.players[i]; + } + } + return false; +} + +check_for_botb_port() +{ + found = 0; + foreach(port in level.net_port_botb) + { + if (getdvar("net_port") == port) + found = 1; + } + if (found == 0) + return false; + return true; +} + +check_for_raid_port() +{ + found = 0; + if (isdefined(level.net_port_raid)) + { + foreach(port in level.net_port_raid) + { + if (getdvar("net_port") == port) + found = 1; + } + } + if (found == 0) + return false; + return true; +} \ No newline at end of file diff --git a/t6/uncompiled mods/8playerhud-compiled.gsc b/t6/uncompiled mods/8playerhud-compiled.gsc new file mode 100644 index 0000000000000000000000000000000000000000..b75ccbacc73191b5da38bbb8928b2841dc1c2256 GIT binary patch literal 1224 zcmb`GPe>F|9LK+JcNKQcG{`~>*Ns{hYV!}_maA?gtA=8smUVF%cc1IV?CiEPD=Hm? zBtoP^hYk|bA;LqTfm8>P=nzYo2kFqw&|6>!4?+j2@62u)LY*4;%xAiK^UGnQzmQgyahVy(#*kFfdTlaY8&{Ij z7*9(*GLfu}a3+$Jx~|0KKUQRogo>1w-z=KaG#NEy4EriSgIGd0l^#uHB#cx%uFAZ& z-i91A5Y0%%ki#j>(2Yz&i{t9hZSIyBmC&V;P9-!0ZQ-8&a4&kVbaeJZRfeRB!G=C_ z)25oi02DPnq9D%IR&zS6-4j|?mu3Zpsvxyk#BA2wcT`cc6joisN=&9kWyVNwu8SWj zNsbH5!-YANUq6M@{z{z30*4zzUw;5zcMWogTnwTcekbrYE+ji1y$S@G#aL@G#%*_IQO4URS*+8*rgnlnZTALjTT>wH1IM8@bR$u7qh z>EDpM^i#wsY= 5 && self.scoretext.alpha == 0) + { + self.scoretext.alpha = 1; + if(self.scoreInUse == 0) + self thread displayScore(); + } + else if(getplayers().size < 5 && self.scoretext.alpha == 1) + { + self.scoretext.alpha = 0; + self.scoreInUse = 0; + } +} + +displayScore() +{ + self endon( "disconnect" ); + level endon( "end_game" ); + self.scoreText = CreateFontString("Objective", 1.5); + self.scoretext setPoint("CENTER", "RIGHT", "CENTER", "RIGHT"); + self.scoreText.label = &"^2Score: ^7"; + self.scoretext.alpha = 0; + while(true) + { + self.scoretext SetValue(self.score); + if(getplayers().size >= 5 && self.scoretext.alpha == 0) + { + self.scoretext FadeOverTime( 1 ); + self.scoretext.alpha = 1; + } + else if(getplayers().size < 5 && self.scoretext.alpha >= 0) + { + self.scoretext FadeOverTime( 1 ); + self.scoretext.alpha = 0; + } + wait 0.1; + } +} \ No newline at end of file diff --git a/t6/uncompiled mods/AATs_Perks - Copie.gsc b/t6/uncompiled mods/AATs_Perks - Copie.gsc new file mode 100644 index 0000000..2ac6626 --- /dev/null +++ b/t6/uncompiled mods/AATs_Perks - Copie.gsc @@ -0,0 +1,3145 @@ +#include maps/mp/_utility; +#include common_scripts/utility; +#include maps/mp/gametypes_zm/_hud_util; +#include maps/mp/zombies/_zm_weapons; +#include maps/mp/zombies/_zm_stats; +#include maps/mp/gametypes_zm/_spawnlogic; +#include maps/mp/animscripts/traverse/shared; +#include maps/mp/animscripts/utility; +#include maps/mp/zombies/_load; +#include maps/mp/_createfx; +#include maps/mp/_music; +#include maps/mp/_busing; +#include maps/mp/_script_gen; +#include maps/mp/gametypes_zm/_globallogic_audio; +#include maps/mp/gametypes_zm/_tweakables; +#include maps/mp/_challenges; +#include maps/mp/gametypes_zm/_weapons; +#include maps/mp/_demo; +#include maps/mp/gametypes_zm/_hud_message; +#include maps/mp/gametypes_zm/_spawning; +#include maps/mp/gametypes_zm/_globallogic_utils; +#include maps/mp/gametypes_zm/_spectating; +#include maps/mp/gametypes_zm/_globallogic_spawn; +#include maps/mp/gametypes_zm/_globallogic_ui; +#include maps/mp/gametypes_zm/_hostmigration; +#include maps/mp/gametypes_zm/_globallogic_score; +#include maps/mp/gametypes_zm/_globallogic; +#include maps/mp/zombies/_zm; +#include maps/mp/zombies/_zm_ai_faller; +#include maps/mp/zombies/_zm_spawner; +#include maps/mp/zombies/_zm_pers_upgrades_functions; +#include maps/mp/zombies/_zm_pers_upgrades; +#include maps/mp/zombies/_zm_score; +#include maps/mp/zombies/_zm_powerups; +#include maps/mp/animscripts/zm_run; +#include maps/mp/animscripts/zm_death; +#include maps/mp/zombies/_zm_blockers; +#include maps/mp/animscripts/zm_shared; +#include maps/mp/animscripts/zm_utility; +#include maps/mp/zombies/_zm_ai_basic; +#include maps/mp/zombies/_zm_laststand; +#include maps/mp/zombies/_zm_net; +#include maps/mp/zombies/_zm_audio; +#include maps/mp/gametypes_zm/_zm_gametype; +#include maps/mp/_visionset_mgr; +#include maps/mp/zombies/_zm_equipment; +#include maps/mp/zombies/_zm_power; +#include maps/mp/zombies/_zm_server_throttle; +#include maps/mp/gametypes/_hud_util; +#include maps/mp/zombies/_zm_unitrigger; +#include maps/mp/zombies/_zm_zonemgr; +#include maps/mp/zombies/_zm_perks; +#include maps/mp/zombies/_zm_melee_weapon; +#include maps/mp/zombies/_zm_audio_announcer; +#include maps/mp/zombies/_zm_magicbox; +#include maps/mp/zombies/_zm_utility; +#include maps/mp/zombies/_zm_ai_dogs; +#include maps/mp/gametypes_zm/_hud_message; +#include maps/mp/zombies/_zm_game_module; +#include maps/mp/zombies/_zm_buildables; +#include codescripts/character; +#include maps/mp/zombies/_zm_weap_riotshield; +#include maps/mp/zm_transit_bus; +#include maps/mp/zm_transit_utility; +#include maps/mp/zombies/_zm_equip_turret; +#include maps/mp/zombies/_zm_mgturret; +#include maps\mp\zombies\_zm_weap_jetgun; + +#include maps/mp/zombies/_zm_ai_sloth; +#include maps/mp/zombies/_zm_ai_sloth_ffotd; +#include maps/mp/zombies/_zm_ai_sloth_utility; +#include maps/mp/zombies/_zm_ai_sloth_magicbox; +#include maps/mp/zombies/_zm_ai_sloth_crawler; +#include maps/mp/zombies/_zm_ai_sloth_buildables; + + +#include maps/mp/zombies/_zm_tombstone; +#include maps/mp/zombies/_zm_chugabud; + + + +//customperkinclude +#include maps/mp/_utility; +#include common_scripts/utility; +#include maps/mp/gametypes_zm/_hud_util; +#include maps/mp/zombies/_zm_weapons; +#include maps/mp/zombies/_zm_stats; +#include maps/mp/gametypes_zm/_spawnlogic; +#include maps/mp/animscripts/traverse/shared; +#include maps/mp/animscripts/utility; +#include maps/mp/zombies/_load; +#include maps/mp/_createfx; +#include maps/mp/_music; +#include maps/mp/_busing; +#include maps/mp/_script_gen; +#include maps/mp/gametypes_zm/_globallogic_audio; +#include maps/mp/gametypes_zm/_tweakables; +#include maps/mp/_challenges; +#include maps/mp/gametypes_zm/_weapons; +#include maps/mp/_demo; +#include maps/mp/gametypes_zm/_hud_message; +#include maps/mp/gametypes_zm/_spawning; +#include maps/mp/gametypes_zm/_globallogic_utils; +#include maps/mp/gametypes_zm/_spectating; +#include maps/mp/gametypes_zm/_globallogic_spawn; +#include maps/mp/gametypes_zm/_globallogic_ui; +#include maps/mp/gametypes_zm/_hostmigration; +#include maps/mp/gametypes_zm/_globallogic_score; +#include maps/mp/gametypes_zm/_globallogic; +#include maps/mp/zombies/_zm; +#include maps/mp/zombies/_zm_ai_faller; +#include maps/mp/zombies/_zm_spawner; +#include maps/mp/zombies/_zm_pers_upgrades_functions; +#include maps/mp/zombies/_zm_pers_upgrades; +#include maps/mp/zombies/_zm_score; +#include maps/mp/animscripts/zm_run; +#include maps/mp/animscripts/zm_death; +#include maps/mp/zombies/_zm_blockers; +#include maps/mp/animscripts/zm_shared; +#include maps/mp/animscripts/zm_utility; +#include maps/mp/zombies/_zm_ai_basic; +#include maps/mp/zombies/_zm_laststand; +#include maps/mp/zombies/_zm_net; +#include maps/mp/zombies/_zm_audio; +#include maps/mp/gametypes_zm/_zm_gametype; +#include maps/mp/_visionset_mgr; +#include maps/mp/zombies/_zm_equipment; +#include maps/mp/zombies/_zm_power; +#include maps/mp/zombies/_zm_server_throttle; +#include maps/mp/gametypes/_hud_util; +#include maps/mp/zombies/_zm_unitrigger; +#include maps/mp/zombies/_zm_zonemgr; +#include maps/mp/zombies/_zm_perks; +#include maps/mp/zombies/_zm_melee_weapon; +#include maps/mp/zombies/_zm_audio_announcer; +#include maps/mp/zombies/_zm_magicbox; +#include maps/mp/zombies/_zm_utility; +#include maps/mp/zombies/_zm_ai_dogs; +#include maps/mp/gametypes_zm/_hud_message; +#include maps/mp/zombies/_zm_game_module; +#include maps/mp/zombies/_zm_buildables; +#include codescripts/character; +#include maps/mp/zombies/_zm_weap_riotshield; + +//tomb damage callback +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zm_tomb_utility; +#include maps\mp\zm_tomb_gamemodes; +#include maps\mp\zm_tomb_fx; +#include maps\mp\zm_tomb_ffotd; +#include maps\mp\zm_tomb_tank; +#include maps\mp\zm_tomb_quest_fire; +#include maps\mp\zm_tomb_capture_zones; +#include maps\mp\zm_tomb_teleporter; +#include maps\mp\zm_tomb_giant_robot; +#include maps\mp\zombies\_zm; +#include maps\mp\animscripts\zm_death; +#include maps\mp\zm_tomb_amb; +#include maps\mp\zombies\_zm_ai_mechz; +#include maps\mp\zombies\_zm_ai_quadrotor; +#include maps\mp\zombies\_load; +#include maps\mp\gametypes_zm\_spawning; +#include maps\mp\zm_tomb_vo; +#include maps\mp\zombies\_zm_perk_divetonuke; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm_perk_electric_cherry; +#include maps\mp\zombies\_zm_weap_one_inch_punch; +#include maps\mp\zombies\_zm_weap_staff_fire; +#include maps\mp\zombies\_zm_weap_staff_water; +#include maps\mp\zombies\_zm_weap_staff_lightning; +#include maps\mp\zombies\_zm_weap_staff_air; +#include maps\mp\zm_tomb; +#include maps\mp\zm_tomb_achievement; +#include maps\mp\zm_tomb_distance_tracking; +#include maps\mp\zombies\_zm_magicbox_tomb; +#include maps\mp\zombies\_zm_spawner; +#include maps\mp\zm_tomb_challenges; +#include maps\mp\zombies\_zm_perk_random; +#include maps\mp\_sticky_grenade; +#include maps\mp\zombies\_zm_weap_beacon; +#include maps\mp\zombies\_zm_weap_claymore; +#include maps\mp\zombies\_zm_weap_riotshield_tomb; +#include maps\mp\zombies\_zm_weap_staff_revive; +#include maps\mp\zombies\_zm_weap_cymbal_monkey; +#include maps\mp\zm_tomb_ambient_scripts; +#include maps\mp\zm_tomb_dig; +#include maps\mp\zm_tomb_main_quest; +#include maps\mp\zm_tomb_ee_main; +#include maps\mp\zm_tomb_ee_side; +#include maps\mp\zombies\_zm_zonemgr; +#include maps\mp\zm_tomb_chamber; +#include maps\mp\_visionset_mgr; +#include maps\mp\zombies\_zm_audio; +#include character\c_usa_dempsey_dlc4; +#include character\c_rus_nikolai_dlc4; +#include character\c_ger_richtofen_dlc4; +#include character\c_jap_takeo_dlc4; +#include maps\mp\zombies\_zm_powerup_zombie_blood; +#include maps\mp\zombies\_zm_devgui; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_challenges; +#include maps\mp\zombies\_zm_laststand; + +#include scripts\zm\AATs+Perks-compiled; + +main() +{ + + replaceFunc( maps\mp\animscripts\zm_utility::wait_network_frame, ::wait_network_frame_override ); + replaceFunc( maps\mp\zombies\_zm_utility::wait_network_frame, ::wait_network_frame_override ); + //replaceFunc (maps\mp\zombies\_zm::register_player_damage_callback, ::playerdamagelastcheck ); + //replaceFunc (maps\mp\zm_tomb::tomb_player_damage_callback, ::playerdamagelastcheck2 ); +} + +init() +{ + register_player_damage_callback( ::playerdamagelastcheck ); //moved to main from init because of it not loading in origins + tomb_player_damage_callback( ::playerdamagelastcheck2 ); //moved to main from init because of it not loading in origins +// replaceFunc (maps\mp\zm_tomb::tomb_player_damage_callback, ::playerdamagelastcheck2 );*/ +//-------------------CUSTOMPERK------------------------ + + // if( (getdvar( "mapname" ) == "zm_transit" || getdvar( "mapname" ) == "zm_highrise") && getdvar ( "g_gametype") == "zstandard" ) + // { + precacheshader("menu_mp_lobby_icon_film"); + precacheshader( "menu_mp_lobby_icon_customgamemode" ); + precacheshader( "waypoint_revive" ); + precacheshader( "killiconheadshot" ); + precacheshader( "menu_lobby_icon_twitter" ); + precacheshader( "hud_grenadeicon" ); + precacheshader( "menu_mp_weapons_1911" ); + precacheshader( "menu_mp_lobby_icon_screenshot" ); + precacheshader( "damage_feedback" ); + precacheshader( "zombies_rank_1" ); + precacheshader( "zombies_rank_3" ); + precacheshader( "zombies_rank_2" ); + precacheshader( "zombies_rank_4" ); + precacheshader( "menu_mp_weapons_xm8" ); + precacheshader( "faction_cdc" ); + precacheshader( "menu_mp_weapons_hamr" ); + precacheshader( "zombies_rank_5" ); + precacheshader( "hud_icon_sticky_grenade" ); + precacheshader( "specialty_instakill_zombies" ); + precacheshader( "menu_mp_weapons_1911" ); + precacheshader( "hud_icon_colt" ); + precachemodel("p6_zm_buildable_sq_meteor"); + precachemodel( "collision_player_wall_512x512x10" ); + precachemodel( "collision_physics_512x512x10" ); + precachemodel( "t5_foliage_tree_burnt03" ); + precachemodel( "p_rus_door_roller" ); + precachemodel( "ch_tombstone1" ); + precachemodel( "collision_geo_256x256x10_standard" ); + precachemodel( "zombie_vending_tombstone_on" ); + precachemodel( "zombie_vending_revive_on" ); + precachemodel( "zombie_vending_sleight_on" ); + precachemodel( "zombie_vending_doubletap2_on" ); + precachemodel( "zombie_pickup_perk_bottle" ); + precachemodel( "zm_collision_perks1" ); + precachemodel( "p6_zm_screecher_hole" ); + precachemodel( "p_cub_door01_wood_fullsize" ); + precachemodel( "veh_t6_civ_microbus_dead" ); + precachemodel( "p_rus_door_white_window_plain_left" ); + if (level.script != "zm_prison") + { + level._effect["fx_zombie_cola_revive_on"] = loadfx( "misc/fx_zombie_cola_revive_on" ); + level._effect["fx_zombie_cola_dtap_on"] = loadfx( "misc/fx_zombie_cola_dtap_on" ); + } + + level._effect["fx_zombie_cola_on"] = loadfx( "misc/fx_zombie_cola_on" ); + if (!(level.script == "zm_tomb" || level.script == "zm_prison")) + { + level._effect["fx_zmb_wall_buy_taseknuck"] = loadfx( "maps/zombie/fx_zmb_wall_buy_taseknuck" ); + level._effect["fx_zmb_wall_buy_bowie"] = loadfx( "maps/zombie/fx_zmb_wall_buy_bowie" ); + } + // level._effect["fx_default_explosion"] = loadfx( "explosions/fx_default_explosion" ); + + + if( level.script == "zm_buried" || level.script == "zm_tomb" ) + { + level._effect["fx_default_explosion"] = level._effect[ "divetonuke_groundhit"]; + } + else + { + level._effect["fx_default_explosion"] = loadfx( "explosions/fx_default_explosion" ); + } + + + level.town = 1; + level.diner = 0; + + level thread onPlayerConnect(); + + //level thread perk_machine_removal( "specialty_scavenger" ); + init_custom_map(); + + if(level.script != "zm_buried" && level.script != "zm_highrise" && level.script != "zm_tomb" && level.script != "zm_prison") + level.get_player_weapon_limit = ::custom_get_player_weapon_limit; + level.zombie_last_stand = ::LastStand; + level.custom_vending_precaching = ::default_vending_precaching; + + + + + level.player_out_of_playable_area_monitor = 0; + level.perk_purchase_limit = 50; + if( getdvar( "mapname" ) == "zm_transit" && getdvar ( "g_gametype" ) == "zstandard" ) + { + foreach( weapon in level.zombie_weapons) + { + weapon.is_in_box = 1; + } + } + +// } + + + +//-------------------ENDCUSTOMPERK------------------------ + + //isTown(); + + precacheshader("damage_feedback"); + precacheshader("hud_status_dead"); + if( getdvar( "mapname" ) == "zm_transit" ) + { + level._effect[ "jetgun_smoke_cloud" ] = loadfx( "weapon/thunder_gun/fx_thundergun_smoke_cloud" ); + } + level.custom_pap_validation = thread new_pap_trigger(); + level._poi_override = ::turned_zombie; + flag_wait( "initial_blackscreen_passed" ); + + level.original_damagecallback = level.callbackactordamage; + level.callbackactordamage = ::actor_damage_override_wrapper; + //get_players()[0] thread perks_gived(); //test tombstone and whos who aat recovery + wait 1; +// level.chugabud_laststand_func = ::chugabud_laststand; //recover aat on whos who revive + +// level.tombstone_spawn_func = ::tombstone_spawn; //recover aat on tombstone revive +} + + + +//-------------------CUSTOMPERK------------------------ + +onPlayerConnect() +{ + while( 1 ) + { + level waittill( "connected", player ); + player thread onPlayerSpawned(); + } +} + +onPlayerSpawned() +{ + self endon( "disconnect" ); + level endon( "game_ended" ); + self waittill( "spawned_player" ); + + self.perkarray = []; + self.dying_wish_on_cooldown = 0; + self.perk_reminder = 0; + self.perk_count = 0; + self.num_perks = 0; + self thread removeperkshader(); + self thread perkboughtcheck(); + self thread damagehitmarker(); + for(;;) + { + self waittill( "spawned_player" ); + if(self.score < 10000) + { + self.score = 10000; + } + } +} + +wait_network_frame_override() +{ + wait 0.1; +} + +damagehitmarker() +{ + self endon ("disconnect"); + level endon( "end_game" ); + self thread startwaiting(); + self.hitmarker = newdamageindicatorhudelem( self ); + self.hitmarker.horzalign = "center"; + self.hitmarker.vertalign = "middle"; + self.hitmarker.x = -12; + self.hitmarker.y = -12; + self.hitmarker.alpha = 0; + self.hitmarker setshader( "damage_feedback", 24, 48 ); + +} + +startwaiting() +{ + self endon ("disconnect"); + level endon( "end_game" ); + while( 1 ) + { + foreach( zombie in getaiarray( level.zombie_team ) ) + { + if( !(IsDefined( zombie.waitingfordamage )) ) + { + zombie thread hitmark(); + } + } + wait 0.25; + } +} + +hitmark() +{ + self endon ("disconnect"); + level endon( "end_game" ); + self endon( "killed" ); + self.waitingfordamage = 1; + while( 1 ) + { + self waittill( "damage", amount, attacker, dir, point, mod ); + attacker.hitmarker.alpha = 0; + if( isplayer( attacker ) ) + { + if( isalive( self ) ) + { + attacker.hitmarker.color = ( 1, 1, 1 ); + attacker.hitmarker.alpha = 1; + attacker.hitmarker fadeovertime( 1 ); + attacker.hitmarker.alpha = 0; + } + else + { + attacker.hitmarker.color = ( 1, 0, 0 ); + attacker.hitmarker.alpha = 1; + attacker.hitmarker fadeovertime( 1 ); + attacker.hitmarker.alpha = 0; + self notify( "killed" ); + } + } + } +} + + + + +init_custom_map() +{ + if( level.script == "zm_transit" ) + { + perk_system( "script_model", ( 1856, -810.722, -55.875), "zombie_vending_tombstone_on", ( 0, 180, 0 ), "custom", "mus_perks_deadshot_sting", "Deadshot", 2000, "tombstone_light", "deadshot" ); + perk_system( "script_model", ( 2460, -780, -55.875 ), "zombie_vending_tombstone_on", ( 0, 225, 0 ), "custom", "mus_perks_doubletap_sting", "Burn Heart", 2500, "jugger_light", "Burn_Heart" ); + perk_system( "script_model", ( 901.86, -1575.574, -47.875 ), "zombie_vending_tombstone_on", ( 0, 180, 0 ), "custom", "mus_perks_deadshot_sting", "Widow's Wine", 4000, "tombstone_light", "WIDOWS_WINE" ); + perk_system( "script_model", ( 450, -300.574, -61.875 ), "zombie_vending_tombstone_on", ( 0, 45, 0 ), "custom", "mus_perks_packa_sting", "Electric Cherry", 2000, "tombstone_light", "ELECTRIC_CHERRY" ); // 613,-250,z 0,0,0 + perk_system( "script_model", ( 1069, -1133, 120.125 ), "zombie_vending_tombstone_on", ( 0, 180, 0 ), "custom", "mus_perks_doubletap_sting", "Ethereal Razor", 3500, "tombstone_light", "Ethereal_Razor" ); + perk_system( "script_model", ( 1823.86, 670.574, -55.875 ), "zombie_vending_tombstone_on", ( 0, 45, 0 ), "custom", "mus_perks_doubletap_sting", "Mule Kick", 4000, "tombstone_light", "MULE" ); + perk_system( "script_model", ( 840, 603.809, -40.875 ), "zombie_vending_tombstone_on", ( 0, 0, 0 ), "custom", "mus_perks_packa_sting", "PhD Flopper", 2500, "tombstone_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( 2358, -87, -55.875 ), "zombie_vending_tombstone_on", ( 0, -90, 0 ), "custom", "mus_perks_doubletap_sting", "Downer's Delight", 2000, "tombstone_light", "Downers_Delight" ); + perk_system( "script_model", ( 2015, 858, -56.875 ), "zombie_vending_tombstone_on", ( 0, -90, 0 ), "custom", "mus_perks_doubletap_sting", "Dying Wish", 6000, "tombstone_light", "Dying_Wish" ); + perk_system( "script_model", ( 559, -1364, 120.125 ), "zombie_vending_tombstone_on", ( 0, 180, 0 ), "custom", "mus_perks_doubletap_sting", "Ammo Regen", 3000, "tombstone_light", "Ammo_Regen" ); + } + if( level.script == "zm_highrise") + { + perk_system( "script_model", ( 1884.42, 491.946, 1298.72), "zombie_vending_jugg_on", ( 0, 418.728, 0 ), "custom", "mus_perks_deadshot_sting", "Deadshot", 2000, "tombstone_light", "deadshot" ); +// perk_system( "script_model", ( 2764.64, 1868.03, 1391.01 ), "zombie_vending_jugg_on", ( 0, 384.236, 0 ), "custom", "mus_perks_doubletap_sting", "Burn Heart", 2500, "jugger_light", "Burn_Heart" ); + perk_system( "script_model", ( 1978.25, 597.657, 2704.13 ), "zombie_vending_jugg_on", ( 0, 329.291, 0 ), "custom", "mus_perks_deadshot_sting", "Widow's Wine", 4000, "tombstone_light", "WIDOWS_WINE" ); +// perk_system( "script_model", ( 1415.64, 2108.36, 3220.26 ), "zombie_vending_jugg_on", ( 0, 406.661, 0 ), "custom", "mus_perks_packa_sting", "Electric Cherry", 2000, "tombstone_light", "ELECTRIC_CHERRY" ); // 613,-250,z 0,0,0 + perk_system( "script_model", ( 1901.97, 1431.36, 3216.13 ), "zombie_vending_jugg_on", ( 0, 404.762, 0 ), "custom", "mus_perks_doubletap_sting", "Ethereal Razor", 3500, "tombstone_light", "Ethereal_Razor" ); +// perk_system( "script_model", ( 1891.64, 1119.64, 3048.36 ), "zombie_vending_jugg_on", ( 0, 45, 0 ), "custom", "mus_perks_doubletap_sting", "Mule Kick", 4000, "tombstone_light", "MULE" ); + perk_system( "script_model", ( 1429.29, -453.397, 2880.13 ), "zombie_vending_jugg_on", ( 0, 149.1426, 0 ), "custom", "mus_perks_packa_sting", "PhD Flopper", 2500, "tombstone_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( 1109.64, 2701.36, 3043.82 ), "zombie_vending_jugg_on", ( 0, 394.926, 0 ), "custom", "mus_perks_doubletap_sting", "Downer's Delight", 2000, "tombstone_light", "Downers_Delight" ); + perk_system( "script_model", ( 1706.28, 1055.64, 3395.1 ), "zombie_vending_jugg_on", ( 0, 180, 0 ), "custom", "mus_perks_doubletap_sting", "Dying Wish", 6000, "tombstone_light", "Dying_Wish" ); + perk_system( "script_model", ( 2269.17, 182.377, 2880.13 ), "zombie_vending_jugg_on", ( 0, 418.596, 0 ), "custom", "mus_perks_doubletap_sting", "Ammo Regen", 3000, "tombstone_light", "Ammo_Regen" ); + } + if( level.script == "zm_buried") + { + perk_system( "script_model", ( 1618.14, 1513.46, 200.62), "zombie_vending_jugg_on", ( 0, 250.147, 0 ), "custom", "mus_perks_deadshot_sting", "Deadshot", 2000, "sleight_light", "deadshot" ); +// perk_system( "script_model", ( -1176.36, 508.26, 144.125 ), "zombie_vending_jugg_on", ( 0, 448.269, 0 ), "custom", "mus_perks_doubletap_sting", "Burn Heart", 2500, "sleight_light", "Burn_Heart" ); + perk_system( "script_model", ( -1176.36, 510.625, 144.125 ), "zombie_vending_jugg_on", ( 0, 449.412, 0 ), "custom", "mus_perks_deadshot_sting", "Widow's Wine", 4000, "sleight_light", "WIDOWS_WINE" ); + perk_system( "script_model", ( -448.859, 131.435, 143.491 ), "zombie_vending_jugg_on", ( 0, 180.3, 0 ), "custom", "mus_perks_packa_sting", "Electric Cherry", 2000, "sleight_light", "ELECTRIC_CHERRY" ); // 613,-250,z 0,0,0 + perk_system( "script_model", ( 890.359, -840.206, -22.8006 ), "zombie_vending_jugg_on", ( 0, 270.367, 0 ), "custom", "mus_perks_doubletap_sting", "Ethereal Razor", 3500, "sleight_light", "Ethereal_Razor" ); +// perk_system( "script_model", ( 1891.64, 1119.64, 3048.36 ), "zombie_vending_jugg_on", ( 0, 45, 0 ), "custom", "mus_perks_doubletap_sting", "Mule Kick", 4000, "sleight_light", "MULE" ); + perk_system( "script_model", ( 572.507, -712.359, 149.95 ), "zombie_vending_jugg_on", ( 0, 178.4505, 0 ), "custom", "mus_perks_packa_sting", "PhD Flopper", 2500, "sleight_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( 488.324, 727.641, 176.125 ), "zombie_vending_jugg_on", ( 0, 178.9998, 0 ), "custom", "mus_perks_doubletap_sting", "Downer's Delight", 2000, "sleight_light", "Downers_Delight" ); + perk_system( "script_model", ( -1298.32, -837.178, -23.875 ), "zombie_vending_jugg_on", ( 0, 91.37286, 0 ), "custom", "mus_perks_doubletap_sting", "Dying Wish", 6000, "sleight_light", "Dying_Wish" ); + perk_system( "script_model", ( -122.161, -1469.21, 168.125 ), "zombie_vending_jugg_on", ( 0, 448.841, 0 ), "custom", "mus_perks_doubletap_sting", "Ammo Regen", 3000, "sleight_light", "Ammo_Regen" ); + } + if( level.script == "zm_nuked") + { + perk_system( "script_model", ( 28.8155, -356.18, -65.8346 ), "zombie_vending_jugg_on", ( 0, 129.8755, 0 ), "custom", "mus_perks_deadshot_sting", "Deadshot", 2000, "sleight_light", "deadshot" ); +// perk_system( "script_model", ( ), "zombie_vending_jugg_on", ( ), "custom", "mus_perks_doubletap_sting", "Burn Heart", 2500, "sleight_light", "Burn_Heart" ); + perk_system( "script_model", ( -954.194, 714.594, 84.0385 ), "zombie_vending_jugg_on", ( 0, 429.46, 0 ), "custom", "mus_perks_deadshot_sting", "Widow's Wine", 4000, "sleight_light", "WIDOWS_WINE" ); + perk_system( "script_model", ( 683.524, 618.635, -56.875 ), "zombie_vending_jugg_on", ( 0, 102.5635, 0 ), "custom", "mus_perks_packa_sting", "Electric Cherry", 2000, "sleight_light", "ELECTRIC_CHERRY" ); // 613,-250,z 0,0,0 + perk_system( "script_model", ( 1420.35, -21.4313, -63.8849 ), "zombie_vending_jugg_on", ( 0, 194.085, 0 ), "custom", "mus_perks_doubletap_sting", "Ethereal Razor", 3500, "sleight_light", "Ethereal_Razor" ); + perk_system( "script_model", ( 618.292, -188.322, -56.3686 ), "zombie_vending_jugg_on", ( 0, 105.5011, 0 ), "custom", "mus_perks_doubletap_sting", "Mule Kick", 4000, "sleight_light", "MULE" ); + perk_system( "script_model", ( 1152.5, 160.6, 79.125 ), "zombie_vending_jugg_on", ( 0, 392.541, 0 ), "custom", "mus_perks_packa_sting", "PhD Flopper", 2500, "sleight_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( 156.738, 513.899, -62.3141 ), "zombie_vending_jugg_on", ( 0, 101.8164, 0 ), "custom", "mus_perks_doubletap_sting", "Downer's Delight", 2000, "sleight_light", "Downers_Delight" ); + perk_system( "script_model", ( -646.863, 271.522, -55.875 ), "zombie_vending_jugg_on", ( 0, 160.8405, 0 ), "custom", "mus_perks_doubletap_sting", "Dying Wish", 6000, "sleight_light", "Dying_Wish" ); + perk_system( "script_model", ( -1582.46, 112.604, -63.2092 ), "zombie_vending_jugg_on", ( 0, 250.829, 0 ), "custom", "mus_perks_doubletap_sting", "Ammo Regen", 3000, "sleight_light", "Ammo_Regen" ); + } + if( level.script == "zm_tomb") + { + perk_system( "script_model", ( 184.995, -2422.49, 50.125), "zombie_vending_jugg_on", ( 0, 369.091, 0 ), "custom", "mus_perks_deadshot_sting", "Deadshot", 2000, "sleight_light", "deadshot" ); + perk_system( "script_model", ( 160.359, 3781.17, -351.875 ), "zombie_vending_jugg_on", ( 0, 266.122, 0 ), "custom", "mus_perks_deadshot_sting", "Widow's Wine", 4000, "sleight_light", "WIDOWS_WINE" ); + perk_system( "script_model", ( 375.771, 2119.22, -122.951 ), "zombie_vending_jugg_on", ( 0, 179.5935, 0 ), "custom", "mus_perks_doubletap_sting", "Ethereal Razor", 3500, "sleight_light", "Ethereal_Razor" ); + perk_system( "script_model", ( -335.604, -187.006, 325.273 ), "zombie_vending_jugg_on", ( 0, 132.9565, 0 ), "custom", "mus_perks_packa_sting", "PhD Flopper", 2500, "sleight_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( 924.47, 360.72, 131.005 ), "zombie_vending_jugg_on", ( 0, 373.266, 0 ), "custom", "mus_perks_doubletap_sting", "Downer's Delight", 2000, "sleight_light", "Downers_Delight" ); + perk_system( "script_model", ( 1345.09, -3822.62, 302.125 ), "zombie_vending_jugg_on", ( 0, 270.593, 0 ), "custom", "mus_perks_doubletap_sting", "Dying Wish", 6000, "sleight_light", "Dying_Wish" ); + perk_system( "script_model", ( 2972.36, 5218.91, -378.566 ), "zombie_vending_jugg_on", ( 0, 270.379, 0 ), "custom", "mus_perks_doubletap_sting", "Ammo Regen", 3000, "sleight_light", "Ammo_Regen" ); + } + if( level.script == "zm_prison") + { + perk_system( "script_model", ( -1344.65, 5598.31, -71.875 ), "p6_zm_al_vending_jugg_on", ( 0, 98.34412, 0 ), "custom", "mus_perks_deadshot_sting", "Deadshot", 2000, "sleight_light", "deadshot" ); + perk_system( "script_model", ( 3763.64, 9669.99, 1704.13 ), "p6_zm_al_vending_jugg_on", ( 0, 90, 0 ), "custom", "mus_perks_deadshot_sting", "Widow's Wine", 4000, "sleight_light", "WIDOWS_WINE" ); + perk_system( "script_model", ( 2160.71, 9247.64, 1558.13 ), "p6_zm_al_vending_jugg_on", ( 0, 179.1815, 0 ), "custom", "mus_perks_doubletap_sting", "Ethereal Razor", 3500, "sleight_light", "Ethereal_Razor" ); + perk_system( "script_model", ( 597.633, 8546.86, 832.125 ), "p6_zm_al_vending_jugg_on", ( 0, 221.984, 0 ), "custom", "mus_perks_doubletap_sting", "Mule Kick", 4000, "sleight_light", "MULE" ); + perk_system( "script_model", ( 456.359, 8679.51, 1128.13 ), "p6_zm_al_vending_jugg_on", ( 0, 269.533, 0 ), "custom", "mus_perks_packa_sting", "PhD Flopper", 2500, "sleight_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( -685.943, 9199.64, 1336.13 ), "p6_zm_al_vending_jugg_on", ( 0, 178.5443, 0 ), "custom", "mus_perks_doubletap_sting", "Downer's Delight", 2000, "sleight_light", "Downers_Delight" ); + perk_system( "script_model", ( 1728.56, 10688.4, 1336.13 ), "p6_zm_al_vending_jugg_on", ( 0, 357.896, 0 ), "custom", "mus_perks_doubletap_sting", "Dying Wish", 6000, "sleight_light", "Dying_Wish" ); + perk_system( "script_model", ( 1367.28, 10096.4, 1128.13 ), "p6_zm_al_vending_jugg_on", ( 0, 358.687, 0 ), "custom", "mus_perks_doubletap_sting", "Ammo Regen", 3000, "sleight_light", "Ammo_Regen" ); + } +} + +play_fx( fx ) +{ + playfxontag( level._effect[ fx ], self, "tag_origin" ); +} + +defaulth_vending_precaching() +{ + level._effect[ "sleight_light" ] = loadfx( "misc/fx_zombie_cola_on" ); + level._effect[ "tombstone_light" ] = loadfx( "misc/fx_zombie_cola_on" ); + level._effect[ "revive_light" ] = loadfx( "misc/fx_zombie_cola_revive_on" ); + level._effect[ "marathon_light" ] = loadfx( "maps/zombie/fx_zmb_cola_staminup_on" ); + level._effect[ "jugger_light" ] = loadfx( "misc/fx_zombie_cola_jugg_on" ); + level._effect[ "doubletap_light" ] = loadfx( "misc/fx_zombie_cola_dtap_on" ); + level._effect[ "deadshot_light" ] = loadfx( "misc/fx_zombie_cola_dtap_on" ); + level._effect[ "additionalprimaryweapon_light" ] = loadfx( "misc/fx_zombie_cola_arsenal_on" ); + level._effect[ "packapunch_fx" ] = loadfx( "maps/zombie/fx_zombie_packapunch" ); + level._effect[ "wall_taseknuck" ] = loadfx( "maps/zombie/fx_zmb_wall_buy_taseknuck" ); +} + + +playchalkfx(effect, origin, angles) +{ + fx = SpawnFX(level._effect[ effect ], origin,AnglesToForward(angles),AnglesToUp(angles)); + TriggerFX(fx); + level waittill("connected", player); + fx Delete(); +} + + + +perk_system( script, pos, model, angles, type, sound, name, cost, fx, perk) +{ + col = spawn( script, pos); + col setmodel( model ); + col.angles = angles; + x = spawn( script, pos ); + x setmodel( "zm_collision_perks1" ); + x.angles = angles; + col thread buy_system( perk, sound, name, cost, type ); + col thread play_fx( fx ); +} + +buy_system( perk, sound, name, cost, type ) +{ + level endon("end_game"); + self endon("disconnect"); + self endon( "game_ended" ); + while( 1 ) + { + foreach( player in level.players ) + { + if(!player.machine_is_in_use) + { + if( distance( self.origin, player.origin ) <= 70 ) + { + player thread SpawnHint( self.origin, 30, 30, "HINT_ACTIVATE", "Hold ^3&&1^7 for " + name + " [Cost: " + cost + "]" ); + if(player usebuttonpressed() && !player hasperk(perk) && !player hascustomperk(perk) && player.score >= cost && !player maps/mp/zombies/_zm_laststand::player_is_in_laststand()) + { + player.machine_is_in_use = 1; + player playsound( "zmb_cha_ching" ); + player.score -= cost; + player playsound( sound ); + player thread drawshader_and_shadermove( perk, 1, 1, type ); + wait 4; + player.machine_is_in_use = 0; + } + else + { + if( player usebuttonpressed() && player.score < cost ) + { + player maps/mp/zombies/_zm_audio::create_and_play_dialog( "general", "perk_deny", undefined, 0 ); + } + } + } + } + } + wait 0.1; + } +} + +hascustomperk(perk) +{ + for(i = 0; i < self.perkarray.size; i++) + { + if(self.perkarray[i].name == perk) + { + return 1; + } + } + return 0; +} + +removeperkshader() +{ + self endon ("disconnect"); + level endon( "end_game" ); + common_scripts/utility::flag_wait( "initial_blackscreen_passed" ); + for(;;) + { + self waittill_any_return( "fake_death", "player_downed", "player_revived", "spawned_player", "disconnect", "death" ); + self.num_perks = 0; + self.perk_reminder = 0; + self.perk_count = 0; + self.dying_wish_on_cooldown = 0; + self removeallcustomshader(); + self.perkarray = []; + self notify( "stopcustomperk" ); + self.bleedout_time = 30; + self.ignore_lava_damage = 0; + self setclientfieldtoplayer( "deadshot_perk", 0 ); + } +} + +removeallcustomshader() +{ + for(i = 0; i < self.perkarray.size; i++) + { + self.perkarray[i] destroy(); + } +} + +drawshader( shader, x, y, width, height, color, alpha, sort ) +{ + level endon("end_game"); + self endon("disconnect"); + hud = newclienthudelem( self ); + hud.elemtype = "icon"; + hud.color = color; + hud.alpha = alpha; + hud.sort = sort; + hud.children = []; + hud.hidewheninmenu = 1; + hud setparent( level.uiparent ); + hud setshader( shader, width, height ); + hud.x = x; + hud.y = y; + return hud; +} + +perkboughtcheck() +{ + self endon("death"); + self endon("disconnect"); + for(;;) + { + self.perk_reminder = self.num_perks; + self waittill("perk_acquired"); + n = 1; + if(!(self.num_perks > self.perk_reminder)) + { + n = (self.num_perks - self.perk_reminder); + self.num_perks = (self.perk_reminder + n); + } + self.perk_reminder = self.num_perks; + self.perk_count += n; + self drawshader_and_shadermove("none", 0, 0, "normal"); //modified to remove perk alignement since 2 perk lines Added "normal" for type check + } +} + +drawshader_and_shadermove(perk, custom, print, type) +{ + level endon("end_game"); + self endon("disconnect"); + if(custom) + { + self allowProne(false); + self allowSprint(false); + self disableoffhandweapons(); + self disableweaponcycling(); + weapona = self getcurrentweapon(); + weaponb = "zombie_perk_bottle_jugg"; + self giveweapon( weaponb ); + self switchtoweapon( weaponb ); + self waittill( "weapon_change_complete" ); + self enableoffhandweapons(); + self enableweaponcycling(); + self takeweapon( weaponb ); + self switchtoweapon( weapona ); + self maps/mp/zombies/_zm_audio::playerexert( "burp" ); + self setblur( 4, 0.1 ); + wait 0.1; + self setblur( 0, 0.1 ); + self allowProne(true); + self allowSprint(true); + } + + yPerk = 325; + if (level.script == "zm_buried") + { + yPerk = 300; + } + if (level.script == "zm_tomb") + { + yPerk = 275; + } + + x = -408; + for(i = 0; i < self.perkarray.size; i++) + { + if (type == "custom") + { + x += 15; + } + } + /*if (perk == "custom") + { + for(i = 0; i < self.perkarray.size; i++) + { + self.perkarray[i].x = self.perkarray[i].x + 30; + } + }*/ + if(perk == "Downers_Delight") + { + self.perk1back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk1front = self drawshader( "waypoint_revive", x, yPerk, 23, 23, ( 0, 1, 1 ), 100, 0 ); + self.perk1front.name = perk; + self.perkarray[self.perkarray.size] = self.perk1front; + self.perk1back.name = perk; + self.perkarray[self.perkarray.size] = self.perk1back; + self.num_perks++; + self thread DDown(); + if(print) + { + self iprintln("^9Downer's Delight"); + wait 0.2; + self iprintln("This Perk will increase players bleedout time by 10 seconds and current weapons is used in laststand."); + } + } + if(perk == "MULE") + { + self.perk2back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk2front = self drawshader( "menu_mp_weapons_1911", x, yPerk, 22, 22, ( 0, 1, 0 ), 100, 0 ); + self.perk2front.name = perk; + self.perkarray[self.perkarray.size] = self.perk2front; + self.perk2back.name = perk; + self.perkarray[self.perkarray.size] = self.perk2back; + self.num_perks++; + if(print) + { + self iprintln("^9Mule Kick"); + wait 0.2; + self iprintln("This Perk enables additional primary weapon slot for player. "); + } + } + if(perk == "PHD_FLOPPER") + { + self.perk3back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk3front = self drawshader( "hud_icon_sticky_grenade", x, yPerk, 23, 23, (1, 0, 1 ), 100, 0 ); + self.perk3front.name = perk; + self.perkarray[self.perkarray.size] = self.perk3front; + self.perk3back.name = perk; + self.perkarray[self.perkarray.size] = self.perk3back; + self.num_perks++; + if(print) + { + self iprintln("^9PhD Flopper"); + wait 0.2; + self iprintln("This Perk removes explosion and fall damage also player creates explosion when dive to prone."); + } + } + if(perk == "Victorious_Tortoise") + { + self.perk4back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 200, 0 ), 100, 0 ); + self.perk4front = self drawshader( "zombies_rank_2", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk4front.name = perk; + self.perkarray[self.perkarray.size] = self.perk4front; + self.perk4back.name = perk; + self.perkarray[self.perkarray.size] = self.perk4back; + self.num_perks++; + self thread start_vt(); + if(print) + { + self iprintln("^9Victorious Tortoise"); + wait 0.2; + self iprintln("This Perk allows shield block damage from all directions when in use."); + } + } + if(perk == "ELECTRIC_CHERRY") + { + self.perk5back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 200 ), 100, 0 ); + self.perk5front = self drawshader( "zombies_rank_5", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk5front.name = perk; + self.perkarray[self.perkarray.size] = self.perk5front; + self.perk5back.name = perk; + self.perkarray[self.perkarray.size] = self.perk5back; + self.num_perks++; + self thread start_ec(); + if(print) + { + self iprintln("^9Electric Cherry"); + wait 0.2; + self iprintln("This Perk creates an electric shockwave around the player whenever they reload."); + } + } + if(perk == "WIDOWS_WINE") + { + self.perk6back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk6front = self drawshader( "zombies_rank_3", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk6front.name = perk; + self.perkarray[self.perkarray.size] = self.perk6front; + self.perk6back.name = perk; + self.perkarray[self.perkarray.size] = self.perk6back; + self.num_perks++; + self takeweapon( self get_player_lethal_grenade() ); + self set_player_lethal_grenade( "sticky_grenade_zm" ); + self giveweapon("sticky_grenade_zm"); + self thread ww_nades(); + if(print) + { + self iprintln("^9Widow's Wine"); + wait 0.2; + self iprintln("This Perk damages zombies around the player when player is hit and grenades are upgraded."); + } + } + if(perk == "Ethereal_Razor") + { + self.perk7back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 200, 0, 0 ), 100, 0 ); + self.perk7front = self drawshader( "zombies_rank_4", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk7front.name = perk; + self.perkarray[self.perkarray.size] = self.perk7front; + self.perk7back.name = perk; + self.perkarray[self.perkarray.size] = self.perk7back; + self.num_perks++; + if(print) + { + self iprintln("^9Ethereal Razor"); + wait 0.2; + self iprintln("This Perk deals extra damage when player using melee attacks and restores a small amount of health."); + } + } + if(perk == "Ammo_Regen") + { + self.perk8back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk8front = self drawshader( "menu_mp_lobby_icon_customgamemode", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk8front.name = perk; + self.perkarray[self.perkarray.size] = self.perk8front; + self.perk8back.name = perk; + self.perkarray[self.perkarray.size] = self.perk8back; + self.num_perks++; + self thread ammoregen(); + self thread grenadesregen(); + if(print) + { + self iprintln("^9Ammo Regen"); + wait 0.2; + self iprintln("This Perk will slowly regenerades players ammonation and grenades."); + } + } + if(perk == "Burn_Heart") + { + self.perk9back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 200, 0, 0 ), 100, 0 ); + self.perk9front = self drawshader( "faction_cdc", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk9front.name = perk; + self.perkarray[self.perkarray.size] = self.perk9front; + self.perk9back.name = perk; + self.perkarray[self.perkarray.size] = self.perk9back; + self.num_perks++; + self.ignore_lava_damage = 1; + if(print) + { + self iprintln("^9Burn Heart"); + wait 0.2; + self iprintln("This Perk removes lava damage."); + } + } + if(perk == "Dying_Wish") + { + self.perk10back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 200, 0, 0 ), 100, 0 ); + self.perk10front = self drawshader( "zombies_rank_5", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk10front.name = perk; + self.perkarray[self.perkarray.size] = self.perk10front; + self.perk10back.name = perk; + self.perkarray[self.perkarray.size] = self.perk10back; + self.num_perks++; + self thread dying_wish_checker(); + if(print) + { + self iprintln("^9Dying Wish"); + wait 0.2; + self iprintln("This Perk allow player to go berserker mode for 9 seconds instead of laststand."); + wait 0.1; + self iprintln(" (cooldown 5mins and it's increased 30sec every time perk is used. - max 10mins) "); + } + } + if(perk == "deadshot") + { + self.perk11back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk11front = self drawshader( "killiconheadshot", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk11front.name = perk; + self.perkarray[self.perkarray.size] = self.perk11front; + self.perk11back.name = perk; + self.perkarray[self.perkarray.size] = self.perk11back; + self.num_perks++; + self setclientfieldtoplayer( "deadshot_perk", 1 ); + if(print) + { + self iprintln("^9Deadshot"); + wait 0.2; + self iprintln("This Perk aims automatically enemys head instead of body."); + } + } +} + +custom_get_player_weapon_limit( player ) +{ + level endon("end_game"); + self endon("disconnect"); + weapon_limit = 2; + if ( player hascustomperk("MULE") ) + { + weapon_limit = 3; + } + else + { + weapons = self getWeaponsListPrimaries(); + if(weapons.size > 2) + { + self takeWeapon(weapons[2]); + } + } + return weapon_limit; +} + +ammoregen() +{ + self endon( "disconnect" ); + level endon( "end_game" ); + self endon( "stopcustomperk" ); + for(;;) + { + if (self GetCurrentWeapon() == "ray_gun_upgraded_zm" || self GetCurrentWeapon() == "ray_gun_zm") + { + stockcount = self getweaponammostock( self GetCurrentWeapon() ); + self setWeaponAmmostock( self GetCurrentWeapon(), stockcount + 1 ); + wait 2; + } + else if (self GetCurrentWeapon() == "raygun_mark2_zm" || self GetCurrentWeapon() == "raygun_mark2_upgraded_zm") + { + stockcount = self getweaponammostock( self GetCurrentWeapon() ); + self setWeaponAmmostock( self GetCurrentWeapon(), stockcount + 1 ); + wait 2; + } + else if (self GetCurrentWeapon() == "m1911_upgraded_zm" || self GetCurrentWeapon() == "usrpg_upgraded_zm") + { + stockcount = self getweaponammostock( self GetCurrentWeapon() ); + self setWeaponAmmostock( self GetCurrentWeapon(), stockcount + 1 ); + wait 2; + } + else if(!self GetCurrentWeapon() == "" && !is_grenade_launcher( self GetCurrentWeapon()) && self GetCurrentWeapon() != "slipgun_zm" +&& self GetCurrentWeapon() != "staff_fire_zm" && self GetCurrentWeapon() != "staff_fire_upgraded_zm" +&& self GetCurrentWeapon() != "staff_air_zm" && self GetCurrentWeapon() != "staff_air_upgraded_zm" +&& self GetCurrentWeapon() != "staff_water_zm" && self GetCurrentWeapon() != "staff_water_upgraded_zm" +&& self GetCurrentWeapon() != "staff_lightning_zm" && self GetCurrentWeapon() != "staff_lightning_upgraded_zm" +&& self GetCurrentWeapon() != "blundersplat_upgraded_zm") + { + stockcount = self getweaponammostock( self GetCurrentWeapon() ); + self setWeaponAmmostock( self GetCurrentWeapon(), stockcount + 3 ); + wait 2; + } + wait 0.1; + } +} + +grenadesregen() +{ + self endon( "disconnect" ); + level endon( "end_game" ); + self endon( "stopcustomperk" ); + for(;;) + { + grenades = self get_player_lethal_grenade(); + grenade_count = self getweaponammoclip(grenades); + if(grenade_count < 4) + { + self setweaponammoclip(grenades, (grenade_count + 1)); + } + tactical_grenades = self get_player_tactical_grenade(); + tactical_grenade_count = self getweaponammoclip(tactical_grenades); + if(tactical_grenade_count < 3 ) + { + self setweaponammoclip(tactical_grenades, (tactical_grenade_count + 1)); + } + wait 300; + } +} + +start_ec() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("stopcustomperk"); + for(;;) + { + self waittill( "reload_start" ); + playfxontag( level._effect[ "poltergeist"], self, "J_SpineUpper" ); + self EnableInvulnerability(); + RadiusDamage(self.origin, 120, 200, 100, self); + self DisableInvulnerability(); + self playsound( "zmb_turbine_explo" ); + wait 1; + } +} + +start_vt() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("stopcustomperk"); + for(;;) + { + if(self getcurrentweapon() == "riotshield_zm" ) + { + self enableInvulnerability(); + self.shielddamagetaken += 100; + wait 0.9; + } + else + { + self disableInvulnerability(); + } + wait 0.1; + } +} + +start_er() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("stopcustomperk"); + for(;;) + { + if (self hascustomperk("Ethereal_Razor") && self ismeleeing()) + { + /* foreach(zombie in getAiArray(level.zombie_team)) + { + if( distance( self.origin, zombie.origin ) <= 100 ) + { + + } + }*/ //removed for test + self.health += 20; + if(self.health > self.maxhealth) + { + self.health = self.maxhealth; + } + while(self ismeleeing()) + { + wait 0.1; + } + } + wait 0.05; + } +} + +LastStand() +{ + level endon("end_game"); + self endon("disconnect"); + if(self hascustomperk("Downers_Delight")) + { + self.customlaststandweapon = self getcurrentweapon(); + self switchtoweapon( self.customlaststandweapon ); + self setweaponammoclip( self.customlaststandweapon, 150 ); + self.bleedout_time = 40; + } + else + { + self maps/mp/zombies/_zm::last_stand_pistol_swap(); + } +} + +DDown() +{ + self endon( "disconnect" ); + level endon( "end_game" ); + self endon( "stopcustomperk" ); + for(;;) + { + self waittill("player_downed"); + self playsound( "zmb_phdflop_explo" ); + playfx(loadfx("explosions/fx_default_explosion"), self.origin, anglestoforward( ( 0, 45, 55 ) ) ); + RadiusDamage(self.origin, 150, 600, 400, self); + wait 0.1; + } +} + +doGivePerk(perk) +{ + self endon("disconnect"); + self endon("death"); + level endon("game_ended"); + self endon("perk_abort_drinking"); + if (!(self hasperk(perk) || (self maps/mp/zombies/_zm_perks::has_perk_paused(perk)))) + { + gun = self maps/mp/zombies/_zm_perks::perk_give_bottle_begin(perk); + evt = self waittill_any_return("fake_death", "death", "player_downed", "weapon_change_complete"); + if (evt == "weapon_change_complete") + self thread maps/mp/zombies/_zm_perks::wait_give_perk(perk, 1); + self maps/mp/zombies/_zm_perks::perk_give_bottle_end(gun, perk); + if (self maps/mp/zombies/_zm_laststand::player_is_in_laststand() || isDefined(self.intermission) && self.intermission) + return; + self notify("burp"); + } +} + + +SpawnHint( origin, width, height, cursorhint, string ) +{ + level endon("end_game"); + self endon("disconnect"); + hint = spawn( "trigger_radius", origin, 1, width, height ); + hint setcursorhint( cursorhint, hint ); + hint sethintstring( string ); + hint setvisibletoall(); + wait 0.2; + hint delete(); +} + + +ww_points( player ) +{ + level endon("end_game"); + self endon("disconnect"); + for(i = 0; i < 3; i++) + { + self maps/mp/zombies/_zm_utility::set_zombie_run_cycle("walk"); + player maps/mp/zombies/_zm_score::add_to_player_score( 10 ); + PlayFXOnTag(level.effect_WebFX,self,"j_spineupper"); + self doDamage(150, (0, 0, 0)); + wait 1; + } +} + +ww_nade_explosion() +{ + level endon("end_game"); + self endon("disconnect"); + wait 2; + // if( self maps/mp/zm_transit_lava::object_touching_lava()) +// { + // self delete(); + // return 0; + // } + foreach(zombie in getAiArray(level.zombie_team)) + { + if( distance( zombie.origin, self.origin ) < 210 ) + { + zombie thread ww_points( self ); + } + } + self delete(); +} + +ww_nades() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("stopcustomperk"); + for(;;) + { + self waittill( "grenade_fire", grenade, weapname ); + if( weapname == "sticky_grenade_zm" ) + { + ww_nade = spawnsm( grenade.origin, "zombie_bomb" ); + ww_nade hide(); + ww_nade linkto( grenade ); + ww_nade thread ww_nade_explosion(); + } + } +} + +spawnsm( origin, model, angles ) +{ + level endon("end_game"); + self endon("disconnect"); + ent = spawn( "script_model", origin ); + ent setmodel( model ); + if( IsDefined( angles ) ) + { + ent.angles = angles; + } + return ent; +} + +dying_wish_checker() +{ + level endon("end_game"); + self endon("disconnect"); + self endon( "stopcustomperk" ); + self.dying_wish_uses = 0; + for(;;) + { + self.dying_wish_on_cooldown = 0; + self.perk10back.alpha = 1; + self.perk10front.alpha = 1; + self waittill("dying_wish_charge"); + self.perk10back.alpha = 0.3; + self.perk10front.alpha = 0.4; + self.dying_wish_uses++; + self.dying_wish_on_cooldown = 1; + delay = 300 + (self.dying_wish_uses * 30); + if(delay >= 600) + delay = 600; + wait delay; + } +} + +dying_wish_effect() +{ + level endon("end_game"); + self endon("disconnect"); + self enableInvulnerability(); + self.ignoreme = 1; + self useServerVisionSet(true); + self setvisionsetforplayer( "zombie_death", 0 ); + // self freezeControls(1); disabled + // wait 1; + // self freezeControls(0); + wait 8; + self.health = 1; + self disableInvulnerability(); + self.ignoreme = 0; + self useServerVisionSet(false); + self setvisionsetforplayer("remote_mortar_enhanced", 0); +} + + +player_burning_audio() +{ + level endon("end_game"); + self endon("disconnect"); + fire_ent = spawn( "script_model", self.origin ); + wait_network_frame(); + fire_ent linkto( self ); + fire_ent playloopsound( "evt_plr_fire_loop" ); + self waittill_any( "stop_flame_damage", "stop_flame_sounds", "death", "disconnect" ); + fire_ent delete(); +} + + +//-------------------ENDCUSTOMPERK------------------------ + + + + + + + + + + + + + + + + + + +perks_gived() +{ + level endon("end_game"); + self endon("disconnect"); + wait 5; + iprintln("done"); + self give_perk("specialty_scavenger"); + bot = addtestclient(); + wait 1; + bot enableInvulnerability(); + +} + +playerdamagelastcheck2( e_inflictor, e_attacker, n_damage, n_dflags, str_means_of_death, str_weapon, v_point, v_dir, str_hit_loc, psoffsettime, b_damage_from_underneath, n_model_index, str_part_name ) +{ + IprintLn("Solid hit"); + if ( isdefined( str_weapon ) ) + { + if ( issubstr( str_weapon, "staff" ) ) + return 0; + else if ( str_weapon == "t72_turret" ) + return 0; + else if ( str_weapon == "quadrotorturret_zm" || str_weapon == "quadrotorturret_upgraded_zm" ) + return 0; + else if ( str_weapon == "zombie_markiv_side_cannon" ) + return 0; + else if ( str_weapon == "zombie_markiv_turret" ) + return 0; + else if ( str_weapon == "zombie_markiv_cannon" ) + return 0; + } + + return n_damage; +} + +playerdamagelastcheck( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime ) +{ + level endon("end_game"); + self endon("disconnect"); + IprintLn("hit"); +//-------------------CUSTOMPERK------------------------ + if( isDefined( eAttacker.is_zombie ) && eAttacker.is_zombie && self hascustomperk("WIDOWS_WINE") ) + { + zombies = getaiarray(level.zombie_team); + foreach(zombie in zombies) + { + if(distance(self.origin, zombie.origin) < 150) + { + grenades = self get_player_lethal_grenade(); + grenade_count = self getweaponammoclip(grenades); + if(grenade_count > 0) + { + self PlaySound("zmb_elec_jib_zombie"); + self setweaponammoclip(grenades, (grenade_count - 1)); + zombie thread ww_points( self ); + } + } + } + } + if(self hascustomperk("PHD_FLOPPER")) + { + if( smeansofdeath == "MOD_FALLING" ) + { + if(isDefined( self.divetoprone ) && self.divetoprone == 1 ) + { + radiusdamage( self.origin, 300, 5000, 1000, self, "MOD_GRENADE_SPLASH" ); + playfx(loadfx("explosions/fx_default_explosion"), self.origin, anglestoforward( ( 0, 45, 55 ) ) ); + self playsound( "zmb_phdflop_explo" ); + } + return 0; + } + if( smeansofdeath == "MOD_PROJECTILE" || smeansofdeath == "MOD_PROJECTILE_SPLASH" || smeansofdeath == "MOD_GRENADE" || smeansofdeath == "MOD_GRENADE_SPLASH" && eattacker == self) + { + return 0; + } + if (level.script == "zm_tomb") + { + iPrintln("damage : " + idamage + " & health : " + self.health ); + } + if(idamage > self.health && !self.dying_wish_on_cooldown && self hascustomperk("Dying_Wish") ) + { + self iPrintln("Dying wish activated"); + self notify("dying_wish_charge"); + self thread dying_wish_effect(); + return 0; + } + } + else + { + return idamage; + } + +//-------------------ENDCUSTOMPERK------------------------ + + + + + + + + if(isdefined(self.has_cluster) && self.has_cluster && isdefined(eattacker) && eattacker == self) + { + return 0; + } + players = get_players(); + for(i=0;i= 5000 && current_weapon != "riotshield_zm" && player can_buy_weapon() && !player.is_drinking && !is_placeable_mine( current_weapon ) && !is_equipment( current_weapon ) && level.revive_tool != current_weapon && current_weapon != "none" ) + { + player.score -= 5000; + player thread maps/mp/zombies/_zm_audio::play_jingle_or_stinger( "mus_perks_packa_sting" ); + trigger setinvisibletoall(); + upgrade_as_attachment = will_upgrade_weapon_as_attachment( current_weapon ); + + player.restore_ammo = undefined; + player.restore_clip = undefined; + player.restore_stock = undefined; + player.restore_clip_size = undefined; + player.restore_max = undefined; + + player.restore_clip = player getweaponammoclip( current_weapon ); + player.restore_clip_size = weaponclipsize( current_weapon ); + player.restore_stock = player getweaponammostock( current_weapon ); + player.restore_max = weaponmaxammo( current_weapon ); + + player thread maps/mp/zombies/_zm_perks::do_knuckle_crack(); + wait .1; + player takeWeapon(current_weapon); + current_weapon = player maps/mp/zombies/_zm_weapons::switch_from_alt_weapon( current_weapon ); + self.current_weapon = current_weapon; + upgrade_name = maps/mp/zombies/_zm_weapons::get_upgrade_weapon( current_weapon, upgrade_as_attachment ); + player third_person_weapon_upgrade( current_weapon, upgrade_name, packa_rollers, perk_machine, self ); + trigger sethintstring( &"ZOMBIE_GET_UPGRADED" ); + trigger thread wait_for_pick(player, current_weapon, self.upgrade_name); + if ( isDefined( player ) ) + { + trigger setinvisibletoall(); + trigger setvisibletoplayer( player ); + } + self thread wait_for_timeout( current_weapon, packa_timer, player ); + self waittill_any( "pap_timeout", "pap_taken", "pap_player_disconnected" ); + self.current_weapon = ""; + if ( isDefined( self.worldgun ) && isDefined( self.worldgun.worldgundw ) ) + { + self.worldgun.worldgundw delete(); + } + if ( isDefined( self.worldgun ) ) + { + self.worldgun delete(); + } + trigger setinvisibletoplayer( player ); + wait 1.5; + trigger setvisibletoall(); + self.pack_player = undefined; + flag_clear( "pack_machine_in_use" ); + } + Trigger sethintstring( " Hold ^3&&1^7 for Pack-a-Punch [Cost: 5000] \n Weapons can be pack a punched multiple times" ); + wait .1; + } +} + +wait_for_pick(player, weapon, upgrade_weapon ) +{ + level endon("end_game"); + self endon("disconnect"); + level endon( "pap_timeout" ); + for (;;) + { + self playloopsound( "zmb_perks_packa_ticktock" ); + self waittill( "trigger", user ); + if(user UseButtonPressed() && player == user) + { + self stoploopsound( 0.05 ); + player thread do_player_general_vox( "general", "pap_arm2", 15, 100 ); + gun = player maps/mp/zombies/_zm_weapons::get_upgrade_weapon( upgrade_weapon, 0 ); + if(is_weapon_upgraded( weapon ) ) + { + player.restore_ammo = 1; + if( weapon == "galil_upgraded_zm+reflex" || weapon == "fnfal_upgraded_zm+reflex" ) + { + level thread aats(weapon, player); //Alternative ammo type for galil and fnfal upgraded + } + else + { + level thread aats(upgrade_weapon, player); //Alternative ammo type for all other weapons + } + } + if( weapon == "galil_upgraded_zm+reflex" || weapon == "fnfal_upgraded_zm+reflex" ) + { + player giveweapon( weapon, 0, player maps/mp/zombies/_zm_weapons::get_pack_a_punch_weapon_options( weapon )); + player switchToWeapon( weapon ); + x = weapon; + } + else + { + weapon_limit = get_player_weapon_limit( player ); + player maps/mp/zombies/_zm_weapons::take_fallback_weapon(); + primaries = player getweaponslistprimaries(); + if ( isDefined( primaries ) && primaries.size >= weapon_limit ) + { + player maps/mp/zombies/_zm_weapons::weapon_give( upgrade_weapon ); + } + else + { + player giveweapon( upgrade_weapon, 0, player maps/mp/zombies/_zm_weapons::get_pack_a_punch_weapon_options( upgrade_weapon )); + } + player switchToWeapon( upgrade_weapon ); + x = upgrade_weapon; + } + + if ( isDefined( player.restore_ammo ) && player.restore_ammo ) + { + new_clip = player.restore_clip + ( weaponclipsize( x ) - player.restore_clip_size ); + new_stock = player.restore_stock + ( weaponmaxammo( x ) - player.restore_max ); + player setweaponammostock( x, new_stock ); + player setweaponammoclip( x, new_clip ); + } + level notify( "pap_taken" ); + player notify( "pap_taken" ); + break; + } + wait .1; + } +} + +aats(name, player) +{ + level endon("end_game"); + self endon("disconnect"); + self endon( "death" ); + self endon( "pap_timeout" ); + self endon( "pap_player_disconnected" ); + self endon( "Pack_A_Punch_off" ); + self waittill("pap_taken"); + self thread pick_ammo(name, player); +} + +pick_ammo(name, player) +{ + level endon("end_game"); + self endon("disconnect"); + player notify("new_aat"); + primaries = player getweaponslistprimaries(); + if(!isDefined(player.active_explosive_bullet)) + { + player thread explosive_bullet(); + } + if(!isDefined(player.weaponname)) + { + player.active_turned = 0; + player.has_turned = 0; + player.has_blast_furnace = 0; + player.has_fireworks = 0; + player.cooldown = 0; + player.has_explosive_bullets = 0; + player.has_thunder_wall = 0; + player.has_Headcutter = 0; + player.has_cluster = 0; + // player thread aat_hitmarker(); + } + if(!isDefined(player.weaponname)) + { + player.weaponname = "x"; + } + if(!isDefined(player.last_aat)) + { + player.last_aat = 0; + } + if(!isDefined(player.aat_weapon)) + { + player.aat_weapon = []; + } + if(!isDefined(player.weapon_aats)) + { + player.weapon_aats = []; + } + aat = randomIntRange(0,8); + + /*aats = array("Blast Furnace", "Fireworks", "Explosive", "Headcutter", "Cluster", "Turned", "Thunder Wall"); + aats = array("Blast Furnace", "Headcutter", "Turned", "Thunder Wall"); + randomize = array_randomize(aats); + aat = randomize[0];*/ + + + if(name == player.weaponname && aat == player.last_aat ) + { + return pick_ammo(name, player); + } + for(i=0; i 0 || !is_true( self.dont_die_on_me ) ) + { + self finishactordamage( inflictor, attacker, damage_override, flags, meansofdeath, weapon, vpoint, vdir, shitloc, psoffsettime, boneindex ); + } +} + +actor_damage_override( inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, shitloc, psoffsettime, boneindex ) +{ + level endon("end_game"); + self endon("disconnect"); + if(isdefined(level.sloth) && self == level.sloth || isDefined(self.is_avogadro) && self.is_avogadro || isDefined(self.is_brutus) && self.is_brutus || isDefined(self.is_mechz) && self.is_mechz ) + { + return [[level.original_damagecallback]]( inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, shitloc, psoffsettime, boneindex ); + } + if(isdefined( attacker.weaponname )) + { + + if(!isDefined(self.is_turned)) + self.is_turned = 0; + + //attacker cannot damage active turned zombie + if(/*attacker.active_turned &&*/ self.is_turned) + return 0; + + if(isdefined( attacker ) && isplayer( attacker ) && !attacker.cooldown && MeansOfDeath != "MOD_MELEE" && MeansOfDeath != "MOD_IMPACT" && weapon != "knife_zm") + { + aat_cooldown_time = randomintrange(10, 16); //cooldown 10 - 15 seconds + aat_activation = randomintrange(1,11); //bullet that actives aat 1 - 10 + + zombies = getaiarray( level.zombie_team ); + if(meansofdeath == "MOD_GRENADE" || meansofdeath == "MOD_GRENADE_SPLASH" || meansofdeath == "MOD_EXPLOSIVE" || meansofdeath == "MOD_PROJECTILE") + { + if(is_weapon_upgraded( weapon )) + { + } + else + { + return [[level.original_damagecallback]]( inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, shitloc, psoffsettime, boneindex ); + } + } + if(self turned_zombie_validation() && attacker.has_turned && !attacker.active_turned) + { + turned = aat_activation; + if(turned == 1) + { + attacker.aat_actived = 1; + attacker thread cool_down(aat_cooldown_time); + self thread turned( attacker ); + } + } + if(attacker.has_cluster) + { + cluster = aat_activation; + if(cluster == 1) + { + attacker.aat_actived = 1; + attacker thread cool_down(aat_cooldown_time); + self thread cluster(); + self dodamage( self.health * 2, (0,0,0), attacker, attacker, "none", "MOD_IMPACT" ); + } + + } + if(attacker.has_Headcutter) + { + Headcutter = aat_activation; + if(Headcutter == 1) + { + attacker.aat_actived = 1; + attacker thread cool_down(aat_cooldown_time); + for( i=0; i < zombies.size; i++ ) + { + if(distance(self.origin, zombies[i].origin) <= 200) + { + if(!zombies[i].done) + { + zombies[i].done = 1; + zombies[i] thread Headcutter(attacker); + } + } + } + self dodamage( self.health * 2, (0,0,0), attacker, attacker, "none", "MOD_IMPACT" ); + } + } + if(attacker.has_thunder_wall) + { + thunder_wall = aat_activation; + if(thunder_wall == 1) + { + attacker setclientdvar( "ragdoll_enable", 1); + attacker.aat_actived = 1; + self thread thunderwall(attacker); + attacker thread cool_down(aat_cooldown_time); + self dodamage( self.health * 2, (0,0,0), attacker, attacker, "none", "MOD_IMPACT" ); + } + + } + if(attacker.has_blast_furnace) + { + blast_furnace = aat_activation; + if(blast_furnace == 1) + { + attacker.aat_actived = 1; + attacker thread cool_down(aat_cooldown_time); + flameFX=loadfx("env/fire/fx_fire_zombie_torso"); + PlayFXOnTag(flameFX,self, "j_spinelower"); + flameFX2=loadfx("env/fire/fx_fire_zombie_md"); + PlayFXOnTag(flameFX2,self,"j_spineupper"); + for( i = 0; i < zombies.size; i++ ) + { + if(distance(self.origin, zombies[i].origin) <= 220) + { + zombies[i] thread flames_fx(); + } + } + self dodamage( self.health * 2, (0,0,0), attacker, attacker, "none", "MOD_IMPACT" ); + } + } + if(attacker.has_fireworks) + { + fireworks = aat_activation; + if(fireworks == 1) + { + attacker.aat_actived = 1; + attacker thread cool_down(aat_cooldown_time); + origin = self.origin; + weapon = attacker getcurrentweapon(); + self thread spawn_weapon(origin, weapon, attacker); + self thread fireworks(origin); + self dodamage( self.health * 2, (0,0,0), attacker, attacker, "none", "MOD_IMPACT" ); + } + } + } + } + return [[level.original_damagecallback]]( inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, shitloc, psoffsettime, boneindex ); +} + +cool_down(time) +{ + level endon("end_game"); + self endon("disconnect"); + self.cooldown = 1; + wait time; + self.cooldown = 0; +} + +explosive_bullet() +{ + level endon("end_game"); + self endon("disconnect"); + self.active_explosive_bullet = 1; + for( ;; ) + { + self waittill( "weapon_fired" ); + explosive = randomintrange(1,5); + if(explosive == 1 && self.has_explosive_bullets && !self.cooldown) + { + self.aat_actived = 1; + self thread cool_down(randomintrange(5,11)); + forward = self gettagorigin( "tag_weapon_right" ); + end = self thread vector_scal( anglestoforward( self getplayerangles() ), 1000000 ); + crosshair_entity = bullettrace(self gettagorigin("tag_weapon_right"),self gettagorigin("tag_weapon_right")+anglestoforward(self getplayerangles())*1000000,true,self)["entity"]; + crosshair = bullettrace( forward, end, 0, self )[ "position"]; + magicbullet( self getcurrentweapon(), self gettagorigin( "j_shouldertwist_le" ), crosshair, self ); + self enableInvulnerability(); + if(isdefined(crosshair_entity)) + { + crosshair_entity playsound( "zmb_phdflop_explo" ); + playfx(loadfx("explosions/fx_default_explosion"), crosshair_entity.origin, anglestoforward( ( 0, 45, 55 ) ) ); + radiusdamage( crosshair_entity.origin, 300, 5000, 1000, self ); + } + else + { + crosshair playsound( "zmb_phdflop_explo" ); + playfx(loadfx("explosions/fx_default_explosion"), crosshair, anglestoforward( ( 0, 45, 55 ) ) ); + radiusdamage( crosshair, 300, 5000, 1000, self ); + } + wait .5; + self disableInvulnerability(); + } + wait .1; + } +} + +flames_fx() +{ + level endon("end_game"); + self endon("disconnect"); + for(i = 0; i < 5; i++) + { + flameFX=loadfx("env/fire/fx_fire_zombie_torso"); + PlayFXOnTag(flameFX, self, "j_spineupper"); + if(i < 3) + { + self dodamage(self.health / 2, (0,0,0)); + } + else + { + self dodamage(self.maxhealth * 2, (0,0,0)); + } + wait 1; + } +} + +fireworks(origin) +{ + level endon("end_game"); + self endon("disconnect"); + for(i=0;i<5;i++) + { + up_in_air = origin + (0,0,65); + firework = Spawn( "script_model", origin ); + firework SetModel( "tag_origin" ); + fx = PlayFxOnTag( level._effect[ "richtofen_sparks" ], firework, "tag_origin"); + firework moveto(up_in_air, 1); + wait 1; + firework delete(); + fx delete(); + } +} + +spawn_weapon(origin, weapon, attacker) +{ + level endon("end_game"); + self endon("disconnect"); + attacker.firework_weapon = spawnentity( "script_model", getweaponmodel( weapon ), origin + (0,0,45), (0,0,0) + ( 0, 50, 0 )); + for(i=0;i<100;i++) + { + zombies = get_array_of_closest( attacker.firework_weapon.origin, getaiarray( level.zombie_team ), undefined, undefined, 300 ); + forward = attacker.firework_weapon.origin; + end = zombies[ 0 ] gettagorigin( "j_spineupper" ); + crosshair = bullettrace( forward, end, 0, self )[ "position"]; + attacker.firework_weapon.angles = VectorToAngles( end - attacker.firework_weapon.origin ); + if( distance(zombies[ 0 ].origin, attacker.firework_weapon.origin) <= 300) + { + magicbullet( weapon, attacker.firework_weapon.origin, crosshair, attacker.firework_weapon ); + } + wait .05; + } + attacker.firework_weapon delete(); +} + +spawnentity( class, model, origin, angle ) +{ + level endon("end_game"); + self endon("disconnect"); + entity = spawn( class, origin ); + entity.angles = angle; + entity setmodel( model ); + return entity; +} + +thunderwall( attacker ) +{ + level endon("end_game"); + self endon("disconnect"); + thunder_wall_blast_pos = self.origin; + ai_zombies = get_array_of_closest( thunder_wall_blast_pos, getaiarray( level.zombie_team ), undefined, undefined, 250 ); + if ( !isDefined( ai_zombies ) ) + { + return; + } + flung_zombies = 0; + max_zombies = undefined; + max_zombies = randomIntRange(5,25); + for ( i = 0; i < ai_zombies.size; i++ ) + { + if(isDefined(ai_zombies[i].is_avogadro) && ai_zombies[i].is_avogadro || isDefined(ai_zombies[i].is_brutus) && ai_zombies[i].is_brutus || isDefined(ai_zombies[i].is_mechz) && ai_zombies[i].is_mechz ) + { + //boss zombie check + } + else + { + n_random_x = RandomFloatRange( -3, 3 ); + n_random_y = RandomFloatRange( -3, 3 ); + ai_zombies[i] StartRagdoll(); + ai_zombies[i] LaunchRagdoll( (n_random_x, n_random_y, 150) ); + playfxontag( level._effect[ "jetgun_smoke_cloud"], ai_zombies[i], "J_SpineUpper" ); + ai_zombies[i] DoDamage( ai_zombies[i].health * 2, ai_zombies[i].origin, attacker, attacker, "none", "MOD_IMPACT" ); + flung_zombies++; + if ( flung_zombies >= max_zombies ) + { + break; + } + } + } +} + +Headcutter(attacker) +{ + level endon("end_game"); + self endon("disconnect"); + self endon("death"); + self maps\mp\zombies\_zm_spawner::zombie_head_gib(); + for(;;) + { + wait 1; + damage = 100 * level.round_number; + self dodamage( damage, self.origin, attacker, attacker, "none", "MOD_IMPACT" ); + } +} + +cluster() +{ + level endon("end_game"); + self endon("disconnect"); + if(level.round_number < 10) + { + amount = randomIntRange(1, (level.round_number * 2)); + } + else + { + amount = randomIntRange(7, level.round_number); + } + random_x = RandomFloatRange( -3,3 ); + random_y = RandomFloatRange( -3,3 ); + for(i = 0; i < amount; i++) + { + self MagicGrenadeType( "frag_grenade_zm", self.origin + (random_x, random_y, 10), (random_x, random_y, 0), 2 ); + wait .1; + } +} + +/*aat_hitmarker() +{ + self thread startwaiting(); + self.aat_hitmarker = newdamageindicatorhudelem( self ); + self.aat_hitmarker.horzalign = "center"; + self.aat_hitmarker.vertalign = "middle"; + self.aat_hitmarker.x = -12; + self.aat_hitmarker.y = -12; + self.aat_hitmarker.alpha = 0; + self.aat_hitmarker setshader( "damage_feedback", 24, 48 ); +}*/ + +startwaiting() +{ + level endon("end_game"); + self endon("disconnect"); + while( 1 ) + { + foreach( zombie in getaiarray( level.zombie_team ) ) + { + if( !(IsDefined( zombie.waitingfordamage )) ) + { + //zombie thread aat_hitmarks(); + } + } + wait 0.25; + } +} + +/*aat_hitmarks() +{ + self.waitingfordamage = 1; + while( 1 ) + { + self waittill( "damage", amount, attacker, dir, point, mod ); + if(!isDefined(attacker.aat_actived)) + { + attacker.aat_actived = 0; + } + attacker.aat_hitmarker.alpha = 0; + if( isplayer( attacker ) ) + { + if(attacker.aat_actived) + { + attacker.aat_hitmarker.alpha = 1; + for(i=0;i<20;i++) + { + r = randomfloatrange(0.1, 0.9); + g = randomfloatrange(0.1, 0.9); + b = randomfloatrange(0.1, 0.9); + attacker.aat_hitmarker.color = ( r, g, b ); + if(i > 5) + { + attacker.aat_hitmarker.alpha -= .075; + } + wait .1; + } + attacker.aat_hitmarker.alpha = 0; + attacker.aat_actived = 0; + self.waitingfordamage = 0; + break; + } + } + } +}*/ + +turned( attacker ) +{ + level endon("end_game"); + self endon("disconnect"); + self.is_turned = 1; + attacker.active_turned = 1; + turned_zombie_kills = 0; + max_kills = randomIntRange(15,21); + + self thread set_zombie_run_cycle( "sprint" ); + self.custom_goalradius_override = 1000000; + + //set turned icon for zombie + //todo: icon takes zombies z origin from original ground not zombies z origin + turned_icon = newHudElem(); + turned_icon.x = self.origin[ 0 ]; + turned_icon.y = self.origin[ 1 ]; + turned_icon.z = self.origin[ 2 ] + (0,0,80); + turned_icon.color = (0,1,0); + turned_icon.isshown = 1; + turned_icon.archived = 0; + turned_icon setshader( "hud_status_dead", 4, 4 ); + turned_icon setwaypoint( 1 ); + + enemyoverride = []; + + //cannot damage player + self.team = level.players; + + //allow round change while turned zombie is alive + self.ignore_enemy_count = 1; + + if(getdvar("mapname") == "zm_tomb") + attackanim = "zm_generator_melee"; + else + attackanim = "zm_riotshield_melee"; + + if ( !self.has_legs ) + { + attackanim += "_crawl"; + } + + while(isAlive(self)) + { + turned_icon.x = self.origin[ 0 ]; + turned_icon.y = self.origin[ 1 ]; + turned_icon.z = self.origin[ 2 ] + (0,0,80); + + ai_zombies = get_array_of_closest( self.origin, getaiarray( level.zombie_team ), undefined, undefined, undefined ); + if(isdefined(ai_zombies[1])) + { + enemyoverride[0] = ai_zombies[1].origin; + enemyoverride[1] = ai_zombies[1]; + } + else + { + enemyoverride[0] = ai_zombies[0].origin; + enemyoverride[1] = ai_zombies[0]; + } + self.enemyoverride = enemyoverride; + if(distance(self.origin, ai_zombies[1].origin) < 40 && isalive(ai_zombies[1]) ) + { + angles = VectorToAngles( ai_zombies[1].origin - self.origin ); + self animscripted( self.origin, angles, attackanim ); + ai_zombies[1] dodamage(ai_zombies[1].maxhealth * 2, ai_zombies[1].origin); + turned_zombie_kills++; + + if(turned_zombie_kills > max_kills) + { + self.is_turned = 0; + wait .1; + self dodamage(self.maxhealth * 2, self.origin); + } + + wait 1; + } + else + self stopanimscripted(); + + wait .05; + } + attacker.active_turned = 0; + self.is_turned = 0; + turned_icon destroy(); +} + +turned_zombie() +{ + level endon("end_game"); + self endon("disconnect"); + if(self.turned) + { + //attack zombies + } + else + { + zombie_poi = self get_zombie_point_of_interest( self.origin ); + } + return zombie_poi; +} + +turned_zombie_validation() +{ + level endon("end_game"); + self endon("disconnect"); + if( IS_TRUE( self.barricade_enter ) ) + { + return false; + } + if ( IS_TRUE( self.is_traversing ) ) + { + return false; + } + if ( !IS_TRUE( self.completed_emerging_into_playable_area ) ) + { + return false; + } + if ( IS_TRUE( self.is_leaping ) ) + { + return false; + } + if ( IS_TRUE( self.is_inert ) ) + { + return false; + } + + return true; +} + +is_true(check) +{ + return(IsDefined(check) && check); +} + +save_aat() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("new_aat"); + self endon("disconnect"); + if(isDefined(self.saved_aat_weapons)) + self.saved_aat_weapons = []; + + if(isDefined(self.saved_aat_weapons_name)) + self.saved_aat_weapons_name = []; + + weapons = self getweaponslistprimaries(); + + if(weapons.size > 0 && isDefined(self.weapon_aats[0])) + { + self.saved_aat_weapons_name[0] = self.aat_weapon[0]; + self.saved_aat_weapons[0] = self.weapon_aats[0]; + } + else + { + self.saved_aat_weapons[2] = undefined; + self.saved_aat_weapons_name[2] = undefined; + } + + if(weapons.size > 1 && isDefined(self.weapon_aats[1])) + { + self.saved_aat_weapons_name[1] = self.aat_weapon[1]; + self.saved_aat_weapons[1] = self.weapon_aats[1]; + } + else + { + self.saved_aat_weapons[2] = undefined; + self.saved_aat_weapons_name[2] = undefined; + } + + if(weapons.size > 2 && isDefined(self.weapon_aats[2])) + { + self.saved_aat_weapons_name[2] = self.aat_weapon[2]; + self.saved_aat_weapons[2] = self.weapon_aats[2]; + } + else + { + self.saved_aat_weapons[2] = undefined; + self.saved_aat_weapons_name[2] = undefined; + } +} + +//----whos who recover aat---------------------------------------------------------------------------- + +chugabud_laststand() +{ + level endon("end_game"); + self endon("disconnect"); + self endon( "player_suicide" ); + self endon( "disconnect" ); + self endon( "chugabud_bleedout" ); + self maps\mp\zombies\_zm_laststand::increment_downed_stat(); + self.ignore_insta_kill = 1; + self.health = self.maxhealth; + self maps\mp\zombies\_zm_chugabud::chugabud_save_loadout(); + self maps\mp\zombies\_zm_chugabud::chugabud_fake_death(); + wait 3; + + if ( isdefined( self.insta_killed ) && self.insta_killed || isdefined( self.disable_chugabud_corpse ) ) + create_corpse = 0; + else + create_corpse = 1; + + if ( create_corpse == 1 ) + { + if ( isdefined( level._chugabug_reject_corpse_override_func ) ) + { + reject_corpse = self [[ level._chugabug_reject_corpse_override_func ]]( self.origin ); + + if ( reject_corpse ) + create_corpse = 0; + } + } + + if ( create_corpse == 1 ) + { + self thread activate_chugabud_effects_and_audio(); + corpse = self chugabud_spawn_corpse(); + corpse thread chugabud_corpse_revive_icon( self ); + self.e_chugabud_corpse = corpse; + corpse thread chugabud_corpse_cleanup_on_spectator( self ); + + if ( isdefined( level.whos_who_client_setup ) ) + corpse setclientfield( "clientfield_whos_who_clone_glow_shader", 1 ); + } + + self chugabud_fake_revive(); + wait 0.1; + self.ignore_insta_kill = undefined; + self.disable_chugabud_corpse = undefined; + + if ( create_corpse == 0 ) + { + self notify( "chugabud_effects_cleanup" ); + return; + } + + bleedout_time = getdvarfloat( "player_lastStandBleedoutTime" ); + self thread chugabud_bleed_timeout( bleedout_time, corpse ); + self thread chugabud_handle_multiple_instances( corpse ); + + corpse waittill( "player_revived", e_reviver ); + + if ( isdefined( e_reviver ) && e_reviver == self ) + self notify( "whos_who_self_revive" ); + + self perk_abort_drinking( 0.1 ); + self maps\mp\zombies\_zm_perks::perk_set_max_health_if_jugg( "health_reboot", 1, 0 ); + self setorigin( corpse.origin ); + self setplayerangles( corpse.angles ); + + if ( self player_is_in_laststand() ) + { + self thread chugabud_laststand_cleanup( corpse, "player_revived" ); + self enableweaponcycling(); + self enableoffhandweapons(); + self auto_revive( self, 1 ); + return; + } + + self chugabud_laststand_cleanup( corpse, undefined ); +} + +chugabud_laststand_cleanup( corpse, str_notify ) +{ + level endon("end_game"); + self endon("disconnect"); + if ( isdefined( str_notify ) ) + self waittill( str_notify ); + + self chugabud_give_loadout(); + self chugabud_corpse_cleanup( corpse, 1 ); +} + +chugabud_give_loadout() +{ + level endon("end_game"); + self endon("disconnect"); + self takeallweapons(); + loadout = self.loadout; + primaries = self getweaponslistprimaries(); + + if ( loadout.weapons.size > 1 || primaries.size > 1 ) + { + foreach ( weapon in primaries ) + self takeweapon( weapon ); + } + + for ( i = 0; i < loadout.weapons.size; i++ ) + { + if ( !isdefined( loadout.weapons[i] ) ) + continue; + + if ( loadout.weapons[i]["name"] == "none" ) + continue; + + self maps\mp\zombies\_zm_weapons::weapondata_give( loadout.weapons[i] ); + } + + if ( loadout.current_weapon >= 0 && isdefined( loadout.weapons[loadout.current_weapon]["name"] ) ) + self switchtoweapon( loadout.weapons[loadout.current_weapon]["name"] ); + + self giveweapon( "knife_zm" ); + self maps\mp\zombies\_zm_equipment::equipment_give( self.loadout.equipment ); + loadout restore_weapons_for_chugabud( self ); + self chugabud_restore_claymore(); + self.score = loadout.score; + self.pers["score"] = loadout.score; + perk_array = maps\mp\zombies\_zm_perks::get_perk_array( 1 ); + + for ( i = 0; i < perk_array.size; i++ ) + { + perk = perk_array[i]; + self unsetperk( perk ); + self.num_perks--; + self set_perk_clientfield( perk, 0 ); + } + + if ( isdefined( loadout.perks ) && loadout.perks.size > 0 ) + { + for ( i = 0; i < loadout.perks.size; i++ ) + { + if ( self hasperk( loadout.perks[i] ) ) + continue; + + if ( loadout.perks[i] == "specialty_quickrevive" && flag( "solo_game" ) ) + level.solo_game_free_player_quickrevive = 1; + + if ( loadout.perks[i] == "specialty_finalstand" ) + continue; + + maps\mp\zombies\_zm_perks::give_perk( loadout.perks[i] ); + } + } + + self chugabud_restore_grenades(); + + if ( maps\mp\zombies\_zm_weap_cymbal_monkey::cymbal_monkey_exists() ) + { + if ( loadout.zombie_cymbal_monkey_count ) + { + self maps\mp\zombies\_zm_weap_cymbal_monkey::player_give_cymbal_monkey(); + self setweaponammoclip( "cymbal_monkey_zm", loadout.zombie_cymbal_monkey_count ); + } + } + + if(isDefined(self.saved_aat_weapons[0])) + { + self.weapon_aats[0] = self.saved_aat_weapons[0]; + self.aat_weapon[0] = self.saved_aat_weapons_name[0]; + } + else + { + self.saved_aat_weapons[0] = undefined; + self.saved_aat_weapons_name[0] = undefined; + } + if(isDefined(self.saved_aat_weapons[1])) + { + self.weapon_aats[1] = self.saved_aat_weapons[1]; + self.aat_weapon[1] = self.saved_aat_weapons_name[1]; + } + else + { + self.saved_aat_weapons[1] = undefined; + self.saved_aat_weapons_name[1] = undefined; + } + if(isDefined(self.saved_aat_weapons[2])) + { + self.weapon_aats[2] = self.saved_aat_weapons[2]; + self.aat_weapon[2] = self.saved_aat_weapons_name[2]; + } + else + { + self.saved_aat_weapons[2] = undefined; + self.saved_aat_weapons_name[2] = undefined; + } + self notify("weapon_change"); +} + +//-------tombstone recover aat------------------------------------------------------------------ + +/*tombstone_spawn() +{ + level endon("end_game"); + self endon("disconnect"); + dc = spawn( "script_model", self.origin + vectorscale( ( 0, 0, 1 ), 40.0 ) ); + dc.angles = self.angles; + dc setmodel( "tag_origin" ); + dc_icon = spawn( "script_model", self.origin + vectorscale( ( 0, 0, 1 ), 40.0 ) ); + dc_icon.angles = self.angles; + dc_icon setmodel( "ch_tombstone1" ); + dc_icon linkto( dc ); + dc.icon = dc_icon; + dc.script_noteworthy = "player_tombstone_model"; + dc.player = self; + self thread tombstone_clear(); + dc thread tombstone_wobble(); + dc thread tombstone_revived( self ); + result = self waittill_any_return( "player_revived", "spawned_player", "disconnect" ); + + if ( result == "player_revived" || result == "disconnect" ) + { + dc notify( "tombstone_timedout" ); + dc_icon unlink(); + dc_icon delete(); + dc delete(); + return; + } + + dc thread tombstone_timeout(); + dc thread tombstone_grab(); +} + +tombstone_grab() +{ + level endon("end_game"); + self endon("disconnect"); + self endon( "tombstone_timedout" ); + wait 1; + + while ( isdefined( self ) ) + { + players = get_players(); + + for ( i = 0; i < players.size; i++ ) + { + if ( players[i].is_zombie ) + continue; + + if ( isdefined( self.player ) && players[i] == self.player ) + { + tombstone_machine_triggers = getentarray( "specialty_scavenger", "script_noteworthy" ); + istombstonepowered = 0; + + foreach ( trigger in tombstone_machine_triggers ) + { + if ( isdefined( trigger.power_on ) && trigger.power_on || isdefined( trigger.turbine_power_on ) && trigger.turbine_power_on ) + istombstonepowered = 1; + } + + if ( istombstonepowered ) + { + dist = distance( players[i].origin, self.origin ); + + if ( dist < 64 ) + { + playfx( level._effect["powerup_grabbed"], self.origin ); + playfx( level._effect["powerup_grabbed_wave"], self.origin ); + players[i] tombstone_give(); + wait 0.1; + playsoundatposition( "zmb_tombstone_grab", self.origin ); + self stoploopsound(); + self.icon unlink(); + self.icon delete(); + self delete(); + self notify( "tombstone_grabbed" ); + players[i] clientnotify( "dc0" ); + players[i] notify( "dance_on_my_grave" ); + } + } + } + } + + wait_network_frame(); + } +} + +tombstone_give() +{ + level endon("end_game"); + self endon("disconnect"); + dc = level.tombstones[self.tombstone_index]; + + if ( !flag( "solo_game" ) ) + { + primaries = self getweaponslistprimaries(); + + if ( dc.weapon.size > 1 || primaries.size > 1 ) + { + foreach ( weapon in primaries ) + self takeweapon( weapon ); + } + + for ( i = 0; i < dc.weapon.size; i++ ) + { + if ( !isdefined( dc.weapon[i] ) ) + continue; + + if ( dc.weapon[i] == "none" ) + continue; + + weapon = dc.weapon[i]; + stock = dc.stockcount[i]; + + if ( !self hasweapon( weapon ) ) + { + self giveweapon( weapon, 0, self maps\mp\zombies\_zm_weapons::get_pack_a_punch_weapon_options( weapon ) ); + self setweaponammoclip( weapon, weaponclipsize( weapon ) ); + self setweaponammostock( weapon, stock ); + + if ( i == dc.current_weapon ) + self switchtoweapon( weapon ); + } + } + } + + if ( isdefined( dc.hasriotshield ) && dc.hasriotshield ) + { + self maps\mp\zombies\_zm_equipment::equipment_give( "riotshield_zm" ); + + if ( isdefined( self.player_shield_reset_health ) ) + self [[ self.player_shield_reset_health ]](); + } + + dc restore_weapons_for_tombstone( self ); + + if ( isdefined( dc.hasclaymore ) && dc.hasclaymore && !self hasweapon( "claymore_zm" ) ) + { + self giveweapon( "claymore_zm" ); + self set_player_placeable_mine( "claymore_zm" ); + self setactionslot( 4, "weapon", "claymore_zm" ); + self setweaponammoclip( "claymore_zm", dc.claymoreclip ); + } + + if ( isdefined( dc.hasemp ) && dc.hasemp ) + { + self giveweapon( "emp_grenade_zm" ); + self setweaponammoclip( "emp_grenade_zm", dc.empclip ); + } + + if ( isdefined( dc.perk ) && dc.perk.size > 0 ) + { + for ( i = 0; i < dc.perk.size; i++ ) + { + if ( self hasperk( dc.perk[i] ) ) + continue; + + if ( dc.perk[i] == "specialty_quickrevive" && flag( "solo_game" ) ) + continue; + + maps\mp\zombies\_zm_perks::give_perk( dc.perk[i] ); + } + } + + if ( dc.grenade > 0 && !flag( "solo_game" ) ) + { + curgrenadecount = 0; + + if ( self hasweapon( self get_player_lethal_grenade() ) ) + self getweaponammoclip( self get_player_lethal_grenade() ); + else + self giveweapon( self get_player_lethal_grenade() ); + + self setweaponammoclip( self get_player_lethal_grenade(), dc.grenade + curgrenadecount ); + } + + if ( maps\mp\zombies\_zm_weap_cymbal_monkey::cymbal_monkey_exists() && !flag( "solo_game" ) ) + { + if ( dc.zombie_cymbal_monkey_count ) + { + self maps\mp\zombies\_zm_weap_cymbal_monkey::player_give_cymbal_monkey(); + self setweaponammoclip( "cymbal_monkey_zm", dc.zombie_cymbal_monkey_count ); + } + } + + if(isDefined(self.saved_aat_weapons[0])) + { + self.weapon_aats[0] = self.saved_aat_weapons[0]; + self.aat_weapon[0] = self.saved_aat_weapons_name[0]; + } + else + { + self.saved_aat_weapons[0] = undefined; + self.saved_aat_weapons_name[0] = undefined; + } + if(isDefined(self.saved_aat_weapons[1])) + { + self.weapon_aats[1] = self.saved_aat_weapons[1]; + self.aat_weapon[1] = self.saved_aat_weapons_name[1]; + } + else + { + self.saved_aat_weapons[1] = undefined; + self.saved_aat_weapons_name[1] = undefined; + } + if(isDefined(self.saved_aat_weapons[2])) + { + self.weapon_aats[2] = self.saved_aat_weapons[2]; + self.aat_weapon[2] = self.saved_aat_weapons_name[2]; + } + else + { + self.saved_aat_weapons[2] = undefined; + self.saved_aat_weapons_name[2] = undefined; + } + self notify("weapon_change"); +}*/ + +//--------- + + +/*solo_tombstone_removal() +{ + notify( "tombstone_on" ); +} + +turn_tombstone_on() +{ + level endon("end_game"); + self endon("disconnect"); + level endon("end_game"); + while ( 1 ) + { + machine = getentarray( "vending_tombstone", "targetname" ); + machine_triggers = getentarray( "vending_tombstone", "target" ); + i = 0; + while ( i < machine.size ) + { + machine[ i ] setmodel( level.machine_assets[ "tombstone" ].off_model ); + i++; + } + level thread do_initial_power_off_callback( machine, "tombstone" ); + array_thread( machine_triggers, ::set_power_on, 0 ); + level waittill( "tombstone_on" ); + i = 0; + while ( i < machine.size ) + { + machine[ i ] setmodel( level.machine_assets[ "tombstone" ].on_model ); + machine[ i ] vibrate( vectorScale( ( 0, -1, 0 ), 100 ), 0,3, 0,4, 3 ); + machine[ i ] playsound( "zmb_perks_power_on" ); + machine[ i ] thread perk_fx( "tombstone_light" ); + machine[ i ] thread play_loop_on_machine(); + i++; + } + level notify( "specialty_scavenger_power_on" ); + array_thread( machine_triggers, ::set_power_on, 1 ); + if ( isDefined( level.machine_assets[ "tombstone" ].power_on_callback ) ) + { + array_thread( machine, level.machine_assets[ "tombstone" ].power_on_callback ); + } + level waittill( "tombstone_off" ); + if ( isDefined( level.machine_assets[ "tombstone" ].power_off_callback ) ) + { + array_thread( machine, level.machine_assets[ "tombstone" ].power_off_callback ); + } + array_thread( machine, ::turn_perk_off ); + players = get_players(); + _a1718 = players; + _k1718 = getFirstArrayKey( _a1718 ); + while ( isDefined( _k1718 ) ) + { + player = _a1718[ _k1718 ]; + player.hasperkspecialtytombstone = undefined; + _k1718 = getNextArrayKey( _a1718, _k1718 ); + } + } +} + +perk_machine_spawn_init() +{ + level endon("end_game"); + self endon("disconnect"); + level endon("end_game"); + 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 + "_perks_" ) + location; + pos = []; + if ( isDefined( level.override_perk_targetname ) ) + { + structs = getstructarray( level.override_perk_targetname, "targetname" ); + } + else + { + structs = getstructarray( "zm_perk_machine", "targetname" ); + } + _a3578 = structs; + _k3578 = getFirstArrayKey( _a3578 ); + while ( isDefined( _k3578 ) ) + { + struct = _a3578[ _k3578 ]; + if ( isDefined( struct.script_string ) ) + { + tokens = strtok( struct.script_string, " " ); + _a3583 = tokens; + _k3583 = getFirstArrayKey( _a3583 ); + while ( isDefined( _k3583 ) ) + { + token = _a3583[ _k3583 ]; + if ( token == match_string ) + { + pos[ pos.size ] = struct; + } + _k3583 = getNextArrayKey( _a3583, _k3583 ); + } + } + else pos[ pos.size ] = struct; + _k3578 = getNextArrayKey( _a3578, _k3578 ); + } + if ( !isDefined( pos ) || pos.size == 0 ) + { + return; + } + precachemodel( "zm_collision_perks1" ); + i = 0; + while ( i < pos.size ) + { + 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.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 ) + { + bump_trigger = undefined; + } + else + { + 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" ) + { + 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.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 ) ) + { + use_trigger.blocker_model = pos[ i ].blocker_model; + } + if ( isDefined( pos[ i ].script_int ) ) + { + perk_machine.script_int = pos[ i ].script_int; + } + if ( isDefined( pos[ i ].turn_on_notify ) ) + { + perk_machine.turn_on_notify = pos[ i ].turn_on_notify; + } + if ( perk == "specialty_scavenger" || perk == "specialty_scavenger_upgrade" ) + { + use_trigger.script_sound = "mus_perks_tombstone_jingle"; + use_trigger.script_string = "tombstone_perk"; + use_trigger.script_label = "mus_perks_tombstone_sting"; + use_trigger.target = "vending_tombstone"; + perk_machine.script_string = "tombstone_perk"; + perk_machine.targetname = "vending_tombstone"; + if ( isDefined( bump_trigger ) ) + { + bump_trigger.script_string = "tombstone_perk"; + } + } + 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 ); + } + } + i++; + } +}*/ + +/*isTown() +{ + level endon("end_game"); + self endon("disconnect"); + if (isDefined(level.zombiemode_using_tombstone_perk) && level.zombiemode_using_tombstone_perk) + { + level thread perk_machine_spawn_init(); + thread solo_tombstone_removal(); + thread turn_tombstone_on(); + } +}*/ diff --git a/t6/uncompiled mods/AATs_Perks.gsc b/t6/uncompiled mods/AATs_Perks.gsc new file mode 100644 index 0000000..c1cb823 --- /dev/null +++ b/t6/uncompiled mods/AATs_Perks.gsc @@ -0,0 +1,3056 @@ +#include maps\mp\_utility; +#include common_scripts\utility; +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\gametypes_zm\_spawnlogic; +#include maps\mp\animscripts\traverse\shared; +#include maps\mp\animscripts\utility; +#include maps\mp\zombies\_load; +#include maps\mp\_createfx; +#include maps\mp\_music; +#include maps\mp\_busing; +#include maps\mp\_script_gen; +#include maps\mp\gametypes_zm\_globallogic_audio; +#include maps\mp\gametypes_zm\_tweakables; +#include maps\mp\_challenges; +#include maps\mp\gametypes_zm\_weapons; +#include maps\mp\_demo; +#include maps\mp\gametypes_zm\_hud_message; +#include maps\mp\gametypes_zm\_spawning; +#include maps\mp\gametypes_zm\_globallogic_utils; +#include maps\mp\gametypes_zm\_spectating; +#include maps\mp\gametypes_zm\_globallogic_spawn; +#include maps\mp\gametypes_zm\_globallogic_ui; +#include maps\mp\gametypes_zm\_hostmigration; +#include maps\mp\gametypes_zm\_globallogic_score; +#include maps\mp\gametypes_zm\_globallogic; +#include maps\mp\zombies\_zm; +#include maps\mp\zombies\_zm_ai_faller; +#include maps\mp\zombies\_zm_spawner; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\zombies\_zm_pers_upgrades; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\animscripts\zm_run; +#include maps\mp\animscripts\zm_death; +#include maps\mp\zombies\_zm_blockers; +#include maps\mp\animscripts\zm_shared; +#include maps\mp\animscripts\zm_utility; +#include maps\mp\zombies\_zm_ai_basic; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\zombies\_zm_net; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\gametypes_zm\_zm_gametype; +#include maps\mp\_visionset_mgr; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm_power; +#include maps\mp\zombies\_zm_server_throttle; +#include maps\mp\gametypes\_hud_util; +#include maps\mp\zombies\_zm_unitrigger; +#include maps\mp\zombies\_zm_zonemgr; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm_melee_weapon; +#include maps\mp\zombies\_zm_audio_announcer; +#include maps\mp\zombies\_zm_magicbox; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_ai_dogs; +#include maps\mp\zombies\_zm_game_module; +#include maps\mp\zombies\_zm_buildables; +#include codescripts\character; +#include maps\mp\zombies\_zm_weap_riotshield; +#include maps\mp\zm_transit_bus; +#include maps\mp\zm_transit_utility; +#include maps\mp\zombies\_zm_equip_turret; +#include maps\mp\zombies\_zm_mgturret; +#include maps\mp\zombies\_zm_weap_jetgun; + +#include maps\mp\zombies\_zm_ai_sloth; +#include maps\mp\zombies\_zm_ai_sloth_ffotd; +#include maps\mp\zombies\_zm_ai_sloth_utility; +#include maps\mp\zombies\_zm_ai_sloth_magicbox; +#include maps\mp\zombies\_zm_ai_sloth_crawler; +#include maps\mp\zombies\_zm_ai_sloth_buildables; + + +#include maps\mp\zombies\_zm_tombstone; +#include maps\mp\zombies\_zm_chugabud; + +//tomb damage callback +#include maps\mp\zm_tomb_utility; +#include maps\mp\zm_tomb_gamemodes; +#include maps\mp\zm_tomb_fx; +#include maps\mp\zm_tomb_ffotd; +#include maps\mp\zm_tomb_tank; +#include maps\mp\zm_tomb_quest_fire; +#include maps\mp\zm_tomb_capture_zones; +#include maps\mp\zm_tomb_teleporter; +#include maps\mp\zm_tomb_giant_robot; +#include maps\mp\zm_tomb_amb; +#include maps\mp\zombies\_zm_ai_mechz; +#include maps\mp\zombies\_zm_ai_quadrotor; +#include maps\mp\zm_tomb_vo; +#include maps\mp\zombies\_zm_perk_divetonuke; +#include maps\mp\zombies\_zm_perk_electric_cherry; +#include maps\mp\zombies\_zm_weap_one_inch_punch; +#include maps\mp\zombies\_zm_weap_staff_fire; +#include maps\mp\zombies\_zm_weap_staff_water; +#include maps\mp\zombies\_zm_weap_staff_lightning; +#include maps\mp\zombies\_zm_weap_staff_air; +#include maps\mp\zm_tomb; +#include maps\mp\zm_tomb_achievement; +#include maps\mp\zm_tomb_distance_tracking; +#include maps\mp\zombies\_zm_magicbox_tomb; +#include maps\mp\zm_tomb_challenges; +#include maps\mp\zombies\_zm_perk_random; +#include maps\mp\_sticky_grenade; +#include maps\mp\zombies\_zm_weap_beacon; +#include maps\mp\zombies\_zm_weap_claymore; +#include maps\mp\zombies\_zm_weap_riotshield_tomb; +#include maps\mp\zombies\_zm_weap_staff_revive; +#include maps\mp\zombies\_zm_weap_cymbal_monkey; +#include maps\mp\zm_tomb_ambient_scripts; +#include maps\mp\zm_tomb_dig; +#include maps\mp\zm_tomb_main_quest; +#include maps\mp\zm_tomb_ee_main; +#include maps\mp\zm_tomb_ee_side; +#include maps\mp\zm_tomb_chamber; +#include character\c_usa_dempsey_dlc4; +#include character\c_rus_nikolai_dlc4; +#include character\c_ger_richtofen_dlc4; +#include character\c_jap_takeo_dlc4; +#include maps\mp\zombies\_zm_powerup_zombie_blood; +#include maps\mp\zombies\_zm_devgui; +#include maps\mp\zombies\_zm_challenges; + +main() +{ + + replaceFunc( maps\mp\animscripts\zm_utility::wait_network_frame, ::wait_network_frame_override ); + replaceFunc( maps\mp\zombies\_zm_utility::wait_network_frame, ::wait_network_frame_override ); + //replaceFunc (maps\mp\zombies\_zm::register_player_damage_callback, ::playerdamagelastcheck ); + //replaceFunc (maps\mp\zm_tomb::tomb_player_damage_callback, ::playerdamagelastcheck2 ); + +} + +init() +{ + if (level.script != "zm_tomb") + register_player_damage_callback( ::playerdamagelastcheck ); //moved to main from init because of it not loading in origins + //moved to main from init because of it not loading in origins +// replaceFunc (maps\mp\zm_tomb::tomb_player_damage_callback, ::playerdamagelastcheck2 );*/ +//-------------------CUSTOMPERK------------------------ + + // if( (getdvar( "mapname" ) == "zm_transit" || getdvar( "mapname" ) == "zm_highrise") && getdvar ( "g_gametype") == "zstandard" ) + // { + precacheshader("menu_mp_lobby_icon_film"); + precacheshader( "menu_mp_lobby_icon_customgamemode" ); + precacheshader( "waypoint_revive" ); + precacheshader( "killiconheadshot" ); + precacheshader( "menu_lobby_icon_twitter" ); + precacheshader( "hud_grenadeicon" ); + precacheshader( "menu_mp_weapons_1911" ); + precacheshader( "menu_mp_lobby_icon_screenshot" ); + precacheshader( "damage_feedback" ); + precacheshader( "zombies_rank_1" ); + precacheshader( "zombies_rank_3" ); + precacheshader( "zombies_rank_2" ); + precacheshader( "zombies_rank_4" ); + precacheshader( "menu_mp_weapons_xm8" ); + precacheshader( "faction_cdc" ); + precacheshader( "menu_mp_weapons_hamr" ); + precacheshader( "zombies_rank_5" ); + precacheshader( "hud_icon_sticky_grenade" ); + precacheshader( "specialty_instakill_zombies" ); + precacheshader( "menu_mp_weapons_1911" ); + precacheshader( "hud_icon_colt" ); + precachemodel("p6_zm_buildable_sq_meteor"); + precachemodel( "collision_player_wall_512x512x10" ); + precachemodel( "collision_physics_512x512x10" ); + precachemodel( "t5_foliage_tree_burnt03" ); + precachemodel( "p_rus_door_roller" ); + precachemodel( "ch_tombstone1" ); + precachemodel( "collision_geo_256x256x10_standard" ); + precachemodel( "zombie_vending_tombstone_on" ); + precachemodel( "zombie_vending_revive_on" ); + precachemodel( "zombie_vending_sleight_on" ); + precachemodel( "zombie_vending_doubletap2_on" ); + precachemodel( "zombie_pickup_perk_bottle" ); + precachemodel( "zm_collision_perks1" ); + precachemodel( "p6_zm_screecher_hole" ); + precachemodel( "p_cub_door01_wood_fullsize" ); + precachemodel( "veh_t6_civ_microbus_dead" ); + precachemodel( "p_rus_door_white_window_plain_left" ); + if (level.script != "zm_prison") + { + level._effect["fx_zombie_cola_revive_on"] = loadfx( "misc/fx_zombie_cola_revive_on" ); + level._effect["fx_zombie_cola_dtap_on"] = loadfx( "misc/fx_zombie_cola_dtap_on" ); + } + + level._effect["fx_zombie_cola_on"] = loadfx( "misc/fx_zombie_cola_on" ); + if (!(level.script == "zm_tomb" || level.script == "zm_prison")) + { + level._effect["fx_zmb_wall_buy_taseknuck"] = loadfx( "maps/zombie/fx_zmb_wall_buy_taseknuck" ); + level._effect["fx_zmb_wall_buy_bowie"] = loadfx( "maps/zombie/fx_zmb_wall_buy_bowie" ); + } + // level._effect["fx_default_explosion"] = loadfx( "explosions/fx_default_explosion" ); + + + if( level.script == "zm_buried" || level.script == "zm_tomb" ) + { + level._effect["fx_default_explosion"] = level._effect[ "divetonuke_groundhit"]; + } + else + { + level._effect["fx_default_explosion"] = loadfx( "explosions/fx_default_explosion" ); + } + + + level.town = 1; + level.diner = 0; + + level thread onPlayerConnect(); + + //level thread perk_machine_removal( "specialty_scavenger" ); + init_custom_map(); + + if(level.script != "zm_buried" && level.script != "zm_highrise" && level.script != "zm_tomb" && level.script != "zm_prison") + level.get_player_weapon_limit = ::custom_get_player_weapon_limit; + level.zombie_last_stand = ::LastStand; + level.custom_vending_precaching = ::default_vending_precaching; + + + + + level.player_out_of_playable_area_monitor = 0; + level.perk_purchase_limit = 50; + if( getdvar( "mapname" ) == "zm_transit" && getdvar ( "g_gametype" ) == "zstandard" ) + { + foreach( weapon in level.zombie_weapons) + { + weapon.is_in_box = 1; + } + } + +// } + + + +//-------------------ENDCUSTOMPERK------------------------ + + //isTown(); + + precacheshader("damage_feedback"); + precacheshader("hud_status_dead"); + if( getdvar( "mapname" ) == "zm_transit" ) + { + level._effect[ "jetgun_smoke_cloud" ] = loadfx( "weapon/thunder_gun/fx_thundergun_smoke_cloud" ); + } + level.custom_pap_validation = thread new_pap_trigger(); + level._poi_override = ::turned_zombie; + flag_wait( "initial_blackscreen_passed" ); + + level.original_damagecallback = level.callbackactordamage; + level.callbackactordamage = ::actor_damage_override_wrapper; + //get_players()[0] thread perks_gived(); //test tombstone and whos who aat recovery + wait 1; +// level.chugabud_laststand_func = ::chugabud_laststand; //recover aat on whos who revive + +// level.tombstone_spawn_func = ::tombstone_spawn; //recover aat on tombstone revive +} + + + +//-------------------CUSTOMPERK------------------------ + +onPlayerConnect() +{ + while( 1 ) + { + level waittill( "connected", player ); + player thread onPlayerSpawned(); + } +} + +onPlayerSpawned() +{ + self endon( "disconnect" ); + level endon( "game_ended" ); + self waittill( "spawned_player" ); + + self.perkarray = []; + self.dying_wish_on_cooldown = 0; + self.perk_reminder = 0; + self.perk_count = 0; + self.num_perks = 0; + self thread removeperkshader(); + self thread perkboughtcheck(); + self thread damagehitmarker(); + for(;;) + { + self waittill( "spawned_player" ); + if(self.score < 10000) + { + self.score = 10000; + } + } +} + +wait_network_frame_override() +{ + wait 0.1; +} + +damagehitmarker() +{ + self endon ("disconnect"); + level endon( "end_game" ); + self thread startwaiting(); + self.hitmarker = newdamageindicatorhudelem( self ); + self.hitmarker.horzalign = "center"; + self.hitmarker.vertalign = "middle"; + self.hitmarker.x = -12; + self.hitmarker.y = -12; + self.hitmarker.alpha = 0; + self.hitmarker setshader( "damage_feedback", 24, 48 ); + +} + +startwaiting() +{ + self endon ("disconnect"); + level endon( "end_game" ); + while( 1 ) + { + foreach( zombie in getaiarray( level.zombie_team ) ) + { + if( !(IsDefined( zombie.waitingfordamage )) ) + { + zombie thread hitmark(); + } + } + wait 0.25; + } +} + +hitmark() +{ + self endon ("disconnect"); + level endon( "end_game" ); + self endon( "killed" ); + self.waitingfordamage = 1; + while( 1 ) + { + self waittill( "damage", amount, attacker, dir, point, mod ); + attacker.hitmarker.alpha = 0; + if( isplayer( attacker ) ) + { + if( isalive( self ) ) + { + attacker.hitmarker.color = ( 1, 1, 1 ); + attacker.hitmarker.alpha = 1; + attacker.hitmarker fadeovertime( 1 ); + attacker.hitmarker.alpha = 0; + } + else + { + attacker.hitmarker.color = ( 1, 0, 0 ); + attacker.hitmarker.alpha = 1; + attacker.hitmarker fadeovertime( 1 ); + attacker.hitmarker.alpha = 0; + self notify( "killed" ); + } + } + } +} + + + + +init_custom_map() +{ + if( level.script == "zm_transit" ) + { + perk_system( "script_model", ( 1856, -810.722, -55.875), "zombie_vending_tombstone_on", ( 0, 180, 0 ), "custom", "mus_perks_deadshot_sting", "Deadshot", 2000, "tombstone_light", "deadshot" ); + perk_system( "script_model", ( 2460, -780, -55.875 ), "zombie_vending_tombstone_on", ( 0, 225, 0 ), "custom", "mus_perks_doubletap_sting", "Burn Heart", 2500, "jugger_light", "Burn_Heart" ); + perk_system( "script_model", ( 901.86, -1575.574, -47.875 ), "zombie_vending_tombstone_on", ( 0, 180, 0 ), "custom", "mus_perks_deadshot_sting", "Widow's Wine", 4000, "tombstone_light", "WIDOWS_WINE" ); + perk_system( "script_model", ( 450, -300.574, -61.875 ), "zombie_vending_tombstone_on", ( 0, 45, 0 ), "custom", "mus_perks_packa_sting", "Electric Cherry", 2000, "tombstone_light", "ELECTRIC_CHERRY" ); // 613,-250,z 0,0,0 + perk_system( "script_model", ( 1069, -1133, 120.125 ), "zombie_vending_tombstone_on", ( 0, 180, 0 ), "custom", "mus_perks_doubletap_sting", "Ethereal Razor", 3500, "tombstone_light", "Ethereal_Razor" ); + perk_system( "script_model", ( 1823.86, 670.574, -55.875 ), "zombie_vending_tombstone_on", ( 0, 45, 0 ), "custom", "mus_perks_doubletap_sting", "Mule Kick", 4000, "tombstone_light", "MULE" ); + perk_system( "script_model", ( 840, 603.809, -40.875 ), "zombie_vending_tombstone_on", ( 0, 0, 0 ), "custom", "mus_perks_packa_sting", "PhD Flopper", 2500, "tombstone_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( 2358, -87, -55.875 ), "zombie_vending_tombstone_on", ( 0, -90, 0 ), "custom", "mus_perks_doubletap_sting", "Downer's Delight", 2000, "tombstone_light", "Downers_Delight" ); + perk_system( "script_model", ( 2015, 858, -56.875 ), "zombie_vending_tombstone_on", ( 0, -90, 0 ), "custom", "mus_perks_doubletap_sting", "Dying Wish", 6000, "tombstone_light", "Dying_Wish" ); + perk_system( "script_model", ( 559, -1364, 120.125 ), "zombie_vending_tombstone_on", ( 0, 180, 0 ), "custom", "mus_perks_doubletap_sting", "Ammo Regen", 3000, "tombstone_light", "Ammo_Regen" ); + } + if( level.script == "zm_highrise") + { + perk_system( "script_model", ( 1884.42, 491.946, 1298.72), "zombie_vending_jugg_on", ( 0, 418.728, 0 ), "custom", "mus_perks_deadshot_sting", "Deadshot", 2000, "tombstone_light", "deadshot" ); +// perk_system( "script_model", ( 2764.64, 1868.03, 1391.01 ), "zombie_vending_jugg_on", ( 0, 384.236, 0 ), "custom", "mus_perks_doubletap_sting", "Burn Heart", 2500, "jugger_light", "Burn_Heart" ); + perk_system( "script_model", ( 1978.25, 597.657, 2704.13 ), "zombie_vending_jugg_on", ( 0, 329.291, 0 ), "custom", "mus_perks_deadshot_sting", "Widow's Wine", 4000, "tombstone_light", "WIDOWS_WINE" ); +// perk_system( "script_model", ( 1415.64, 2108.36, 3220.26 ), "zombie_vending_jugg_on", ( 0, 406.661, 0 ), "custom", "mus_perks_packa_sting", "Electric Cherry", 2000, "tombstone_light", "ELECTRIC_CHERRY" ); // 613,-250,z 0,0,0 + perk_system( "script_model", ( 1901.97, 1431.36, 3216.13 ), "zombie_vending_jugg_on", ( 0, 404.762, 0 ), "custom", "mus_perks_doubletap_sting", "Ethereal Razor", 3500, "tombstone_light", "Ethereal_Razor" ); +// perk_system( "script_model", ( 1891.64, 1119.64, 3048.36 ), "zombie_vending_jugg_on", ( 0, 45, 0 ), "custom", "mus_perks_doubletap_sting", "Mule Kick", 4000, "tombstone_light", "MULE" ); + perk_system( "script_model", ( 1429.29, -453.397, 2880.13 ), "zombie_vending_jugg_on", ( 0, 149.1426, 0 ), "custom", "mus_perks_packa_sting", "PhD Flopper", 2500, "tombstone_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( 1109.64, 2701.36, 3043.82 ), "zombie_vending_jugg_on", ( 0, 394.926, 0 ), "custom", "mus_perks_doubletap_sting", "Downer's Delight", 2000, "tombstone_light", "Downers_Delight" ); + perk_system( "script_model", ( 1706.28, 1055.64, 3395.1 ), "zombie_vending_jugg_on", ( 0, 180, 0 ), "custom", "mus_perks_doubletap_sting", "Dying Wish", 6000, "tombstone_light", "Dying_Wish" ); + perk_system( "script_model", ( 2269.17, 182.377, 2880.13 ), "zombie_vending_jugg_on", ( 0, 418.596, 0 ), "custom", "mus_perks_doubletap_sting", "Ammo Regen", 3000, "tombstone_light", "Ammo_Regen" ); + } + if( level.script == "zm_buried") + { + perk_system( "script_model", ( 1618.14, 1513.46, 200.62), "zombie_vending_jugg_on", ( 0, 250.147, 0 ), "custom", "mus_perks_deadshot_sting", "Deadshot", 2000, "sleight_light", "deadshot" ); +// perk_system( "script_model", ( -1176.36, 508.26, 144.125 ), "zombie_vending_jugg_on", ( 0, 448.269, 0 ), "custom", "mus_perks_doubletap_sting", "Burn Heart", 2500, "sleight_light", "Burn_Heart" ); + perk_system( "script_model", ( -1176.36, 510.625, 144.125 ), "zombie_vending_jugg_on", ( 0, 449.412, 0 ), "custom", "mus_perks_deadshot_sting", "Widow's Wine", 4000, "sleight_light", "WIDOWS_WINE" ); +// perk_system( "script_model", ( -448.859, 131.435, 143.491 ), "zombie_vending_jugg_on", ( 0, 180.3, 0 ), "custom", "mus_perks_packa_sting", "Electric Cherry", 2000, "sleight_light", "ELECTRIC_CHERRY" ); // 613,-250,z 0,0,0 + perk_system( "script_model", ( 890.359, -840.206, -22.8006 ), "zombie_vending_jugg_on", ( 0, 270.367, 0 ), "custom", "mus_perks_doubletap_sting", "Ethereal Razor", 3500, "sleight_light", "Ethereal_Razor" ); +// perk_system( "script_model", ( 1891.64, 1119.64, 3048.36 ), "zombie_vending_jugg_on", ( 0, 45, 0 ), "custom", "mus_perks_doubletap_sting", "Mule Kick", 4000, "sleight_light", "MULE" ); + perk_system( "script_model", ( 572.507, -712.359, 149.95 ), "zombie_vending_jugg_on", ( 0, 178.4505, 0 ), "custom", "mus_perks_packa_sting", "PhD Flopper", 2500, "sleight_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( 488.324, 727.641, 176.125 ), "zombie_vending_jugg_on", ( 0, 178.9998, 0 ), "custom", "mus_perks_doubletap_sting", "Downer's Delight", 2000, "sleight_light", "Downers_Delight" ); + perk_system( "script_model", ( -1298.32, -837.178, -23.875 ), "zombie_vending_jugg_on", ( 0, 91.37286, 0 ), "custom", "mus_perks_doubletap_sting", "Dying Wish", 6000, "sleight_light", "Dying_Wish" ); + perk_system( "script_model", ( -122.161, -1469.21, 168.125 ), "zombie_vending_jugg_on", ( 0, 448.841, 0 ), "custom", "mus_perks_doubletap_sting", "Ammo Regen", 3000, "sleight_light", "Ammo_Regen" ); + } + if( level.script == "zm_nuked") + { + perk_system( "script_model", ( 28.8155, -356.18, -65.8346 ), "zombie_vending_jugg_on", ( 0, 129.8755, 0 ), "custom", "mus_perks_deadshot_sting", "Deadshot", 2000, "sleight_light", "deadshot" ); +// perk_system( "script_model", ( ), "zombie_vending_jugg_on", ( ), "custom", "mus_perks_doubletap_sting", "Burn Heart", 2500, "sleight_light", "Burn_Heart" ); + perk_system( "script_model", ( -954.194, 714.594, 84.0385 ), "zombie_vending_jugg_on", ( 0, 429.46, 0 ), "custom", "mus_perks_deadshot_sting", "Widow's Wine", 4000, "sleight_light", "WIDOWS_WINE" ); + perk_system( "script_model", ( 683.524, 618.635, -56.875 ), "zombie_vending_jugg_on", ( 0, 102.5635, 0 ), "custom", "mus_perks_packa_sting", "Electric Cherry", 2000, "sleight_light", "ELECTRIC_CHERRY" ); // 613,-250,z 0,0,0 + perk_system( "script_model", ( 1420.35, -21.4313, -63.8849 ), "zombie_vending_jugg_on", ( 0, 194.085, 0 ), "custom", "mus_perks_doubletap_sting", "Ethereal Razor", 3500, "sleight_light", "Ethereal_Razor" ); + perk_system( "script_model", ( 618.292, -188.322, -56.3686 ), "zombie_vending_jugg_on", ( 0, 105.5011, 0 ), "custom", "mus_perks_doubletap_sting", "Mule Kick", 4000, "sleight_light", "MULE" ); + perk_system( "script_model", ( 1152.5, 160.6, 79.125 ), "zombie_vending_jugg_on", ( 0, 392.541, 0 ), "custom", "mus_perks_packa_sting", "PhD Flopper", 2500, "sleight_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( 156.738, 513.899, -62.3141 ), "zombie_vending_jugg_on", ( 0, 101.8164, 0 ), "custom", "mus_perks_doubletap_sting", "Downer's Delight", 2000, "sleight_light", "Downers_Delight" ); + perk_system( "script_model", ( -646.863, 271.522, -55.875 ), "zombie_vending_jugg_on", ( 0, 160.8405, 0 ), "custom", "mus_perks_doubletap_sting", "Dying Wish", 6000, "sleight_light", "Dying_Wish" ); + perk_system( "script_model", ( -1582.46, 112.604, -63.2092 ), "zombie_vending_jugg_on", ( 0, 250.829, 0 ), "custom", "mus_perks_doubletap_sting", "Ammo Regen", 3000, "sleight_light", "Ammo_Regen" ); + } + if( level.script == "zm_tomb") + { + perk_system( "script_model", ( 184.995, -2422.49, 50.125), "zombie_vending_jugg_on", ( 0, 369.091, 0 ), "custom", "mus_perks_deadshot_sting", "Deadshot", 2000, "sleight_light", "deadshot" ); + perk_system( "script_model", ( 160.359, 3781.17, -351.875 ), "zombie_vending_jugg_on", ( 0, 266.122, 0 ), "custom", "mus_perks_deadshot_sting", "Widow's Wine", 4000, "sleight_light", "WIDOWS_WINE" ); + perk_system( "script_model", ( 375.771, 2119.22, -122.951 ), "zombie_vending_jugg_on", ( 0, 179.5935, 0 ), "custom", "mus_perks_doubletap_sting", "Ethereal Razor", 3500, "sleight_light", "Ethereal_Razor" ); + perk_system( "script_model", ( -335.604, -187.006, 325.273 ), "zombie_vending_jugg_on", ( 0, 132.9565, 0 ), "custom", "mus_perks_packa_sting", "PhD Flopper", 2500, "sleight_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( 924.47, 360.72, 131.005 ), "zombie_vending_jugg_on", ( 0, 373.266, 0 ), "custom", "mus_perks_doubletap_sting", "Downer's Delight", 2000, "sleight_light", "Downers_Delight" ); + perk_system( "script_model", ( 1345.09, -3822.62, 302.125 ), "zombie_vending_jugg_on", ( 0, 270.593, 0 ), "custom", "mus_perks_doubletap_sting", "Dying Wish", 6000, "sleight_light", "Dying_Wish" ); + perk_system( "script_model", ( 2972.36, 5218.91, -378.566 ), "zombie_vending_jugg_on", ( 0, 270.379, 0 ), "custom", "mus_perks_doubletap_sting", "Ammo Regen", 3000, "sleight_light", "Ammo_Regen" ); + } + if( level.script == "zm_prison") + { + perk_system( "script_model", ( -1344.65, 5598.31, -71.875 ), "p6_zm_al_vending_jugg_on", ( 0, 98.34412, 0 ), "custom", "mus_perks_deadshot_sting", "Deadshot", 2000, "sleight_light", "deadshot" ); + perk_system( "script_model", ( 3763.64, 9669.99, 1704.13 ), "p6_zm_al_vending_jugg_on", ( 0, 90, 0 ), "custom", "mus_perks_deadshot_sting", "Widow's Wine", 4000, "sleight_light", "WIDOWS_WINE" ); + perk_system( "script_model", ( 2160.71, 9247.64, 1558.13 ), "p6_zm_al_vending_jugg_on", ( 0, 179.1815, 0 ), "custom", "mus_perks_doubletap_sting", "Ethereal Razor", 3500, "sleight_light", "Ethereal_Razor" ); + perk_system( "script_model", ( 597.633, 8546.86, 832.125 ), "p6_zm_al_vending_jugg_on", ( 0, 221.984, 0 ), "custom", "mus_perks_doubletap_sting", "Mule Kick", 4000, "sleight_light", "MULE" ); + perk_system( "script_model", ( 456.359, 8679.51, 1128.13 ), "p6_zm_al_vending_jugg_on", ( 0, 269.533, 0 ), "custom", "mus_perks_packa_sting", "PhD Flopper", 2500, "sleight_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( -685.943, 9199.64, 1336.13 ), "p6_zm_al_vending_jugg_on", ( 0, 178.5443, 0 ), "custom", "mus_perks_doubletap_sting", "Downer's Delight", 2000, "sleight_light", "Downers_Delight" ); + perk_system( "script_model", ( 1728.56, 10688.4, 1336.13 ), "p6_zm_al_vending_jugg_on", ( 0, 357.896, 0 ), "custom", "mus_perks_doubletap_sting", "Dying Wish", 6000, "sleight_light", "Dying_Wish" ); + perk_system( "script_model", ( 1367.28, 10096.4, 1128.13 ), "p6_zm_al_vending_jugg_on", ( 0, 358.687, 0 ), "custom", "mus_perks_doubletap_sting", "Ammo Regen", 3000, "sleight_light", "Ammo_Regen" ); + } +} + +play_fx( fx ) +{ + playfxontag( level._effect[ fx ], self, "tag_origin" ); +} + +defaulth_vending_precaching() +{ + level._effect[ "sleight_light" ] = loadfx( "misc/fx_zombie_cola_on" ); + level._effect[ "tombstone_light" ] = loadfx( "misc/fx_zombie_cola_on" ); + level._effect[ "revive_light" ] = loadfx( "misc/fx_zombie_cola_revive_on" ); + level._effect[ "marathon_light" ] = loadfx( "maps/zombie/fx_zmb_cola_staminup_on" ); + level._effect[ "jugger_light" ] = loadfx( "misc/fx_zombie_cola_jugg_on" ); + level._effect[ "doubletap_light" ] = loadfx( "misc/fx_zombie_cola_dtap_on" ); + level._effect[ "deadshot_light" ] = loadfx( "misc/fx_zombie_cola_dtap_on" ); + level._effect[ "additionalprimaryweapon_light" ] = loadfx( "misc/fx_zombie_cola_arsenal_on" ); + level._effect[ "packapunch_fx" ] = loadfx( "maps/zombie/fx_zombie_packapunch" ); + level._effect[ "wall_taseknuck" ] = loadfx( "maps/zombie/fx_zmb_wall_buy_taseknuck" ); +} + + +playchalkfx(effect, origin, angles) +{ + fx = SpawnFX(level._effect[ effect ], origin,AnglesToForward(angles),AnglesToUp(angles)); + TriggerFX(fx); + level waittill("connected", player); + fx Delete(); +} + + + +perk_system( script, pos, model, angles, type, sound, name, cost, fx, perk) +{ + col = spawn( script, pos); + col setmodel( model ); + col.angles = angles; + x = spawn( script, pos ); + x setmodel( "zm_collision_perks1" ); + x.angles = angles; + col thread buy_system( perk, sound, name, cost, type ); + col thread play_fx( fx ); +} + +buy_system( perk, sound, name, cost, type ) +{ + level endon("end_game"); + self endon("disconnect"); + self endon( "game_ended" ); + while( 1 ) + { + foreach( player in level.players ) + { + if(!player.machine_is_in_use) + { + if( distance( self.origin, player.origin ) <= 70 ) + { + player thread SpawnHint( self.origin, 30, 30, "HINT_ACTIVATE", "Hold ^3&&1^7 for " + name + " [Cost: " + cost + "]" ); + if(player usebuttonpressed() && !player hasperk(perk) && !player hascustomperk(perk) && player.score >= cost && !player maps\mp\zombies\_zm_laststand::player_is_in_laststand()) + { + player.machine_is_in_use = 1; + player playsound( "zmb_cha_ching" ); + player.score -= cost; + player playsound( sound ); + player thread drawshader_and_shadermove( perk, 1, 1, type ); + wait 4; + player.machine_is_in_use = 0; + } + else + { + if( player usebuttonpressed() && player.score < cost ) + { + player maps\mp\zombies\_zm_audio::create_and_play_dialog( "general", "perk_deny", undefined, 0 ); + } + } + } + } + } + wait 0.1; + } +} + +hascustomperk(perk) +{ + for(i = 0; i < self.perkarray.size; i++) + { + if(self.perkarray[i].name == perk) + { + return 1; + } + } + return 0; +} + +removeperkshader() +{ + self endon ("disconnect"); + level endon( "end_game" ); + common_scripts\utility::flag_wait( "initial_blackscreen_passed" ); + for(;;) + { + self waittill_any_return( "fake_death", "player_downed", "player_revived", "spawned_player", "disconnect", "death" ); + self.num_perks = 0; + self.perk_reminder = 0; + self.perk_count = 0; + self.dying_wish_on_cooldown = 0; + self removeallcustomshader(); + self.perkarray = []; + self notify( "stopcustomperk" ); + self.bleedout_time = 30; + self.ignore_lava_damage = 0; + self setclientfieldtoplayer( "deadshot_perk", 0 ); + } +} + +removeallcustomshader() +{ + for(i = 0; i < self.perkarray.size; i++) + { + self.perkarray[i] destroy(); + } +} + +drawshader( shader, x, y, width, height, color, alpha, sort ) +{ + level endon("end_game"); + self endon("disconnect"); + hud = newclienthudelem( self ); + hud.elemtype = "icon"; + hud.color = color; + hud.alpha = alpha; + hud.sort = sort; + hud.children = []; + hud.hidewheninmenu = 1; + hud setparent( level.uiparent ); + hud setshader( shader, width, height ); + hud.x = x; + hud.y = y; + return hud; +} + +perkboughtcheck() +{ + self endon("death"); + self endon("disconnect"); + for(;;) + { + self.perk_reminder = self.num_perks; + self waittill("perk_acquired"); + n = 1; + if(!(self.num_perks > self.perk_reminder)) + { + n = (self.num_perks - self.perk_reminder); + self.num_perks = (self.perk_reminder + n); + } + self.perk_reminder = self.num_perks; + self.perk_count += n; + self drawshader_and_shadermove("none", 0, 0, "normal"); //modified to remove perk alignement since 2 perk lines Added "normal" for type check + } +} + +drawshader_and_shadermove(perk, custom, print, type) +{ + level endon("end_game"); + self endon("disconnect"); + if(custom) + { + self allowProne(false); + self allowSprint(false); + self disableoffhandweapons(); + self disableweaponcycling(); + weapona = self getcurrentweapon(); + weaponb = "zombie_perk_bottle_jugg"; + self giveweapon( weaponb ); + self switchtoweapon( weaponb ); + self waittill( "weapon_change_complete" ); + self enableoffhandweapons(); + self enableweaponcycling(); + self takeweapon( weaponb ); + self switchtoweapon( weapona ); + self maps\mp\zombies\_zm_audio::playerexert( "burp" ); + self setblur( 4, 0.1 ); + wait 0.1; + self setblur( 0, 0.1 ); + self allowProne(true); + self allowSprint(true); + } + + yPerk = 325; + if (level.script == "zm_buried") + { + yPerk = 300; + } + if (level.script == "zm_tomb") + { + yPerk = 275; + } + + x = -408; + for(i = 0; i < self.perkarray.size; i++) + { + if (type == "custom") + { + x += 15; + } + } + /*if (perk == "custom") + { + for(i = 0; i < self.perkarray.size; i++) + { + self.perkarray[i].x = self.perkarray[i].x + 30; + } + }*/ + if(perk == "Downers_Delight") + { + self.perk1back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk1front = self drawshader( "waypoint_revive", x, yPerk, 23, 23, ( 0, 1, 1 ), 100, 0 ); + self.perk1front.name = perk; + self.perkarray[self.perkarray.size] = self.perk1front; + self.perk1back.name = perk; + self.perkarray[self.perkarray.size] = self.perk1back; + self.num_perks++; + self thread DDown(); + if(print) + { + self iprintln("^9Downer's Delight"); + wait 0.2; + self iprintln("This Perk will increase players bleedout time by 10 seconds and current weapons is used in laststand."); + } + } + if(perk == "MULE") + { + self.perk2back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk2front = self drawshader( "menu_mp_weapons_1911", x, yPerk, 22, 22, ( 0, 1, 0 ), 100, 0 ); + self.perk2front.name = perk; + self.perkarray[self.perkarray.size] = self.perk2front; + self.perk2back.name = perk; + self.perkarray[self.perkarray.size] = self.perk2back; + self.num_perks++; + if(print) + { + self iprintln("^9Mule Kick"); + wait 0.2; + self iprintln("This Perk enables additional primary weapon slot for player. "); + } + } + if(perk == "PHD_FLOPPER") + { + self.perk3back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk3front = self drawshader( "hud_icon_sticky_grenade", x, yPerk, 23, 23, (1, 0, 1 ), 100, 0 ); + self.perk3front.name = perk; + self.perkarray[self.perkarray.size] = self.perk3front; + self.perk3back.name = perk; + self.perkarray[self.perkarray.size] = self.perk3back; + self.num_perks++; + if(print) + { + self iprintln("^9PhD Flopper"); + wait 0.2; + self iprintln("This Perk removes explosion and fall damage also player creates explosion when dive to prone."); + } + } + if(perk == "Victorious_Tortoise") + { + self.perk4back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 200, 0 ), 100, 0 ); + self.perk4front = self drawshader( "zombies_rank_2", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk4front.name = perk; + self.perkarray[self.perkarray.size] = self.perk4front; + self.perk4back.name = perk; + self.perkarray[self.perkarray.size] = self.perk4back; + self.num_perks++; + self thread start_vt(); + if(print) + { + self iprintln("^9Victorious Tortoise"); + wait 0.2; + self iprintln("This Perk allows shield block damage from all directions when in use."); + } + } + if(perk == "ELECTRIC_CHERRY") + { + self.perk5back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 200 ), 100, 0 ); + self.perk5front = self drawshader( "zombies_rank_5", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk5front.name = perk; + self.perkarray[self.perkarray.size] = self.perk5front; + self.perk5back.name = perk; + self.perkarray[self.perkarray.size] = self.perk5back; + self.num_perks++; + self thread start_ec(); + if(print) + { + self iprintln("^9Electric Cherry"); + wait 0.2; + self iprintln("This Perk creates an electric shockwave around the player whenever they reload."); + } + } + if(perk == "WIDOWS_WINE") + { + self.perk6back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk6front = self drawshader( "zombies_rank_3", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk6front.name = perk; + self.perkarray[self.perkarray.size] = self.perk6front; + self.perk6back.name = perk; + self.perkarray[self.perkarray.size] = self.perk6back; + self.num_perks++; + self takeweapon( self get_player_lethal_grenade() ); + self set_player_lethal_grenade( "sticky_grenade_zm" ); + self giveweapon("sticky_grenade_zm"); + self thread ww_nades(); + if(print) + { + self iprintln("^9Widow's Wine"); + wait 0.2; + self iprintln("This Perk damages zombies around the player when player is hit and grenades are upgraded."); + } + } + if(perk == "Ethereal_Razor") + { + self.perk7back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 200, 0, 0 ), 100, 0 ); + self.perk7front = self drawshader( "zombies_rank_4", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk7front.name = perk; + self.perkarray[self.perkarray.size] = self.perk7front; + self.perk7back.name = perk; + self.perkarray[self.perkarray.size] = self.perk7back; + self.num_perks++; + if(print) + { + self iprintln("^9Ethereal Razor"); + wait 0.2; + self iprintln("This Perk deals extra damage when player using melee attacks and restores a small amount of health."); + } + } + if(perk == "Ammo_Regen") + { + self.perk8back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk8front = self drawshader( "menu_mp_lobby_icon_customgamemode", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk8front.name = perk; + self.perkarray[self.perkarray.size] = self.perk8front; + self.perk8back.name = perk; + self.perkarray[self.perkarray.size] = self.perk8back; + self.num_perks++; + self thread ammoregen(); + self thread grenadesregen(); + if(print) + { + self iprintln("^9Ammo Regen"); + wait 0.2; + self iprintln("This Perk will slowly regenerades players ammonation and grenades."); + } + } + if(perk == "Burn_Heart") + { + self.perk9back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 200, 0, 0 ), 100, 0 ); + self.perk9front = self drawshader( "faction_cdc", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk9front.name = perk; + self.perkarray[self.perkarray.size] = self.perk9front; + self.perk9back.name = perk; + self.perkarray[self.perkarray.size] = self.perk9back; + self.num_perks++; + self.ignore_lava_damage = 1; + if(print) + { + self iprintln("^9Burn Heart"); + wait 0.2; + self iprintln("This Perk removes lava damage."); + } + } + if(perk == "Dying_Wish") + { + self.perk10back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 200, 0, 0 ), 100, 0 ); + self.perk10front = self drawshader( "zombies_rank_5", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk10front.name = perk; + self.perkarray[self.perkarray.size] = self.perk10front; + self.perk10back.name = perk; + self.perkarray[self.perkarray.size] = self.perk10back; + self.num_perks++; + self thread dying_wish_checker(); + if(print) + { + self iprintln("^9Dying Wish"); + wait 0.2; + self iprintln("This Perk allow player to go berserker mode for 9 seconds instead of laststand."); + wait 0.1; + self iprintln(" (cooldown 5mins and it's increased 30sec every time perk is used. - max 10mins) "); + } + } + if(perk == "deadshot") + { + self.perk11back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk11front = self drawshader( "killiconheadshot", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk11front.name = perk; + self.perkarray[self.perkarray.size] = self.perk11front; + self.perk11back.name = perk; + self.perkarray[self.perkarray.size] = self.perk11back; + self.num_perks++; + self setclientfieldtoplayer( "deadshot_perk", 1 ); + if(print) + { + self iprintln("^9Deadshot"); + wait 0.2; + self iprintln("This Perk aims automatically enemys head instead of body."); + } + } +} + +custom_get_player_weapon_limit( player ) +{ + level endon("end_game"); + self endon("disconnect"); + weapon_limit = 2; + if ( player hascustomperk("MULE") ) + { + weapon_limit = 3; + } + else + { + weapons = self getWeaponsListPrimaries(); + if(weapons.size > 2) + { + self takeWeapon(weapons[2]); + } + } + return weapon_limit; +} + +ammoregen() +{ + self endon( "disconnect" ); + level endon( "end_game" ); + self endon( "stopcustomperk" ); + for(;;) + { + if (self GetCurrentWeapon() == "ray_gun_upgraded_zm" || self GetCurrentWeapon() == "ray_gun_zm") + { + stockcount = self getweaponammostock( self GetCurrentWeapon() ); + self setWeaponAmmostock( self GetCurrentWeapon(), stockcount + 1 ); + wait 2; + } + else if (self GetCurrentWeapon() == "raygun_mark2_zm" || self GetCurrentWeapon() == "raygun_mark2_upgraded_zm") + { + stockcount = self getweaponammostock( self GetCurrentWeapon() ); + self setWeaponAmmostock( self GetCurrentWeapon(), stockcount + 1 ); + wait 2; + } + else if (self GetCurrentWeapon() == "m1911_upgraded_zm" || self GetCurrentWeapon() == "usrpg_upgraded_zm") + { + stockcount = self getweaponammostock( self GetCurrentWeapon() ); + self setWeaponAmmostock( self GetCurrentWeapon(), stockcount + 1 ); + wait 2; + } + else if(!self GetCurrentWeapon() == "" && !is_grenade_launcher( self GetCurrentWeapon()) && self GetCurrentWeapon() != "slipgun_zm" +&& self GetCurrentWeapon() != "staff_fire_zm" && self GetCurrentWeapon() != "staff_fire_upgraded_zm" +&& self GetCurrentWeapon() != "staff_air_zm" && self GetCurrentWeapon() != "staff_air_upgraded_zm" +&& self GetCurrentWeapon() != "staff_water_zm" && self GetCurrentWeapon() != "staff_water_upgraded_zm" +&& self GetCurrentWeapon() != "staff_lightning_zm" && self GetCurrentWeapon() != "staff_lightning_upgraded_zm" +&& self GetCurrentWeapon() != "blundersplat_upgraded_zm") + { + stockcount = self getweaponammostock( self GetCurrentWeapon() ); + self setWeaponAmmostock( self GetCurrentWeapon(), stockcount + 5 ); + wait 2; + } + wait 0.1; + } +} + +grenadesregen() +{ + self endon( "disconnect" ); + level endon( "end_game" ); + self endon( "stopcustomperk" ); + for(;;) + { + grenades = self get_player_lethal_grenade(); + grenade_count = self getweaponammoclip(grenades); + if(grenade_count < 4) + { + self setweaponammoclip(grenades, (grenade_count + 1)); + } + tactical_grenades = self get_player_tactical_grenade(); + tactical_grenade_count = self getweaponammoclip(tactical_grenades); + if(tactical_grenade_count < 3 ) + { + self setweaponammoclip(tactical_grenades, (tactical_grenade_count + 1)); + } + wait 300; + } +} + +start_ec() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("stopcustomperk"); + for(;;) + { + self waittill( "reload_start" ); + playfxontag( level._effect[ "poltergeist"], self, "J_SpineUpper" ); + self EnableInvulnerability(); + RadiusDamage(self.origin, 120, 200, 100, self); + self DisableInvulnerability(); + self playsound( "zmb_turbine_explo" ); + wait 1; + } +} + +start_vt() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("stopcustomperk"); + for(;;) + { + if(self getcurrentweapon() == "riotshield_zm" ) + { + self enableInvulnerability(); + self.shielddamagetaken += 100; + wait 0.9; + } + else + { + self disableInvulnerability(); + } + wait 0.1; + } +} + +start_er() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("stopcustomperk"); + for(;;) + { + if (self hascustomperk("Ethereal_Razor") && self ismeleeing()) + { + /* foreach(zombie in getAiArray(level.zombie_team)) + { + if( distance( self.origin, zombie.origin ) <= 100 ) + { + + } + }*/ //removed for test + self.health += 20; + if(self.health > self.maxhealth) + { + self.health = self.maxhealth; + } + while(self ismeleeing()) + { + wait 0.1; + } + } + wait 0.05; + } +} + +LastStand() +{ + level endon("end_game"); + self endon("disconnect"); + if(self hascustomperk("Downers_Delight")) + { + self.customlaststandweapon = self getcurrentweapon(); + self switchtoweapon( self.customlaststandweapon ); + self setweaponammoclip( self.customlaststandweapon, 150 ); + self.bleedout_time = 40; + } + else + { + self maps\mp\zombies\_zm::last_stand_pistol_swap(); + } +} + +DDown() +{ + self endon( "disconnect" ); + level endon( "end_game" ); + self endon( "stopcustomperk" ); + for(;;) + { + self waittill("player_downed"); + self playsound( "zmb_phdflop_explo" ); + playfx(loadfx("explosions/fx_default_explosion"), self.origin, anglestoforward( ( 0, 45, 55 ) ) ); + RadiusDamage(self.origin, 150, 600, 400, self); + wait 0.1; + } +} + +doGivePerk(perk) +{ + self endon("disconnect"); + self endon("death"); + level endon("game_ended"); + self endon("perk_abort_drinking"); + if (!(self hasperk(perk) || (self maps\mp\zombies\_zm_perks::has_perk_paused(perk)))) + { + gun = self maps\mp\zombies\_zm_perks::perk_give_bottle_begin(perk); + evt = self waittill_any_return("fake_death", "death", "player_downed", "weapon_change_complete"); + if (evt == "weapon_change_complete") + self thread maps\mp\zombies\_zm_perks::wait_give_perk(perk, 1); + self maps\mp\zombies\_zm_perks::perk_give_bottle_end(gun, perk); + if (self maps\mp\zombies\_zm_laststand::player_is_in_laststand() || isDefined(self.intermission) && self.intermission) + return; + self notify("burp"); + } +} + + +SpawnHint( origin, width, height, cursorhint, string ) +{ + level endon("end_game"); + self endon("disconnect"); + hint = spawn( "trigger_radius", origin, 1, width, height ); + hint setcursorhint( cursorhint, hint ); + hint sethintstring( string ); + hint setvisibletoall(); + wait 0.2; + hint delete(); +} + + +ww_points( player ) +{ + level endon("end_game"); + self endon("disconnect"); + for(i = 0; i < 3; i++) + { + self maps\mp\zombies\_zm_utility::set_zombie_run_cycle("walk"); + player maps\mp\zombies\_zm_score::add_to_player_score( 10 ); + PlayFXOnTag(level.effect_WebFX,self,"j_spineupper"); + self doDamage(150, (0, 0, 0)); + wait 1; + } +} + +ww_nade_explosion() +{ + level endon("end_game"); + self endon("disconnect"); + wait 2; + // if( self maps/mp/zm_transit_lava::object_touching_lava()) +// { + // self delete(); + // return 0; + // } + foreach(zombie in getAiArray(level.zombie_team)) + { + if( distance( zombie.origin, self.origin ) < 210 ) + { + zombie thread ww_points( self ); + } + } + self delete(); +} + +ww_nades() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("stopcustomperk"); + for(;;) + { + self waittill( "grenade_fire", grenade, weapname ); + if( weapname == "sticky_grenade_zm" ) + { + ww_nade = spawnsm( grenade.origin, "zombie_bomb" ); + ww_nade hide(); + ww_nade linkto( grenade ); + ww_nade thread ww_nade_explosion(); + } + } +} + +spawnsm( origin, model, angles ) +{ + level endon("end_game"); + self endon("disconnect"); + ent = spawn( "script_model", origin ); + ent setmodel( model ); + if( IsDefined( angles ) ) + { + ent.angles = angles; + } + return ent; +} + +dying_wish_checker() +{ + level endon("end_game"); + self endon("disconnect"); + self endon( "stopcustomperk" ); + self.dying_wish_uses = 0; + for(;;) + { + self.dying_wish_on_cooldown = 0; + self.perk10back.alpha = 1; + self.perk10front.alpha = 1; + self waittill("dying_wish_charge"); + self.perk10back.alpha = 0.3; + self.perk10front.alpha = 0.4; + self.dying_wish_uses++; + self.dying_wish_on_cooldown = 1; + delay = 300 + (self.dying_wish_uses * 30); + if(delay >= 600) + delay = 600; + wait delay; + } +} + +dying_wish_effect() +{ + level endon("end_game"); + self endon("disconnect"); + self enableInvulnerability(); + self.ignoreme = 1; + self useServerVisionSet(true); + self setvisionsetforplayer( "zombie_death", 0 ); + // self freezeControls(1); disabled + // wait 1; + // self freezeControls(0); + wait 8; + self.health = 1; + self disableInvulnerability(); + self.ignoreme = 0; + self useServerVisionSet(false); + self setvisionsetforplayer("remote_mortar_enhanced", 0); +} + + +player_burning_audio() +{ + level endon("end_game"); + self endon("disconnect"); + fire_ent = spawn( "script_model", self.origin ); + wait_network_frame(); + fire_ent linkto( self ); + fire_ent playloopsound( "evt_plr_fire_loop" ); + self waittill_any( "stop_flame_damage", "stop_flame_sounds", "death", "disconnect" ); + fire_ent delete(); +} + + +//-------------------ENDCUSTOMPERK------------------------ + + + + + + + + + + + + + + + + + + +perks_gived() +{ + level endon("end_game"); + self endon("disconnect"); + wait 5; + iprintln("done"); + self give_perk("specialty_scavenger"); + bot = addtestclient(); + wait 1; + bot enableInvulnerability(); + +} + +playerdamagelastcheck( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime ) +{ + level endon("end_game"); + self endon("disconnect"); + + if (level.script == "zm_tomb") //called from zm_tomb.gsc + { + if ( isdefined( sweapon ) ) + { + if ( issubstr( sweapon, "staff" ) ) + return 0; + else if ( sweapon == "t72_turret" ) + return 0; + else if ( sweapon == "quadrotorturret_zm" || sweapon == "quadrotorturret_upgraded_zm" ) + return 0; + else if ( sweapon == "zombie_markiv_side_cannon" ) + return 0; + else if ( sweapon == "zombie_markiv_turret" ) + return 0; + else if ( sweapon == "zombie_markiv_cannon" ) + return 0; + } + } + +//-------------------CUSTOMPERK------------------------ + if( isDefined( eAttacker.is_zombie ) && eAttacker.is_zombie && self hascustomperk("WIDOWS_WINE") ) + { + zombies = getaiarray(level.zombie_team); + foreach(zombie in zombies) + { + if(distance(self.origin, zombie.origin) < 150) + { + grenades = self get_player_lethal_grenade(); + grenade_count = self getweaponammoclip(grenades); + if(grenade_count > 0) + { + self PlaySound("zmb_elec_jib_zombie"); + self setweaponammoclip(grenades, (grenade_count - 1)); + zombie thread ww_points( self ); + } + } + } + } + if(self hascustomperk("PHD_FLOPPER")) + { + if( smeansofdeath == "MOD_FALLING" ) + { + if(isDefined( self.divetoprone ) && self.divetoprone == 1 ) + { + radiusdamage( self.origin, 300, 5000, 1000, self, "MOD_GRENADE_SPLASH" ); + playfx(loadfx("explosions/fx_default_explosion"), self.origin, anglestoforward( ( 0, 45, 55 ) ) ); + self playsound( "zmb_phdflop_explo" ); + } + return 0; + } + if( smeansofdeath == "MOD_PROJECTILE" || smeansofdeath == "MOD_PROJECTILE_SPLASH" || smeansofdeath == "MOD_GRENADE" || smeansofdeath == "MOD_GRENADE_SPLASH" && eattacker == self) + { + return 0; + } + } + if(idamage > self.health && !self.dying_wish_on_cooldown && self hascustomperk("Dying_Wish") ) + { + self notify("dying_wish_charge"); + self thread dying_wish_effect(); + return 0; + } + else + { + return idamage; + } + +//-------------------ENDCUSTOMPERK------------------------ + + + + + + + + if(isdefined(self.has_cluster) && self.has_cluster && isdefined(eattacker) && eattacker == self) + { + return 0; + } + players = get_players(); + for(i=0;i= 5000 && current_weapon != "riotshield_zm" && player can_buy_weapon() && !player.is_drinking && !is_placeable_mine( current_weapon ) && !is_equipment( current_weapon ) && level.revive_tool != current_weapon && current_weapon != "none" ) + { + player.score -= 5000; + player thread maps\mp\zombies\_zm_audio::play_jingle_or_stinger( "mus_perks_packa_sting" ); + trigger setinvisibletoall(); + upgrade_as_attachment = will_upgrade_weapon_as_attachment( current_weapon ); + + player.restore_ammo = undefined; + player.restore_clip = undefined; + player.restore_stock = undefined; + player.restore_clip_size = undefined; + player.restore_max = undefined; + + player.restore_clip = player getweaponammoclip( current_weapon ); + player.restore_clip_size = weaponclipsize( current_weapon ); + player.restore_stock = player getweaponammostock( current_weapon ); + player.restore_max = weaponmaxammo( current_weapon ); + + player thread maps\mp\zombies\_zm_perks::do_knuckle_crack(); + wait .1; + player takeWeapon(current_weapon); + current_weapon = player maps\mp\zombies\_zm_weapons::switch_from_alt_weapon( current_weapon ); + self.current_weapon = current_weapon; + upgrade_name = maps\mp\zombies\_zm_weapons::get_upgrade_weapon( current_weapon, upgrade_as_attachment ); + player third_person_weapon_upgrade( current_weapon, upgrade_name, packa_rollers, perk_machine, self ); + trigger sethintstring( &"ZOMBIE_GET_UPGRADED" ); + trigger thread wait_for_pick(player, current_weapon, self.upgrade_name); + if ( isDefined( player ) ) + { + trigger setinvisibletoall(); + trigger setvisibletoplayer( player ); + } + self thread wait_for_timeout( current_weapon, packa_timer, player ); + self waittill_any( "pap_timeout", "pap_taken", "pap_player_disconnected" ); + self.current_weapon = ""; + if ( isDefined( self.worldgun ) && isDefined( self.worldgun.worldgundw ) ) + { + self.worldgun.worldgundw delete(); + } + if ( isDefined( self.worldgun ) ) + { + self.worldgun delete(); + } + trigger setinvisibletoplayer( player ); + wait 1.5; + trigger setvisibletoall(); + self.pack_player = undefined; + flag_clear( "pack_machine_in_use" ); + } + Trigger sethintstring( " Hold ^3&&1^7 for Pack-a-Punch [Cost: 5000] \n Weapons can be pack a punched multiple times" ); + wait .1; + } +} + +wait_for_pick(player, weapon, upgrade_weapon ) +{ + level endon("end_game"); + self endon("disconnect"); + level endon( "pap_timeout" ); + for (;;) + { + self playloopsound( "zmb_perks_packa_ticktock" ); + self waittill( "trigger", user ); + if(user UseButtonPressed() && player == user) + { + self stoploopsound( 0.05 ); + player thread do_player_general_vox( "general", "pap_arm2", 15, 100 ); + gun = player maps\mp\zombies\_zm_weapons::get_upgrade_weapon( upgrade_weapon, 0 ); + if(is_weapon_upgraded( weapon ) ) + { + player.restore_ammo = 1; + if( weapon == "galil_upgraded_zm+reflex" || weapon == "fnfal_upgraded_zm+reflex" ) + { + level thread aats(weapon, player); //Alternative ammo type for galil and fnfal upgraded + } + else + { + level thread aats(upgrade_weapon, player); //Alternative ammo type for all other weapons + } + } + if( weapon == "galil_upgraded_zm+reflex" || weapon == "fnfal_upgraded_zm+reflex" ) + { + player giveweapon( weapon, 0, player maps\mp\zombies\_zm_weapons::get_pack_a_punch_weapon_options( weapon )); + player switchToWeapon( weapon ); + x = weapon; + } + else + { + weapon_limit = get_player_weapon_limit( player ); + player maps\mp\zombies\_zm_weapons::take_fallback_weapon(); + primaries = player getweaponslistprimaries(); + if ( isDefined( primaries ) && primaries.size >= weapon_limit ) + { + player maps\mp\zombies\_zm_weapons::weapon_give( upgrade_weapon ); + } + else + { + player giveweapon( upgrade_weapon, 0, player maps\mp\zombies\_zm_weapons::get_pack_a_punch_weapon_options( upgrade_weapon )); + } + player switchToWeapon( upgrade_weapon ); + x = upgrade_weapon; + } + + if ( isDefined( player.restore_ammo ) && player.restore_ammo ) + { + new_clip = player.restore_clip + ( weaponclipsize( x ) - player.restore_clip_size ); + new_stock = player.restore_stock + ( weaponmaxammo( x ) - player.restore_max ); + player setweaponammostock( x, new_stock ); + player setweaponammoclip( x, new_clip ); + } + level notify( "pap_taken" ); + player notify( "pap_taken" ); + break; + } + wait .1; + } +} + +aats(name, player) +{ + level endon("end_game"); + self endon("disconnect"); + self endon( "death" ); + self endon( "pap_timeout" ); + self endon( "pap_player_disconnected" ); + self endon( "Pack_A_Punch_off" ); + self waittill("pap_taken"); + self thread pick_ammo(name, player); +} + +pick_ammo(name, player) +{ + level endon("end_game"); + self endon("disconnect"); + player notify("new_aat"); + primaries = player getweaponslistprimaries(); + if(!isDefined(player.active_explosive_bullet)) + { + player thread explosive_bullet(); + } + if(!isDefined(player.weaponname)) + { + player.active_turned = 0; + player.has_turned = 0; + player.has_blast_furnace = 0; + player.has_fireworks = 0; + player.cooldown = 0; + player.has_explosive_bullets = 0; + player.has_thunder_wall = 0; + player.has_Headcutter = 0; + player.has_cluster = 0; + // player thread aat_hitmarker(); + } + if(!isDefined(player.weaponname)) + { + player.weaponname = "x"; + } + if(!isDefined(player.last_aat)) + { + player.last_aat = 0; + } + if(!isDefined(player.aat_weapon)) + { + player.aat_weapon = []; + } + if(!isDefined(player.weapon_aats)) + { + player.weapon_aats = []; + } + aat = randomIntRange(0,8); + + /*aats = array("Blast Furnace", "Fireworks", "Explosive", "Headcutter", "Cluster", "Turned", "Thunder Wall"); + aats = array("Blast Furnace", "Headcutter", "Turned", "Thunder Wall"); + randomize = array_randomize(aats); + aat = randomize[0];*/ + + + if(name == player.weaponname && aat == player.last_aat ) + { + return pick_ammo(name, player); + } + for(i=0; i 0 || !is_true( self.dont_die_on_me ) ) + { + self finishactordamage( inflictor, attacker, damage_override, flags, meansofdeath, weapon, vpoint, vdir, shitloc, psoffsettime, boneindex ); + } +} + +actor_damage_override( inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, shitloc, psoffsettime, boneindex ) +{ + level endon("end_game"); + self endon("disconnect"); + if(isdefined(level.sloth) && self == level.sloth || isDefined(self.is_avogadro) && self.is_avogadro || isDefined(self.is_brutus) && self.is_brutus || isDefined(self.is_mechz) && self.is_mechz ) + { + return [[level.original_damagecallback]]( inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, shitloc, psoffsettime, boneindex ); + } + if(isdefined( attacker.weaponname )) + { + + if(!isDefined(self.is_turned)) + self.is_turned = 0; + + //attacker cannot damage active turned zombie + if(/*attacker.active_turned &&*/ self.is_turned) + return 0; + + if(isdefined( attacker ) && isplayer( attacker ) && !attacker.cooldown && MeansOfDeath != "MOD_MELEE" && MeansOfDeath != "MOD_IMPACT" && weapon != "knife_zm") + { + aat_cooldown_time = randomintrange(10, 16); //cooldown 10 - 15 seconds + aat_activation = randomintrange(1,11); //bullet that actives aat 1 - 10 + + zombies = getaiarray( level.zombie_team ); + if(meansofdeath == "MOD_GRENADE" || meansofdeath == "MOD_GRENADE_SPLASH" || meansofdeath == "MOD_EXPLOSIVE" || meansofdeath == "MOD_PROJECTILE") + { + if(is_weapon_upgraded( weapon )) + { + } + else + { + return [[level.original_damagecallback]]( inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, shitloc, psoffsettime, boneindex ); + } + } + if(self turned_zombie_validation() && attacker.has_turned && !attacker.active_turned) + { + turned = aat_activation; + if(turned == 1) + { + attacker.aat_actived = 1; + attacker thread cool_down(aat_cooldown_time); + self thread turned( attacker ); + } + } + if(attacker.has_cluster) + { + cluster = aat_activation; + if(cluster == 1) + { + attacker.aat_actived = 1; + attacker thread cool_down(aat_cooldown_time); + self thread cluster(); + self dodamage( self.health * 2, (0,0,0), attacker, attacker, "none", "MOD_IMPACT" ); + } + + } + if(attacker.has_Headcutter) + { + Headcutter = aat_activation; + if(Headcutter == 1) + { + attacker.aat_actived = 1; + attacker thread cool_down(aat_cooldown_time); + for( i=0; i < zombies.size; i++ ) + { + if(distance(self.origin, zombies[i].origin) <= 200) + { + if(!zombies[i].done) + { + zombies[i].done = 1; + zombies[i] thread Headcutter(attacker); + } + } + } + self dodamage( self.health * 2, (0,0,0), attacker, attacker, "none", "MOD_IMPACT" ); + } + } + if(attacker.has_thunder_wall) + { + thunder_wall = aat_activation; + if(thunder_wall == 1) + { + attacker setclientdvar( "ragdoll_enable", 1); + attacker.aat_actived = 1; + self thread thunderwall(attacker); + attacker thread cool_down(aat_cooldown_time); + self dodamage( self.health * 2, (0,0,0), attacker, attacker, "none", "MOD_IMPACT" ); + } + + } + if(attacker.has_blast_furnace) + { + blast_furnace = aat_activation; + if(blast_furnace == 1) + { + attacker.aat_actived = 1; + attacker thread cool_down(aat_cooldown_time); + flameFX=loadfx("env/fire/fx_fire_zombie_torso"); + PlayFXOnTag(flameFX,self, "j_spinelower"); + flameFX2=loadfx("env/fire/fx_fire_zombie_md"); + PlayFXOnTag(flameFX2,self,"j_spineupper"); + for( i = 0; i < zombies.size; i++ ) + { + if(distance(self.origin, zombies[i].origin) <= 220) + { + zombies[i] thread flames_fx(); + } + } + self dodamage( self.health * 2, (0,0,0), attacker, attacker, "none", "MOD_IMPACT" ); + } + } + if(attacker.has_fireworks) + { + fireworks = aat_activation; + if(fireworks == 1) + { + attacker.aat_actived = 1; + attacker thread cool_down(aat_cooldown_time); + origin = self.origin; + weapon = attacker getcurrentweapon(); + self thread spawn_weapon(origin, weapon, attacker); + self thread fireworks(origin); + self dodamage( self.health * 2, (0,0,0), attacker, attacker, "none", "MOD_IMPACT" ); + } + } + } + } + return [[level.original_damagecallback]]( inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, shitloc, psoffsettime, boneindex ); +} + +cool_down(time) +{ + level endon("end_game"); + self endon("disconnect"); + self.cooldown = 1; + wait time; + self.cooldown = 0; +} + +explosive_bullet() +{ + level endon("end_game"); + self endon("disconnect"); + self.active_explosive_bullet = 1; + for( ;; ) + { + self waittill( "weapon_fired" ); + explosive = randomintrange(1,5); + if(explosive == 1 && self.has_explosive_bullets && !self.cooldown) + { + self.aat_actived = 1; + self thread cool_down(randomintrange(5,11)); + forward = self gettagorigin( "tag_weapon_right" ); + end = self thread vector_scal( anglestoforward( self getplayerangles() ), 1000000 ); + crosshair_entity = bullettrace(self gettagorigin("tag_weapon_right"),self gettagorigin("tag_weapon_right")+anglestoforward(self getplayerangles())*1000000,true,self)["entity"]; + crosshair = bullettrace( forward, end, 0, self )[ "position"]; + magicbullet( self getcurrentweapon(), self gettagorigin( "j_shouldertwist_le" ), crosshair, self ); + self enableInvulnerability(); + if(isdefined(crosshair_entity)) + { + crosshair_entity playsound( "zmb_phdflop_explo" ); + playfx(loadfx("explosions/fx_default_explosion"), crosshair_entity.origin, anglestoforward( ( 0, 45, 55 ) ) ); + radiusdamage( crosshair_entity.origin, 300, 5000, 1000, self ); + } + else + { + crosshair playsound( "zmb_phdflop_explo" ); + playfx(loadfx("explosions/fx_default_explosion"), crosshair, anglestoforward( ( 0, 45, 55 ) ) ); + radiusdamage( crosshair, 300, 5000, 1000, self ); + } + wait .5; + self disableInvulnerability(); + } + wait .1; + } +} + +flames_fx() +{ + level endon("end_game"); + self endon("disconnect"); + for(i = 0; i < 5; i++) + { + flameFX=loadfx("env/fire/fx_fire_zombie_torso"); + PlayFXOnTag(flameFX, self, "j_spineupper"); + if(i < 3) + { + self dodamage(self.health / 2, (0,0,0)); + } + else + { + self dodamage(self.maxhealth * 2, (0,0,0)); + } + wait 1; + } +} + +fireworks(origin) +{ + level endon("end_game"); + self endon("disconnect"); + for(i=0;i<5;i++) + { + up_in_air = origin + (0,0,65); + firework = Spawn( "script_model", origin ); + firework SetModel( "tag_origin" ); + fx = PlayFxOnTag( level._effect[ "richtofen_sparks" ], firework, "tag_origin"); + firework moveto(up_in_air, 1); + wait 1; + firework delete(); + fx delete(); + } +} + +spawn_weapon(origin, weapon, attacker) +{ + level endon("end_game"); + self endon("disconnect"); + attacker.firework_weapon = spawnentity( "script_model", getweaponmodel( weapon ), origin + (0,0,45), (0,0,0) + ( 0, 50, 0 )); + for(i=0;i<100;i++) + { + zombies = get_array_of_closest( attacker.firework_weapon.origin, getaiarray( level.zombie_team ), undefined, undefined, 300 ); + forward = attacker.firework_weapon.origin; + end = zombies[ 0 ] gettagorigin( "j_spineupper" ); + crosshair = bullettrace( forward, end, 0, self )[ "position"]; + attacker.firework_weapon.angles = VectorToAngles( end - attacker.firework_weapon.origin ); + if( distance(zombies[ 0 ].origin, attacker.firework_weapon.origin) <= 300) + { + magicbullet( weapon, attacker.firework_weapon.origin, crosshair, attacker.firework_weapon ); + } + wait .05; + } + attacker.firework_weapon delete(); +} + +spawnentity( class, model, origin, angle ) +{ + level endon("end_game"); + self endon("disconnect"); + entity = spawn( class, origin ); + entity.angles = angle; + entity setmodel( model ); + return entity; +} + +thunderwall( attacker ) +{ + level endon("end_game"); + self endon("disconnect"); + thunder_wall_blast_pos = self.origin; + ai_zombies = get_array_of_closest( thunder_wall_blast_pos, getaiarray( level.zombie_team ), undefined, undefined, 250 ); + if ( !isDefined( ai_zombies ) ) + { + return; + } + flung_zombies = 0; + max_zombies = undefined; + max_zombies = randomIntRange(5,25); + for ( i = 0; i < ai_zombies.size; i++ ) + { + if(isDefined(ai_zombies[i].is_avogadro) && ai_zombies[i].is_avogadro || isDefined(ai_zombies[i].is_brutus) && ai_zombies[i].is_brutus || isDefined(ai_zombies[i].is_mechz) && ai_zombies[i].is_mechz ) + { + //boss zombie check + } + else + { + n_random_x = RandomFloatRange( -3, 3 ); + n_random_y = RandomFloatRange( -3, 3 ); + ai_zombies[i] StartRagdoll(); + ai_zombies[i] LaunchRagdoll( (n_random_x, n_random_y, 150) ); + playfxontag( level._effect[ "jetgun_smoke_cloud"], ai_zombies[i], "J_SpineUpper" ); + ai_zombies[i] DoDamage( ai_zombies[i].health * 2, ai_zombies[i].origin, attacker, attacker, "none", "MOD_IMPACT" ); + flung_zombies++; + if ( flung_zombies >= max_zombies ) + { + break; + } + } + } +} + +Headcutter(attacker) +{ + level endon("end_game"); + self endon("disconnect"); + self endon("death"); + self maps\mp\zombies\_zm_spawner::zombie_head_gib(); + for(;;) + { + wait 1; + damage = 100 * level.round_number; + self dodamage( damage, self.origin, attacker, attacker, "none", "MOD_IMPACT" ); + } +} + +cluster() +{ + level endon("end_game"); + self endon("disconnect"); + if(level.round_number < 10) + { + amount = randomIntRange(1, (level.round_number * 2)); + } + else + { + amount = randomIntRange(7, level.round_number); + } + random_x = RandomFloatRange( -3,3 ); + random_y = RandomFloatRange( -3,3 ); + for(i = 0; i < amount; i++) + { + self MagicGrenadeType( "frag_grenade_zm", self.origin + (random_x, random_y, 10), (random_x, random_y, 0), 2 ); + wait .1; + } +} + +/*aat_hitmarker() +{ + self thread startwaiting(); + self.aat_hitmarker = newdamageindicatorhudelem( self ); + self.aat_hitmarker.horzalign = "center"; + self.aat_hitmarker.vertalign = "middle"; + self.aat_hitmarker.x = -12; + self.aat_hitmarker.y = -12; + self.aat_hitmarker.alpha = 0; + self.aat_hitmarker setshader( "damage_feedback", 24, 48 ); +}*/ + +startwaiting() +{ + level endon("end_game"); + self endon("disconnect"); + while( 1 ) + { + foreach( zombie in getaiarray( level.zombie_team ) ) + { + if( !(IsDefined( zombie.waitingfordamage )) ) + { + //zombie thread aat_hitmarks(); + } + } + wait 0.25; + } +} + +/*aat_hitmarks() +{ + self.waitingfordamage = 1; + while( 1 ) + { + self waittill( "damage", amount, attacker, dir, point, mod ); + if(!isDefined(attacker.aat_actived)) + { + attacker.aat_actived = 0; + } + attacker.aat_hitmarker.alpha = 0; + if( isplayer( attacker ) ) + { + if(attacker.aat_actived) + { + attacker.aat_hitmarker.alpha = 1; + for(i=0;i<20;i++) + { + r = randomfloatrange(0.1, 0.9); + g = randomfloatrange(0.1, 0.9); + b = randomfloatrange(0.1, 0.9); + attacker.aat_hitmarker.color = ( r, g, b ); + if(i > 5) + { + attacker.aat_hitmarker.alpha -= .075; + } + wait .1; + } + attacker.aat_hitmarker.alpha = 0; + attacker.aat_actived = 0; + self.waitingfordamage = 0; + break; + } + } + } +}*/ + +turned( attacker ) +{ + level endon("end_game"); + self endon("disconnect"); + self.is_turned = 1; + attacker.active_turned = 1; + turned_zombie_kills = 0; + max_kills = randomIntRange(15,21); + + self thread set_zombie_run_cycle( "sprint" ); + self.custom_goalradius_override = 1000000; + + //set turned icon for zombie + //todo: icon takes zombies z origin from original ground not zombies z origin + turned_icon = newHudElem(); + turned_icon.x = self.origin[ 0 ]; + turned_icon.y = self.origin[ 1 ]; + turned_icon.z = self.origin[ 2 ] + (0,0,80); + turned_icon.color = (0,1,0); + turned_icon.isshown = 1; + turned_icon.archived = 0; + turned_icon setshader( "hud_status_dead", 4, 4 ); + turned_icon setwaypoint( 1 ); + + enemyoverride = []; + + //cannot damage player + self.team = level.players; + + //allow round change while turned zombie is alive + self.ignore_enemy_count = 1; + + if(getdvar("mapname") == "zm_tomb") + attackanim = "zm_generator_melee"; + else + attackanim = "zm_riotshield_melee"; + + if ( !self.has_legs ) + { + attackanim += "_crawl"; + } + + while(isAlive(self)) + { + turned_icon.x = self.origin[ 0 ]; + turned_icon.y = self.origin[ 1 ]; + turned_icon.z = self.origin[ 2 ] + (0,0,80); + + ai_zombies = get_array_of_closest( self.origin, getaiarray( level.zombie_team ), undefined, undefined, undefined ); + if(isdefined(ai_zombies[1])) + { + enemyoverride[0] = ai_zombies[1].origin; + enemyoverride[1] = ai_zombies[1]; + } + else + { + enemyoverride[0] = ai_zombies[0].origin; + enemyoverride[1] = ai_zombies[0]; + } + self.enemyoverride = enemyoverride; + if(distance(self.origin, ai_zombies[1].origin) < 40 && isalive(ai_zombies[1]) ) + { + angles = VectorToAngles( ai_zombies[1].origin - self.origin ); + self animscripted( self.origin, angles, attackanim ); + ai_zombies[1] dodamage(ai_zombies[1].maxhealth * 2, ai_zombies[1].origin); + turned_zombie_kills++; + + if(turned_zombie_kills > max_kills) + { + self.is_turned = 0; + wait .1; + self dodamage(self.maxhealth * 2, self.origin); + } + + wait 1; + } + else + self stopanimscripted(); + + wait .05; + } + attacker.active_turned = 0; + self.is_turned = 0; + turned_icon destroy(); +} + +turned_zombie() +{ + level endon("end_game"); + self endon("disconnect"); + if(self.turned) + { + //attack zombies + } + else + { + zombie_poi = self get_zombie_point_of_interest( self.origin ); + } + return zombie_poi; +} + +turned_zombie_validation() +{ + level endon("end_game"); + self endon("disconnect"); + if( IS_TRUE( self.barricade_enter ) ) + { + return false; + } + if ( IS_TRUE( self.is_traversing ) ) + { + return false; + } + if ( !IS_TRUE( self.completed_emerging_into_playable_area ) ) + { + return false; + } + if ( IS_TRUE( self.is_leaping ) ) + { + return false; + } + if ( IS_TRUE( self.is_inert ) ) + { + return false; + } + + return true; +} + +is_true(check) +{ + return(IsDefined(check) && check); +} + +save_aat() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("new_aat"); + self endon("disconnect"); + if(isDefined(self.saved_aat_weapons)) + self.saved_aat_weapons = []; + + if(isDefined(self.saved_aat_weapons_name)) + self.saved_aat_weapons_name = []; + + weapons = self getweaponslistprimaries(); + + if(weapons.size > 0 && isDefined(self.weapon_aats[0])) + { + self.saved_aat_weapons_name[0] = self.aat_weapon[0]; + self.saved_aat_weapons[0] = self.weapon_aats[0]; + } + else + { + self.saved_aat_weapons[2] = undefined; + self.saved_aat_weapons_name[2] = undefined; + } + + if(weapons.size > 1 && isDefined(self.weapon_aats[1])) + { + self.saved_aat_weapons_name[1] = self.aat_weapon[1]; + self.saved_aat_weapons[1] = self.weapon_aats[1]; + } + else + { + self.saved_aat_weapons[2] = undefined; + self.saved_aat_weapons_name[2] = undefined; + } + + if(weapons.size > 2 && isDefined(self.weapon_aats[2])) + { + self.saved_aat_weapons_name[2] = self.aat_weapon[2]; + self.saved_aat_weapons[2] = self.weapon_aats[2]; + } + else + { + self.saved_aat_weapons[2] = undefined; + self.saved_aat_weapons_name[2] = undefined; + } +} + +//----whos who recover aat---------------------------------------------------------------------------- + +chugabud_laststand() +{ + level endon("end_game"); + self endon("disconnect"); + self endon( "player_suicide" ); + self endon( "disconnect" ); + self endon( "chugabud_bleedout" ); + self maps\mp\zombies\_zm_laststand::increment_downed_stat(); + self.ignore_insta_kill = 1; + self.health = self.maxhealth; + self maps\mp\zombies\_zm_chugabud::chugabud_save_loadout(); + self maps\mp\zombies\_zm_chugabud::chugabud_fake_death(); + wait 3; + + if ( isdefined( self.insta_killed ) && self.insta_killed || isdefined( self.disable_chugabud_corpse ) ) + create_corpse = 0; + else + create_corpse = 1; + + if ( create_corpse == 1 ) + { + if ( isdefined( level._chugabug_reject_corpse_override_func ) ) + { + reject_corpse = self [[ level._chugabug_reject_corpse_override_func ]]( self.origin ); + + if ( reject_corpse ) + create_corpse = 0; + } + } + + if ( create_corpse == 1 ) + { + self thread activate_chugabud_effects_and_audio(); + corpse = self chugabud_spawn_corpse(); + corpse thread chugabud_corpse_revive_icon( self ); + self.e_chugabud_corpse = corpse; + corpse thread chugabud_corpse_cleanup_on_spectator( self ); + + if ( isdefined( level.whos_who_client_setup ) ) + corpse setclientfield( "clientfield_whos_who_clone_glow_shader", 1 ); + } + + self chugabud_fake_revive(); + wait 0.1; + self.ignore_insta_kill = undefined; + self.disable_chugabud_corpse = undefined; + + if ( create_corpse == 0 ) + { + self notify( "chugabud_effects_cleanup" ); + return; + } + + bleedout_time = getdvarfloat( "player_lastStandBleedoutTime" ); + self thread chugabud_bleed_timeout( bleedout_time, corpse ); + self thread chugabud_handle_multiple_instances( corpse ); + + corpse waittill( "player_revived", e_reviver ); + + if ( isdefined( e_reviver ) && e_reviver == self ) + self notify( "whos_who_self_revive" ); + + self perk_abort_drinking( 0.1 ); + self maps\mp\zombies\_zm_perks::perk_set_max_health_if_jugg( "health_reboot", 1, 0 ); + self setorigin( corpse.origin ); + self setplayerangles( corpse.angles ); + + if ( self player_is_in_laststand() ) + { + self thread chugabud_laststand_cleanup( corpse, "player_revived" ); + self enableweaponcycling(); + self enableoffhandweapons(); + self auto_revive( self, 1 ); + return; + } + + self chugabud_laststand_cleanup( corpse, undefined ); +} + +chugabud_laststand_cleanup( corpse, str_notify ) +{ + level endon("end_game"); + self endon("disconnect"); + if ( isdefined( str_notify ) ) + self waittill( str_notify ); + + self chugabud_give_loadout(); + self chugabud_corpse_cleanup( corpse, 1 ); +} + +chugabud_give_loadout() +{ + level endon("end_game"); + self endon("disconnect"); + self takeallweapons(); + loadout = self.loadout; + primaries = self getweaponslistprimaries(); + + if ( loadout.weapons.size > 1 || primaries.size > 1 ) + { + foreach ( weapon in primaries ) + self takeweapon( weapon ); + } + + for ( i = 0; i < loadout.weapons.size; i++ ) + { + if ( !isdefined( loadout.weapons[i] ) ) + continue; + + if ( loadout.weapons[i]["name"] == "none" ) + continue; + + self maps\mp\zombies\_zm_weapons::weapondata_give( loadout.weapons[i] ); + } + + if ( loadout.current_weapon >= 0 && isdefined( loadout.weapons[loadout.current_weapon]["name"] ) ) + self switchtoweapon( loadout.weapons[loadout.current_weapon]["name"] ); + + self giveweapon( "knife_zm" ); + self maps\mp\zombies\_zm_equipment::equipment_give( self.loadout.equipment ); + loadout restore_weapons_for_chugabud( self ); + self chugabud_restore_claymore(); + self.score = loadout.score; + self.pers["score"] = loadout.score; + perk_array = maps\mp\zombies\_zm_perks::get_perk_array( 1 ); + + for ( i = 0; i < perk_array.size; i++ ) + { + perk = perk_array[i]; + self unsetperk( perk ); + self.num_perks--; + self set_perk_clientfield( perk, 0 ); + } + + if ( isdefined( loadout.perks ) && loadout.perks.size > 0 ) + { + for ( i = 0; i < loadout.perks.size; i++ ) + { + if ( self hasperk( loadout.perks[i] ) ) + continue; + + if ( loadout.perks[i] == "specialty_quickrevive" && flag( "solo_game" ) ) + level.solo_game_free_player_quickrevive = 1; + + if ( loadout.perks[i] == "specialty_finalstand" ) + continue; + + maps\mp\zombies\_zm_perks::give_perk( loadout.perks[i] ); + } + } + + self chugabud_restore_grenades(); + + if ( maps\mp\zombies\_zm_weap_cymbal_monkey::cymbal_monkey_exists() ) + { + if ( loadout.zombie_cymbal_monkey_count ) + { + self maps\mp\zombies\_zm_weap_cymbal_monkey::player_give_cymbal_monkey(); + self setweaponammoclip( "cymbal_monkey_zm", loadout.zombie_cymbal_monkey_count ); + } + } + + if(isDefined(self.saved_aat_weapons[0])) + { + self.weapon_aats[0] = self.saved_aat_weapons[0]; + self.aat_weapon[0] = self.saved_aat_weapons_name[0]; + } + else + { + self.saved_aat_weapons[0] = undefined; + self.saved_aat_weapons_name[0] = undefined; + } + if(isDefined(self.saved_aat_weapons[1])) + { + self.weapon_aats[1] = self.saved_aat_weapons[1]; + self.aat_weapon[1] = self.saved_aat_weapons_name[1]; + } + else + { + self.saved_aat_weapons[1] = undefined; + self.saved_aat_weapons_name[1] = undefined; + } + if(isDefined(self.saved_aat_weapons[2])) + { + self.weapon_aats[2] = self.saved_aat_weapons[2]; + self.aat_weapon[2] = self.saved_aat_weapons_name[2]; + } + else + { + self.saved_aat_weapons[2] = undefined; + self.saved_aat_weapons_name[2] = undefined; + } + self notify("weapon_change"); +} + +//-------tombstone recover aat------------------------------------------------------------------ + +/*tombstone_spawn() +{ + level endon("end_game"); + self endon("disconnect"); + dc = spawn( "script_model", self.origin + vectorscale( ( 0, 0, 1 ), 40.0 ) ); + dc.angles = self.angles; + dc setmodel( "tag_origin" ); + dc_icon = spawn( "script_model", self.origin + vectorscale( ( 0, 0, 1 ), 40.0 ) ); + dc_icon.angles = self.angles; + dc_icon setmodel( "ch_tombstone1" ); + dc_icon linkto( dc ); + dc.icon = dc_icon; + dc.script_noteworthy = "player_tombstone_model"; + dc.player = self; + self thread tombstone_clear(); + dc thread tombstone_wobble(); + dc thread tombstone_revived( self ); + result = self waittill_any_return( "player_revived", "spawned_player", "disconnect" ); + + if ( result == "player_revived" || result == "disconnect" ) + { + dc notify( "tombstone_timedout" ); + dc_icon unlink(); + dc_icon delete(); + dc delete(); + return; + } + + dc thread tombstone_timeout(); + dc thread tombstone_grab(); +} + +tombstone_grab() +{ + level endon("end_game"); + self endon("disconnect"); + self endon( "tombstone_timedout" ); + wait 1; + + while ( isdefined( self ) ) + { + players = get_players(); + + for ( i = 0; i < players.size; i++ ) + { + if ( players[i].is_zombie ) + continue; + + if ( isdefined( self.player ) && players[i] == self.player ) + { + tombstone_machine_triggers = getentarray( "specialty_scavenger", "script_noteworthy" ); + istombstonepowered = 0; + + foreach ( trigger in tombstone_machine_triggers ) + { + if ( isdefined( trigger.power_on ) && trigger.power_on || isdefined( trigger.turbine_power_on ) && trigger.turbine_power_on ) + istombstonepowered = 1; + } + + if ( istombstonepowered ) + { + dist = distance( players[i].origin, self.origin ); + + if ( dist < 64 ) + { + playfx( level._effect["powerup_grabbed"], self.origin ); + playfx( level._effect["powerup_grabbed_wave"], self.origin ); + players[i] tombstone_give(); + wait 0.1; + playsoundatposition( "zmb_tombstone_grab", self.origin ); + self stoploopsound(); + self.icon unlink(); + self.icon delete(); + self delete(); + self notify( "tombstone_grabbed" ); + players[i] clientnotify( "dc0" ); + players[i] notify( "dance_on_my_grave" ); + } + } + } + } + + wait_network_frame(); + } +} + +tombstone_give() +{ + level endon("end_game"); + self endon("disconnect"); + dc = level.tombstones[self.tombstone_index]; + + if ( !flag( "solo_game" ) ) + { + primaries = self getweaponslistprimaries(); + + if ( dc.weapon.size > 1 || primaries.size > 1 ) + { + foreach ( weapon in primaries ) + self takeweapon( weapon ); + } + + for ( i = 0; i < dc.weapon.size; i++ ) + { + if ( !isdefined( dc.weapon[i] ) ) + continue; + + if ( dc.weapon[i] == "none" ) + continue; + + weapon = dc.weapon[i]; + stock = dc.stockcount[i]; + + if ( !self hasweapon( weapon ) ) + { + self giveweapon( weapon, 0, self maps\mp\zombies\_zm_weapons::get_pack_a_punch_weapon_options( weapon ) ); + self setweaponammoclip( weapon, weaponclipsize( weapon ) ); + self setweaponammostock( weapon, stock ); + + if ( i == dc.current_weapon ) + self switchtoweapon( weapon ); + } + } + } + + if ( isdefined( dc.hasriotshield ) && dc.hasriotshield ) + { + self maps\mp\zombies\_zm_equipment::equipment_give( "riotshield_zm" ); + + if ( isdefined( self.player_shield_reset_health ) ) + self [[ self.player_shield_reset_health ]](); + } + + dc restore_weapons_for_tombstone( self ); + + if ( isdefined( dc.hasclaymore ) && dc.hasclaymore && !self hasweapon( "claymore_zm" ) ) + { + self giveweapon( "claymore_zm" ); + self set_player_placeable_mine( "claymore_zm" ); + self setactionslot( 4, "weapon", "claymore_zm" ); + self setweaponammoclip( "claymore_zm", dc.claymoreclip ); + } + + if ( isdefined( dc.hasemp ) && dc.hasemp ) + { + self giveweapon( "emp_grenade_zm" ); + self setweaponammoclip( "emp_grenade_zm", dc.empclip ); + } + + if ( isdefined( dc.perk ) && dc.perk.size > 0 ) + { + for ( i = 0; i < dc.perk.size; i++ ) + { + if ( self hasperk( dc.perk[i] ) ) + continue; + + if ( dc.perk[i] == "specialty_quickrevive" && flag( "solo_game" ) ) + continue; + + maps\mp\zombies\_zm_perks::give_perk( dc.perk[i] ); + } + } + + if ( dc.grenade > 0 && !flag( "solo_game" ) ) + { + curgrenadecount = 0; + + if ( self hasweapon( self get_player_lethal_grenade() ) ) + self getweaponammoclip( self get_player_lethal_grenade() ); + else + self giveweapon( self get_player_lethal_grenade() ); + + self setweaponammoclip( self get_player_lethal_grenade(), dc.grenade + curgrenadecount ); + } + + if ( maps\mp\zombies\_zm_weap_cymbal_monkey::cymbal_monkey_exists() && !flag( "solo_game" ) ) + { + if ( dc.zombie_cymbal_monkey_count ) + { + self maps\mp\zombies\_zm_weap_cymbal_monkey::player_give_cymbal_monkey(); + self setweaponammoclip( "cymbal_monkey_zm", dc.zombie_cymbal_monkey_count ); + } + } + + if(isDefined(self.saved_aat_weapons[0])) + { + self.weapon_aats[0] = self.saved_aat_weapons[0]; + self.aat_weapon[0] = self.saved_aat_weapons_name[0]; + } + else + { + self.saved_aat_weapons[0] = undefined; + self.saved_aat_weapons_name[0] = undefined; + } + if(isDefined(self.saved_aat_weapons[1])) + { + self.weapon_aats[1] = self.saved_aat_weapons[1]; + self.aat_weapon[1] = self.saved_aat_weapons_name[1]; + } + else + { + self.saved_aat_weapons[1] = undefined; + self.saved_aat_weapons_name[1] = undefined; + } + if(isDefined(self.saved_aat_weapons[2])) + { + self.weapon_aats[2] = self.saved_aat_weapons[2]; + self.aat_weapon[2] = self.saved_aat_weapons_name[2]; + } + else + { + self.saved_aat_weapons[2] = undefined; + self.saved_aat_weapons_name[2] = undefined; + } + self notify("weapon_change"); +}*/ + +//--------- + + +/*solo_tombstone_removal() +{ + notify( "tombstone_on" ); +} + +turn_tombstone_on() +{ + level endon("end_game"); + self endon("disconnect"); + level endon("end_game"); + while ( 1 ) + { + machine = getentarray( "vending_tombstone", "targetname" ); + machine_triggers = getentarray( "vending_tombstone", "target" ); + i = 0; + while ( i < machine.size ) + { + machine[ i ] setmodel( level.machine_assets[ "tombstone" ].off_model ); + i++; + } + level thread do_initial_power_off_callback( machine, "tombstone" ); + array_thread( machine_triggers, ::set_power_on, 0 ); + level waittill( "tombstone_on" ); + i = 0; + while ( i < machine.size ) + { + machine[ i ] setmodel( level.machine_assets[ "tombstone" ].on_model ); + machine[ i ] vibrate( vectorScale( ( 0, -1, 0 ), 100 ), 0,3, 0,4, 3 ); + machine[ i ] playsound( "zmb_perks_power_on" ); + machine[ i ] thread perk_fx( "tombstone_light" ); + machine[ i ] thread play_loop_on_machine(); + i++; + } + level notify( "specialty_scavenger_power_on" ); + array_thread( machine_triggers, ::set_power_on, 1 ); + if ( isDefined( level.machine_assets[ "tombstone" ].power_on_callback ) ) + { + array_thread( machine, level.machine_assets[ "tombstone" ].power_on_callback ); + } + level waittill( "tombstone_off" ); + if ( isDefined( level.machine_assets[ "tombstone" ].power_off_callback ) ) + { + array_thread( machine, level.machine_assets[ "tombstone" ].power_off_callback ); + } + array_thread( machine, ::turn_perk_off ); + players = get_players(); + _a1718 = players; + _k1718 = getFirstArrayKey( _a1718 ); + while ( isDefined( _k1718 ) ) + { + player = _a1718[ _k1718 ]; + player.hasperkspecialtytombstone = undefined; + _k1718 = getNextArrayKey( _a1718, _k1718 ); + } + } +} + +perk_machine_spawn_init() +{ + level endon("end_game"); + self endon("disconnect"); + level endon("end_game"); + 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 + "_perks_" ) + location; + pos = []; + if ( isDefined( level.override_perk_targetname ) ) + { + structs = getstructarray( level.override_perk_targetname, "targetname" ); + } + else + { + structs = getstructarray( "zm_perk_machine", "targetname" ); + } + _a3578 = structs; + _k3578 = getFirstArrayKey( _a3578 ); + while ( isDefined( _k3578 ) ) + { + struct = _a3578[ _k3578 ]; + if ( isDefined( struct.script_string ) ) + { + tokens = strtok( struct.script_string, " " ); + _a3583 = tokens; + _k3583 = getFirstArrayKey( _a3583 ); + while ( isDefined( _k3583 ) ) + { + token = _a3583[ _k3583 ]; + if ( token == match_string ) + { + pos[ pos.size ] = struct; + } + _k3583 = getNextArrayKey( _a3583, _k3583 ); + } + } + else pos[ pos.size ] = struct; + _k3578 = getNextArrayKey( _a3578, _k3578 ); + } + if ( !isDefined( pos ) || pos.size == 0 ) + { + return; + } + precachemodel( "zm_collision_perks1" ); + i = 0; + while ( i < pos.size ) + { + 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.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 ) + { + bump_trigger = undefined; + } + else + { + 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" ) + { + 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.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 ) ) + { + use_trigger.blocker_model = pos[ i ].blocker_model; + } + if ( isDefined( pos[ i ].script_int ) ) + { + perk_machine.script_int = pos[ i ].script_int; + } + if ( isDefined( pos[ i ].turn_on_notify ) ) + { + perk_machine.turn_on_notify = pos[ i ].turn_on_notify; + } + if ( perk == "specialty_scavenger" || perk == "specialty_scavenger_upgrade" ) + { + use_trigger.script_sound = "mus_perks_tombstone_jingle"; + use_trigger.script_string = "tombstone_perk"; + use_trigger.script_label = "mus_perks_tombstone_sting"; + use_trigger.target = "vending_tombstone"; + perk_machine.script_string = "tombstone_perk"; + perk_machine.targetname = "vending_tombstone"; + if ( isDefined( bump_trigger ) ) + { + bump_trigger.script_string = "tombstone_perk"; + } + } + 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 ); + } + } + i++; + } +}*/ + +/*isTown() +{ + level endon("end_game"); + self endon("disconnect"); + if (isDefined(level.zombiemode_using_tombstone_perk) && level.zombiemode_using_tombstone_perk) + { + level thread perk_machine_spawn_init(); + thread solo_tombstone_removal(); + thread turn_tombstone_on(); + } +}*/ diff --git a/t6/uncompiled mods/Compiler.exe b/t6/uncompiled mods/Compiler.exe new file mode 100644 index 0000000000000000000000000000000000000000..7f5721586770d092c9078e66b44a4ca6230125f6 GIT binary patch literal 49664 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

9`IW74-kviw&U?L+;fdL?=v3yz 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 literal 0 HcmV?d00001 diff --git a/t6/uncompiled mods/Perks.gsc b/t6/uncompiled mods/Perks.gsc new file mode 100644 index 0000000..d9b6248 --- /dev/null +++ b/t6/uncompiled mods/Perks.gsc @@ -0,0 +1,3016 @@ +#include maps/mp/_utility; +#include common_scripts/utility; +#include maps/mp/gametypes_zm/_hud_util; +#include maps/mp/zombies/_zm_weapons; +#include maps/mp/zombies/_zm_stats; +#include maps/mp/gametypes_zm/_spawnlogic; +#include maps/mp/animscripts/traverse/shared; +#include maps/mp/animscripts/utility; +#include maps/mp/zombies/_load; +#include maps/mp/_createfx; +#include maps/mp/_music; +#include maps/mp/_busing; +#include maps/mp/_script_gen; +#include maps/mp/gametypes_zm/_globallogic_audio; +#include maps/mp/gametypes_zm/_tweakables; +#include maps/mp/_challenges; +#include maps/mp/gametypes_zm/_weapons; +#include maps/mp/_demo; +#include maps/mp/gametypes_zm/_hud_message; +#include maps/mp/gametypes_zm/_spawning; +#include maps/mp/gametypes_zm/_globallogic_utils; +#include maps/mp/gametypes_zm/_spectating; +#include maps/mp/gametypes_zm/_globallogic_spawn; +#include maps/mp/gametypes_zm/_globallogic_ui; +#include maps/mp/gametypes_zm/_hostmigration; +#include maps/mp/gametypes_zm/_globallogic_score; +#include maps/mp/gametypes_zm/_globallogic; +#include maps/mp/zombies/_zm; +#include maps/mp/zombies/_zm_ai_faller; +#include maps/mp/zombies/_zm_spawner; +#include maps/mp/zombies/_zm_pers_upgrades_functions; +#include maps/mp/zombies/_zm_pers_upgrades; +#include maps/mp/zombies/_zm_score; +#include maps/mp/zombies/_zm_powerups; +#include maps/mp/animscripts/zm_run; +#include maps/mp/animscripts/zm_death; +#include maps/mp/zombies/_zm_blockers; +#include maps/mp/animscripts/zm_shared; +#include maps/mp/animscripts/zm_utility; +#include maps/mp/zombies/_zm_ai_basic; +#include maps/mp/zombies/_zm_laststand; +#include maps/mp/zombies/_zm_net; +#include maps/mp/zombies/_zm_audio; +#include maps/mp/gametypes_zm/_zm_gametype; +#include maps/mp/_visionset_mgr; +#include maps/mp/zombies/_zm_equipment; +#include maps/mp/zombies/_zm_power; +#include maps/mp/zombies/_zm_server_throttle; +#include maps/mp/gametypes/_hud_util; +#include maps/mp/zombies/_zm_unitrigger; +#include maps/mp/zombies/_zm_zonemgr; +#include maps/mp/zombies/_zm_perks; +#include maps/mp/zombies/_zm_melee_weapon; +#include maps/mp/zombies/_zm_audio_announcer; +#include maps/mp/zombies/_zm_magicbox; +#include maps/mp/zombies/_zm_utility; +#include maps/mp/zombies/_zm_ai_dogs; +#include maps/mp/gametypes_zm/_hud_message; +#include maps/mp/zombies/_zm_game_module; +#include maps/mp/zombies/_zm_buildables; +#include codescripts/character; +#include maps/mp/zombies/_zm_weap_riotshield; +#include maps/mp/zm_transit_bus; +#include maps/mp/zm_transit_utility; +#include maps/mp/zombies/_zm_equip_turret; +#include maps/mp/zombies/_zm_mgturret; +#include maps\mp\zombies\_zm_weap_jetgun; + +#include maps/mp/zombies/_zm_ai_sloth; +#include maps/mp/zombies/_zm_ai_sloth_ffotd; +#include maps/mp/zombies/_zm_ai_sloth_utility; +#include maps/mp/zombies/_zm_ai_sloth_magicbox; +#include maps/mp/zombies/_zm_ai_sloth_crawler; +#include maps/mp/zombies/_zm_ai_sloth_buildables; + + +#include maps/mp/zombies/_zm_tombstone; +#include maps/mp/zombies/_zm_chugabud; + + + +//customperkinclude +#include maps/mp/_utility; +#include common_scripts/utility; +#include maps/mp/gametypes_zm/_hud_util; +#include maps/mp/zombies/_zm_weapons; +#include maps/mp/zombies/_zm_stats; +#include maps/mp/gametypes_zm/_spawnlogic; +#include maps/mp/animscripts/traverse/shared; +#include maps/mp/animscripts/utility; +#include maps/mp/zombies/_load; +#include maps/mp/_createfx; +#include maps/mp/_music; +#include maps/mp/_busing; +#include maps/mp/_script_gen; +#include maps/mp/gametypes_zm/_globallogic_audio; +#include maps/mp/gametypes_zm/_tweakables; +#include maps/mp/_challenges; +#include maps/mp/gametypes_zm/_weapons; +#include maps/mp/_demo; +#include maps/mp/gametypes_zm/_hud_message; +#include maps/mp/gametypes_zm/_spawning; +#include maps/mp/gametypes_zm/_globallogic_utils; +#include maps/mp/gametypes_zm/_spectating; +#include maps/mp/gametypes_zm/_globallogic_spawn; +#include maps/mp/gametypes_zm/_globallogic_ui; +#include maps/mp/gametypes_zm/_hostmigration; +#include maps/mp/gametypes_zm/_globallogic_score; +#include maps/mp/gametypes_zm/_globallogic; +#include maps/mp/zombies/_zm; +#include maps/mp/zombies/_zm_ai_faller; +#include maps/mp/zombies/_zm_spawner; +#include maps/mp/zombies/_zm_pers_upgrades_functions; +#include maps/mp/zombies/_zm_pers_upgrades; +#include maps/mp/zombies/_zm_score; +#include maps/mp/animscripts/zm_run; +#include maps/mp/animscripts/zm_death; +#include maps/mp/zombies/_zm_blockers; +#include maps/mp/animscripts/zm_shared; +#include maps/mp/animscripts/zm_utility; +#include maps/mp/zombies/_zm_ai_basic; +#include maps/mp/zombies/_zm_laststand; +#include maps/mp/zombies/_zm_net; +#include maps/mp/zombies/_zm_audio; +#include maps/mp/gametypes_zm/_zm_gametype; +#include maps/mp/_visionset_mgr; +#include maps/mp/zombies/_zm_equipment; +#include maps/mp/zombies/_zm_power; +#include maps/mp/zombies/_zm_server_throttle; +#include maps/mp/gametypes/_hud_util; +#include maps/mp/zombies/_zm_unitrigger; +#include maps/mp/zombies/_zm_zonemgr; +#include maps/mp/zombies/_zm_perks; +#include maps/mp/zombies/_zm_melee_weapon; +#include maps/mp/zombies/_zm_audio_announcer; +#include maps/mp/zombies/_zm_magicbox; +#include maps/mp/zombies/_zm_utility; +#include maps/mp/zombies/_zm_ai_dogs; +#include maps/mp/gametypes_zm/_hud_message; +#include maps/mp/zombies/_zm_game_module; +#include maps/mp/zombies/_zm_buildables; +#include codescripts/character; +#include maps/mp/zombies/_zm_weap_riotshield; + + +main() +{ + register_player_damage_callback( ::playerdamagelastcheck ); //moved to main from init because of it not loading in origins + replaceFunc( maps\mp\animscripts\zm_utility::wait_network_frame, ::wait_network_frame_override ); + replaceFunc( maps\mp\zombies\_zm_utility::wait_network_frame, ::wait_network_frame_override ); +} + +init() +{ +//-------------------CUSTOMPERK------------------------ + + // if( (getdvar( "mapname" ) == "zm_transit" || getdvar( "mapname" ) == "zm_highrise") && getdvar ( "g_gametype") == "zstandard" ) + // { + precacheshader("menu_mp_lobby_icon_film"); + precacheshader( "menu_mp_lobby_icon_customgamemode" ); + precacheshader( "waypoint_revive" ); + precacheshader( "killiconheadshot" ); + precacheshader( "menu_lobby_icon_twitter" ); + precacheshader( "hud_grenadeicon" ); + precacheshader( "menu_mp_weapons_1911" ); + precacheshader( "menu_mp_lobby_icon_screenshot" ); + precacheshader( "damage_feedback" ); + precacheshader( "zombies_rank_1" ); + precacheshader( "zombies_rank_3" ); + precacheshader( "zombies_rank_2" ); + precacheshader( "zombies_rank_4" ); + precacheshader( "menu_mp_weapons_xm8" ); + precacheshader( "faction_cdc" ); + precacheshader( "menu_mp_weapons_hamr" ); + precacheshader( "zombies_rank_5" ); + precacheshader( "hud_icon_sticky_grenade" ); + precacheshader( "specialty_instakill_zombies" ); + precacheshader( "menu_mp_weapons_1911" ); + precacheshader( "hud_icon_colt" ); + precachemodel("p6_zm_buildable_sq_meteor"); + precachemodel( "collision_player_wall_512x512x10" ); + precachemodel( "collision_physics_512x512x10" ); + precachemodel( "t5_foliage_tree_burnt03" ); + precachemodel( "p_rus_door_roller" ); + precachemodel( "ch_tombstone1" ); + precachemodel( "collision_geo_256x256x10_standard" ); + precachemodel( "zombie_vending_tombstone_on" ); + precachemodel( "zombie_vending_revive_on" ); + precachemodel( "zombie_vending_sleight_on" ); + precachemodel( "zombie_vending_doubletap2_on" ); + precachemodel( "zombie_pickup_perk_bottle" ); + precachemodel( "zm_collision_perks1" ); + precachemodel( "p6_zm_screecher_hole" ); + precachemodel( "p_cub_door01_wood_fullsize" ); + precachemodel( "veh_t6_civ_microbus_dead" ); + precachemodel( "p_rus_door_white_window_plain_left" ); + if (level.script != "zm_prison") + { + level._effect["fx_zombie_cola_revive_on"] = loadfx( "misc/fx_zombie_cola_revive_on" ); + level._effect["fx_zombie_cola_dtap_on"] = loadfx( "misc/fx_zombie_cola_dtap_on" ); + } + + level._effect["fx_zombie_cola_on"] = loadfx( "misc/fx_zombie_cola_on" ); + if (!(level.script == "zm_tomb" || level.script == "zm_prison")) + { + level._effect["fx_zmb_wall_buy_taseknuck"] = loadfx( "maps/zombie/fx_zmb_wall_buy_taseknuck" ); + level._effect["fx_zmb_wall_buy_bowie"] = loadfx( "maps/zombie/fx_zmb_wall_buy_bowie" ); + } + // level._effect["fx_default_explosion"] = loadfx( "explosions/fx_default_explosion" ); + + + if( level.script == "zm_buried" || level.script == "zm_tomb" ) + { + level._effect["fx_default_explosion"] = level._effect[ "divetonuke_groundhit"]; + } + else + { + level._effect["fx_default_explosion"] = loadfx( "explosions/fx_default_explosion" ); + } + + + level.town = 1; + level.diner = 0; + + level thread onPlayerConnect(); + + //level thread perk_machine_removal( "specialty_scavenger" ); + init_custom_map(); + + if(level.script != "zm_buried" && level.script != "zm_highrise" && level.script != "zm_tomb" && level.script != "zm_prison") + level.get_player_weapon_limit = ::custom_get_player_weapon_limit; + level.zombie_last_stand = ::LastStand; + level.custom_vending_precaching = ::default_vending_precaching; + + + + + level.player_out_of_playable_area_monitor = 0; + level.perk_purchase_limit = 50; + if( getdvar( "mapname" ) == "zm_transit" && getdvar ( "g_gametype" ) == "zstandard" ) + { + foreach( weapon in level.zombie_weapons) + { + weapon.is_in_box = 1; + } + } + +// } + + + +//-------------------ENDCUSTOMPERK------------------------ + + isTown(); + +/* precacheshader("damage_feedback"); + precacheshader("hud_status_dead"); + if( getdvar( "mapname" ) == "zm_transit" ) + { + level._effect[ "jetgun_smoke_cloud" ] = loadfx( "weapon/thunder_gun/fx_thundergun_smoke_cloud" ); + } + level.custom_pap_validation = thread new_pap_trigger(); + level._poi_override = ::turned_zombie; + flag_wait( "initial_blackscreen_passed" ); + + level.original_damagecallback = level.callbackactordamage; + level.callbackactordamage = ::actor_damage_override_wrapper; + //get_players()[0] thread perks_gived(); //test tombstone and whos who aat recovery + wait 1; + level.chugabud_laststand_func = ::chugabud_laststand; //recover aat on whos who revive + + level.tombstone_spawn_func = ::tombstone_spawn; //recover aat on tombstone revive*/ +} + + + +//-------------------CUSTOMPERK------------------------ + +onPlayerConnect() +{ + while( 1 ) + { + level waittill( "connected", player ); + player thread onPlayerSpawned(); + } +} + +onPlayerSpawned() +{ + self endon( "disconnect" ); + level endon( "game_ended" ); + self waittill( "spawned_player" ); + + self.perkarray = []; + self.dying_wish_on_cooldown = 0; + self.perk_reminder = 0; + self.perk_count = 0; + self.num_perks = 0; + self thread removeperkshader(); + self thread perkboughtcheck(); + self thread damagehitmarker(); + for(;;) + { + self waittill( "spawned_player" ); + if(self.score < 1500) + { + self.score = 1500; + } + } +} + +wait_network_frame_override() +{ + wait 0.1; +} + +damagehitmarker() +{ + self endon ("disconnect"); + level endon( "end_game" ); + self thread startwaiting(); + self.hitmarker = newdamageindicatorhudelem( self ); + self.hitmarker.horzalign = "center"; + self.hitmarker.vertalign = "middle"; + self.hitmarker.x = -12; + self.hitmarker.y = -12; + self.hitmarker.alpha = 0; + self.hitmarker setshader( "damage_feedback", 24, 48 ); + +} + +startwaiting() +{ + self endon ("disconnect"); + level endon( "end_game" ); + while( 1 ) + { + foreach( zombie in getaiarray( level.zombie_team ) ) + { + if( !(IsDefined( zombie.waitingfordamage )) ) + { + zombie thread hitmark(); + } + } + wait 0.25; + } +} + +hitmark() +{ + self endon ("disconnect"); + level endon( "end_game" ); + self endon( "killed" ); + self.waitingfordamage = 1; + while( 1 ) + { + self waittill( "damage", amount, attacker, dir, point, mod ); + attacker.hitmarker.alpha = 0; + if( isplayer( attacker ) ) + { + if( isalive( self ) ) + { + attacker.hitmarker.color = ( 1, 1, 1 ); + attacker.hitmarker.alpha = 1; + attacker.hitmarker fadeovertime( 1 ); + attacker.hitmarker.alpha = 0; + } + else + { + attacker.hitmarker.color = ( 1, 0, 0 ); + attacker.hitmarker.alpha = 1; + attacker.hitmarker fadeovertime( 1 ); + attacker.hitmarker.alpha = 0; + self notify( "killed" ); + } + } + } +} + + + + +init_custom_map() +{ + if( level.script == "zm_transit" ) + { + perk_system( "script_model", ( 1856, -810.722, -55.875), "zombie_vending_tombstone_on", ( 0, 180, 0 ), "custom", "mus_perks_deadshot_sting", "Deadshot", 2000, "tombstone_light", "deadshot" ); + perk_system( "script_model", ( 2460, -780, -55.875 ), "zombie_vending_tombstone_on", ( 0, 225, 0 ), "custom", "mus_perks_doubletap_sting", "Burn Heart", 2500, "jugger_light", "Burn_Heart" ); + perk_system( "script_model", ( 901.86, -1575.574, -47.875 ), "zombie_vending_tombstone_on", ( 0, 180, 0 ), "custom", "mus_perks_deadshot_sting", "Widow's Wine", 4000, "tombstone_light", "WIDOWS_WINE" ); + perk_system( "script_model", ( 450, -300.574, -61.875 ), "zombie_vending_tombstone_on", ( 0, 45, 0 ), "custom", "mus_perks_packa_sting", "Electric Cherry", 2000, "tombstone_light", "ELECTRIC_CHERRY" ); // 613,-250,z 0,0,0 + perk_system( "script_model", ( 1069, -1133, 120.125 ), "zombie_vending_tombstone_on", ( 0, 180, 0 ), "custom", "mus_perks_doubletap_sting", "Ethereal Razor", 3500, "tombstone_light", "Ethereal_Razor" ); + perk_system( "script_model", ( 1823.86, 670.574, -55.875 ), "zombie_vending_tombstone_on", ( 0, 45, 0 ), "custom", "mus_perks_doubletap_sting", "Mule Kick", 4000, "tombstone_light", "MULE" ); + perk_system( "script_model", ( 840, 603.809, -40.875 ), "zombie_vending_tombstone_on", ( 0, 0, 0 ), "custom", "mus_perks_packa_sting", "PhD Flopper", 2500, "tombstone_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( 2358, -87, -55.875 ), "zombie_vending_tombstone_on", ( 0, -90, 0 ), "custom", "mus_perks_doubletap_sting", "Downer's Delight", 2000, "tombstone_light", "Downers_Delight" ); + perk_system( "script_model", ( 2015, 858, -56.875 ), "zombie_vending_tombstone_on", ( 0, -90, 0 ), "custom", "mus_perks_doubletap_sting", "Dying Wish", 6000, "tombstone_light", "Dying_Wish" ); + perk_system( "script_model", ( 559, -1364, 120.125 ), "zombie_vending_tombstone_on", ( 0, 180, 0 ), "custom", "mus_perks_doubletap_sting", "Ammo Regen", 3000, "tombstone_light", "Ammo_Regen" ); + } + if( level.script == "zm_highrise") + { + perk_system( "script_model", ( 1884.42, 491.946, 1298.72), "zombie_vending_jugg_on", ( 0, 418.728, 0 ), "custom", "mus_perks_deadshot_sting", "Deadshot", 2000, "tombstone_light", "deadshot" ); +// perk_system( "script_model", ( 2764.64, 1868.03, 1391.01 ), "zombie_vending_jugg_on", ( 0, 384.236, 0 ), "custom", "mus_perks_doubletap_sting", "Burn Heart", 2500, "jugger_light", "Burn_Heart" ); + perk_system( "script_model", ( 1978.25, 597.657, 2704.13 ), "zombie_vending_jugg_on", ( 0, 329.291, 0 ), "custom", "mus_perks_deadshot_sting", "Widow's Wine", 4000, "tombstone_light", "WIDOWS_WINE" ); + perk_system( "script_model", ( 1415.64, 2108.36, 3220.26 ), "zombie_vending_jugg_on", ( 0, 406.661, 0 ), "custom", "mus_perks_packa_sting", "Electric Cherry", 2000, "tombstone_light", "ELECTRIC_CHERRY" ); // 613,-250,z 0,0,0 + perk_system( "script_model", ( 1901.97, 1431.36, 3216.13 ), "zombie_vending_jugg_on", ( 0, 404.762, 0 ), "custom", "mus_perks_doubletap_sting", "Ethereal Razor", 3500, "tombstone_light", "Ethereal_Razor" ); +// perk_system( "script_model", ( 1891.64, 1119.64, 3048.36 ), "zombie_vending_jugg_on", ( 0, 45, 0 ), "custom", "mus_perks_doubletap_sting", "Mule Kick", 4000, "tombstone_light", "MULE" ); + perk_system( "script_model", ( 1429.29, -453.397, 2880.13 ), "zombie_vending_jugg_on", ( 0, 149.1426, 0 ), "custom", "mus_perks_packa_sting", "PhD Flopper", 2500, "tombstone_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( 1109.64, 2701.36, 3043.82 ), "zombie_vending_jugg_on", ( 0, 394.926, 0 ), "custom", "mus_perks_doubletap_sting", "Downer's Delight", 2000, "tombstone_light", "Downers_Delight" ); + perk_system( "script_model", ( 1706.28, 1055.64, 3395.1 ), "zombie_vending_jugg_on", ( 0, 180, 0 ), "custom", "mus_perks_doubletap_sting", "Dying Wish", 6000, "tombstone_light", "Dying_Wish" ); + perk_system( "script_model", ( 2269.17, 182.377, 2880.13 ), "zombie_vending_jugg_on", ( 0, 418.596, 0 ), "custom", "mus_perks_doubletap_sting", "Ammo Regen", 3000, "tombstone_light", "Ammo_Regen" ); + } + if( level.script == "zm_buried") + { + perk_system( "script_model", ( 1618.14, 1513.46, 200.62), "zombie_vending_jugg_on", ( 0, 250.147, 0 ), "custom", "mus_perks_deadshot_sting", "Deadshot", 2000, "sleight_light", "deadshot" ); +// perk_system( "script_model", ( -1176.36, 508.26, 144.125 ), "zombie_vending_jugg_on", ( 0, 448.269, 0 ), "custom", "mus_perks_doubletap_sting", "Burn Heart", 2500, "sleight_light", "Burn_Heart" ); + perk_system( "script_model", ( -1176.36, 510.625, 144.125 ), "zombie_vending_jugg_on", ( 0, 449.412, 0 ), "custom", "mus_perks_deadshot_sting", "Widow's Wine", 4000, "sleight_light", "WIDOWS_WINE" ); + perk_system( "script_model", ( -448.859, 131.435, 143.491 ), "zombie_vending_jugg_on", ( 0, 180.3, 0 ), "custom", "mus_perks_packa_sting", "Electric Cherry", 2000, "sleight_light", "ELECTRIC_CHERRY" ); // 613,-250,z 0,0,0 + perk_system( "script_model", ( 890.359, -840.206, -22.8006 ), "zombie_vending_jugg_on", ( 0, 270.367, 0 ), "custom", "mus_perks_doubletap_sting", "Ethereal Razor", 3500, "sleight_light", "Ethereal_Razor" ); +// perk_system( "script_model", ( 1891.64, 1119.64, 3048.36 ), "zombie_vending_jugg_on", ( 0, 45, 0 ), "custom", "mus_perks_doubletap_sting", "Mule Kick", 4000, "sleight_light", "MULE" ); + perk_system( "script_model", ( 572.507, -712.359, 149.95 ), "zombie_vending_jugg_on", ( 0, 178.4505, 0 ), "custom", "mus_perks_packa_sting", "PhD Flopper", 2500, "sleight_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( 488.324, 727.641, 176.125 ), "zombie_vending_jugg_on", ( 0, 178.9998, 0 ), "custom", "mus_perks_doubletap_sting", "Downer's Delight", 2000, "sleight_light", "Downers_Delight" ); + perk_system( "script_model", ( -1298.32, -837.178, -23.875 ), "zombie_vending_jugg_on", ( 0, 91.37286, 0 ), "custom", "mus_perks_doubletap_sting", "Dying Wish", 6000, "sleight_light", "Dying_Wish" ); + perk_system( "script_model", ( -122.161, -1469.21, 168.125 ), "zombie_vending_jugg_on", ( 0, 448.841, 0 ), "custom", "mus_perks_doubletap_sting", "Ammo Regen", 3000, "sleight_light", "Ammo_Regen" ); + } + if( level.script == "zm_nuked") + { + perk_system( "script_model", ( 28.8155, -356.18, -65.8346 ), "zombie_vending_jugg_on", ( 0, 129.8755, 0 ), "custom", "mus_perks_deadshot_sting", "Deadshot", 2000, "sleight_light", "deadshot" ); +// perk_system( "script_model", ( ), "zombie_vending_jugg_on", ( ), "custom", "mus_perks_doubletap_sting", "Burn Heart", 2500, "sleight_light", "Burn_Heart" ); + perk_system( "script_model", ( -954.194, 714.594, 84.0385 ), "zombie_vending_jugg_on", ( 0, 429.46, 0 ), "custom", "mus_perks_deadshot_sting", "Widow's Wine", 4000, "sleight_light", "WIDOWS_WINE" ); + perk_system( "script_model", ( 683.524, 618.635, -56.875 ), "zombie_vending_jugg_on", ( 0, 102.5635, 0 ), "custom", "mus_perks_packa_sting", "Electric Cherry", 2000, "sleight_light", "ELECTRIC_CHERRY" ); // 613,-250,z 0,0,0 + perk_system( "script_model", ( 1420.35, -21.4313, -63.8849 ), "zombie_vending_jugg_on", ( 0, 194.085, 0 ), "custom", "mus_perks_doubletap_sting", "Ethereal Razor", 3500, "sleight_light", "Ethereal_Razor" ); + perk_system( "script_model", ( 618.292, -188.322, -56.3686 ), "zombie_vending_jugg_on", ( 0, 105.5011, 0 ), "custom", "mus_perks_doubletap_sting", "Mule Kick", 4000, "sleight_light", "MULE" ); + perk_system( "script_model", ( 1152.5, 160.6, 79.125 ), "zombie_vending_jugg_on", ( 0, 392.541, 0 ), "custom", "mus_perks_packa_sting", "PhD Flopper", 2500, "sleight_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( 156.738, 513.899, -62.3141 ), "zombie_vending_jugg_on", ( 0, 101.8164, 0 ), "custom", "mus_perks_doubletap_sting", "Downer's Delight", 2000, "sleight_light", "Downers_Delight" ); + perk_system( "script_model", ( -646.863, 271.522, -55.875 ), "zombie_vending_jugg_on", ( 0, 160.8405, 0 ), "custom", "mus_perks_doubletap_sting", "Dying Wish", 6000, "sleight_light", "Dying_Wish" ); + perk_system( "script_model", ( -1582.46, 112.604, -63.2092 ), "zombie_vending_jugg_on", ( 0, 250.829, 0 ), "custom", "mus_perks_doubletap_sting", "Ammo Regen", 3000, "sleight_light", "Ammo_Regen" ); + } + if( level.script == "zm_tomb") + { + perk_system( "script_model", ( 184.995, -2422.49, 50.125), "zombie_vending_jugg_on", ( 0, 369.091, 0 ), "custom", "mus_perks_deadshot_sting", "Deadshot", 2000, "sleight_light", "deadshot" ); + perk_system( "script_model", ( 160.359, 3781.17, -351.875 ), "zombie_vending_jugg_on", ( 0, 266.122, 0 ), "custom", "mus_perks_deadshot_sting", "Widow's Wine", 4000, "sleight_light", "WIDOWS_WINE" ); + perk_system( "script_model", ( 375.771, 2119.22, -122.951 ), "zombie_vending_jugg_on", ( 0, 179.5935, 0 ), "custom", "mus_perks_doubletap_sting", "Ethereal Razor", 3500, "sleight_light", "Ethereal_Razor" ); + perk_system( "script_model", ( -335.604, -187.006, 325.273 ), "zombie_vending_jugg_on", ( 0, 132.9565, 0 ), "custom", "mus_perks_packa_sting", "PhD Flopper", 2500, "sleight_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( 924.47, 360.72, 131.005 ), "zombie_vending_jugg_on", ( 0, 373.266, 0 ), "custom", "mus_perks_doubletap_sting", "Downer's Delight", 2000, "sleight_light", "Downers_Delight" ); + perk_system( "script_model", ( 1345.09, -3822.62, 302.125 ), "zombie_vending_jugg_on", ( 0, 270.593, 0 ), "custom", "mus_perks_doubletap_sting", "Dying Wish", 6000, "sleight_light", "Dying_Wish" ); + perk_system( "script_model", ( 2972.36, 5218.91, -378.566 ), "zombie_vending_jugg_on", ( 0, 270.379, 0 ), "custom", "mus_perks_doubletap_sting", "Ammo Regen", 3000, "sleight_light", "Ammo_Regen" ); + } + if( level.script == "zm_prison") + { + perk_system( "script_model", ( -1344.65, 5598.31, -71.875 ), "p6_zm_al_vending_jugg_on", ( 0, 98.34412, 0 ), "custom", "mus_perks_deadshot_sting", "Deadshot", 2000, "sleight_light", "deadshot" ); + perk_system( "script_model", ( 3763.64, 9669.99, 1704.13 ), "p6_zm_al_vending_jugg_on", ( 0, 90, 0 ), "custom", "mus_perks_deadshot_sting", "Widow's Wine", 4000, "sleight_light", "WIDOWS_WINE" ); + perk_system( "script_model", ( 2160.71, 9247.64, 1558.13 ), "p6_zm_al_vending_jugg_on", ( 0, 179.1815, 0 ), "custom", "mus_perks_doubletap_sting", "Ethereal Razor", 3500, "sleight_light", "Ethereal_Razor" ); + perk_system( "script_model", ( 597.633, 8546.86, 832.125 ), "p6_zm_al_vending_jugg_on", ( 0, 221.984, 0 ), "custom", "mus_perks_doubletap_sting", "Mule Kick", 4000, "sleight_light", "MULE" ); + perk_system( "script_model", ( 456.359, 8679.51, 1128.13 ), "p6_zm_al_vending_jugg_on", ( 0, 269.533, 0 ), "custom", "mus_perks_packa_sting", "PhD Flopper", 2500, "sleight_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( -685.943, 9199.64, 1336.13 ), "p6_zm_al_vending_jugg_on", ( 0, 178.5443, 0 ), "custom", "mus_perks_doubletap_sting", "Downer's Delight", 2000, "sleight_light", "Downers_Delight" ); + perk_system( "script_model", ( 1728.56, 10688.4, 1336.13 ), "p6_zm_al_vending_jugg_on", ( 0, 357.896, 0 ), "custom", "mus_perks_doubletap_sting", "Dying Wish", 6000, "sleight_light", "Dying_Wish" ); + perk_system( "script_model", ( 1367.28, 10096.4, 1128.13 ), "p6_zm_al_vending_jugg_on", ( 0, 358.687, 0 ), "custom", "mus_perks_doubletap_sting", "Ammo Regen", 3000, "sleight_light", "Ammo_Regen" ); + } +} + +play_fx( fx ) +{ + playfxontag( level._effect[ fx ], self, "tag_origin" ); +} + +defaulth_vending_precaching() +{ + level._effect[ "sleight_light" ] = loadfx( "misc/fx_zombie_cola_on" ); + level._effect[ "tombstone_light" ] = loadfx( "misc/fx_zombie_cola_on" ); + level._effect[ "revive_light" ] = loadfx( "misc/fx_zombie_cola_revive_on" ); + level._effect[ "marathon_light" ] = loadfx( "maps/zombie/fx_zmb_cola_staminup_on" ); + level._effect[ "jugger_light" ] = loadfx( "misc/fx_zombie_cola_jugg_on" ); + level._effect[ "doubletap_light" ] = loadfx( "misc/fx_zombie_cola_dtap_on" ); + level._effect[ "deadshot_light" ] = loadfx( "misc/fx_zombie_cola_dtap_on" ); + level._effect[ "additionalprimaryweapon_light" ] = loadfx( "misc/fx_zombie_cola_arsenal_on" ); + level._effect[ "packapunch_fx" ] = loadfx( "maps/zombie/fx_zombie_packapunch" ); + level._effect[ "wall_taseknuck" ] = loadfx( "maps/zombie/fx_zmb_wall_buy_taseknuck" ); +} + + +playchalkfx(effect, origin, angles) +{ + fx = SpawnFX(level._effect[ effect ], origin,AnglesToForward(angles),AnglesToUp(angles)); + TriggerFX(fx); + level waittill("connected", player); + fx Delete(); +} + + + +perk_system( script, pos, model, angles, type, sound, name, cost, fx, perk) +{ + col = spawn( script, pos); + col setmodel( model ); + col.angles = angles; + x = spawn( script, pos ); + x setmodel( "zm_collision_perks1" ); + x.angles = angles; + col thread buy_system( perk, sound, name, cost, type ); + col thread play_fx( fx ); +} + +buy_system( perk, sound, name, cost, type ) +{ + level endon("end_game"); + self endon("disconnect"); + self endon( "game_ended" ); + while( 1 ) + { + foreach( player in level.players ) + { + if(!player.machine_is_in_use) + { + if( distance( self.origin, player.origin ) <= 70 ) + { + player thread SpawnHint( self.origin, 30, 30, "HINT_ACTIVATE", "Hold ^3&&1^7 for " + name + " [Cost: " + cost + "]" ); + if(player usebuttonpressed() && !player hasperk(perk) && !player hascustomperk(perk) && player.score >= cost && !player maps/mp/zombies/_zm_laststand::player_is_in_laststand()) + { + player.machine_is_in_use = 1; + player playsound( "zmb_cha_ching" ); + player.score -= cost; + player playsound( sound ); + player thread drawshader_and_shadermove( perk, 1, 1, type ); + wait 4; + player.machine_is_in_use = 0; + } + else + { + if( player usebuttonpressed() && player.score < cost ) + { + player maps/mp/zombies/_zm_audio::create_and_play_dialog( "general", "perk_deny", undefined, 0 ); + } + } + } + } + } + wait 0.1; + } +} + +hascustomperk(perk) +{ + for(i = 0; i < self.perkarray.size; i++) + { + if(self.perkarray[i].name == perk) + { + return 1; + } + } + return 0; +} + +removeperkshader() +{ + self endon ("disconnect"); + level endon( "end_game" ); + common_scripts/utility::flag_wait( "initial_blackscreen_passed" ); + for(;;) + { + self waittill_any_return( "fake_death", "player_downed", "player_revived", "spawned_player", "disconnect", "death" ); + self.num_perks = 0; + self.perk_reminder = 0; + self.perk_count = 0; + self.dying_wish_on_cooldown = 0; + self removeallcustomshader(); + self.perkarray = []; + self notify( "stopcustomperk" ); + self.bleedout_time = 30; + self.ignore_lava_damage = 0; + self setclientfieldtoplayer( "deadshot_perk", 0 ); + } +} + +removeallcustomshader() +{ + for(i = 0; i < self.perkarray.size; i++) + { + self.perkarray[i] destroy(); + } +} + +drawshader( shader, x, y, width, height, color, alpha, sort ) +{ + level endon("end_game"); + self endon("disconnect"); + hud = newclienthudelem( self ); + hud.elemtype = "icon"; + hud.color = color; + hud.alpha = alpha; + hud.sort = sort; + hud.children = []; + hud.hidewheninmenu = 1; + hud setparent( level.uiparent ); + hud setshader( shader, width, height ); + hud.x = x; + hud.y = y; + return hud; +} + +perkboughtcheck() +{ + self endon("death"); + self endon("disconnect"); + for(;;) + { + self.perk_reminder = self.num_perks; + self waittill("perk_acquired"); + n = 1; + if(!(self.num_perks > self.perk_reminder)) + { + n = (self.num_perks - self.perk_reminder); + self.num_perks = (self.perk_reminder + n); + } + self.perk_reminder = self.num_perks; + self.perk_count += n; + self drawshader_and_shadermove("none", 0, 0, "normal"); //modified to remove perk alignement since 2 perk lines Added "normal" for type check + } +} + +drawshader_and_shadermove(perk, custom, print, type) +{ + level endon("end_game"); + self endon("disconnect"); + if(custom) + { + self allowProne(false); + self allowSprint(false); + self disableoffhandweapons(); + self disableweaponcycling(); + weapona = self getcurrentweapon(); + weaponb = "zombie_perk_bottle_jugg"; + self giveweapon( weaponb ); + self switchtoweapon( weaponb ); + self waittill( "weapon_change_complete" ); + self enableoffhandweapons(); + self enableweaponcycling(); + self takeweapon( weaponb ); + self switchtoweapon( weapona ); + self maps/mp/zombies/_zm_audio::playerexert( "burp" ); + self setblur( 4, 0.1 ); + wait 0.1; + self setblur( 0, 0.1 ); + self allowProne(true); + self allowSprint(true); + } + + yPerk = 325; + if (level.script == "zm_buried") + { + yPerk = 300; + } + if (level.script == "zm_tomb") + { + yPerk = 275; + } + + x = -408; + for(i = 0; i < self.perkarray.size; i++) + { + if (type == "custom") + { + x += 15; + } + } + /*if (perk == "custom") + { + for(i = 0; i < self.perkarray.size; i++) + { + self.perkarray[i].x = self.perkarray[i].x + 30; + } + }*/ + if(perk == "Downers_Delight") + { + self.perk1back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk1front = self drawshader( "waypoint_revive", x, yPerk, 23, 23, ( 0, 1, 1 ), 100, 0 ); + self.perk1front.name = perk; + self.perkarray[self.perkarray.size] = self.perk1front; + self.perk1back.name = perk; + self.perkarray[self.perkarray.size] = self.perk1back; + self.num_perks++; + self thread DDown(); + if(print) + { + self iprintln("^9Downer's Delight"); + wait 0.2; + self iprintln("This Perk will increase players bleedout time by 10 seconds and current weapons is used in laststand."); + } + } + if(perk == "MULE") + { + self.perk2back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk2front = self drawshader( "menu_mp_weapons_1911", x, yPerk, 22, 22, ( 0, 1, 0 ), 100, 0 ); + self.perk2front.name = perk; + self.perkarray[self.perkarray.size] = self.perk2front; + self.perk2back.name = perk; + self.perkarray[self.perkarray.size] = self.perk2back; + self.num_perks++; + if(print) + { + self iprintln("^9Mule Kick"); + wait 0.2; + self iprintln("This Perk enables additional primary weapon slot for player. "); + } + } + if(perk == "PHD_FLOPPER") + { + self.perk3back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk3front = self drawshader( "hud_icon_sticky_grenade", x, yPerk, 23, 23, (1, 0, 1 ), 100, 0 ); + self.perk3front.name = perk; + self.perkarray[self.perkarray.size] = self.perk3front; + self.perk3back.name = perk; + self.perkarray[self.perkarray.size] = self.perk3back; + self.num_perks++; + if(print) + { + self iprintln("^9PhD Flopper"); + wait 0.2; + self iprintln("This Perk removes explosion and fall damage also player creates explosion when dive to prone."); + } + } + if(perk == "Victorious_Tortoise") + { + self.perk4back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 200, 0 ), 100, 0 ); + self.perk4front = self drawshader( "zombies_rank_2", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk4front.name = perk; + self.perkarray[self.perkarray.size] = self.perk4front; + self.perk4back.name = perk; + self.perkarray[self.perkarray.size] = self.perk4back; + self.num_perks++; + self thread start_vt(); + if(print) + { + self iprintln("^9Victorious Tortoise"); + wait 0.2; + self iprintln("This Perk allows shield block damage from all directions when in use."); + } + } + if(perk == "ELECTRIC_CHERRY") + { + self.perk5back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 200 ), 100, 0 ); + self.perk5front = self drawshader( "zombies_rank_5", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk5front.name = perk; + self.perkarray[self.perkarray.size] = self.perk5front; + self.perk5back.name = perk; + self.perkarray[self.perkarray.size] = self.perk5back; + self.num_perks++; + self thread start_ec(); + if(print) + { + self iprintln("^9Electric Cherry"); + wait 0.2; + self iprintln("This Perk creates an electric shockwave around the player whenever they reload."); + } + } + if(perk == "WIDOWS_WINE") + { + self.perk6back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk6front = self drawshader( "zombies_rank_3", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk6front.name = perk; + self.perkarray[self.perkarray.size] = self.perk6front; + self.perk6back.name = perk; + self.perkarray[self.perkarray.size] = self.perk6back; + self.num_perks++; + self takeweapon( self get_player_lethal_grenade() ); + self set_player_lethal_grenade( "sticky_grenade_zm" ); + self giveweapon("sticky_grenade_zm"); + self thread ww_nades(); + if(print) + { + self iprintln("^9Widow's Wine"); + wait 0.2; + self iprintln("This Perk damages zombies around the player when player is hit and grenades are upgraded."); + } + } + if(perk == "Ethereal_Razor") + { + self.perk7back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 200, 0, 0 ), 100, 0 ); + self.perk7front = self drawshader( "zombies_rank_4", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk7front.name = perk; + self.perkarray[self.perkarray.size] = self.perk7front; + self.perk7back.name = perk; + self.perkarray[self.perkarray.size] = self.perk7back; + self.num_perks++; + if(print) + { + self iprintln("^9Ethereal Razor"); + wait 0.2; + self iprintln("This Perk deals extra damage when player using melee attacks and restores a small amount of health."); + } + } + if(perk == "Ammo_Regen") + { + self.perk8back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk8front = self drawshader( "menu_mp_lobby_icon_customgamemode", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk8front.name = perk; + self.perkarray[self.perkarray.size] = self.perk8front; + self.perk8back.name = perk; + self.perkarray[self.perkarray.size] = self.perk8back; + self.num_perks++; + self thread ammoregen(); + self thread grenadesregen(); + if(print) + { + self iprintln("^9Ammo Regen"); + wait 0.2; + self iprintln("This Perk will slowly regenerades players ammonation and grenades."); + } + } + if(perk == "Burn_Heart") + { + self.perk9back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 200, 0, 0 ), 100, 0 ); + self.perk9front = self drawshader( "faction_cdc", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk9front.name = perk; + self.perkarray[self.perkarray.size] = self.perk9front; + self.perk9back.name = perk; + self.perkarray[self.perkarray.size] = self.perk9back; + self.num_perks++; + self.ignore_lava_damage = 1; + if(print) + { + self iprintln("^9Burn Heart"); + wait 0.2; + self iprintln("This Perk removes lava damage."); + } + } + if(perk == "Dying_Wish") + { + self.perk10back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 200, 0, 0 ), 100, 0 ); + self.perk10front = self drawshader( "zombies_rank_5", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk10front.name = perk; + self.perkarray[self.perkarray.size] = self.perk10front; + self.perk10back.name = perk; + self.perkarray[self.perkarray.size] = self.perk10back; + self.num_perks++; + self thread dying_wish_checker(); + if(print) + { + self iprintln("^9Dying Wish"); + wait 0.2; + self iprintln("This Perk allow player to go berserker mode for 9 seconds instead of laststand."); + wait 0.1; + self iprintln(" (cooldown 5mins and it's increased 30sec every time perk is used. - max 10mins) "); + } + } + if(perk == "deadshot") + { + self.perk11back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk11front = self drawshader( "killiconheadshot", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk11front.name = perk; + self.perkarray[self.perkarray.size] = self.perk11front; + self.perk11back.name = perk; + self.perkarray[self.perkarray.size] = self.perk11back; + self.num_perks++; + self setclientfieldtoplayer( "deadshot_perk", 1 ); + if(print) + { + self iprintln("^9Deadshot"); + wait 0.2; + self iprintln("This Perk aims automatically enemys head instead of body."); + } + } +} + +custom_get_player_weapon_limit( player ) +{ + level endon("end_game"); + self endon("disconnect"); + weapon_limit = 2; + if ( player hascustomperk("MULE") ) + { + weapon_limit = 3; + } + else + { + weapons = self getWeaponsListPrimaries(); + if(weapons.size > 2) + { + self takeWeapon(weapons[2]); + } + } + return weapon_limit; +} + +ammoregen() +{ + self endon( "disconnect" ); + level endon( "end_game" ); + self endon( "stopcustomperk" ); + for(;;) + { + if(!self GetCurrentWeapon() == "" && !is_grenade_launcher( self GetCurrentWeapon()) && self GetCurrentWeapon() != "slipgun_zm" +&& self GetCurrentWeapon() != "staff_fire_zm" && self GetCurrentWeapon() != "staff_fire_upgraded_zm" +&& self GetCurrentWeapon() != "staff_air_zm" && self GetCurrentWeapon() != "staff_air_upgraded_zm" +&& self GetCurrentWeapon() != "staff_water_zm" && self GetCurrentWeapon() != "staff_water_upgraded_zm" +&& self GetCurrentWeapon() != "staff_lightning_zm" && self GetCurrentWeapon() != "staff_lightning_upgraded_zm" +&& self GetCurrentWeapon() != "blundersplat_upgraded_zm") + { + stockcount = self getweaponammostock( self GetCurrentWeapon() ); + self setWeaponAmmostock( self GetCurrentWeapon(), stockcount + 1 ); + wait 2; + } + wait 0.1; + } +} + +grenadesregen() +{ + self endon( "disconnect" ); + level endon( "end_game" ); + self endon( "stopcustomperk" ); + for(;;) + { + grenades = self get_player_lethal_grenade(); + grenade_count = self getweaponammoclip(grenades); + if(grenade_count < 4) + { + self setweaponammoclip(grenades, (grenade_count + 1)); + } + tactical_grenades = self get_player_tactical_grenade(); + tactical_grenade_count = self getweaponammoclip(tactical_grenades); + if(tactical_grenade_count < 3 ) + { + self setweaponammoclip(tactical_grenades, (tactical_grenade_count + 1)); + } + wait 300; + } +} + +start_ec() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("stopcustomperk"); + for(;;) + { + self waittill( "reload_start" ); + playfxontag( level._effect[ "poltergeist"], self, "J_SpineUpper" ); + self EnableInvulnerability(); + RadiusDamage(self.origin, 120, 200, 100, self); + self DisableInvulnerability(); + self playsound( "zmb_turbine_explo" ); + wait 1; + } +} + +start_vt() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("stopcustomperk"); + for(;;) + { + if(self getcurrentweapon() == "riotshield_zm" ) + { + self enableInvulnerability(); + self.shielddamagetaken += 100; + wait 0.9; + } + else + { + self disableInvulnerability(); + } + wait 0.1; + } +} + +start_er() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("stopcustomperk"); + for(;;) + { + if (self hascustomperk("Ethereal_Razor") && self ismeleeing()) + { + foreach(zombie in getAiArray(level.zombie_team)) + { + if( distance( self.origin, zombie.origin ) <= 100 ) + { + + } + } + self.health += 20; + if(self.health > self.maxhealth) + { + self.health = self.maxhealth; + } + while(self ismeleeing()) + { + wait 0.1; + } + } + wait 0.05; + } +} + +LastStand() +{ + level endon("end_game"); + self endon("disconnect"); + if(self hascustomperk("Downers_Delight")) + { + self.customlaststandweapon = self getcurrentweapon(); + self switchtoweapon( self.customlaststandweapon ); + self setweaponammoclip( self.customlaststandweapon, 150 ); + self.bleedout_time = 40; + } + else + { + self maps/mp/zombies/_zm::last_stand_pistol_swap(); + } +} + +DDown() +{ + self endon( "disconnect" ); + level endon( "end_game" ); + self endon( "stopcustomperk" ); + for(;;) + { + self waittill("player_downed"); + self playsound( "zmb_phdflop_explo" ); + playfx(loadfx("explosions/fx_default_explosion"), self.origin, anglestoforward( ( 0, 45, 55 ) ) ); + RadiusDamage(self.origin, 150, 600, 400, self); + wait 0.1; + } +} + +doGivePerk(perk) +{ + self endon("disconnect"); + self endon("death"); + level endon("game_ended"); + self endon("perk_abort_drinking"); + if (!(self hasperk(perk) || (self maps/mp/zombies/_zm_perks::has_perk_paused(perk)))) + { + gun = self maps/mp/zombies/_zm_perks::perk_give_bottle_begin(perk); + evt = self waittill_any_return("fake_death", "death", "player_downed", "weapon_change_complete"); + if (evt == "weapon_change_complete") + self thread maps/mp/zombies/_zm_perks::wait_give_perk(perk, 1); + self maps/mp/zombies/_zm_perks::perk_give_bottle_end(gun, perk); + if (self maps/mp/zombies/_zm_laststand::player_is_in_laststand() || isDefined(self.intermission) && self.intermission) + return; + self notify("burp"); + } +} + + +SpawnHint( origin, width, height, cursorhint, string ) +{ + level endon("end_game"); + self endon("disconnect"); + hint = spawn( "trigger_radius", origin, 1, width, height ); + hint setcursorhint( cursorhint, hint ); + hint sethintstring( string ); + hint setvisibletoall(); + wait 0.2; + hint delete(); +} + + +ww_points( player ) +{ + level endon("end_game"); + self endon("disconnect"); + for(i = 0; i < 3; i++) + { + self maps/mp/zombies/_zm_utility::set_zombie_run_cycle("walk"); + player maps/mp/zombies/_zm_score::add_to_player_score( 10 ); + PlayFXOnTag(level.effect_WebFX,self,"j_spineupper"); + self doDamage(150, (0, 0, 0)); + wait 1; + } +} + +ww_nade_explosion() +{ + level endon("end_game"); + self endon("disconnect"); + wait 2; + // if( self maps/mp/zm_transit_lava::object_touching_lava()) +// { + // self delete(); + // return 0; + // } + foreach(zombie in getAiArray(level.zombie_team)) + { + if( distance( zombie.origin, self.origin ) < 210 ) + { + zombie thread ww_points( self ); + } + } + self delete(); +} + +ww_nades() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("stopcustomperk"); + for(;;) + { + self waittill( "grenade_fire", grenade, weapname ); + if( weapname == "sticky_grenade_zm" ) + { + ww_nade = spawnsm( grenade.origin, "zombie_bomb" ); + ww_nade hide(); + ww_nade linkto( grenade ); + ww_nade thread ww_nade_explosion(); + } + } +} + +spawnsm( origin, model, angles ) +{ + level endon("end_game"); + self endon("disconnect"); + ent = spawn( "script_model", origin ); + ent setmodel( model ); + if( IsDefined( angles ) ) + { + ent.angles = angles; + } + return ent; +} + +dying_wish_checker() +{ + level endon("end_game"); + self endon("disconnect"); + self endon( "stopcustomperk" ); + self.dying_wish_uses = 0; + for(;;) + { + self.dying_wish_on_cooldown = 0; + self.perk10back.alpha = 1; + self.perk10front.alpha = 1; + self waittill("dying_wish_charge"); + self.perk10back.alpha = 0.3; + self.perk10front.alpha = 0.4; + self.dying_wish_uses++; + self.dying_wish_on_cooldown = 1; + delay = 300 + (self.dying_wish_uses * 30); + if(delay >= 600) + delay = 600; + wait delay; + } +} + +dying_wish_effect() +{ + level endon("end_game"); + self endon("disconnect"); + self enableInvulnerability(); + self.ignoreme = 1; + self useServerVisionSet(true); + self setvisionsetforplayer( "zombie_death", 0 ); + self freezeControls(1); + wait 1; + self freezeControls(0); + wait 8; + self.health = 1; + self disableInvulnerability(); + self.ignoreme = 0; + self useServerVisionSet(false); + self setvisionsetforplayer("remote_mortar_enhanced", 0); +} + + +player_burning_audio() +{ + level endon("end_game"); + self endon("disconnect"); + fire_ent = spawn( "script_model", self.origin ); + wait_network_frame(); + fire_ent linkto( self ); + fire_ent playloopsound( "evt_plr_fire_loop" ); + self waittill_any( "stop_flame_damage", "stop_flame_sounds", "death", "disconnect" ); + fire_ent delete(); +} + + +//-------------------ENDCUSTOMPERK------------------------ + + + +perks_gived() +{ + level endon("end_game"); + self endon("disconnect"); + wait 5; + iprintln("done"); + self give_perk("specialty_scavenger"); + bot = addtestclient(); + wait 1; + bot enableInvulnerability(); + +} + +playerdamagelastcheck( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime ) +{ + level endon("end_game"); + self endon("disconnect"); +//-------------------CUSTOMPERK------------------------ + if( isDefined( eAttacker.is_zombie ) && eAttacker.is_zombie && self hascustomperk("WIDOWS_WINE") ) + { + zombies = getaiarray(level.zombie_team); + foreach(zombie in zombies) + { + if(distance(self.origin, zombie.origin) < 150) + { + grenades = self get_player_lethal_grenade(); + grenade_count = self getweaponammoclip(grenades); + if(grenade_count > 0) + { + self PlaySound("zmb_elec_jib_zombie"); + self setweaponammoclip(grenades, (grenade_count - 1)); + zombie thread ww_points( self ); + } + } + } + } + if(self hascustomperk("PHD_FLOPPER")) + { + if( smeansofdeath == "MOD_FALLING" ) + { + if(isDefined( self.divetoprone ) && self.divetoprone == 1 ) + { + radiusdamage( self.origin, 300, 5000, 1000, self, "MOD_GRENADE_SPLASH" ); + playfx(loadfx("explosions/fx_default_explosion"), self.origin, anglestoforward( ( 0, 45, 55 ) ) ); + self playsound( "zmb_phdflop_explo" ); + } + return 0; + } + if( smeansofdeath == "MOD_PROJECTILE" || smeansofdeath == "MOD_PROJECTILE_SPLASH" || smeansofdeath == "MOD_GRENADE" || smeansofdeath == "MOD_GRENADE_SPLASH" && eattacker == self) + { + return 0; + } + } + if(idamage > self.health && !self.dying_wish_on_cooldown && self hascustomperk("Dying_Wish") ) + { + self notify("dying_wish_charge"); + self thread dying_wish_effect(); + return 0; + } + else + { + return idamage; + } + +//-------------------ENDCUSTOMPERK------------------------ + + + + + + + + if(isdefined(self.has_cluster) && self.has_cluster && isdefined(eattacker) && eattacker == self) + { + return 0; + } + players = get_players(); + for(i=0;i= 5000 && current_weapon != "riotshield_zm" && player can_buy_weapon() && !player.is_drinking && !is_placeable_mine( current_weapon ) && !is_equipment( current_weapon ) && level.revive_tool != current_weapon && current_weapon != "none" ) + { + player.score -= 5000; + player thread maps/mp/zombies/_zm_audio::play_jingle_or_stinger( "mus_perks_packa_sting" ); + trigger setinvisibletoall(); + upgrade_as_attachment = will_upgrade_weapon_as_attachment( current_weapon ); + + player.restore_ammo = undefined; + player.restore_clip = undefined; + player.restore_stock = undefined; + player.restore_clip_size = undefined; + player.restore_max = undefined; + + player.restore_clip = player getweaponammoclip( current_weapon ); + player.restore_clip_size = weaponclipsize( current_weapon ); + player.restore_stock = player getweaponammostock( current_weapon ); + player.restore_max = weaponmaxammo( current_weapon ); + + player thread maps/mp/zombies/_zm_perks::do_knuckle_crack(); + wait .1; + player takeWeapon(current_weapon); + current_weapon = player maps/mp/zombies/_zm_weapons::switch_from_alt_weapon( current_weapon ); + self.current_weapon = current_weapon; + upgrade_name = maps/mp/zombies/_zm_weapons::get_upgrade_weapon( current_weapon, upgrade_as_attachment ); + player third_person_weapon_upgrade( current_weapon, upgrade_name, packa_rollers, perk_machine, self ); + trigger sethintstring( &"ZOMBIE_GET_UPGRADED" ); + trigger thread wait_for_pick(player, current_weapon, self.upgrade_name); + if ( isDefined( player ) ) + { + trigger setinvisibletoall(); + trigger setvisibletoplayer( player ); + } + self thread wait_for_timeout( current_weapon, packa_timer, player ); + self waittill_any( "pap_timeout", "pap_taken", "pap_player_disconnected" ); + self.current_weapon = ""; + if ( isDefined( self.worldgun ) && isDefined( self.worldgun.worldgundw ) ) + { + self.worldgun.worldgundw delete(); + } + if ( isDefined( self.worldgun ) ) + { + self.worldgun delete(); + } + trigger setinvisibletoplayer( player ); + wait 1.5; + trigger setvisibletoall(); + self.pack_player = undefined; + flag_clear( "pack_machine_in_use" ); + } + Trigger sethintstring( " Hold ^3&&1^7 for Pack-a-Punch [Cost: 5000] \n Weapons can be pack a punched multiple times" ); + wait .1; + } +} + +wait_for_pick(player, weapon, upgrade_weapon ) +{ + level endon("end_game"); + self endon("disconnect"); + level endon( "pap_timeout" ); + for (;;) + { + self playloopsound( "zmb_perks_packa_ticktock" ); + self waittill( "trigger", user ); + if(user UseButtonPressed() && player == user) + { + self stoploopsound( 0.05 ); + player thread do_player_general_vox( "general", "pap_arm2", 15, 100 ); + gun = player maps/mp/zombies/_zm_weapons::get_upgrade_weapon( upgrade_weapon, 0 ); + if(is_weapon_upgraded( weapon ) ) + { + player.restore_ammo = 1; + if( weapon == "galil_upgraded_zm+reflex" || weapon == "fnfal_upgraded_zm+reflex" ) + { + level thread aats(weapon, player); //Alternative ammo type for galil and fnfal upgraded + } + else + { + level thread aats(upgrade_weapon, player); //Alternative ammo type for all other weapons + } + } + if( weapon == "galil_upgraded_zm+reflex" || weapon == "fnfal_upgraded_zm+reflex" ) + { + player giveweapon( weapon, 0, player maps/mp/zombies/_zm_weapons::get_pack_a_punch_weapon_options( weapon )); + player switchToWeapon( weapon ); + x = weapon; + } + else + { + weapon_limit = get_player_weapon_limit( player ); + player maps/mp/zombies/_zm_weapons::take_fallback_weapon(); + primaries = player getweaponslistprimaries(); + if ( isDefined( primaries ) && primaries.size >= weapon_limit ) + { + player maps/mp/zombies/_zm_weapons::weapon_give( upgrade_weapon ); + } + else + { + player giveweapon( upgrade_weapon, 0, player maps/mp/zombies/_zm_weapons::get_pack_a_punch_weapon_options( upgrade_weapon )); + } + player switchToWeapon( upgrade_weapon ); + x = upgrade_weapon; + } + + if ( isDefined( player.restore_ammo ) && player.restore_ammo ) + { + new_clip = player.restore_clip + ( weaponclipsize( x ) - player.restore_clip_size ); + new_stock = player.restore_stock + ( weaponmaxammo( x ) - player.restore_max ); + player setweaponammostock( x, new_stock ); + player setweaponammoclip( x, new_clip ); + } + level notify( "pap_taken" ); + player notify( "pap_taken" ); + break; + } + wait .1; + } +} + +aats(name, player) +{ + level endon("end_game"); + self endon("disconnect"); + self endon( "death" ); + self endon( "pap_timeout" ); + self endon( "pap_player_disconnected" ); + self endon( "Pack_A_Punch_off" ); + self waittill("pap_taken"); + self thread pick_ammo(name, player); +} + +pick_ammo(name, player) +{ + level endon("end_game"); + self endon("disconnect"); + player notify("new_aat"); + primaries = player getweaponslistprimaries(); + if(!isDefined(player.active_explosive_bullet)) + { + player thread explosive_bullet(); + } + if(!isDefined(player.weaponname)) + { + player.active_turned = 0; + player.has_turned = 0; + player.has_blast_furnace = 0; + player.has_fireworks = 0; + player.cooldown = 0; + player.has_explosive_bullets = 0; + player.has_thunder_wall = 0; + player.has_Headcutter = 0; + player.has_cluster = 0; + // player thread aat_hitmarker(); + } + if(!isDefined(player.weaponname)) + { + player.weaponname = "x"; + } + if(!isDefined(player.last_aat)) + { + player.last_aat = 0; + } + if(!isDefined(player.aat_weapon)) + { + player.aat_weapon = []; + } + if(!isDefined(player.weapon_aats)) + { + player.weapon_aats = []; + } + aat = randomIntRange(0,8); + + /*aats = array("Blast Furnace", "Fireworks", "Explosive", "Headcutter", "Cluster", "Turned", "Thunder Wall"); + aats = array("Blast Furnace", "Headcutter", "Turned", "Thunder Wall"); + randomize = array_randomize(aats); + aat = randomize[0];*/ + + + if(name == player.weaponname && aat == player.last_aat ) + { + return pick_ammo(name, player); + } + for(i=0; i 0 || !is_true( self.dont_die_on_me ) ) + { + self finishactordamage( inflictor, attacker, damage_override, flags, meansofdeath, weapon, vpoint, vdir, shitloc, psoffsettime, boneindex ); + } +} + +actor_damage_override( inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, shitloc, psoffsettime, boneindex ) +{ + level endon("end_game"); + self endon("disconnect"); + if(isdefined(level.sloth) && self == level.sloth || isDefined(self.is_avogadro) && self.is_avogadro || isDefined(self.is_brutus) && self.is_brutus || isDefined(self.is_mechz) && self.is_mechz ) + { + return [[level.original_damagecallback]]( inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, shitloc, psoffsettime, boneindex ); + } + if(isdefined( attacker.weaponname )) + { + + if(!isDefined(self.is_turned)) + self.is_turned = 0; + + //attacker cannot damage active turned zombie + if(/*attacker.active_turned &&*/ self.is_turned) + return 0; + + if(isdefined( attacker ) && isplayer( attacker ) && !attacker.cooldown && MeansOfDeath != "MOD_MELEE" && MeansOfDeath != "MOD_IMPACT" && weapon != "knife_zm") + { + aat_cooldown_time = randomintrange(10, 16); //cooldown 10 - 15 seconds + aat_activation = randomintrange(1,11); //bullet that actives aat 1 - 10 + + zombies = getaiarray( level.zombie_team ); + if(meansofdeath == "MOD_GRENADE" || meansofdeath == "MOD_GRENADE_SPLASH" || meansofdeath == "MOD_EXPLOSIVE" || meansofdeath == "MOD_PROJECTILE") + { + if(is_weapon_upgraded( weapon )) + { + } + else + { + return [[level.original_damagecallback]]( inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, shitloc, psoffsettime, boneindex ); + } + } + if(self turned_zombie_validation() && attacker.has_turned && !attacker.active_turned) + { + turned = aat_activation; + if(turned == 1) + { + attacker.aat_actived = 1; + attacker thread cool_down(aat_cooldown_time); + self thread turned( attacker ); + } + } + if(attacker.has_cluster) + { + cluster = aat_activation; + if(cluster == 1) + { + attacker.aat_actived = 1; + attacker thread cool_down(aat_cooldown_time); + self thread cluster(); + self dodamage( self.health * 2, (0,0,0), attacker, attacker, "none", "MOD_IMPACT" ); + } + + } + if(attacker.has_Headcutter) + { + Headcutter = aat_activation; + if(Headcutter == 1) + { + attacker.aat_actived = 1; + attacker thread cool_down(aat_cooldown_time); + for( i=0; i < zombies.size; i++ ) + { + if(distance(self.origin, zombies[i].origin) <= 200) + { + if(!zombies[i].done) + { + zombies[i].done = 1; + zombies[i] thread Headcutter(attacker); + } + } + } + self dodamage( self.health * 2, (0,0,0), attacker, attacker, "none", "MOD_IMPACT" ); + } + } + if(attacker.has_thunder_wall) + { + thunder_wall = aat_activation; + if(thunder_wall == 1) + { + attacker setclientdvar( "ragdoll_enable", 1); + attacker.aat_actived = 1; + self thread thunderwall(attacker); + attacker thread cool_down(aat_cooldown_time); + self dodamage( self.health * 2, (0,0,0), attacker, attacker, "none", "MOD_IMPACT" ); + } + + } + if(attacker.has_blast_furnace) + { + blast_furnace = aat_activation; + if(blast_furnace == 1) + { + attacker.aat_actived = 1; + attacker thread cool_down(aat_cooldown_time); + flameFX=loadfx("env/fire/fx_fire_zombie_torso"); + PlayFXOnTag(flameFX,self, "j_spinelower"); + flameFX2=loadfx("env/fire/fx_fire_zombie_md"); + PlayFXOnTag(flameFX2,self,"j_spineupper"); + for( i = 0; i < zombies.size; i++ ) + { + if(distance(self.origin, zombies[i].origin) <= 220) + { + zombies[i] thread flames_fx(); + } + } + self dodamage( self.health * 2, (0,0,0), attacker, attacker, "none", "MOD_IMPACT" ); + } + } + if(attacker.has_fireworks) + { + fireworks = aat_activation; + if(fireworks == 1) + { + attacker.aat_actived = 1; + attacker thread cool_down(aat_cooldown_time); + origin = self.origin; + weapon = attacker getcurrentweapon(); + self thread spawn_weapon(origin, weapon, attacker); + self thread fireworks(origin); + self dodamage( self.health * 2, (0,0,0), attacker, attacker, "none", "MOD_IMPACT" ); + } + } + } + } + return [[level.original_damagecallback]]( inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, shitloc, psoffsettime, boneindex ); +} + +cool_down(time) +{ + level endon("end_game"); + self endon("disconnect"); + self.cooldown = 1; + wait time; + self.cooldown = 0; +} + +explosive_bullet() +{ + level endon("end_game"); + self endon("disconnect"); + self.active_explosive_bullet = 1; + for( ;; ) + { + self waittill( "weapon_fired" ); + explosive = randomintrange(1,5); + if(explosive == 1 && self.has_explosive_bullets && !self.cooldown) + { + self.aat_actived = 1; + self thread cool_down(randomintrange(5,11)); + forward = self gettagorigin( "tag_weapon_right" ); + end = self thread vector_scal( anglestoforward( self getplayerangles() ), 1000000 ); + crosshair_entity = bullettrace(self gettagorigin("tag_weapon_right"),self gettagorigin("tag_weapon_right")+anglestoforward(self getplayerangles())*1000000,true,self)["entity"]; + crosshair = bullettrace( forward, end, 0, self )[ "position"]; + magicbullet( self getcurrentweapon(), self gettagorigin( "j_shouldertwist_le" ), crosshair, self ); + self enableInvulnerability(); + if(isdefined(crosshair_entity)) + { + crosshair_entity playsound( "zmb_phdflop_explo" ); + playfx(loadfx("explosions/fx_default_explosion"), crosshair_entity.origin, anglestoforward( ( 0, 45, 55 ) ) ); + radiusdamage( crosshair_entity.origin, 300, 5000, 1000, self ); + } + else + { + crosshair playsound( "zmb_phdflop_explo" ); + playfx(loadfx("explosions/fx_default_explosion"), crosshair, anglestoforward( ( 0, 45, 55 ) ) ); + radiusdamage( crosshair, 300, 5000, 1000, self ); + } + wait .5; + self disableInvulnerability(); + } + wait .1; + } +} + +flames_fx() +{ + level endon("end_game"); + self endon("disconnect"); + for(i = 0; i < 5; i++) + { + flameFX=loadfx("env/fire/fx_fire_zombie_torso"); + PlayFXOnTag(flameFX, self, "j_spineupper"); + if(i < 3) + { + self dodamage(self.health / 2, (0,0,0)); + } + else + { + self dodamage(self.maxhealth * 2, (0,0,0)); + } + wait 1; + } +} + +fireworks(origin) +{ + level endon("end_game"); + self endon("disconnect"); + for(i=0;i<5;i++) + { + up_in_air = origin + (0,0,65); + firework = Spawn( "script_model", origin ); + firework SetModel( "tag_origin" ); + fx = PlayFxOnTag( level._effect[ "richtofen_sparks" ], firework, "tag_origin"); + firework moveto(up_in_air, 1); + wait 1; + firework delete(); + fx delete(); + } +} + +spawn_weapon(origin, weapon, attacker) +{ + level endon("end_game"); + self endon("disconnect"); + attacker.firework_weapon = spawnentity( "script_model", getweaponmodel( weapon ), origin + (0,0,45), (0,0,0) + ( 0, 50, 0 )); + for(i=0;i<100;i++) + { + zombies = get_array_of_closest( attacker.firework_weapon.origin, getaiarray( level.zombie_team ), undefined, undefined, 300 ); + forward = attacker.firework_weapon.origin; + end = zombies[ 0 ] gettagorigin( "j_spineupper" ); + crosshair = bullettrace( forward, end, 0, self )[ "position"]; + attacker.firework_weapon.angles = VectorToAngles( end - attacker.firework_weapon.origin ); + if( distance(zombies[ 0 ].origin, attacker.firework_weapon.origin) <= 300) + { + magicbullet( weapon, attacker.firework_weapon.origin, crosshair, attacker.firework_weapon ); + } + wait .05; + } + attacker.firework_weapon delete(); +} + +spawnentity( class, model, origin, angle ) +{ + level endon("end_game"); + self endon("disconnect"); + entity = spawn( class, origin ); + entity.angles = angle; + entity setmodel( model ); + return entity; +} + +thunderwall( attacker ) +{ + level endon("end_game"); + self endon("disconnect"); + thunder_wall_blast_pos = self.origin; + ai_zombies = get_array_of_closest( thunder_wall_blast_pos, getaiarray( level.zombie_team ), undefined, undefined, 250 ); + if ( !isDefined( ai_zombies ) ) + { + return; + } + flung_zombies = 0; + max_zombies = undefined; + max_zombies = randomIntRange(5,25); + for ( i = 0; i < ai_zombies.size; i++ ) + { + if(isDefined(ai_zombies[i].is_avogadro) && ai_zombies[i].is_avogadro || isDefined(ai_zombies[i].is_brutus) && ai_zombies[i].is_brutus || isDefined(ai_zombies[i].is_mechz) && ai_zombies[i].is_mechz ) + { + //boss zombie check + } + else + { + n_random_x = RandomFloatRange( -3, 3 ); + n_random_y = RandomFloatRange( -3, 3 ); + ai_zombies[i] StartRagdoll(); + ai_zombies[i] LaunchRagdoll( (n_random_x, n_random_y, 150) ); + playfxontag( level._effect[ "jetgun_smoke_cloud"], ai_zombies[i], "J_SpineUpper" ); + ai_zombies[i] DoDamage( ai_zombies[i].health * 2, ai_zombies[i].origin, attacker, attacker, "none", "MOD_IMPACT" ); + flung_zombies++; + if ( flung_zombies >= max_zombies ) + { + break; + } + } + } +} + +Headcutter(attacker) +{ + level endon("end_game"); + self endon("disconnect"); + self endon("death"); + self maps\mp\zombies\_zm_spawner::zombie_head_gib(); + for(;;) + { + wait 1; + damage = 100 * level.round_number; + self dodamage( damage, self.origin, attacker, attacker, "none", "MOD_IMPACT" ); + } +} + +cluster() +{ + level endon("end_game"); + self endon("disconnect"); + if(level.round_number < 10) + { + amount = randomIntRange(1, (level.round_number * 2)); + } + else + { + amount = randomIntRange(7, level.round_number); + } + random_x = RandomFloatRange( -3,3 ); + random_y = RandomFloatRange( -3,3 ); + for(i = 0; i < amount; i++) + { + self MagicGrenadeType( "frag_grenade_zm", self.origin + (random_x, random_y, 10), (random_x, random_y, 0), 2 ); + wait .1; + } +} + +/*aat_hitmarker() +{ + self thread startwaiting(); + self.aat_hitmarker = newdamageindicatorhudelem( self ); + self.aat_hitmarker.horzalign = "center"; + self.aat_hitmarker.vertalign = "middle"; + self.aat_hitmarker.x = -12; + self.aat_hitmarker.y = -12; + self.aat_hitmarker.alpha = 0; + self.aat_hitmarker setshader( "damage_feedback", 24, 48 ); +}*/ + +startwaiting() +{ + level endon("end_game"); + self endon("disconnect"); + while( 1 ) + { + foreach( zombie in getaiarray( level.zombie_team ) ) + { + if( !(IsDefined( zombie.waitingfordamage )) ) + { + //zombie thread aat_hitmarks(); + } + } + wait 0.25; + } +} + +/*aat_hitmarks() +{ + self.waitingfordamage = 1; + while( 1 ) + { + self waittill( "damage", amount, attacker, dir, point, mod ); + if(!isDefined(attacker.aat_actived)) + { + attacker.aat_actived = 0; + } + attacker.aat_hitmarker.alpha = 0; + if( isplayer( attacker ) ) + { + if(attacker.aat_actived) + { + attacker.aat_hitmarker.alpha = 1; + for(i=0;i<20;i++) + { + r = randomfloatrange(0.1, 0.9); + g = randomfloatrange(0.1, 0.9); + b = randomfloatrange(0.1, 0.9); + attacker.aat_hitmarker.color = ( r, g, b ); + if(i > 5) + { + attacker.aat_hitmarker.alpha -= .075; + } + wait .1; + } + attacker.aat_hitmarker.alpha = 0; + attacker.aat_actived = 0; + self.waitingfordamage = 0; + break; + } + } + } +}*/ + +turned( attacker ) +{ + level endon("end_game"); + self endon("disconnect"); + self.is_turned = 1; + attacker.active_turned = 1; + turned_zombie_kills = 0; + max_kills = randomIntRange(15,21); + + self thread set_zombie_run_cycle( "sprint" ); + self.custom_goalradius_override = 1000000; + + //set turned icon for zombie + //todo: icon takes zombies z origin from original ground not zombies z origin + turned_icon = newHudElem(); + turned_icon.x = self.origin[ 0 ]; + turned_icon.y = self.origin[ 1 ]; + turned_icon.z = self.origin[ 2 ] + (0,0,80); + turned_icon.color = (0,1,0); + turned_icon.isshown = 1; + turned_icon.archived = 0; + turned_icon setshader( "hud_status_dead", 4, 4 ); + turned_icon setwaypoint( 1 ); + + enemyoverride = []; + + //cannot damage player + self.team = level.players; + + //allow round change while turned zombie is alive + self.ignore_enemy_count = 1; + + if(getdvar("mapname") == "zm_tomb") + attackanim = "zm_generator_melee"; + else + attackanim = "zm_riotshield_melee"; + + if ( !self.has_legs ) + { + attackanim += "_crawl"; + } + + while(isAlive(self)) + { + turned_icon.x = self.origin[ 0 ]; + turned_icon.y = self.origin[ 1 ]; + turned_icon.z = self.origin[ 2 ] + (0,0,80); + + ai_zombies = get_array_of_closest( self.origin, getaiarray( level.zombie_team ), undefined, undefined, undefined ); + if(isdefined(ai_zombies[1])) + { + enemyoverride[0] = ai_zombies[1].origin; + enemyoverride[1] = ai_zombies[1]; + } + else + { + enemyoverride[0] = ai_zombies[0].origin; + enemyoverride[1] = ai_zombies[0]; + } + self.enemyoverride = enemyoverride; + if(distance(self.origin, ai_zombies[1].origin) < 40 && isalive(ai_zombies[1]) ) + { + angles = VectorToAngles( ai_zombies[1].origin - self.origin ); + self animscripted( self.origin, angles, attackanim ); + ai_zombies[1] dodamage(ai_zombies[1].maxhealth * 2, ai_zombies[1].origin); + turned_zombie_kills++; + + if(turned_zombie_kills > max_kills) + { + self.is_turned = 0; + wait .1; + self dodamage(self.maxhealth * 2, self.origin); + } + + wait 1; + } + else + self stopanimscripted(); + + wait .05; + } + attacker.active_turned = 0; + self.is_turned = 0; + turned_icon destroy(); +} + +turned_zombie() +{ + level endon("end_game"); + self endon("disconnect"); + if(self.turned) + { + //attack zombies + } + else + { + zombie_poi = self get_zombie_point_of_interest( self.origin ); + } + return zombie_poi; +} + +turned_zombie_validation() +{ + level endon("end_game"); + self endon("disconnect"); + if( IS_TRUE( self.barricade_enter ) ) + { + return false; + } + if ( IS_TRUE( self.is_traversing ) ) + { + return false; + } + if ( !IS_TRUE( self.completed_emerging_into_playable_area ) ) + { + return false; + } + if ( IS_TRUE( self.is_leaping ) ) + { + return false; + } + if ( IS_TRUE( self.is_inert ) ) + { + return false; + } + + return true; +} + +is_true(check) +{ + return(IsDefined(check) && check); +} + +save_aat() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("new_aat"); + self endon("disconnect"); + if(isDefined(self.saved_aat_weapons)) + self.saved_aat_weapons = []; + + if(isDefined(self.saved_aat_weapons_name)) + self.saved_aat_weapons_name = []; + + weapons = self getweaponslistprimaries(); + + if(weapons.size > 0 && isDefined(self.weapon_aats[0])) + { + self.saved_aat_weapons_name[0] = self.aat_weapon[0]; + self.saved_aat_weapons[0] = self.weapon_aats[0]; + } + else + { + self.saved_aat_weapons[2] = undefined; + self.saved_aat_weapons_name[2] = undefined; + } + + if(weapons.size > 1 && isDefined(self.weapon_aats[1])) + { + self.saved_aat_weapons_name[1] = self.aat_weapon[1]; + self.saved_aat_weapons[1] = self.weapon_aats[1]; + } + else + { + self.saved_aat_weapons[2] = undefined; + self.saved_aat_weapons_name[2] = undefined; + } + + if(weapons.size > 2 && isDefined(self.weapon_aats[2])) + { + self.saved_aat_weapons_name[2] = self.aat_weapon[2]; + self.saved_aat_weapons[2] = self.weapon_aats[2]; + } + else + { + self.saved_aat_weapons[2] = undefined; + self.saved_aat_weapons_name[2] = undefined; + } +} + +//----whos who recover aat---------------------------------------------------------------------------- + +chugabud_laststand() +{ + level endon("end_game"); + self endon("disconnect"); + self endon( "player_suicide" ); + self endon( "disconnect" ); + self endon( "chugabud_bleedout" ); + self maps\mp\zombies\_zm_laststand::increment_downed_stat(); + self.ignore_insta_kill = 1; + self.health = self.maxhealth; + self maps\mp\zombies\_zm_chugabud::chugabud_save_loadout(); + self maps\mp\zombies\_zm_chugabud::chugabud_fake_death(); + wait 3; + + if ( isdefined( self.insta_killed ) && self.insta_killed || isdefined( self.disable_chugabud_corpse ) ) + create_corpse = 0; + else + create_corpse = 1; + + if ( create_corpse == 1 ) + { + if ( isdefined( level._chugabug_reject_corpse_override_func ) ) + { + reject_corpse = self [[ level._chugabug_reject_corpse_override_func ]]( self.origin ); + + if ( reject_corpse ) + create_corpse = 0; + } + } + + if ( create_corpse == 1 ) + { + self thread activate_chugabud_effects_and_audio(); + corpse = self chugabud_spawn_corpse(); + corpse thread chugabud_corpse_revive_icon( self ); + self.e_chugabud_corpse = corpse; + corpse thread chugabud_corpse_cleanup_on_spectator( self ); + + if ( isdefined( level.whos_who_client_setup ) ) + corpse setclientfield( "clientfield_whos_who_clone_glow_shader", 1 ); + } + + self chugabud_fake_revive(); + wait 0.1; + self.ignore_insta_kill = undefined; + self.disable_chugabud_corpse = undefined; + + if ( create_corpse == 0 ) + { + self notify( "chugabud_effects_cleanup" ); + return; + } + + bleedout_time = getdvarfloat( "player_lastStandBleedoutTime" ); + self thread chugabud_bleed_timeout( bleedout_time, corpse ); + self thread chugabud_handle_multiple_instances( corpse ); + + corpse waittill( "player_revived", e_reviver ); + + if ( isdefined( e_reviver ) && e_reviver == self ) + self notify( "whos_who_self_revive" ); + + self perk_abort_drinking( 0.1 ); + self maps\mp\zombies\_zm_perks::perk_set_max_health_if_jugg( "health_reboot", 1, 0 ); + self setorigin( corpse.origin ); + self setplayerangles( corpse.angles ); + + if ( self player_is_in_laststand() ) + { + self thread chugabud_laststand_cleanup( corpse, "player_revived" ); + self enableweaponcycling(); + self enableoffhandweapons(); + self auto_revive( self, 1 ); + return; + } + + self chugabud_laststand_cleanup( corpse, undefined ); +} + +chugabud_laststand_cleanup( corpse, str_notify ) +{ + level endon("end_game"); + self endon("disconnect"); + if ( isdefined( str_notify ) ) + self waittill( str_notify ); + + self chugabud_give_loadout(); + self chugabud_corpse_cleanup( corpse, 1 ); +} + +chugabud_give_loadout() +{ + level endon("end_game"); + self endon("disconnect"); + self takeallweapons(); + loadout = self.loadout; + primaries = self getweaponslistprimaries(); + + if ( loadout.weapons.size > 1 || primaries.size > 1 ) + { + foreach ( weapon in primaries ) + self takeweapon( weapon ); + } + + for ( i = 0; i < loadout.weapons.size; i++ ) + { + if ( !isdefined( loadout.weapons[i] ) ) + continue; + + if ( loadout.weapons[i]["name"] == "none" ) + continue; + + self maps\mp\zombies\_zm_weapons::weapondata_give( loadout.weapons[i] ); + } + + if ( loadout.current_weapon >= 0 && isdefined( loadout.weapons[loadout.current_weapon]["name"] ) ) + self switchtoweapon( loadout.weapons[loadout.current_weapon]["name"] ); + + self giveweapon( "knife_zm" ); + self maps\mp\zombies\_zm_equipment::equipment_give( self.loadout.equipment ); + loadout restore_weapons_for_chugabud( self ); + self chugabud_restore_claymore(); + self.score = loadout.score; + self.pers["score"] = loadout.score; + perk_array = maps\mp\zombies\_zm_perks::get_perk_array( 1 ); + + for ( i = 0; i < perk_array.size; i++ ) + { + perk = perk_array[i]; + self unsetperk( perk ); + self.num_perks--; + self set_perk_clientfield( perk, 0 ); + } + + if ( isdefined( loadout.perks ) && loadout.perks.size > 0 ) + { + for ( i = 0; i < loadout.perks.size; i++ ) + { + if ( self hasperk( loadout.perks[i] ) ) + continue; + + if ( loadout.perks[i] == "specialty_quickrevive" && flag( "solo_game" ) ) + level.solo_game_free_player_quickrevive = 1; + + if ( loadout.perks[i] == "specialty_finalstand" ) + continue; + + maps\mp\zombies\_zm_perks::give_perk( loadout.perks[i] ); + } + } + + self chugabud_restore_grenades(); + + if ( maps\mp\zombies\_zm_weap_cymbal_monkey::cymbal_monkey_exists() ) + { + if ( loadout.zombie_cymbal_monkey_count ) + { + self maps\mp\zombies\_zm_weap_cymbal_monkey::player_give_cymbal_monkey(); + self setweaponammoclip( "cymbal_monkey_zm", loadout.zombie_cymbal_monkey_count ); + } + } + + if(isDefined(self.saved_aat_weapons[0])) + { + self.weapon_aats[0] = self.saved_aat_weapons[0]; + self.aat_weapon[0] = self.saved_aat_weapons_name[0]; + } + else + { + self.saved_aat_weapons[0] = undefined; + self.saved_aat_weapons_name[0] = undefined; + } + if(isDefined(self.saved_aat_weapons[1])) + { + self.weapon_aats[1] = self.saved_aat_weapons[1]; + self.aat_weapon[1] = self.saved_aat_weapons_name[1]; + } + else + { + self.saved_aat_weapons[1] = undefined; + self.saved_aat_weapons_name[1] = undefined; + } + if(isDefined(self.saved_aat_weapons[2])) + { + self.weapon_aats[2] = self.saved_aat_weapons[2]; + self.aat_weapon[2] = self.saved_aat_weapons_name[2]; + } + else + { + self.saved_aat_weapons[2] = undefined; + self.saved_aat_weapons_name[2] = undefined; + } + self notify("weapon_change"); +} + +//-------tombstone recover aat------------------------------------------------------------------ + +tombstone_spawn() +{ + level endon("end_game"); + self endon("disconnect"); + dc = spawn( "script_model", self.origin + vectorscale( ( 0, 0, 1 ), 40.0 ) ); + dc.angles = self.angles; + dc setmodel( "tag_origin" ); + dc_icon = spawn( "script_model", self.origin + vectorscale( ( 0, 0, 1 ), 40.0 ) ); + dc_icon.angles = self.angles; + dc_icon setmodel( "ch_tombstone1" ); + dc_icon linkto( dc ); + dc.icon = dc_icon; + dc.script_noteworthy = "player_tombstone_model"; + dc.player = self; + self thread tombstone_clear(); + dc thread tombstone_wobble(); + dc thread tombstone_revived( self ); + result = self waittill_any_return( "player_revived", "spawned_player", "disconnect" ); + + if ( result == "player_revived" || result == "disconnect" ) + { + dc notify( "tombstone_timedout" ); + dc_icon unlink(); + dc_icon delete(); + dc delete(); + return; + } + + dc thread tombstone_timeout(); + dc thread tombstone_grab(); +} + +tombstone_grab() +{ + level endon("end_game"); + self endon("disconnect"); + self endon( "tombstone_timedout" ); + wait 1; + + while ( isdefined( self ) ) + { + players = get_players(); + + for ( i = 0; i < players.size; i++ ) + { + if ( players[i].is_zombie ) + continue; + + if ( isdefined( self.player ) && players[i] == self.player ) + { + tombstone_machine_triggers = getentarray( "specialty_scavenger", "script_noteworthy" ); + istombstonepowered = 0; + + foreach ( trigger in tombstone_machine_triggers ) + { + if ( isdefined( trigger.power_on ) && trigger.power_on || isdefined( trigger.turbine_power_on ) && trigger.turbine_power_on ) + istombstonepowered = 1; + } + + if ( istombstonepowered ) + { + dist = distance( players[i].origin, self.origin ); + + if ( dist < 64 ) + { + playfx( level._effect["powerup_grabbed"], self.origin ); + playfx( level._effect["powerup_grabbed_wave"], self.origin ); + players[i] tombstone_give(); + wait 0.1; + playsoundatposition( "zmb_tombstone_grab", self.origin ); + self stoploopsound(); + self.icon unlink(); + self.icon delete(); + self delete(); + self notify( "tombstone_grabbed" ); + players[i] clientnotify( "dc0" ); + players[i] notify( "dance_on_my_grave" ); + } + } + } + } + + wait_network_frame(); + } +} + +tombstone_give() +{ + level endon("end_game"); + self endon("disconnect"); + dc = level.tombstones[self.tombstone_index]; + + if ( !flag( "solo_game" ) ) + { + primaries = self getweaponslistprimaries(); + + if ( dc.weapon.size > 1 || primaries.size > 1 ) + { + foreach ( weapon in primaries ) + self takeweapon( weapon ); + } + + for ( i = 0; i < dc.weapon.size; i++ ) + { + if ( !isdefined( dc.weapon[i] ) ) + continue; + + if ( dc.weapon[i] == "none" ) + continue; + + weapon = dc.weapon[i]; + stock = dc.stockcount[i]; + + if ( !self hasweapon( weapon ) ) + { + self giveweapon( weapon, 0, self maps\mp\zombies\_zm_weapons::get_pack_a_punch_weapon_options( weapon ) ); + self setweaponammoclip( weapon, weaponclipsize( weapon ) ); + self setweaponammostock( weapon, stock ); + + if ( i == dc.current_weapon ) + self switchtoweapon( weapon ); + } + } + } + + if ( isdefined( dc.hasriotshield ) && dc.hasriotshield ) + { + self maps\mp\zombies\_zm_equipment::equipment_give( "riotshield_zm" ); + + if ( isdefined( self.player_shield_reset_health ) ) + self [[ self.player_shield_reset_health ]](); + } + + dc restore_weapons_for_tombstone( self ); + + if ( isdefined( dc.hasclaymore ) && dc.hasclaymore && !self hasweapon( "claymore_zm" ) ) + { + self giveweapon( "claymore_zm" ); + self set_player_placeable_mine( "claymore_zm" ); + self setactionslot( 4, "weapon", "claymore_zm" ); + self setweaponammoclip( "claymore_zm", dc.claymoreclip ); + } + + if ( isdefined( dc.hasemp ) && dc.hasemp ) + { + self giveweapon( "emp_grenade_zm" ); + self setweaponammoclip( "emp_grenade_zm", dc.empclip ); + } + + if ( isdefined( dc.perk ) && dc.perk.size > 0 ) + { + for ( i = 0; i < dc.perk.size; i++ ) + { + if ( self hasperk( dc.perk[i] ) ) + continue; + + if ( dc.perk[i] == "specialty_quickrevive" && flag( "solo_game" ) ) + continue; + + maps\mp\zombies\_zm_perks::give_perk( dc.perk[i] ); + } + } + + if ( dc.grenade > 0 && !flag( "solo_game" ) ) + { + curgrenadecount = 0; + + if ( self hasweapon( self get_player_lethal_grenade() ) ) + self getweaponammoclip( self get_player_lethal_grenade() ); + else + self giveweapon( self get_player_lethal_grenade() ); + + self setweaponammoclip( self get_player_lethal_grenade(), dc.grenade + curgrenadecount ); + } + + if ( maps\mp\zombies\_zm_weap_cymbal_monkey::cymbal_monkey_exists() && !flag( "solo_game" ) ) + { + if ( dc.zombie_cymbal_monkey_count ) + { + self maps\mp\zombies\_zm_weap_cymbal_monkey::player_give_cymbal_monkey(); + self setweaponammoclip( "cymbal_monkey_zm", dc.zombie_cymbal_monkey_count ); + } + } + + if(isDefined(self.saved_aat_weapons[0])) + { + self.weapon_aats[0] = self.saved_aat_weapons[0]; + self.aat_weapon[0] = self.saved_aat_weapons_name[0]; + } + else + { + self.saved_aat_weapons[0] = undefined; + self.saved_aat_weapons_name[0] = undefined; + } + if(isDefined(self.saved_aat_weapons[1])) + { + self.weapon_aats[1] = self.saved_aat_weapons[1]; + self.aat_weapon[1] = self.saved_aat_weapons_name[1]; + } + else + { + self.saved_aat_weapons[1] = undefined; + self.saved_aat_weapons_name[1] = undefined; + } + if(isDefined(self.saved_aat_weapons[2])) + { + self.weapon_aats[2] = self.saved_aat_weapons[2]; + self.aat_weapon[2] = self.saved_aat_weapons_name[2]; + } + else + { + self.saved_aat_weapons[2] = undefined; + self.saved_aat_weapons_name[2] = undefined; + } + self notify("weapon_change"); +} + +//--------- + + +solo_tombstone_removal() +{ + notify( "tombstone_on" ); +} + +turn_tombstone_on() +{ + level endon("end_game"); + self endon("disconnect"); + level endon("end_game"); + while ( 1 ) + { + machine = getentarray( "vending_tombstone", "targetname" ); + machine_triggers = getentarray( "vending_tombstone", "target" ); + i = 0; + while ( i < machine.size ) + { + machine[ i ] setmodel( level.machine_assets[ "tombstone" ].off_model ); + i++; + } + level thread do_initial_power_off_callback( machine, "tombstone" ); + array_thread( machine_triggers, ::set_power_on, 0 ); + level waittill( "tombstone_on" ); + i = 0; + while ( i < machine.size ) + { + machine[ i ] setmodel( level.machine_assets[ "tombstone" ].on_model ); + machine[ i ] vibrate( vectorScale( ( 0, -1, 0 ), 100 ), 0,3, 0,4, 3 ); + machine[ i ] playsound( "zmb_perks_power_on" ); + machine[ i ] thread perk_fx( "tombstone_light" ); + machine[ i ] thread play_loop_on_machine(); + i++; + } + level notify( "specialty_scavenger_power_on" ); + array_thread( machine_triggers, ::set_power_on, 1 ); + if ( isDefined( level.machine_assets[ "tombstone" ].power_on_callback ) ) + { + array_thread( machine, level.machine_assets[ "tombstone" ].power_on_callback ); + } + level waittill( "tombstone_off" ); + if ( isDefined( level.machine_assets[ "tombstone" ].power_off_callback ) ) + { + array_thread( machine, level.machine_assets[ "tombstone" ].power_off_callback ); + } + array_thread( machine, ::turn_perk_off ); + players = get_players(); + _a1718 = players; + _k1718 = getFirstArrayKey( _a1718 ); + while ( isDefined( _k1718 ) ) + { + player = _a1718[ _k1718 ]; + player.hasperkspecialtytombstone = undefined; + _k1718 = getNextArrayKey( _a1718, _k1718 ); + } + } +} + +perk_machine_spawn_init() +{ + level endon("end_game"); + self endon("disconnect"); + level endon("end_game"); + 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 + "_perks_" ) + location; + pos = []; + if ( isDefined( level.override_perk_targetname ) ) + { + structs = getstructarray( level.override_perk_targetname, "targetname" ); + } + else + { + structs = getstructarray( "zm_perk_machine", "targetname" ); + } + _a3578 = structs; + _k3578 = getFirstArrayKey( _a3578 ); + while ( isDefined( _k3578 ) ) + { + struct = _a3578[ _k3578 ]; + if ( isDefined( struct.script_string ) ) + { + tokens = strtok( struct.script_string, " " ); + _a3583 = tokens; + _k3583 = getFirstArrayKey( _a3583 ); + while ( isDefined( _k3583 ) ) + { + token = _a3583[ _k3583 ]; + if ( token == match_string ) + { + pos[ pos.size ] = struct; + } + _k3583 = getNextArrayKey( _a3583, _k3583 ); + } + } + else pos[ pos.size ] = struct; + _k3578 = getNextArrayKey( _a3578, _k3578 ); + } + if ( !isDefined( pos ) || pos.size == 0 ) + { + return; + } + precachemodel( "zm_collision_perks1" ); + i = 0; + while ( i < pos.size ) + { + 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.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 ) + { + bump_trigger = undefined; + } + else + { + 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" ) + { + 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.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 ) ) + { + use_trigger.blocker_model = pos[ i ].blocker_model; + } + if ( isDefined( pos[ i ].script_int ) ) + { + perk_machine.script_int = pos[ i ].script_int; + } + if ( isDefined( pos[ i ].turn_on_notify ) ) + { + perk_machine.turn_on_notify = pos[ i ].turn_on_notify; + } + if ( perk == "specialty_scavenger" || perk == "specialty_scavenger_upgrade" ) + { + use_trigger.script_sound = "mus_perks_tombstone_jingle"; + use_trigger.script_string = "tombstone_perk"; + use_trigger.script_label = "mus_perks_tombstone_sting"; + use_trigger.target = "vending_tombstone"; + perk_machine.script_string = "tombstone_perk"; + perk_machine.targetname = "vending_tombstone"; + if ( isDefined( bump_trigger ) ) + { + bump_trigger.script_string = "tombstone_perk"; + } + } + 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 ); + } + } + i++; + } +} + +isTown() +{ + level endon("end_game"); + self endon("disconnect"); + if (isDefined(level.zombiemode_using_tombstone_perk) && level.zombiemode_using_tombstone_perk) + { + level thread perk_machine_spawn_init(); + thread solo_tombstone_removal(); + thread turn_tombstone_on(); + } +} diff --git a/t6/uncompiled mods/Zompiler.exe b/t6/uncompiled mods/Zompiler.exe new file mode 100644 index 0000000000000000000000000000000000000000..7f5721586770d092c9078e66b44a4ca6230125f6 GIT binary patch literal 49664 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 literal 0 HcmV?d00001 diff --git a/t6/uncompiled mods/_zm_weap_slowgun.gsc b/t6/uncompiled mods/_zm_weap_slowgun.gsc new file mode 100644 index 0000000..8a8230e --- /dev/null +++ b/t6/uncompiled mods/_zm_weap_slowgun.gsc @@ -0,0 +1,814 @@ +// T6 GSC SOURCE +// Decompiled by https://github.com/xensik/gsc-tool +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_spawner; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_audio; + +init() +{ +// if ( !maps\mp\zombies\_zm_weapons::is_weapon_included( "slowgun_zm" ) ) + // return; + + registerclientfield( "actor", "slowgun_fx", 12000, 3, "int" ); + registerclientfield( "actor", "anim_rate", 7000, 5, "float" ); + registerclientfield( "allplayers", "anim_rate", 7000, 5, "float" ); + registerclientfield( "toplayer", "sndParalyzerLoop", 12000, 1, "int" ); + registerclientfield( "toplayer", "slowgun_fx", 12000, 1, "int" ); + level.sliquifier_distance_checks = 0; + maps\mp\zombies\_zm_spawner::add_cusom_zombie_spawn_logic( ::slowgun_on_zombie_spawned ); + maps\mp\zombies\_zm_spawner::register_zombie_damage_callback( ::slowgun_zombie_damage_response ); + maps\mp\zombies\_zm_spawner::register_zombie_death_animscript_callback( ::slowgun_zombie_death_response ); + level._effect["zombie_slowgun_explosion"] = loadfx( "weapon/paralyzer/fx_paralyzer_body_disintegrate" ); + level._effect["zombie_slowgun_explosion_ug"] = loadfx( "weapon/paralyzer/fx_paralyzer_body_disintegrate_ug" ); + level._effect["zombie_slowgun_sizzle"] = loadfx( "weapon/paralyzer/fx_paralyzer_hit_dmg" ); + level._effect["zombie_slowgun_sizzle_ug"] = loadfx( "weapon/paralyzer/fx_paralyzer_hit_dmg_ug" ); + level._effect["player_slowgun_sizzle"] = loadfx( "weapon/paralyzer/fx_paralyzer_hit_noharm" ); + level._effect["player_slowgun_sizzle_ug"] = loadfx( "weapon/paralyzer/fx_paralyzer_hit_noharm" ); + level._effect["player_slowgun_sizzle_1st"] = loadfx( "weapon/paralyzer/fx_paralyzer_hit_noharm_view" ); + onplayerconnect_callback( ::slowgun_player_connect ); + level.slowgun_damage = 40; + level.slowgun_damage_ug = 60; + level.slowgun_damage_mod = "MOD_PROJECTILE_SPLASH"; + precacherumble( "damage_heavy" ); +/# + level thread show_anim_rates(); +#/ +} + +slowgun_player_connect() +{ + self thread watch_reset_anim_rate(); + self thread watch_slowgun_fired(); + self thread sndwatchforweapswitch(); +} + +sndwatchforweapswitch() +{ + self endon( "disconnect" ); + + while ( true ) + { + self waittill( "weapon_change", weapon ); + + if ( weapon == "slowgun_zm" || weapon == "slowgun_upgraded_zm" ) + { + self setclientfieldtoplayer( "sndParalyzerLoop", 1 ); + + self waittill( "weapon_change" ); + + self setclientfieldtoplayer( "sndParalyzerLoop", 0 ); + } + } +} + +watch_reset_anim_rate() +{ + self set_anim_rate( 1.0 ); + self setclientfieldtoplayer( "slowgun_fx", 0 ); + + while ( true ) + { + self waittill_any( "spawned", "entering_last_stand", "player_revived", "player_suicide", "respawned" ); + self setclientfieldtoplayer( "slowgun_fx", 0 ); + self set_anim_rate( 1.0 ); + } +} + +watch_slowgun_fired() +{ + self endon( "disconnect" ); + + self waittill( "spawned_player" ); + + for (;;) + { + self waittill( "weapon_fired", weapon ); + + if ( weapon == "slowgun_zm" ) + { + self slowgun_fired( 0 ); + continue; + } + + if ( weapon == "slowgun_upgraded_zm" ) + self slowgun_fired( 1 ); + } +} + +slowgun_fired( upgraded ) +{ + origin = self getweaponmuzzlepoint(); + forward = self getweaponforwarddir(); +/# + show_muzzle( origin, forward ); +#/ + targets = self get_targets_in_range( upgraded, origin, forward ); + + if ( targets.size ) + { + foreach ( target in targets ) + { + if ( isplayer( target ) ) + { + if ( is_player_valid( target ) && self != target ) + target thread player_paralyzed( self, upgraded ); + + continue; + } + + if ( isdefined( target.paralyzer_hit_callback ) ) + { + target thread [[ target.paralyzer_hit_callback ]]( self, upgraded ); + continue; + } + + target thread zombie_paralyzed( self, upgraded ); + } + } + + dot = vectordot( forward, ( 0, 0, -1 ) ); + + if ( dot > 0.8 ) + self thread player_paralyzed( self, upgraded ); +} + +slowgun_get_enemies_in_range( upgraded, position, forward, possible_targets ) +{ + inner_range = 12; + outer_range = 660; + cylinder_radius = 48; + level.slowgun_enemies = []; + view_pos = position; + + if ( !isdefined( possible_targets ) ) + return level.slowgun_enemies; + + slowgun_inner_range_squared = inner_range * inner_range; + slowgun_outer_range_squared = outer_range * outer_range; + cylinder_radius_squared = cylinder_radius * cylinder_radius; + forward_view_angles = forward; + end_pos = view_pos + vectorscale( forward_view_angles, outer_range ); +/# + if ( 2 == getdvarint( _hash_61A711C2 ) ) + { + near_circle_pos = view_pos + vectorscale( forward_view_angles, 2 ); + circle( near_circle_pos, cylinder_radius, ( 1, 0, 0 ), 0, 0, 100 ); + line( near_circle_pos, end_pos, ( 0, 0, 1 ), 1, 0, 100 ); + circle( end_pos, cylinder_radius, ( 1, 0, 0 ), 0, 0, 100 ); + } +#/ + for ( i = 0; i < possible_targets.size; i++ ) + { + if ( !isdefined( possible_targets[i] ) || !isalive( possible_targets[i] ) ) + continue; + + test_origin = possible_targets[i] getcentroid(); + test_range_squared = distancesquared( view_pos, test_origin ); + + if ( test_range_squared > slowgun_outer_range_squared ) + { + possible_targets[i] slowgun_debug_print( "range", ( 1, 0, 0 ) ); + continue; + } + + normal = vectornormalize( test_origin - view_pos ); + dot = vectordot( forward_view_angles, normal ); + + if ( 0 > dot ) + { + possible_targets[i] slowgun_debug_print( "dot", ( 1, 0, 0 ) ); + continue; + } + + radial_origin = pointonsegmentnearesttopoint( view_pos, end_pos, test_origin ); + + if ( distancesquared( test_origin, radial_origin ) > cylinder_radius_squared ) + { + possible_targets[i] slowgun_debug_print( "cylinder", ( 1, 0, 0 ) ); + continue; + } + + if ( 0 == possible_targets[i] damageconetrace( view_pos, self ) ) + { + possible_targets[i] slowgun_debug_print( "cone", ( 1, 0, 0 ) ); + continue; + } + + level.slowgun_enemies[level.slowgun_enemies.size] = possible_targets[i]; + } + + return level.slowgun_enemies; +} + +get_targets_in_range( upgraded, position, forward ) +{ + if ( !isdefined( self.slowgun_targets ) || gettime() - self.slowgun_target_time > 150 ) + { + targets = []; + possible_targets = getaispeciesarray( level.zombie_team, "all" ); + possible_targets = arraycombine( possible_targets, get_players(), 1, 0 ); + + if ( isdefined( level.possible_slowgun_targets ) && level.possible_slowgun_targets.size > 0 ) + possible_targets = arraycombine( possible_targets, level.possible_slowgun_targets, 1, 0 ); + + targets = slowgun_get_enemies_in_range( 0, position, forward, possible_targets ); + self.slowgun_targets = targets; + self.slowgun_target_time = gettime(); + } + + return self.slowgun_targets; +} + +slowgun_on_zombie_spawned() +{ + self set_anim_rate( 1.0 ); + self.paralyzer_hit_callback = ::zombie_paralyzed; + self.paralyzer_damaged_multiplier = 1; + self.paralyzer_score_time_ms = gettime(); + self.paralyzer_slowtime = 0; + self setclientfield( "slowgun_fx", 0 ); +} + +can_be_paralyzed( zombie ) +{ + if ( is_true( zombie.is_ghost ) ) + return false; + + if ( is_true( zombie.guts_explosion ) ) + return false; + + if ( isdefined( zombie ) && zombie.health > 0 ) + return true; + + return false; +} + +set_anim_rate( rate ) +{ + if ( isdefined( self ) ) + { + self.slowgun_anim_rate = rate; + + if ( !is_true( level.ignore_slowgun_anim_rates ) && !is_true( self.ignore_slowgun_anim_rates ) ) + { + self setclientfield( "anim_rate", rate ); + qrate = self getclientfield( "anim_rate" ); + self setentityanimrate( qrate ); + + if ( isdefined( self.set_anim_rate ) ) + self [[ self.set_anim_rate ]]( rate ); + } + } +} + +reset_anim() +{ + wait_network_frame(); + + if ( !isdefined( self ) ) + return; + + if ( is_true( self.is_traversing ) ) + { + animstate = self getanimstatefromasd(); + + if ( !is_true( self.no_restart ) ) + { + self.no_restart = 1; + animstate += "_no_restart"; + } + + substate = self getanimsubstatefromasd(); + self setanimstatefromasd( animstate, substate ); + } + else + { + self.needs_run_update = 1; + self notify( "needs_run_update" ); + } +} + +zombie_change_rate( time, newrate ) +{ + self set_anim_rate( newrate ); + + if ( isdefined( self.reset_anim ) ) + self thread [[ self.reset_anim ]](); + else + self thread reset_anim(); + + if ( time > 0 ) + wait( time ); +} + +zombie_slow_for_time( time, multiplier = 2.0 ) +{ + paralyzer_time_per_frame = 0.1 * ( 1.0 + multiplier ); + + if ( self.paralyzer_slowtime <= time ) + self.paralyzer_slowtime = time + paralyzer_time_per_frame; + else + self.paralyzer_slowtime += paralyzer_time_per_frame; + + if ( !isdefined( self.slowgun_anim_rate ) ) + self.slowgun_anim_rate = 1; + + if ( !isdefined( self.slowgun_desired_anim_rate ) ) + self.slowgun_desired_anim_rate = 1; + + if ( self.slowgun_desired_anim_rate > 0.3 ) + self.slowgun_desired_anim_rate -= 0.2; + else + self.slowgun_desired_anim_rate = 0.05; + + if ( is_true( self.slowing ) ) + return; + + self.slowing = 1; + self.preserve_asd_substates = 1; + self playloopsound( "wpn_paralyzer_slowed_loop", 0.1 ); + + while ( self.paralyzer_slowtime > 0 && isalive( self ) ) + { + if ( self.paralyzer_slowtime < 0.1 ) + self.slowgun_desired_anim_rate = 1; + else if ( self.paralyzer_slowtime < 2 * 0.1 ) + self.slowgun_desired_anim_rate = max( self.slowgun_desired_anim_rate, 0.8 ); + else if ( self.paralyzer_slowtime < 3 * 0.1 ) + self.slowgun_desired_anim_rate = max( self.slowgun_desired_anim_rate, 0.6 ); + else if ( self.paralyzer_slowtime < 4 * 0.1 ) + self.slowgun_desired_anim_rate = max( self.slowgun_desired_anim_rate, 0.4 ); + else if ( self.paralyzer_slowtime < 5 * 0.1 ) + self.slowgun_desired_anim_rate = max( self.slowgun_desired_anim_rate, 0.2 ); + + if ( self.slowgun_desired_anim_rate == self.slowgun_anim_rate ) + { + self.paralyzer_slowtime -= 0.1; + wait 0.1; + } + else if ( self.slowgun_desired_anim_rate >= self.slowgun_anim_rate ) + { + new_rate = self.slowgun_desired_anim_rate; + + if ( self.slowgun_desired_anim_rate - self.slowgun_anim_rate > 0.2 ) + new_rate = self.slowgun_anim_rate + 0.2; + + self.paralyzer_slowtime -= 0.1; + zombie_change_rate( 0.1, new_rate ); + self.paralyzer_damaged_multiplier = 1; + } + else if ( self.slowgun_desired_anim_rate <= self.slowgun_anim_rate ) + { + new_rate = self.slowgun_desired_anim_rate; + + if ( self.slowgun_anim_rate - self.slowgun_desired_anim_rate > 0.2 ) + new_rate = self.slowgun_anim_rate - 0.2; + + self.paralyzer_slowtime -= 0.25; + zombie_change_rate( 0.25, new_rate ); + } + } + + if ( self.slowgun_anim_rate < 1 ) + self zombie_change_rate( 0, 1 ); + + self.preserve_asd_substates = 0; + self.slowing = 0; + self.paralyzer_damaged_multiplier = 1; + self setclientfield( "slowgun_fx", 0 ); + self stoploopsound( 0.1 ); +} + +zombie_paralyzed( player, upgraded ) +{ + if ( !can_be_paralyzed( self ) ) + return; + + insta = player maps\mp\zombies\_zm_powerups::is_insta_kill_active(); + + if ( upgraded ) + self setclientfield( "slowgun_fx", 5 ); + else + self setclientfield( "slowgun_fx", 1 ); + + if ( self.slowgun_anim_rate <= 0.1 || insta && self.slowgun_anim_rate <= 0.5 ) + { + if ( upgraded ) + damage = level.slowgun_damage_ug; + else + damage = level.slowgun_damage; + + damage *= randomfloatrange( 0.667, 1.5 ); + damage *= self.paralyzer_damaged_multiplier; + + if ( !isdefined( self.paralyzer_damage ) ) + self.paralyzer_damage = 0; + + if ( self.paralyzer_damage > 47073 ) + damage *= 47073 / self.paralyzer_damage; + + self.paralyzer_damage += damage; + + if ( insta ) + damage = self.health + 666; + + if ( isalive( self ) ) + self dodamage( damage, player.origin, player, player, "none", level.slowgun_damage_mod, 0, "slowgun_zm" ); + + self.paralyzer_damaged_multiplier *= 1.15; + self.paralyzer_damaged_multiplier = min( self.paralyzer_damaged_multiplier, 50 ); + } + else + self.paralyzer_damaged_multiplier = 1; + + self zombie_slow_for_time( 0.2 ); +} + +get_extra_damage( amount, mod, slow ) +{ + mult = 1.0 - slow; + return amount * slow; +} + +slowgun_zombie_damage_response( mod, hit_location, hit_origin, player, amount ) +{ + if ( !self is_slowgun_damage( self.damagemod, self.damageweapon ) ) + { + if ( isdefined( self.slowgun_anim_rate ) && self.slowgun_anim_rate < 1.0 && mod != level.slowgun_damage_mod ) + { + extra_damage = get_extra_damage( amount, mod, self.slowgun_anim_rate ); + + if ( extra_damage > 0 ) + { + if ( isalive( self ) ) + self dodamage( extra_damage, hit_origin, player, player, hit_location, level.slowgun_damage_mod, 0, "slowgun_zm" ); + + if ( !isalive( self ) ) + return true; + } + } + + return false; + } + + if ( gettime() - self.paralyzer_score_time_ms >= 500 ) + { + self.paralyzer_score_time_ms = gettime(); + + if ( self.paralyzer_damage < 47073 ) + player maps\mp\zombies\_zm_score::player_add_points( "damage", mod, hit_location, self.isdog, level.zombie_team ); + } + + if ( player maps\mp\zombies\_zm_powerups::is_insta_kill_active() ) + amount = self.health + 666; + + if ( isalive( self ) ) + self dodamage( amount, hit_origin, player, player, hit_location, mod, 0, "slowgun_zm" ); + + return true; +} + +explosion_choke() +{ + if ( !isdefined( level.slowgun_explosion_time ) ) + level.slowgun_explosion_time = 0; + + if ( level.slowgun_explosion_time != gettime() ) + { + level.slowgun_explosion_count = 0; + level.slowgun_explosion_time = gettime(); + } + + while ( level.slowgun_explosion_count > 4 ) + { + wait 0.05; + + if ( level.slowgun_explosion_time != gettime() ) + { + level.slowgun_explosion_count = 0; + level.slowgun_explosion_time = gettime(); + } + } + + level.slowgun_explosion_count++; +} + +explode_into_dust( player, upgraded ) +{ + if ( isdefined( self.marked_for_insta_upgraded_death ) ) + return; + + explosion_choke(); + + if ( upgraded ) + self setclientfield( "slowgun_fx", 6 ); + else + self setclientfield( "slowgun_fx", 2 ); + + self.guts_explosion = 1; + self ghost(); +} + +slowgun_zombie_death_response() +{ + if ( !self is_slowgun_damage( self.damagemod, self.damageweapon ) ) + return false; + + level maps\mp\zombies\_zm_spawner::zombie_death_points( self.origin, self.damagemod, self.damagelocation, self.attacker, self ); + self thread explode_into_dust( self.attacker, self.damageweapon == "slowgun_upgraded_zm" ); + return true; +} + +is_slowgun_damage( mod, weapon ) +{ + return isdefined( weapon ) && ( weapon == "slowgun_zm" || weapon == "slowgun_upgraded_zm" ); +} + +setjumpenabled( onoff ) +{ + if ( onoff ) + { + if ( isdefined( self.jump_was_enabled ) ) + { + self allowjump( self.jump_was_enabled ); + self.jump_was_enabled = undefined; + } + else + self allowjump( 1 ); + } + else if ( !isdefined( self.jump_was_enabled ) ) + self.jump_was_enabled = self allowjump( 0 ); +} + +get_ahead_ent() +{ + velocity = self getvelocity(); + + if ( lengthsquared( velocity ) < 225 ) + return undefined; + + start = self geteyeapprox(); + end = start + velocity * 0.25; + mins = ( 0, 0, 0 ); + maxs = ( 0, 0, 0 ); + trace = physicstrace( start, end, vectorscale( ( -1, -1, 0 ), 15.0 ), vectorscale( ( 1, 1, 0 ), 15.0 ), self, level.physicstracemaskclip ); + + if ( isdefined( trace["entity"] ) ) + return trace["entity"]; + else if ( trace["fraction"] < 0.99 || trace["surfacetype"] != "none" ) + return level; + + return undefined; +} + +bump() +{ + self playrumbleonentity( "damage_heavy" ); + earthquake( 0.5, 0.15, self.origin, 1000, self ); +} + +player_fly_rumble() +{ + self endon( "player_slow_stop_flying" ); + self endon( "disconnect" ); + self endon( "platform_collapse" ); + self.slowgun_flying = 1; + last_ground = self getgroundent(); + last_ahead = undefined; + + while ( true ) + { + ground = self getgroundent(); + + if ( isdefined( ground ) != isdefined( last_ground ) || ground != last_ground ) + { + if ( isdefined( ground ) ) + self bump(); + } + + if ( isdefined( ground ) && !self.slowgun_flying ) + { + self thread dont_tread_on_z(); + return; + } + + last_ground = ground; + + if ( isdefined( ground ) ) + last_ahead = undefined; + else + { + ahead = self get_ahead_ent(); + + if ( isdefined( ahead ) ) + { + if ( isdefined( ahead ) != isdefined( last_ahead ) || ahead != last_ahead ) + { + self playsoundtoplayer( "zmb_invis_barrier_hit", self ); + chance = get_response_chance( "invisible_collision" ); + + if ( chance > randomintrange( 1, 100 ) ) + self thread maps\mp\zombies\_zm_audio::create_and_play_dialog( "general", "invisible_collision" ); + + self bump(); + } + } + + last_ahead = ahead; + } + + wait 0.15; + } +} + +dont_tread_on_z() +{ + if ( !isdefined( level.ghost_head_damage ) ) + level.ghost_head_damage = 30; + + ground = self getgroundent(); + + if ( isdefined( ground ) && isdefined( ground.team ) && ground.team == level.zombie_team ) + { + first_ground = ground; + + while ( !isdefined( ground ) || isdefined( ground.team ) && ground.team == level.zombie_team ) + { + if ( is_true( self.slowgun_flying ) ) + return; + + if ( isdefined( ground ) ) + { + self dodamage( level.ghost_head_damage, ground.origin, ground ); + + if ( is_true( ground.is_ghost ) ) + { + level.ghost_head_damage *= 1.5; + + if ( self.score > 4000 ) + self.score -= 4000; + else + self.score = 0; + } + } + else + self dodamage( level.ghost_head_damage, first_ground.origin, first_ground ); + + wait 0.25; + ground = self getgroundent(); + } + } +} + +player_slow_for_time( time ) +{ + self notify( "player_slow_for_time" ); + self endon( "player_slow_for_time" ); + self endon( "disconnect" ); + + if ( !is_true( self.slowgun_flying ) ) + self thread player_fly_rumble(); + + self setclientfieldtoplayer( "slowgun_fx", 1 ); + self set_anim_rate( 0.05 ); + wait( time ); + self set_anim_rate( 1.0 ); + self setclientfieldtoplayer( "slowgun_fx", 0 ); + self.slowgun_flying = 0; +} + +player_paralyzed( byplayer, upgraded ) +{ + self notify( "player_paralyzed" ); + self endon( "player_paralyzed" ); + self endon( "death" ); + + if ( isdefined( level.slowgun_allow_player_paralyze ) ) + { + if ( !self [[ level.slowgun_allow_player_paralyze ]]() ) + return; + } + + if ( self != byplayer ) + { + sizzle = "player_slowgun_sizzle"; + + if ( upgraded ) + sizzle = "player_slowgun_sizzle_ug"; + + if ( isdefined( level._effect[sizzle] ) ) + playfxontag( level._effect[sizzle], self, "J_SpineLower" ); + } + + self thread player_slow_for_time( 0.25 ); +} + +slowgun_debug_print( msg, color ) +{ +/# + if ( getdvarint( _hash_61A711C2 ) != 2 ) + return; + + if ( !isdefined( color ) ) + color = ( 1, 1, 1 ); + + print3d( self.origin + vectorscale( ( 0, 0, 1 ), 60.0 ), msg, color, 1, 1, 40 ); +#/ +} + +show_anim_rate( pos, dsquared ) +{ +/# + if ( distancesquared( pos, self.origin ) > dsquared ) + return; + + rate = self getentityanimrate(); + color = ( 1 - rate, rate, 0 ); + text = "" + int( rate * 100 ) + " S"; + print3d( self.origin + ( 0, 0, 0 ), text, color, 1, 0.5, 1 ); +#/ +} + +show_slow_time( pos, dsquared, insta ) +{ +/# + if ( distancesquared( pos, self.origin ) > dsquared ) + return; + + rate = self.paralyzer_slowtime; + + if ( !isdefined( rate ) || rate < 0.05 ) + return; + + if ( self getentityanimrate() <= 0.1 || insta && self getentityanimrate() <= 0.5 ) + color = ( 1, 0, 0 ); + else + color = ( 0, 1, 0 ); + + text = "" + rate + ""; + print3d( self.origin + vectorscale( ( 0, 0, 1 ), 50.0 ), text, color, 1, 0.5, 1 ); +#/ +} + +show_anim_rates() +{ +/# + while ( true ) + { + if ( getdvarint( _hash_61A711C2 ) == 1 ) + { + lp = get_players()[0]; + insta = lp maps\mp\zombies\_zm_powerups::is_insta_kill_active(); + zombies = getaispeciesarray( "all", "all" ); + + if ( isdefined( zombies ) ) + { + foreach ( zombie in zombies ) + zombie show_slow_time( lp.origin, 360000, insta ); + } + + if ( isdefined( level.sloth ) ) + level.sloth show_slow_time( lp.origin, 360000, 0 ); + } + + if ( getdvarint( _hash_61A711C2 ) == 3 ) + { + lp = get_players()[0]; + + foreach ( player in get_players() ) + player show_anim_rate( lp.origin, 360000 ); + + zombies = getaispeciesarray( "all", "all" ); + + if ( isdefined( zombies ) ) + { + foreach ( zombie in zombies ) + zombie show_anim_rate( lp.origin, 360000 ); + } + } + + wait 0.05; + } +#/ +} + +show_muzzle( origin, forward ) +{ +/# + if ( getdvarint( _hash_61A711C2 ) == 4 ) + { + seconds = 0.25; + grey = vectorscale( ( 1, 1, 1 ), 0.3 ); + green = ( 0, 1, 0 ); + start = origin; + end = origin + 12 * forward; + frames = int( 20 * seconds ); + line( start, end, green, 1, 0, frames ); + } +#/ +} diff --git a/t6/uncompiled mods/_zm_weapon_locker-compiled.gsc b/t6/uncompiled mods/_zm_weapon_locker-compiled.gsc new file mode 100644 index 0000000000000000000000000000000000000000..2a7b44fe8deb92f93bbac391f8706c3120ea65f2 GIT binary patch literal 9558 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 maxweapons) + { + if ( !triggerweaponslockerisvalidweapon( weaponname ) ) + { + self sethintstring( &"ZOMBIE_WEAPON_LOCKER_DENY" ); + return; + } + } + self sethintstring( &"ZOMBIE_WEAPON_LOCKER_GRAB" ); + } +} + +triggerweaponslockerthinkupdateprompt( player ) +{ + self triggerweaponslockerisvalidweaponpromptupdate( player, player getcurrentweapon() ); + return 1; +} + +arr2json(arr) { + if (isObj(arr)) { + return obj2json(arr); + } + keys = getArrayKeys(arr); + string = "["; + for (i = 0; i < keys.size; i++) { + key = keys[i]; + if (!isObj(arr[key])) { + if (isInt(arr[key])) { + string += arr[key]; + } else { + string += "\"" + arr[key] + "\""; + } + } else { + string += obj2json(arr[key]); + } + if (i < keys.size - 1) { + string += ", "; + } + } + string += "]"; + return string; +} + +isInt(var) { + return int(var) == var; +} + +json_encode(obj) { + if (!IsArray(obj)) { + return "\"" + obj + "\"\n"; + } + if (!isObj(obj)) { + return arr2json(obj) + "\n"; + } + return obj2json(obj) + "\n"; +} + +obj2json(obj) { + string = "{"; + keys = getArrayKeys(obj); + if (!isDefined(keys)) { + return "{ struct }"; + } + for (i = 0; i < keys.size; i++) { + key = keys[i]; + if (IsArray(obj[key])) { + string += "\"" + key + "\": " + arr2json(obj[key]); + } else { + if (!isInt(obj[key])) { + string += "\"" + key + "\": \"" + obj[key] + "\""; + } else { + string += "\"" + key + "\": " + obj[key]; + } + } + if (i < keys.size - 1) { + string += ", "; + } + } + string += "}"; + return string; +} + +isObj(obj) { + keys = getArrayKeys(obj); + if (!isDefined(keys)) { + return false; + } + for (i = 0; i < keys.size; i++) { + if (int(keys[i]) == 0 && keys[i] != 0) { + return true; + } + } + return false; +} + +triggerweaponslockerisvalidweapon( weaponname ) +{ + weaponname = get_base_weapon_name( weaponname, 1 ); + if ( !is_weapon_included( weaponname ) ) + { + return 0; + } + if ( is_offhand_weapon( weaponname ) || is_limited_weapon( weaponname ) ) + { + return 0; + } + return 1; +} + +triggerweaponslockerthink() +{ + self.parent_player thread triggerweaponslockerweaponchangethink( self ); + while ( 1 ) + { + self waittill( "trigger", player ); + + if (!isDefined(player.canuselocker)) { + player.canuselocker = true; + } + + if (!player.canuselocker) { + continue; + } + + retrievingweapon = player wl_has_stored_weapondata(); + if ( !retrievingweapon ) + { + curweapon = player getcurrentweapon(); + curweapon = player maps/mp/zombies/_zm_weapons::switch_from_alt_weapon( curweapon ); + if ( !triggerweaponslockerisvalidweapon( curweapon ) ) + { + continue; + } + weapondata = player maps/mp/zombies/_zm_weapons::get_player_weapondata( player ); + player wl_set_stored_weapondata( weapondata ); + + player takeweapon( curweapon ); + primaries = player getweaponslistprimaries(); + if ( isDefined( primaries[ 0 ] ) ) + { + player switchtoweapon( primaries[ 0 ] ); + } + else + { + player maps/mp/zombies/_zm_weapons::give_fallback_weapon(); + } + self triggerweaponslockerisvalidweaponpromptupdate( player, player getcurrentweapon() ); + player playsoundtoplayer( "evt_fridge_locker_close", player ); + player thread maps/mp/zombies/_zm_audio::create_and_play_dialog( "general", "weapon_storage" ); + } + else + { + curweapon = player getcurrentweapon(); + primaries = player getweaponslistprimaries(); + weapondata = player wl_get_stored_weapondata(); + if ( isDefined( level.remap_weapon_locker_weapons ) ) + { + weapondata = remap_weapon( weapondata, level.remap_weapon_locker_weapons ); + } + weapontogive = weapondata[ "name" ]; + while ( !triggerweaponslockerisvalidweapon( weapontogive ) ) + { + player playlocalsound( level.zmb_laugh_alias ); + player wl_clear_stored_weapondata(); + self triggerweaponslockerisvalidweaponpromptupdate( player, player getcurrentweapon() ); + } + curweap_base = maps/mp/zombies/_zm_weapons::get_base_weapon_name( curweapon, 1 ); + weap_base = maps/mp/zombies/_zm_weapons::get_base_weapon_name( weapontogive, 1 ); + while ( player has_weapon_or_upgrade( weap_base ) && weap_base != curweap_base ) + { + self sethintstring( &"ZOMBIE_WEAPON_LOCKER_DENY" ); + wait 3; + self triggerweaponslockerisvalidweaponpromptupdate( player, player getcurrentweapon() ); + } + maxweapons = get_player_weapon_limit( player ); + if (isDefined(primaries) && primaries.size >= maxweapons) + { + curweapon = player maps/mp/zombies/_zm_weapons::switch_from_alt_weapon( curweapon ); + while ( !triggerweaponslockerisvalidweapon( curweapon ) ) + { + self sethintstring( &"ZOMBIE_WEAPON_LOCKER_DENY" ); + wait 3; + self triggerweaponslockerisvalidweaponpromptupdate( player, player getcurrentweapon() ); + } + curweapondata = player maps/mp/zombies/_zm_weapons::get_player_weapondata( player ); + player takeweapon( curweapondata[ "name" ] ); + player maps/mp/zombies/_zm_weapons::weapondata_give( weapondata ); + player wl_set_stored_weapondata( curweapondata ); + player switchtoweapon( weapondata[ "name" ] ); + self triggerweaponslockerisvalidweaponpromptupdate( player, player getcurrentweapon() ); + } + else + { + player thread maps/mp/zombies/_zm_audio::create_and_play_dialog( "general", "wall_withdrawl" ); + player wl_clear_stored_weapondata(); + player maps/mp/zombies/_zm_weapons::weapondata_give( weapondata ); + player switchtoweapon( weapondata[ "name" ] ); + self triggerweaponslockerisvalidweaponpromptupdate( player, player getcurrentweapon() ); + } + level notify( "weapon_locker_grab" ); + player playsoundtoplayer( "evt_fridge_locker_open", player ); + } + wait 0.5; + } +} + +triggerweaponslockerweaponchangethink( trigger ) +{ + self endon( "disconnect" ); + self endon( "death" ); + trigger endon( "kill_trigger" ); + while ( 1 ) + { + self waittill( "weapon_change", newweapon ); + trigger triggerweaponslockerisvalidweaponpromptupdate( self, newweapon ); + } +} + +add_weapon_locker_mapping( fromweapon, toweapon ) +{ + if ( !isDefined( level.remap_weapon_locker_weapons ) ) + { + level.remap_weapon_locker_weapons = []; + } + level.remap_weapon_locker_weapons[ fromweapon ] = toweapon; +} + +remap_weapon( weapondata, maptable ) +{ + name = get_base_name( weapondata[ "name" ] ); + att = get_attachment_name( weapondata[ "name" ] ); + if ( isDefined( maptable[ name ] ) ) + { + weapondata[ "name" ] = maptable[ name ]; + name = weapondata[ "name" ]; + if ( is_weapon_upgraded( name ) ) + { + if ( isDefined( att ) && weapon_supports_attachments( name ) ) + { + base = get_base_weapon_name( name, 1 ); + if ( !weapon_supports_this_attachment( base, att ) ) + { + att = random_attachment( base ); + } + weapondata[ "name" ] = weapondata[ "name" ] + "+" + att; + } + else + { + if ( weapon_supports_default_attachment( name ) ) + { + att = default_attachment( name ); + weapondata[ "name" ] = weapondata[ "name" ] + "+" + att; + } + } + } + } + else + { + return weapondata; + } + name = weapondata[ "name" ]; + dw_name = weapondualwieldweaponname( name ); + alt_name = weaponaltweaponname( name ); + if ( name != "none" ) + { + weapondata[ "clip" ] = int( min( weapondata[ "clip" ], weaponclipsize( name ) ) ); + weapondata[ "stock" ] = int( min( weapondata[ "stock" ], weaponmaxammo( name ) ) ); + } + if ( dw_name != "none" ) + { + weapondata[ "lh_clip" ] = int( min( weapondata[ "lh_clip" ], weaponclipsize( dw_name ) ) ); + } + if ( alt_name != "none" ) + { + weapondata[ "alt_clip" ] = int( min( weapondata[ "alt_clip" ], weaponclipsize( alt_name ) ) ); + weapondata[ "alt_stock" ] = int( min( weapondata[ "alt_stock" ], weaponmaxammo( alt_name ) ) ); + } + weapondata[ "dw_name" ] = dw_name; + weapondata[ "alt_name" ] = alt_name; + return weapondata; +} diff --git a/t6/uncompiled mods/afktocrash.gsc b/t6/uncompiled mods/afktocrash.gsc new file mode 100644 index 0000000..3815fd2 --- /dev/null +++ b/t6/uncompiled mods/afktocrash.gsc @@ -0,0 +1,438 @@ +/* + MustBeAFK + A T6 Zombies AFK System by MustBeLeaving + You can find this script at https://github.com/garryspins/mustbeafk + + Requires: + t6-gsc-utils (https://github.com/fedddddd/t6-gsc-utils) + + DVars: + mafk_name [str = "[^6MAfk^7]"]- What text should be shown before chat messages? + mafk_prefix [str = ".afk"] - What should the prefix be for the chat commands? + + mafk_burps [bool = 1] - Should the player burp when the afk timer is up? + mafk_hud [bool = 1] - Should the message saying youre afk be shown on screen? + + mafk_user_times [bool = 0] - Should the user be able to specify a time to go afk for? + mafk_max_time [float = 15] - If user_times, what should the max time allowed be in minutes? + mafk_def_time [float = 15] - If user_times, what should the default time be if none is specified? + + mafk_time [float = 15] - If not user_times, what should the afk time be? if 0 then time is infinite. + + mafk_max_end [bool = 0] - End the game if everyone is either down or afk? + + mafk_cooldown [float = 15] - How many minutes should you have to wait before using afk again. +*/ + +#include maps\mp\_utility; +#include maps\mp\gametypes_zm\_hud_util; + +// you know +init() { + + if(level.script == "zm_prison") + { + level.mafk_name = getDvarStringDefault("mafk_name", "[^6MAfk^7]"); + level.mafk_prefix = getDvarStringDefault("mafk_prefix", ".afk" ); + + level.mafk_burps = getDvarIntDefault("mafk_burps", 1) == 1; + level.mafk_hud = getDvarIntDefault("mafk_hud", 1) == 0; + + level.mafk_user_times = getDvarIntDefault("mafk_user_times", 0) == 1; + level.mafk_max_time = getDvarFloatDefault("mafk_max_time", 15); + level.mafk_def_time = getDvarFloatDefault("mafk_def_time", 15); + + level.mafk_time = getDvarFloatDefault("mafk_time", 15); + level.mafk_infinite = level.mafk_time == 0; + + level.mafk_max_end = getDVarIntDefault("mafk_max_end", 0) == 1; + + level.mafk_cooldown = (getDvarFloatDefault("mafk_cooldown", 15) * 60) * 1000; + + onPlayerSay(::hook_chat); + + /* if (level.mafk_max_end) { + level thread watchAllDownOrAFK(); + }*/ + + if (level.mafk_cooldown != 0) { + level thread watchCooldown(); + } +} +} + +// a default string dvar getter +// since this doesnt exist anywhere in the std +getDvarStringDefault(dvar, def) { + value = GetDVar(dvar); + + if (value != "") { + return value; + } + + return def; +} + +// trims the whitespace around a string +// only really used once but still +strtrim(str) { + padl = 0; + padr = 0; + for (i = 0; i < str.size; i++) { + if (str[i] == " ") { + padl = i; + } else { + break; + } + } + + for (i = 0; i < str.size; i++) { + if (str[str.size - i] == " ") { + padr = i; + } else { + break; + } + } + + return getSubStr(str, padl, str.size - padr); +} + +// this is manual modulo +// you dont have to tell me how stupid this is, i know! +// modulo is just refusing to work properly in some places +// and i have absolutely no idea why +// so have fun with this! +mod(num, modby) { + while (num >= modby) { + num = num - modby; + } + + return num; +} + +// floor function since it doesnt exist for some reason! +// modulo works here? +floor(num) { + return num - (num % 1); +} + +// formats a time from ms into a pretty string +// this can be improved obviously +fmttime(ms) { + ms = floor(ms); + seconds = mod(floor(ms / 1000), 60); + minutes = mod(floor((ms / 1000) / 60), 60); + hours = floor(floor((ms / 1000) / 60) / 60); + + if (hours) { + text = hours + " hour"; + + if (hours > 1) { + text = text + "s"; + } + + if (minutes) { + text = text + " and " + minutes + " minute"; + + if (minutes > 1) { + text = text + "s"; + } + } + + return text; + } + + if (minutes > 0) { + text = minutes + " minute"; + + if (minutes > 1) { + text = text + "s"; + } + + if (seconds) { + text = text + " and " + seconds + " second"; + + if (seconds > 1) { + text = text + "s"; + } + } + + return text; + } + + if (seconds > 1) { + return seconds + " seconds"; + } + + if (seconds == 1) { + return seconds + " second"; + } + + return "no time"; +} + +// watch for if every player is either down or afk +// if they are then end the game +watchAllDownOrAFK() { + level endon("game_ended"); + for(;;) { + players = getplayers(); + count = 0; + afk = 0; + + foreach(ply in players) { + if (!isAlive(ply)) { + count++; + } else if (ply.afk) { + count++; + afk++; + } + } + + if ((count == players.size) && (afk != 0)) { + level notify("end_game"); + } + + wait 5; + } +} + +// set the players cooldown +// this is separate from set_afk because +// we like to be a little efficient around these parts +watchCooldown() { + + for (;;) { + level endon("game_ended"); + self waittill("mafk_set", ply, val); + + if (val == false) { + ply.mafk_cooldown = getTime() + self.mafk_cooldown; + } + } +} + +// burps! but only if we want burps +burp() { + if (level.mafk_burps) { + self maps\mp\zombies\_zm_audio::playerexert("burp"); + } +} + +// sets the player to be afk or not, accepts a boolean +// this doesnt do anything except set some values on the player +// if you wish to extend anything use the notification +set_afk(value) { + self.afk = value; + self.afk_notify_half = false; + + //self freezeControls(value); + + + + self.ignoreme = value; + + if (value) { + stock = self getweaponammostock( weapon ); + clip = self getweaponammoclip( weapon ); + self setmovespeedscale(0); + self SetWeaponAmmoStock(self.useweapon, 0); + self SetWeaponAmmoClip(self.useweapon, 0); + self enableInvulnerability(); + } else { + self setmovespeedscale(1); + self SetWeaponAmmoStock(self.useweapon, stock); + self SetWeaponAmmoClip(self.useweapon, clip); + self disableInvulnerability(); + } + + level notify("mafk_set", self, value); +} + +// this is the actual logic behind the chat command +// just a series of checks +quick_afk_on(time) { + // is the player down + if (self.sessionstate == "spectator" || !isAlive(self)) { + self tell(level.mafk_name + " You must be alive to go AFK."); + return false; + } + + if (isDefined(self.mafk_cooldown)) { + if (self.mafk_cooldown >= getTime()) { + self tell(level.mafk_name + " You must wait ^4" + fmttime(self.mafk_cooldown - getTime()) + "^7 before going afk again."); + return false; + } + + self.mafk_cooldown = undefined; + } + + if (self.afk) { + if (isDefined(self.mafk_endtime)) { + self tell(level.mafk_name + " You are already AFK, if you would like to go un-afk type ^2.afk off"); + self tell(level.mafk_name + " You have ^4" + fmttime(self.mafk_endtime - getTime()) + "^7 left"); + } else { + self tell(level.mafk_name + " You have as long as you want to be afk."); + } + return false; + } + + if (level.mafk_infinite && !level.mafk_user_times) { + say(level.mafk_name + " " + self.name + " is going AFK in 3 seconds"); + wait 3; + say(level.mafk_name + " " + self.name + " has gone AFK."); + self set_afk(true); + + return false; + } + + say(level.mafk_name + " " + self.name + " has gone AFK for ^4" + fmttime((time * 60) * 1000)); + self tell(level.mafk_name + " You have gone AFK, if you would like to go un-afk type ^2.afk off"); + endtime = getTime() + ((time * 60) * 1000); + + self set_afk(true); + + self.mafk_endtime = endtime; + self thread check_afk_player(endtime); + + /* if (level.mafk_hud) { + self thread afk_player_hud(endtime, (time * 60) * 1000); + }*/ + + self burp(); + + return false; +} + +// what actually hooks onto chat +hook_chat(text, mode) { + text = strtrim(toLower(text)); + + split = strTok(text, " "); + + if (split[0] != level.mafk_prefix) { + return true; + } + + if ((split[1] == undefined) || (split[1] == "on")) { + if (level.mafk_user_times) { + return self quick_afk_on(level.mafk_def_time); + } else { + return self quick_afk_on(level.mafk_time); + } + return false; + } + + if (level.mafk_user_times) { + switch (split[1]) { + case "off": + self tell(level.mafk_name + " You're back!"); + self set_afk(false); + self notify("afkcancel"); + break; + case "time": + case "left": + if (self.afk) { + self tell(level.mafk_name + " You have ^4" + fmttime(self.mafk_endtime - getTime()) + "^7 left"); + } else { + self tell(level.mafk_name + " You are not afk."); + } + + break; + case "help": + self tell(level.mafk_name + " ^2" + level.mafk_prefix + " [number]^7 - Turns on afk for the given amount of time (^2" + mintime + "^7 to ^2" + level.mafk_max_time + "^7 minutes)"); + self tell(level.mafk_name + " ^2" + level.mafk_prefix + " off^7 - Turns off afk"); + self tell(level.mafk_name + " ^2" + level.mafk_prefix + " help^7 - Shows this message"); + self tell(level.mafk_name + " ^2" + level.mafk_prefix + " time^7 - Shows how long youre allowed to be afk"); + + break; + default: + mintime = 1; + time = int(split[1]); + + if ((time < mintime) || (time > level.mafk_max_time)) { + self tell(level.mafk_name + " Please give a valid time from ^2" + mintime + "^7 to ^2" + level.mafk_max_time + "^7 minutes"); + return false; + } + + return self quick_afk_on(time); + } + + return false; + } + + switch (split[1]) { + case "off": + self tell(level.mafk_name + " You're back!"); + self set_afk(false); + self notify("afkcancel"); + break; + case "time": + case "left": + if (self.afk) { + self tell(level.mafk_name + " You have ^4" + fmttime(self.mafk_endtime - getTime()) + "^7 left"); + } else { + self tell(level.mafk_name + " You are not afk."); + } + + break; + case "help": + default: + self tell(level.mafk_name + " ^2" + level.mafk_prefix + " on^7 - Turns on afk"); + self tell(level.mafk_name + " ^2" + level.mafk_prefix + " off^7 - Turns off afk"); + self tell(level.mafk_name + " ^2" + level.mafk_prefix + " help^7 - Shows this message"); + self tell(level.mafk_name + " ^2" + level.mafk_prefix + " time^7 - Shows how much longer you can be afk"); + } + + return false; +} + +// runs on the player to check if he should still be afk or not +check_afk_player(endtime) { + for (;;) { + self endon("disconnect"); + self endon("afkcancel"); + level endon("game_ended"); + + time = getTime(); + + if (time >= endtime) { + self set_afk(false); + self tell(level.mafk_name + " Your AFK time has expired!"); + self burp(); + self.mafk_endtime = undefined; + break; + } + + wait 0.25; + } +} +/* +// only runs if mafk_hud is 1 +// draws the hud! +afk_player_hud(endtime, time) { + if (isDefined(self.mafk_hud)) { + return; + } + + level endon("game_ended"); + self endon("disconnect"); + + self.mafk_hud = createServerFontString("objective", 2); + self.mafk_hud setPoint("CENTER", "TOP", 0, 0); + self.mafk_hud setText("You are currently afk"); + + self.mafk_hud.hideWhenInMenu = 1; + + for(;;) { + if ((getTime() >= endtime) || !self.afk) { + self.mafk_hud destroy(); + break; + } + + // logic to make it slowly fade + self.mafk_hud.alpha = ((endtime - getTime()) / time) + 0.75; + + wait 0.50; + } +}*/ \ No newline at end of file diff --git a/t6/uncompiled mods/announcements.gsc b/t6/uncompiled mods/announcements.gsc new file mode 100644 index 0000000..9b18602 --- /dev/null +++ b/t6/uncompiled mods/announcements.gsc @@ -0,0 +1,37 @@ +init() +{ + setDvar("bold", ""); + setDvar("ln", ""); + level thread AnnouncementWatcher(); +} + +AnnouncementWatcher() +{ + for (;;) + { + if (getDvar("bold") != "") { + printBold = getDvar("bold"); + setDvar("bold", ""); + iprintLnBold(printBold); + wait 2; + iprintLnBold(printBold); + wait 2; + iprintLnBold(printBold); + } + if (getDvar("ln") != "") { + printLn = getDvar("ln"); + setDvar("ln", ""); + iprintLn(printLn); + } + wait 0.5; + } +} + +getPlayerByGuid(guid) { + for (i = 0; i < level.players.size; i++) { + if (isAlive(level.players[i]) && int(level.players[i] getGuid()) == int(guid)) { + return level.players[i]; + } + } + return false; +} \ No newline at end of file diff --git a/t6/uncompiled mods/bankv2 - Copie.gsc b/t6/uncompiled mods/bankv2 - Copie.gsc new file mode 100644 index 0000000..3df0fca --- /dev/null +++ b/t6/uncompiled mods/bankv2 - Copie.gsc @@ -0,0 +1,125 @@ +#include maps\mp\zombies\_zm; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\_visionset_mgr; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\_demo; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\zombies\_zm_power; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_stats; +#include common_scripts\utility; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\zombies\_zm_chugabud; +#include maps\mp\zombies\_zm_afterlife; +#include maps\mp\zombies\_zm_tombstone; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm_perk_vulture; + +init() { + level thread onPlayerConnect(); + mapname = getDvar( "mapname" ); + setDvar("bank_withdraw", ""); + setDvar("bank_deposit", ""); + setDvar("0_can_use_bank", ""); + level thread playerBank(); +} + +onPlayerConnect() +{ + level endon( "end_game" ); + self endon( "disconnect" ); + for (;;) + { + level waittill( "connected", player ); + player thread endPlayerMoney2(); + player thread endPlayerMoney(); // probably not necessary + player thread setPlayerMoney(); + + } +} + +endPlayerMoney() { + self endon("disconnect"); + for (;;) { + level waittill("end_game"); + setDvar(self getEntityNumber() + "_money", 0); + } +} + +endPlayerMoney2() { + self endon("disconnect"); + for (;;) { + level waittill("_zombie_game_over"); + setDvar(self getEntityNumber() + "_money", 0); + } +} + + +setPlayerMoney() { + level endon("end_game"); + level endon("_zombie_game_over"); + self endon("disconnect"); + for (;;) { + if (!isAlive(self)) { + setDvar(self getEntityNumber() + "_money", 0); + } else { + setDvar(self getEntityNumber() + "_money", self.score); + } + wait 0.05; + } +} + +getPlayerByGuid(guid) { + for (i = 0; i < level.players.size; i++) { + if (isAlive(level.players[i]) && int(level.players[i] getGuid()) == int(guid)) { + return level.players[i]; + } + } + return false; +} + +playerBank() { + for (;;) { + if (getDvar("bank_withdraw") != "") { + withdraw = strTok(getDvar("bank_withdraw"), ";"); + setDvar("bank_withdraw", ""); + getPlayerByGuid(withdraw[0]).score += int(withdraw[1]); + getPlayerByGuid(withdraw[0]) iPrintLn("Withdrew ^2$" + int(withdraw[1]) + "^7 from your bank account!"); + } + if (getDvar("bank_deposit") != "") { + + if ( level.script == "zm_buried") + { + if(!flag("time_bomb_restore_active")) + { + setDvar("0_can_use_bank", "0"); + getPlayerByGuid(deposit[0]) iPrintLn("Cannot deposit when ^2Time Bomb ^7is set."); + deposit = strTok(getDvar("bank_deposit"), ";"); + + getPlayerByGuid(deposit[0]).score -= 0; + getPlayerByGuid(deposit[0]) iPrintLn("Deposited ^2$" + int(deposit[1]) + "^7 into your bank account!"); + } + else + { + deposit = strTok(getDvar("bank_deposit"), ";"); + setDvar("bank_deposit", ""); + getPlayerByGuid(deposit[0]).score -= int(deposit[1]); + getPlayerByGuid(deposit[0]) iPrintLn("Deposited ^2$" + int(deposit[1]) + "^7 into your bank account!"); + } + } + else + { + deposit = strTok(getDvar("bank_deposit"), ";"); + setDvar("bank_deposit", ""); + getPlayerByGuid(deposit[0]).score -= int(deposit[1]); + getPlayerByGuid(deposit[0]) iPrintLn("Deposited ^2$" + int(deposit[1]) + "^7 into your bank account!"); + } + } + wait 0.05; + } +} \ No newline at end of file diff --git a/t6/uncompiled mods/bankv2.gsc b/t6/uncompiled mods/bankv2.gsc new file mode 100644 index 0000000..9e7a5c1 --- /dev/null +++ b/t6/uncompiled mods/bankv2.gsc @@ -0,0 +1,517 @@ +#include maps\mp\zombies\_zm_power; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\zombies\_zm_chugabud; +#include maps\mp\zombies\_zm_afterlife; +#include maps\mp\zombies\_zm_tombstone; +#include maps\mp\zombies\_zm_perk_vulture; +#include maps\mp\zombies\_zm_weap_time_bomb; +#include maps\mp\_demo; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\gametypes_zm\_gameobjects; +#include maps\mp\zombies\_zm_buildables; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm_clone; +#include maps\mp\zombies\_zm_weap_cymbal_monkey; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm; +#include maps\mp\_visionset_mgr; +//motd +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_craftables; +#include maps\mp\zm_alcatraz_utility; +#include maps\mp\zm_alcatraz_gamemodes; +#include maps\mp\zm_prison_fx; +#include maps\mp\zm_prison_ffotd; +#include maps\mp\animscripts\zm_death; +#include maps\mp\zm_alcatraz_amb; +#include maps\mp\zombies\_load; +#include maps\mp\zm_prison_achievement; +#include maps\mp\gametypes_zm\_spawning; +#include maps\mp\zombies\_zm_perk_electric_cherry; +#include maps\mp\zombies\_zm_perk_divetonuke; +#include maps\mp\zm_alcatraz_distance_tracking; +#include maps\mp\zm_alcatraz_traps; +#include maps\mp\zm_alcatraz_travel; +#include maps\mp\zombies\_zm_magicbox_prison; +#include maps\mp\zombies\_zm_ai_basic; +#include maps\mp\zombies\_zm_weap_claymore; +#include maps\mp\zombies\_zm_weap_riotshield_prison; +#include maps\mp\zombies\_zm_weap_blundersplat; +#include maps\mp\zombies\_zm_weap_tomahawk; +#include maps\mp\zombies\_zm_zonemgr; +#include maps\mp\zm_alcatraz_weap_quest; +#include maps\mp\zm_alcatraz_grief_cellblock; +#include maps\mp\zm_prison; +#include character\c_zom_arlington; +#include character\c_zom_deluca; +#include character\c_zom_handsome; +#include character\c_zom_oleary; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_blockers; + +//points +#include common_scripts\utility; +#include maps\mp\_utility; + + +//timebomb +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\zombies\_zm_weapon_locker; +#include maps\mp\zombies\_zm_magicbox; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_spawner; + +main() +{ + replaceFunc( maps\mp\zombies\_zm_score::player_add_points, ::disablerevivemoney); +} + +init() { + level thread onPlayerConnect(); + mapname = getDvar( "mapname" ); + setDvar("bank_withdraw", ""); + setDvar("bank_deposit", ""); + level thread playerBank(); + if(getdvar("0_can_use_bank") != "") + setDvar("0_can_use_bank", ""); + if(getdvar("1_can_use_bank") != "") + setDvar("1_can_use_bank", ""); + if(getdvar("2_can_use_bank") != "") + setDvar("2_can_use_bank", ""); + if(getdvar("3_can_use_bank") != "") + setDvar("3_can_use_bank", ""); + if(getdvar("4_can_use_bank") != "") + setDvar("4_can_use_bank", ""); + if(getdvar("5_can_use_bank") != "") + setDvar("5_can_use_bank", ""); + if(getdvar("6_can_use_bank") != "") + setDvar("6_can_use_bank", ""); + if(getdvar("7_can_use_bank") != "") + setDvar("7_can_use_bank", ""); + /*if (level.script == "zm_prison" || level.script == "zm_tomb") + { + setDvar("0_can_use_bank", "2"); + setDvar("1_can_use_bank", "2"); + setDvar("2_can_use_bank", "2"); + setDvar("3_can_use_bank", "2"); + setDvar("4_can_use_bank", "2"); + setDvar("5_can_use_bank", "2"); + setDvar("6_can_use_bank", "2"); + setDvar("7_can_use_bank", "2"); + }*/ + if ( level.script == "zm_buried") + { + level thread checkTimeBombActive(); + } + if ( level.script == "zm_tranzit" && ) + + level._game_module_point_adjustment = ::doublepoints; + + +} + +onPlayerConnect() +{ + for (;;) + { + level waittill( "connected", player ); + player thread endPlayerMoney2(); + player thread endPlayerMoney(); // probably not necessary + player thread setPlayerMoney(); + //player thread showInfo(); + //player thread printDebug(); + if (level.script == "zm_buried" || level.script == "zm_tranzit" || level.script == "zm_highrise") + { + level.ta_tellerfee = 6942000; + level.ta_vaultfee = 1000; + } + if (level.script == "zm_prison") + { + // player thread checkAfterlifeActive(); + // player thread showInfo(); + } + } +} + +doublepoints(player, zombie_team, player_points){ + //if (level.script != "zm_prison" && level.script != "zm_tomb") + //{ + if (player_points != 0) + { + tag = strTok(player.name, "]"); + if (tag[0] == "[^9F^7") + { + player maps\mp\zombies\_zm_score::add_to_player_score( player_points ); + player.pers[ "score" ] = player.score; + } + else if (tag[0] == "[^8E^7") + { + player maps\mp\zombies\_zm_score::add_to_player_score( player_points * 2); + player.pers[ "score" ] = player.score; + } + else if (tag[0] == "[^2D^7") + { + player maps\mp\zombies\_zm_score::add_to_player_score( player_points * 2); + player.pers[ "score" ] = player.score; + } + else if (tag[0] == "[^4C^7") + { + player maps\mp\zombies\_zm_score::add_to_player_score( player_points * 3); + player.pers[ "score" ] = player.score; + } + else if (tag[0] == "[^5B^7") + { + player maps\mp\zombies\_zm_score::add_to_player_score( player_points * 3); + player.pers[ "score" ] = player.score; + } + else if (tag[0] == "[^6A^7") + { + player maps\mp\zombies\_zm_score::add_to_player_score( player_points * 4); + player.pers[ "score" ] = player.score; + } + else if (tag[0] == "[^3S^7") + { + player maps\mp\zombies\_zm_score::add_to_player_score( player_points * 5); + player.pers[ "score" ] = player.score; + } + else if (tag[0] == "[^3SS^7") + { + player maps\mp\zombies\_zm_score::add_to_player_score( player_points * 6); + player.pers[ "score" ] = player.score; + } + else if (tag[0] == "[^3SSS^7") + { + player maps\mp\zombies\_zm_score::add_to_player_score( player_points * 8); + player.pers[ "score" ] = player.score; + } + if (tag[1]) + { + if(tag[1] == "[^3VIP^7" || tag[1] == "^3[VIP") + { + player maps\mp\zombies\_zm_score::add_to_player_score( player_points * 3); + player.pers[ "score" ] = player.score; + } + } + } +// } +} + +disablerevivemoney(event, mod, hit_location, is_dog, zombie_team, damage_weapon) +{ + if ( level.intermission ) + return; + + if ( !is_player_valid( self ) ) + return; + + player_points = 0; + team_points = 0; + multiplier = get_points_multiplier( self ); + + switch ( event ) + { + case "death": + player_points = get_zombie_death_player_points(); + team_points = get_zombie_death_team_points(); + points = self player_add_points_kill_bonus( mod, hit_location ); + + if ( level.zombie_vars[self.team]["zombie_powerup_insta_kill_on"] == 1 && mod == "MOD_UNKNOWN" ) + points *= 2; + + player_points += points; + + if ( team_points > 0 ) + team_points += points; + + if ( mod == "MOD_GRENADE" || mod == "MOD_GRENADE_SPLASH" ) + { + self maps\mp\zombies\_zm_stats::increment_client_stat( "grenade_kills" ); + self maps\mp\zombies\_zm_stats::increment_player_stat( "grenade_kills" ); + } + + break; + case "ballistic_knife_death": + player_points = get_zombie_death_player_points() + level.zombie_vars["zombie_score_bonus_melee"]; + self score_cf_increment_info( "death_melee" ); + break; + case "damage_light": + player_points = level.zombie_vars["zombie_score_damage_light"]; + self score_cf_increment_info( "damage" ); + break; + case "damage": + player_points = level.zombie_vars["zombie_score_damage_normal"]; + self score_cf_increment_info( "damage" ); + break; + case "damage_ads": + player_points = int( level.zombie_vars["zombie_score_damage_normal"] * 1.25 ); + self score_cf_increment_info( "damage" ); + break; + case "rebuild_board": + case "carpenter_powerup": + player_points = mod; + break; + case "bonus_points_powerup": + player_points = mod; + break; + case "nuke_powerup": + player_points = mod; + team_points = mod; + break; + case "thundergun_fling": + case "riotshield_fling": + case "jetgun_fling": + player_points = mod; + break; + case "hacker_transfer": + player_points = mod; + break; + case "reviver": + player_points = 0; + break; + case "vulture": + player_points = mod; + break; + case "build_wallbuy": + player_points = mod; + break; + default: + assert( 0, "Unknown point event" ); + break; + } + + player_points = multiplier * round_up_score( player_points, 5 ); + team_points = multiplier * round_up_score( team_points, 5 ); + + if ( ( event == "death" || event == "ballistic_knife_death" ) && isdefined( self.point_split_receiver )) + { + split_player_points = player_points - round_up_score( player_points * self.point_split_keep_percent, 10 ); + self.point_split_receiver add_to_player_score( split_player_points ); + player_points -= split_player_points; + } + + if ( is_true( level.pers_upgrade_pistol_points ) ) + player_points = self maps\mp\zombies\_zm_pers_upgrades_functions::pers_upgrade_pistol_points_set_score( player_points, event, mod, damage_weapon ); + + self add_to_player_score( player_points ); + self.pers["score"] = self.score; + + if ( isdefined( level._game_module_point_adjustment ) ) + level [[ level._game_module_point_adjustment ]]( self, zombie_team, player_points ); +} + +get_points_multiplier( player ) +{ + multiplier = level.zombie_vars[player.team]["zombie_point_scalar"]; + + if ( isdefined( level.current_game_module ) && level.current_game_module == 2 ) + { + if ( isdefined( level._race_team_double_points ) && level._race_team_double_points == player._race_team ) + return multiplier; + else + return 1; + } + + return multiplier; +} + + +printDebug() +{ + for(;;) + { + if(getDvar("revive")) + { + self iPrintLn("revive dvar is defined"); + self iPrintLn("revive value : " + getDvar("revive")); + self iPrintLn("resetting revive value to 0:"); + setDvar("revive", "0"); + } + else + { + self iPrintLn("test dvar is defined"); + } + wait 5; + } +} + +showInfo() +{ + for(;;) + { + /*if (isdefined(self.afterlife)) + { + self iPrintLn("Time bomb defined"); + } + else + { + self iPrintLn("Time bomb not defined"); + }*/ + + if(isdefined(self.afterlife)) + { + self iPrintLn("TB save ready defined"); + self iPrintLn("Time bomb save_ready value : " + self.afterlife); + } + else + self iPrintLn("Tb save ready not defined"); + wait 5; + } +} + +checkAfterlifeActive() +{ + for (;;) + { + if (self.afterlife == 1) + { + if(getdvar("0_can_use_bank") != "1") + setDvar("0_can_use_bank", "1"); + if(getdvar("1_can_use_bank") != "1") + setDvar("1_can_use_bank", "1"); + if(getdvar("2_can_use_bank") != "1") + setDvar("2_can_use_bank", "1"); + if(getdvar("3_can_use_bank") != "1") + setDvar("3_can_use_bank", "1"); + if(getdvar("4_can_use_bank") != "1") + setDvar("4_can_use_bank", "1"); + if(getdvar("5_can_use_bank") != "1") + setDvar("5_can_use_bank", "1"); + if(getdvar("6_can_use_bank") != "1") + setDvar("6_can_use_bank", "1"); + if(getdvar("7_can_use_bank") != "1") + setDvar("7_can_use_bank", "1"); + } + else + { + if(getdvar("0_can_use_bank") != "") + setDvar("0_can_use_bank", ""); + if(getdvar("1_can_use_bank") != "") + setDvar("1_can_use_bank", ""); + if(getdvar("2_can_use_bank") != "") + setDvar("2_can_use_bank", ""); + if(getdvar("3_can_use_bank") != "") + setDvar("3_can_use_bank", ""); + if(getdvar("4_can_use_bank") != "") + setDvar("4_can_use_bank", ""); + if(getdvar("5_can_use_bank") != "") + setDvar("5_can_use_bank", ""); + if(getdvar("6_can_use_bank") != "") + setDvar("6_can_use_bank", ""); + if(getdvar("7_can_use_bank") != "") + setDvar("7_can_use_bank", ""); + } + wait 0.2; + } +} + +checkTimeBombActive() +{ + for (;;) + { + if (time_bomb_save_exists()) + { + if(getdvar("0_can_use_bank") != "0") + setDvar("0_can_use_bank", "0"); + if(getdvar("1_can_use_bank") != "0") + setDvar("1_can_use_bank", "0"); + if(getdvar("2_can_use_bank") != "0") + setDvar("2_can_use_bank", "0"); + if(getdvar("3_can_use_bank") != "0") + setDvar("3_can_use_bank", "0"); + if(getdvar("4_can_use_bank") != "0") + setDvar("4_can_use_bank", "0"); + if(getdvar("5_can_use_bank") != "0") + setDvar("5_can_use_bank", "0"); + if(getdvar("6_can_use_bank") != "0") + setDvar("6_can_use_bank", "0"); + if(getdvar("7_can_use_bank") != "0") + setDvar("7_can_use_bank", "0"); + } + else + { + if(getdvar("0_can_use_bank") != "") + setDvar("0_can_use_bank", ""); + if(getdvar("1_can_use_bank") != "") + setDvar("1_can_use_bank", ""); + if(getdvar("2_can_use_bank") != "") + setDvar("2_can_use_bank", ""); + if(getdvar("3_can_use_bank") != "") + setDvar("3_can_use_bank", ""); + if(getdvar("4_can_use_bank") != "") + setDvar("4_can_use_bank", ""); + if(getdvar("5_can_use_bank") != "") + setDvar("5_can_use_bank", ""); + if(getdvar("6_can_use_bank") != "") + setDvar("6_can_use_bank", ""); + if(getdvar("7_can_use_bank") != "") + setDvar("7_can_use_bank", ""); + } + wait 0.2; + } +} + +time_bomb_save_exists() +{ + return isdefined( level.time_bomb_save_data ) && isdefined( level.time_bomb_save_data.save_ready ) && level.time_bomb_save_data.save_ready; +} + + +endPlayerMoney() { + self endon("disconnect"); + for (;;) { + level waittill("end_game"); + setDvar(self getEntityNumber() + "_money", 0); + } +} + +endPlayerMoney2() { + self endon("disconnect"); + for (;;) { + level waittill("_zombie_game_over"); + setDvar(self getEntityNumber() + "_money", 0); + } +} + + +setPlayerMoney() { + level endon("end_game"); + level endon("_zombie_game_over"); + for (;;) { + if (!isAlive(self)) { + setDvar(self getEntityNumber() + "_money", 0); + } else { + setDvar(self getEntityNumber() + "_money", self.score); + } + wait 0.05; + } +} + +getPlayerByGuid(guid) { + for (i = 0; i < level.players.size; i++) { + if (isAlive(level.players[i]) && int(level.players[i] getGuid()) == int(guid)) { + return level.players[i]; + } + } + return false; +} + +playerBank() { + for (;;) { + if (getDvar("bank_withdraw") != "") { + withdraw = strTok(getDvar("bank_withdraw"), ";"); + setDvar("bank_withdraw", ""); + getPlayerByGuid(withdraw[0]).score += int(withdraw[1]); + getPlayerByGuid(withdraw[0]) iPrintLn("Withdrew ^2$" + int(withdraw[1]) + "^7 from your bank account!"); + } + if (getDvar("bank_deposit") != "") { + deposit = strTok(getDvar("bank_deposit"), ";"); + setDvar("bank_deposit", ""); + getPlayerByGuid(deposit[0]).score -= int(deposit[1]); + getPlayerByGuid(deposit[0]) iPrintLn("Deposited ^2$" + int(deposit[1]) + "^7 into your bank account!"); + } + wait 0.05; + } +} \ No newline at end of file diff --git a/t6/uncompiled mods/bankv2tournament.gsc b/t6/uncompiled mods/bankv2tournament.gsc new file mode 100644 index 0000000..3af038c --- /dev/null +++ b/t6/uncompiled mods/bankv2tournament.gsc @@ -0,0 +1,567 @@ +#include maps\mp\zombies\_zm; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\_visionset_mgr; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\_demo; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\zombies\_zm_power; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_stats; +#include common_scripts\utility; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\zombies\_zm_chugabud; +#include maps\mp\zombies\_zm_afterlife; +#include maps\mp\zombies\_zm_tombstone; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm_perk_vulture; +#include maps\mp\zombies\_zm_weap_time_bomb; + +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\_demo; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\gametypes_zm\_gameobjects; +#include maps\mp\zombies\_zm_buildables; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm_chugabud; +#include maps\mp\zombies\_zm_perks; + + +#include maps\mp\_utility; +#include common_scripts\utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\zombies\_zm_chugabud; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm_clone; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_weap_cymbal_monkey; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm; +#include maps\mp\_visionset_mgr; + +//motd +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_craftables; +#include maps\mp\zm_alcatraz_utility; +#include maps\mp\zm_alcatraz_gamemodes; +#include maps\mp\zm_prison_fx; +#include maps\mp\zm_prison_ffotd; +#include maps\mp\zombies\_zm; +#include maps\mp\animscripts\zm_death; +#include maps\mp\zm_alcatraz_amb; +#include maps\mp\zombies\_load; +#include maps\mp\zm_prison_achievement; +#include maps\mp\gametypes_zm\_spawning; +#include maps\mp\zombies\_zm_perk_electric_cherry; +#include maps\mp\zombies\_zm_perk_divetonuke; +#include maps\mp\zm_alcatraz_distance_tracking; +#include maps\mp\zm_alcatraz_traps; +#include maps\mp\zm_alcatraz_travel; +#include maps\mp\zombies\_zm_magicbox_prison; +#include maps\mp\zombies\_zm_ai_basic; +#include maps\mp\zombies\_zm_weap_claymore; +#include maps\mp\zombies\_zm_weap_riotshield_prison; +#include maps\mp\zombies\_zm_weap_blundersplat; +#include maps\mp\zombies\_zm_weap_tomahawk; +#include maps\mp\zombies\_zm_zonemgr; +#include maps\mp\zm_alcatraz_weap_quest; +#include maps\mp\zm_alcatraz_grief_cellblock; +#include maps\mp\_visionset_mgr; +#include maps\mp\zm_prison; +#include character\c_zom_arlington; +#include character\c_zom_deluca; +#include character\c_zom_handsome; +#include character\c_zom_oleary; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_blockers; + +//points +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zombies\_zm_pers_upgrades_functions; + + +//timebomb +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\_visionset_mgr; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_blockers; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\zombies\_zm_weapon_locker; +#include maps\mp\zombies\_zm_magicbox; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm; +#include maps\mp\zombies\_zm_spawner; +#include maps\mp\animscripts\zm_death; +#include maps\mp\zombies\_zm_ai_basic; +#include maps\mp\zombies\_zm_weap_time_bomb; + +main() +{ + replaceFunc( maps/mp/zombies/_zm_score::player_add_points, ::disablerevivemoney); +} + +init() { + level thread onPlayerConnect(); + mapname = getDvar( "mapname" ); + setDvar("bank_withdraw", ""); + setDvar("bank_deposit", ""); + setDvar("revive", "0"); + level thread playerBank(); + if(getdvar("0_can_use_bank") != "") + setDvar("0_can_use_bank", ""); + if(getdvar("1_can_use_bank") != "") + setDvar("1_can_use_bank", ""); + if(getdvar("2_can_use_bank") != "") + setDvar("2_can_use_bank", ""); + if(getdvar("3_can_use_bank") != "") + setDvar("3_can_use_bank", ""); + if(getdvar("4_can_use_bank") != "") + setDvar("4_can_use_bank", ""); + if(getdvar("5_can_use_bank") != "") + setDvar("5_can_use_bank", ""); + if(getdvar("6_can_use_bank") != "") + setDvar("6_can_use_bank", ""); + if(getdvar("7_can_use_bank") != "") + setDvar("7_can_use_bank", ""); + if (level.script == "zm_prison") + { + setDvar("0_can_use_bank", "2"); + setDvar("1_can_use_bank", "2"); + setDvar("2_can_use_bank", "2"); + setDvar("3_can_use_bank", "2"); + setDvar("4_can_use_bank", "2"); + setDvar("5_can_use_bank", "2"); + setDvar("6_can_use_bank", "2"); + setDvar("7_can_use_bank", "2"); + } + if ( level.script == "zm_buried") + { + level thread checkTimeBombActive(); + } + + level._game_module_point_adjustment = ::doublepoints; + + +} + + +onPlayerConnect() +{ + for (;;) + { + level waittill( "connected", player ); + player thread endPlayerMoney2(); + player thread endPlayerMoney(); // probably not necessary + player thread setPlayerMoney(); + //player thread showInfo(); + //player thread printDebug(); + if (level.script == "zm_buried" || level.script == "zm_tranzit" || level.script == "zm_highrise") + { + level.ta_tellerfee = 6942000; + level.ta_vaultfee = 1000; + } + + } +} + +doublepoints(player, zombie_team, player_points){ + if (level.script != "zm_prison") + { + if (player_points != 0) + { + tag = strTok(player.name, "]"); + if (tag[0] == "[^9F^7") + { + player maps/mp/zombies/_zm_score::add_to_player_score( player_points ); + player.pers[ "score" ] = player.score; + } + else if (tag[0] == "[^8E^7") + { + player maps/mp/zombies/_zm_score::add_to_player_score( player_points * 2); + player.pers[ "score" ] = player.score; + } + else if (tag[0] == "[^2D^7") + { + player maps/mp/zombies/_zm_score::add_to_player_score( player_points * 2); + player.pers[ "score" ] = player.score; + } + else if (tag[0] == "[^4C^7") + { + player maps/mp/zombies/_zm_score::add_to_player_score( player_points * 3); + player.pers[ "score" ] = player.score; + } + else if (tag[0] == "[^5B^7") + { + player maps/mp/zombies/_zm_score::add_to_player_score( player_points * 3); + player.pers[ "score" ] = player.score; + } + else if (tag[0] == "[^6A^7") + { + player maps/mp/zombies/_zm_score::add_to_player_score( player_points * 4); + player.pers[ "score" ] = player.score; + } + else if (tag[0] == "[^3S^7") + { + player maps/mp/zombies/_zm_score::add_to_player_score( player_points * 5); + player.pers[ "score" ] = player.score; + } + else if (tag[0] == "[^3SS^7") + { + player maps/mp/zombies/_zm_score::add_to_player_score( player_points * 6); + player.pers[ "score" ] = player.score; + } + else if (tag[0] == "[^3SSS^7") + { + player maps/mp/zombies/_zm_score::add_to_player_score( player_points * 8); + player.pers[ "score" ] = player.score; + } + if (tag[1]) + { + if(tag[1] == "[^3VIP^7" || tag[1] == "^3[VIP") + { + player maps/mp/zombies/_zm_score::add_to_player_score( player_points * 3); + player.pers[ "score" ] = player.score; + } + } + } + } +} + +disablerevivemoney(event, mod, hit_location, is_dog, zombie_team, damage_weapon) +{ + if ( level.intermission ) + return; + + if ( !is_player_valid( self ) ) + return; + + player_points = 0; + team_points = 0; + multiplier = get_points_multiplier( self ); + + switch ( event ) + { + case "death": + player_points = get_zombie_death_player_points(); + team_points = get_zombie_death_team_points(); + points = self player_add_points_kill_bonus( mod, hit_location ); + + if ( level.zombie_vars[self.team]["zombie_powerup_insta_kill_on"] == 1 && mod == "MOD_UNKNOWN" ) + points *= 2; + + player_points += points; + + if ( team_points > 0 ) + team_points += points; + + if ( mod == "MOD_GRENADE" || mod == "MOD_GRENADE_SPLASH" ) + { + self maps\mp\zombies\_zm_stats::increment_client_stat( "grenade_kills" ); + self maps\mp\zombies\_zm_stats::increment_player_stat( "grenade_kills" ); + } + + break; + case "ballistic_knife_death": + player_points = get_zombie_death_player_points() + level.zombie_vars["zombie_score_bonus_melee"]; + self score_cf_increment_info( "death_melee" ); + break; + case "damage_light": + player_points = level.zombie_vars["zombie_score_damage_light"]; + self score_cf_increment_info( "damage" ); + break; + case "damage": + player_points = level.zombie_vars["zombie_score_damage_normal"]; + self score_cf_increment_info( "damage" ); + break; + case "damage_ads": + player_points = int( level.zombie_vars["zombie_score_damage_normal"] * 1.25 ); + self score_cf_increment_info( "damage" ); + break; + case "rebuild_board": + case "carpenter_powerup": + player_points = mod; + break; + case "bonus_points_powerup": + player_points = mod; + break; + case "nuke_powerup": + player_points = mod; + team_points = mod; + break; + case "thundergun_fling": + case "riotshield_fling": + case "jetgun_fling": + player_points = mod; + break; + case "hacker_transfer": + player_points = mod; + break; + case "reviver": + player_points = 0; + break; + case "vulture": + player_points = mod; + break; + case "build_wallbuy": + player_points = mod; + break; + default: + assert( 0, "Unknown point event" ); + break; + } + + player_points = multiplier * round_up_score( player_points, 5 ); + team_points = multiplier * round_up_score( team_points, 5 ); + + if ( ( event == "death" || event == "ballistic_knife_death" ) && isdefined( self.point_split_receiver )) + { + split_player_points = player_points - round_up_score( player_points * self.point_split_keep_percent, 10 ); + self.point_split_receiver add_to_player_score( split_player_points ); + player_points -= split_player_points; + } + + if ( is_true( level.pers_upgrade_pistol_points ) ) + player_points = self maps\mp\zombies\_zm_pers_upgrades_functions::pers_upgrade_pistol_points_set_score( player_points, event, mod, damage_weapon ); + + self add_to_player_score( player_points ); + self.pers["score"] = self.score; + + if ( isdefined( level._game_module_point_adjustment ) ) + level [[ level._game_module_point_adjustment ]]( self, zombie_team, player_points ); +} + +get_points_multiplier( player ) +{ + multiplier = level.zombie_vars[player.team]["zombie_point_scalar"]; + + if ( isdefined( level.current_game_module ) && level.current_game_module == 2 ) + { + if ( isdefined( level._race_team_double_points ) && level._race_team_double_points == player._race_team ) + return multiplier; + else + return 1; + } + + return multiplier; +} + + +printDebug() +{ + for(;;) + { + if(getDvar("revive")) + { + self iPrintLn("revive dvar is defined"); + self iPrintLn("revive value : " + getDvar("revive")); + self iPrintLn("resetting revive value to 0:"); + setDvar("revive", "0"); + } + else + { + self iPrintLn("test dvar is defined"); + } + wait 5; + } +} + +showInfo() +{ + for(;;) + { + /*if (isdefined(self.afterlife)) + { + self iPrintLn("Time bomb defined"); + } + else + { + self iPrintLn("Time bomb not defined"); + }*/ + + if(isdefined(self.afterlife)) + { + self iPrintLn("TB save ready defined"); + self iPrintLn("Time bomb save_ready value : " + self.afterlife); + } + else + self iPrintLn("Tb save ready not defined"); + wait 5; + } +} + +checkAfterlifeActive() +{ + for (;;) + { + if (self.afterlife == 1) + { + if(getdvar("0_can_use_bank") != "1") + setDvar("0_can_use_bank", "1"); + if(getdvar("1_can_use_bank") != "1") + setDvar("1_can_use_bank", "1"); + if(getdvar("2_can_use_bank") != "1") + setDvar("2_can_use_bank", "1"); + if(getdvar("3_can_use_bank") != "1") + setDvar("3_can_use_bank", "1"); + if(getdvar("4_can_use_bank") != "1") + setDvar("4_can_use_bank", "1"); + if(getdvar("5_can_use_bank") != "1") + setDvar("5_can_use_bank", "1"); + if(getdvar("6_can_use_bank") != "1") + setDvar("6_can_use_bank", "1"); + if(getdvar("7_can_use_bank") != "1") + setDvar("7_can_use_bank", "1"); + } + else + { + if(getdvar("0_can_use_bank") != "") + setDvar("0_can_use_bank", ""); + if(getdvar("1_can_use_bank") != "") + setDvar("1_can_use_bank", ""); + if(getdvar("2_can_use_bank") != "") + setDvar("2_can_use_bank", ""); + if(getdvar("3_can_use_bank") != "") + setDvar("3_can_use_bank", ""); + if(getdvar("4_can_use_bank") != "") + setDvar("4_can_use_bank", ""); + if(getdvar("5_can_use_bank") != "") + setDvar("5_can_use_bank", ""); + if(getdvar("6_can_use_bank") != "") + setDvar("6_can_use_bank", ""); + if(getdvar("7_can_use_bank") != "") + setDvar("7_can_use_bank", ""); + } + wait 0.2; + } +} + +checkTimeBombActive() +{ + for (;;) + { + if (time_bomb_save_exists()) + { + if(getdvar("0_can_use_bank") != "0") + setDvar("0_can_use_bank", "0"); + if(getdvar("1_can_use_bank") != "0") + setDvar("1_can_use_bank", "0"); + if(getdvar("2_can_use_bank") != "0") + setDvar("2_can_use_bank", "0"); + if(getdvar("3_can_use_bank") != "0") + setDvar("3_can_use_bank", "0"); + if(getdvar("4_can_use_bank") != "0") + setDvar("4_can_use_bank", "0"); + if(getdvar("5_can_use_bank") != "0") + setDvar("5_can_use_bank", "0"); + if(getdvar("6_can_use_bank") != "0") + setDvar("6_can_use_bank", "0"); + if(getdvar("7_can_use_bank") != "0") + setDvar("7_can_use_bank", "0"); + } + else + { + if(getdvar("0_can_use_bank") != "") + setDvar("0_can_use_bank", ""); + if(getdvar("1_can_use_bank") != "") + setDvar("1_can_use_bank", ""); + if(getdvar("2_can_use_bank") != "") + setDvar("2_can_use_bank", ""); + if(getdvar("3_can_use_bank") != "") + setDvar("3_can_use_bank", ""); + if(getdvar("4_can_use_bank") != "") + setDvar("4_can_use_bank", ""); + if(getdvar("5_can_use_bank") != "") + setDvar("5_can_use_bank", ""); + if(getdvar("6_can_use_bank") != "") + setDvar("6_can_use_bank", ""); + if(getdvar("7_can_use_bank") != "") + setDvar("7_can_use_bank", ""); + } + wait 0.2; + } +} + +time_bomb_save_exists() +{ + return isdefined( level.time_bomb_save_data ) && isdefined( level.time_bomb_save_data.save_ready ) && level.time_bomb_save_data.save_ready; +} + + +endPlayerMoney() { + self endon("disconnect"); + for (;;) { + level waittill("end_game"); + setDvar(self getEntityNumber() + "_money", 0); + } +} + +endPlayerMoney2() { + self endon("disconnect"); + for (;;) { + level waittill("_zombie_game_over"); + setDvar(self getEntityNumber() + "_money", 0); + } +} + + +setPlayerMoney() { + level endon("end_game"); + level endon("_zombie_game_over"); + for (;;) { + if (!isAlive(self)) { + setDvar(self getEntityNumber() + "_money", 0); + } else { + setDvar(self getEntityNumber() + "_money", self.score); + } + wait 0.05; + } +} + +getPlayerByGuid(guid) { + for (i = 0; i < level.players.size; i++) { + if (isAlive(level.players[i]) && int(level.players[i] getGuid()) == int(guid)) { + return level.players[i]; + } + } + return false; +} + +playerBank() { + for (;;) { + if (getDvar("bank_withdraw") != "") { + withdraw = strTok(getDvar("bank_withdraw"), ";"); + setDvar("bank_withdraw", ""); + getPlayerByGuid(withdraw[0]).score += int(withdraw[1]); + getPlayerByGuid(withdraw[0]) iPrintLn("Withdrew ^2$" + int(withdraw[1]) + "^7 from your bank account!"); + } + if (getDvar("bank_deposit") != "") { + deposit = strTok(getDvar("bank_deposit"), ";"); + setDvar("bank_deposit", ""); + getPlayerByGuid(deposit[0]).score -= int(deposit[1]); + getPlayerByGuid(deposit[0]) iPrintLn("Deposited ^2$" + int(deposit[1]) + "^7 into your bank account!"); + } + wait 0.05; + } +} \ No newline at end of file diff --git a/t6/uncompiled mods/bo2_aats - Copie.gsc b/t6/uncompiled mods/bo2_aats - Copie.gsc new file mode 100644 index 0000000..daff08d --- /dev/null +++ b/t6/uncompiled mods/bo2_aats - Copie.gsc @@ -0,0 +1,1803 @@ +#include maps/mp/_utility; +#include common_scripts/utility; +#include maps/mp/gametypes_zm/_hud_util; +#include maps/mp/zombies/_zm_weapons; +#include maps/mp/zombies/_zm_stats; +#include maps/mp/gametypes_zm/_spawnlogic; +#include maps/mp/animscripts/traverse/shared; +#include maps/mp/animscripts/utility; +#include maps/mp/zombies/_load; +#include maps/mp/_createfx; +#include maps/mp/_music; +#include maps/mp/_busing; +#include maps/mp/_script_gen; +#include maps/mp/gametypes_zm/_globallogic_audio; +#include maps/mp/gametypes_zm/_tweakables; +#include maps/mp/_challenges; +#include maps/mp/gametypes_zm/_weapons; +#include maps/mp/_demo; +#include maps/mp/gametypes_zm/_hud_message; +#include maps/mp/gametypes_zm/_spawning; +#include maps/mp/gametypes_zm/_globallogic_utils; +#include maps/mp/gametypes_zm/_spectating; +#include maps/mp/gametypes_zm/_globallogic_spawn; +#include maps/mp/gametypes_zm/_globallogic_ui; +#include maps/mp/gametypes_zm/_hostmigration; +#include maps/mp/gametypes_zm/_globallogic_score; +#include maps/mp/gametypes_zm/_globallogic; +#include maps/mp/zombies/_zm; +#include maps/mp/zombies/_zm_ai_faller; +#include maps/mp/zombies/_zm_spawner; +#include maps/mp/zombies/_zm_pers_upgrades_functions; +#include maps/mp/zombies/_zm_pers_upgrades; +#include maps/mp/zombies/_zm_score; +#include maps/mp/zombies/_zm_powerups; +#include maps/mp/animscripts/zm_run; +#include maps/mp/animscripts/zm_death; +#include maps/mp/zombies/_zm_blockers; +#include maps/mp/animscripts/zm_shared; +#include maps/mp/animscripts/zm_utility; +#include maps/mp/zombies/_zm_ai_basic; +#include maps/mp/zombies/_zm_laststand; +#include maps/mp/zombies/_zm_net; +#include maps/mp/zombies/_zm_audio; +#include maps/mp/gametypes_zm/_zm_gametype; +#include maps/mp/_visionset_mgr; +#include maps/mp/zombies/_zm_equipment; +#include maps/mp/zombies/_zm_power; +#include maps/mp/zombies/_zm_server_throttle; +#include maps/mp/gametypes/_hud_util; +#include maps/mp/zombies/_zm_unitrigger; +#include maps/mp/zombies/_zm_zonemgr; +#include maps/mp/zombies/_zm_perks; +#include maps/mp/zombies/_zm_melee_weapon; +#include maps/mp/zombies/_zm_audio_announcer; +#include maps/mp/zombies/_zm_magicbox; +#include maps/mp/zombies/_zm_utility; +#include maps/mp/zombies/_zm_ai_dogs; +#include maps/mp/gametypes_zm/_hud_message; +#include maps/mp/zombies/_zm_game_module; +#include maps/mp/zombies/_zm_buildables; +#include codescripts/character; +#include maps/mp/zombies/_zm_weap_riotshield; +#include maps/mp/zm_transit_bus; +#include maps/mp/zm_transit_utility; +#include maps/mp/zombies/_zm_equip_turret; +#include maps/mp/zombies/_zm_mgturret; +#include maps\mp\zombies\_zm_weap_jetgun; + +#include maps/mp/zombies/_zm_ai_sloth; +#include maps/mp/zombies/_zm_ai_sloth_ffotd; +#include maps/mp/zombies/_zm_ai_sloth_utility; +#include maps/mp/zombies/_zm_ai_sloth_magicbox; +#include maps/mp/zombies/_zm_ai_sloth_crawler; +#include maps/mp/zombies/_zm_ai_sloth_buildables; + + +#include maps/mp/zombies/_zm_tombstone; +#include maps/mp/zombies/_zm_chugabud; + +main() +{ + register_player_damage_callback( ::playerdamagelastcheck ); //moved to main from init because of it not loading in origins +} + +init() +{ + isTown(); + + precacheshader("damage_feedback"); + precacheshader("hud_status_dead"); + if( getdvar( "mapname" ) == "zm_transit" ) + { + level._effect[ "jetgun_smoke_cloud" ] = loadfx( "weapon/thunder_gun/fx_thundergun_smoke_cloud" ); + } + level.custom_pap_validation = thread new_pap_trigger(); + level._poi_override = ::turned_zombie; + flag_wait( "initial_blackscreen_passed" ); + + level.original_damagecallback = level.callbackactordamage; + level.callbackactordamage = ::actor_damage_override_wrapper; + //get_players()[0] thread perks_gived(); //test tombstone and whos who aat recovery + wait 1; + level.chugabud_laststand_func = ::chugabud_laststand; //recover aat on whos who revive + + level.tombstone_spawn_func = ::tombstone_spawn; //recover aat on tombstone revive +} + + + + + + + + + + + + + + + + + + + + + + +perks_gived() +{ + wait 5; + iprintln("done"); + self give_perk("specialty_scavenger"); + bot = addtestclient(); + wait 1; + bot enableInvulnerability(); + +} + +playerdamagelastcheck( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime ) +{ + if(isdefined(self.has_cluster) && self.has_cluster && isdefined(eattacker) && eattacker == self) + { + return 0; + } + players = get_players(); + for(i=0;i= 5000 && current_weapon != "riotshield_zm" && player can_buy_weapon() && !player.is_drinking && !is_placeable_mine( current_weapon ) && !is_equipment( current_weapon ) && level.revive_tool != current_weapon && current_weapon != "none" ) + { + player.score -= 5000; + player thread maps/mp/zombies/_zm_audio::play_jingle_or_stinger( "mus_perks_packa_sting" ); + trigger setinvisibletoall(); + upgrade_as_attachment = will_upgrade_weapon_as_attachment( current_weapon ); + + player.restore_ammo = undefined; + player.restore_clip = undefined; + player.restore_stock = undefined; + player.restore_clip_size = undefined; + player.restore_max = undefined; + + player.restore_clip = player getweaponammoclip( current_weapon ); + player.restore_clip_size = weaponclipsize( current_weapon ); + player.restore_stock = player getweaponammostock( current_weapon ); + player.restore_max = weaponmaxammo( current_weapon ); + + player thread maps/mp/zombies/_zm_perks::do_knuckle_crack(); + wait .1; + player takeWeapon(current_weapon); + current_weapon = player maps/mp/zombies/_zm_weapons::switch_from_alt_weapon( current_weapon ); + self.current_weapon = current_weapon; + upgrade_name = maps/mp/zombies/_zm_weapons::get_upgrade_weapon( current_weapon, upgrade_as_attachment ); + player third_person_weapon_upgrade( current_weapon, upgrade_name, packa_rollers, perk_machine, self ); + trigger sethintstring( &"ZOMBIE_GET_UPGRADED" ); + trigger thread wait_for_pick(player, current_weapon, self.upgrade_name); + if ( isDefined( player ) ) + { + trigger setinvisibletoall(); + trigger setvisibletoplayer( player ); + } + self thread wait_for_timeout( current_weapon, packa_timer, player ); + self waittill_any( "pap_timeout", "pap_taken", "pap_player_disconnected" ); + self.current_weapon = ""; + if ( isDefined( self.worldgun ) && isDefined( self.worldgun.worldgundw ) ) + { + self.worldgun.worldgundw delete(); + } + if ( isDefined( self.worldgun ) ) + { + self.worldgun delete(); + } + trigger setinvisibletoplayer( player ); + wait 1.5; + trigger setvisibletoall(); + self.pack_player = undefined; + flag_clear( "pack_machine_in_use" ); + } + Trigger sethintstring( " Hold ^3&&1^7 for Pack-a-Punch [Cost: 5000] \n Weapons can be pack a punched multiple times" ); + wait .1; + } +} + +wait_for_pick(player, weapon, upgrade_weapon ) +{ + level endon( "pap_timeout" ); + for (;;) + { + self playloopsound( "zmb_perks_packa_ticktock" ); + self waittill( "trigger", user ); + if(user UseButtonPressed() && player == user) + { + self stoploopsound( 0.05 ); + player thread do_player_general_vox( "general", "pap_arm2", 15, 100 ); + gun = player maps/mp/zombies/_zm_weapons::get_upgrade_weapon( upgrade_weapon, 0 ); + if(is_weapon_upgraded( weapon ) ) + { + player.restore_ammo = 1; + if( weapon == "galil_upgraded_zm+reflex" || weapon == "fnfal_upgraded_zm+reflex" ) + { + level thread aats(weapon, player); //Alternative ammo type for galil and fnfal upgraded + } + else + { + level thread aats(upgrade_weapon, player); //Alternative ammo type for all other weapons + } + } + if( weapon == "galil_upgraded_zm+reflex" || weapon == "fnfal_upgraded_zm+reflex" ) + { + player giveweapon( weapon, 0, player maps/mp/zombies/_zm_weapons::get_pack_a_punch_weapon_options( weapon )); + player switchToWeapon( weapon ); + x = weapon; + } + else + { + weapon_limit = get_player_weapon_limit( player ); + player maps/mp/zombies/_zm_weapons::take_fallback_weapon(); + primaries = player getweaponslistprimaries(); + if ( isDefined( primaries ) && primaries.size >= weapon_limit ) + { + player maps/mp/zombies/_zm_weapons::weapon_give( upgrade_weapon ); + } + else + { + player giveweapon( upgrade_weapon, 0, player maps/mp/zombies/_zm_weapons::get_pack_a_punch_weapon_options( upgrade_weapon )); + } + player switchToWeapon( upgrade_weapon ); + x = upgrade_weapon; + } + + if ( isDefined( player.restore_ammo ) && player.restore_ammo ) + { + new_clip = player.restore_clip + ( weaponclipsize( x ) - player.restore_clip_size ); + new_stock = player.restore_stock + ( weaponmaxammo( x ) - player.restore_max ); + player setweaponammostock( x, new_stock ); + player setweaponammoclip( x, new_clip ); + } + level notify( "pap_taken" ); + player notify( "pap_taken" ); + break; + } + wait .1; + } +} + +aats(name, player) +{ + self endon( "death" ); + self endon( "pap_timeout" ); + self endon( "pap_player_disconnected" ); + self endon( "Pack_A_Punch_off" ); + self waittill("pap_taken"); + self thread pick_ammo(name, player); +} + +pick_ammo(name, player) +{ + player notify("new_aat"); + primaries = player getweaponslistprimaries(); + if(!isDefined(player.active_explosive_bullet)) + { + player thread explosive_bullet(); + } + if(!isDefined(player.weaponname)) + { + player.active_turned = 0; + player.has_turned = 0; + player.has_blast_furnace = 0; + player.has_fireworks = 0; + player.cooldown = 0; + player.has_explosive_bullets = 0; + player.has_thunder_wall = 0; + player.has_Headcutter = 0; + player.has_cluster = 0; + player thread aat_hitmarker(); + } + if(!isDefined(player.weaponname)) + { + player.weaponname = "x"; + } + if(!isDefined(player.last_aat)) + { + player.last_aat = 0; + } + if(!isDefined(player.aat_weapon)) + { + player.aat_weapon = []; + } + if(!isDefined(player.weapon_aats)) + { + player.weapon_aats = []; + } + aat = randomIntRange(0,8); + + /* + aats = array("Blast Furnace", "Fireworks", "Explosive", "Headcutter", "Cluster", "Turned", "Thunder Wall"); + randomize = array_randomize(aats); + aat = randomize[0]; + */ + + if(name == player.weaponname && aat == player.last_aat ) + { + return pick_ammo(name, player); + } + for(i=0; i 0 || !is_true( self.dont_die_on_me ) ) + { + self finishactordamage( inflictor, attacker, damage_override, flags, meansofdeath, weapon, vpoint, vdir, shitloc, psoffsettime, boneindex ); + } +} + +actor_damage_override( inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, shitloc, psoffsettime, boneindex ) +{ + if(isdefined(level.sloth) && self == level.sloth || isDefined(self.is_avogadro) && self.is_avogadro || isDefined(self.is_brutus) && self.is_brutus || isDefined(self.is_mechz) && self.is_mechz ) + { + return [[level.original_damagecallback]]( inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, shitloc, psoffsettime, boneindex ); + } + if(isdefined( attacker.weaponname )) + { + + if(!isDefined(self.is_turned)) + self.is_turned = 0; + + //attacker cannot damage active turned zombie + if(/*attacker.active_turned &&*/ self.is_turned) + return 0; + + if(isdefined( attacker ) && isplayer( attacker ) && !attacker.cooldown && MeansOfDeath != "MOD_MELEE" && MeansOfDeath != "MOD_IMPACT" && weapon != "knife_zm") + { + aat_cooldown_time = randomintrange(10, 16); //cooldown 10 - 15 seconds + aat_activation = randomintrange(1,11); //bullet that actives aat 1 - 10 + + zombies = getaiarray( level.zombie_team ); + if(meansofdeath == "MOD_GRENADE" || meansofdeath == "MOD_GRENADE_SPLASH" || meansofdeath == "MOD_EXPLOSIVE" || meansofdeath == "MOD_PROJECTILE") + { + if(is_weapon_upgraded( weapon )) + { + } + else + { + return [[level.original_damagecallback]]( inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, shitloc, psoffsettime, boneindex ); + } + } + if(self turned_zombie_validation() && attacker.has_turned && !attacker.active_turned) + { + turned = aat_activation; + if(turned == 1) + { + attacker.aat_actived = 1; + attacker thread cool_down(aat_cooldown_time); + self thread turned( attacker ); + } + } + if(attacker.has_cluster) + { + cluster = aat_activation; + if(cluster == 1) + { + attacker.aat_actived = 1; + attacker thread cool_down(aat_cooldown_time); + self thread cluster(); + self dodamage( self.health * 2, (0,0,0), attacker, attacker, "none", "MOD_IMPACT" ); + } + + } + if(attacker.has_Headcutter) + { + Headcutter = aat_activation; + if(Headcutter == 1) + { + attacker.aat_actived = 1; + attacker thread cool_down(aat_cooldown_time); + for( i=0; i < zombies.size; i++ ) + { + if(distance(self.origin, zombies[i].origin) <= 200) + { + if(!zombies[i].done) + { + zombies[i].done = 1; + zombies[i] thread Headcutter(attacker); + } + } + } + self dodamage( self.health * 2, (0,0,0), attacker, attacker, "none", "MOD_IMPACT" ); + } + } + if(attacker.has_thunder_wall) + { + thunder_wall = aat_activation; + if(thunder_wall == 1) + { + attacker setclientdvar( "ragdoll_enable", 1); + attacker.aat_actived = 1; + self thread thunderwall(attacker); + attacker thread cool_down(aat_cooldown_time); + self dodamage( self.health * 2, (0,0,0), attacker, attacker, "none", "MOD_IMPACT" ); + } + + } + if(attacker.has_blast_furnace) + { + blast_furnace = aat_activation; + if(blast_furnace == 1) + { + attacker.aat_actived = 1; + attacker thread cool_down(aat_cooldown_time); + flameFX=loadfx("env/fire/fx_fire_zombie_torso"); + PlayFXOnTag(flameFX,self, "j_spinelower"); + flameFX2=loadfx("env/fire/fx_fire_zombie_md"); + PlayFXOnTag(flameFX2,self,"j_spineupper"); + for( i = 0; i < zombies.size; i++ ) + { + if(distance(self.origin, zombies[i].origin) <= 220) + { + zombies[i] thread flames_fx(); + } + } + self dodamage( self.health * 2, (0,0,0), attacker, attacker, "none", "MOD_IMPACT" ); + } + } + if(attacker.has_fireworks) + { + fireworks = aat_activation; + if(fireworks == 1) + { + attacker.aat_actived = 1; + attacker thread cool_down(aat_cooldown_time); + origin = self.origin; + weapon = attacker getcurrentweapon(); + self thread spawn_weapon(origin, weapon, attacker); + self thread fireworks(origin); + self dodamage( self.health * 2, (0,0,0), attacker, attacker, "none", "MOD_IMPACT" ); + } + } + } + } + return [[level.original_damagecallback]]( inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, shitloc, psoffsettime, boneindex ); +} + +cool_down(time) +{ + self.cooldown = 1; + wait time; + self.cooldown = 0; +} + +explosive_bullet() +{ + self.active_explosive_bullet = 1; + for( ;; ) + { + self waittill( "weapon_fired" ); + explosive = randomintrange(1,5); + if(explosive == 1 && self.has_explosive_bullets && !self.cooldown) + { + self.aat_actived = 1; + self thread cool_down(randomintrange(5,11)); + forward = self gettagorigin( "tag_weapon_right" ); + end = self thread vector_scal( anglestoforward( self getplayerangles() ), 1000000 ); + crosshair_entity = bullettrace(self gettagorigin("tag_weapon_right"),self gettagorigin("tag_weapon_right")+anglestoforward(self getplayerangles())*1000000,true,self)["entity"]; + crosshair = bullettrace( forward, end, 0, self )[ "position"]; + magicbullet( self getcurrentweapon(), self gettagorigin( "j_shouldertwist_le" ), crosshair, self ); + self enableInvulnerability(); + if(isdefined(crosshair_entity)) + { + crosshair_entity playsound( "zmb_phdflop_explo" ); + playfx(loadfx("explosions/fx_default_explosion"), crosshair_entity.origin, anglestoforward( ( 0, 45, 55 ) ) ); + radiusdamage( crosshair_entity.origin, 300, 5000, 1000, self ); + } + else + { + crosshair playsound( "zmb_phdflop_explo" ); + playfx(loadfx("explosions/fx_default_explosion"), crosshair, anglestoforward( ( 0, 45, 55 ) ) ); + radiusdamage( crosshair, 300, 5000, 1000, self ); + } + wait .5; + self disableInvulnerability(); + } + wait .1; + } +} + +flames_fx() +{ + for(i = 0; i < 5; i++) + { + flameFX=loadfx("env/fire/fx_fire_zombie_torso"); + PlayFXOnTag(flameFX, self, "j_spineupper"); + if(i < 3) + { + self dodamage(self.health / 2, (0,0,0)); + } + else + { + self dodamage(self.maxhealth * 2, (0,0,0)); + } + wait 1; + } +} + +fireworks(origin) +{ + for(i=0;i<5;i++) + { + up_in_air = origin + (0,0,65); + firework = Spawn( "script_model", origin ); + firework SetModel( "tag_origin" ); + fx = PlayFxOnTag( level._effect[ "richtofen_sparks" ], firework, "tag_origin"); + firework moveto(up_in_air, 1); + wait 1; + firework delete(); + fx delete(); + } +} + +spawn_weapon(origin, weapon, attacker) +{ + attacker.firework_weapon = spawnentity( "script_model", getweaponmodel( weapon ), origin + (0,0,45), (0,0,0) + ( 0, 50, 0 )); + for(i=0;i<100;i++) + { + zombies = get_array_of_closest( attacker.firework_weapon.origin, getaiarray( level.zombie_team ), undefined, undefined, 300 ); + forward = attacker.firework_weapon.origin; + end = zombies[ 0 ] gettagorigin( "j_spineupper" ); + crosshair = bullettrace( forward, end, 0, self )[ "position"]; + attacker.firework_weapon.angles = VectorToAngles( end - attacker.firework_weapon.origin ); + if( distance(zombies[ 0 ].origin, attacker.firework_weapon.origin) <= 300) + { + magicbullet( weapon, attacker.firework_weapon.origin, crosshair, attacker.firework_weapon ); + } + wait .05; + } + attacker.firework_weapon delete(); +} + +spawnentity( class, model, origin, angle ) +{ + entity = spawn( class, origin ); + entity.angles = angle; + entity setmodel( model ); + return entity; +} + +thunderwall( attacker ) +{ + thunder_wall_blast_pos = self.origin; + ai_zombies = get_array_of_closest( thunder_wall_blast_pos, getaiarray( level.zombie_team ), undefined, undefined, 250 ); + if ( !isDefined( ai_zombies ) ) + { + return; + } + flung_zombies = 0; + max_zombies = undefined; + max_zombies = randomIntRange(5,25); + for ( i = 0; i < ai_zombies.size; i++ ) + { + if(isDefined(ai_zombies[i].is_avogadro) && ai_zombies[i].is_avogadro || isDefined(ai_zombies[i].is_brutus) && ai_zombies[i].is_brutus || isDefined(ai_zombies[i].is_mechz) && ai_zombies[i].is_mechz ) + { + //boss zombie check + } + else + { + n_random_x = RandomFloatRange( -3, 3 ); + n_random_y = RandomFloatRange( -3, 3 ); + ai_zombies[i] StartRagdoll(); + ai_zombies[i] LaunchRagdoll( (n_random_x, n_random_y, 150) ); + playfxontag( level._effect[ "jetgun_smoke_cloud"], ai_zombies[i], "J_SpineUpper" ); + ai_zombies[i] DoDamage( ai_zombies[i].health * 2, ai_zombies[i].origin, attacker, attacker, "none", "MOD_IMPACT" ); + flung_zombies++; + if ( flung_zombies >= max_zombies ) + { + break; + } + } + } +} + +Headcutter(attacker) +{ + self endon("death"); + self maps\mp\zombies\_zm_spawner::zombie_head_gib(); + for(;;) + { + wait 1; + damage = 100 * level.round_number; + self dodamage( damage, self.origin, attacker, attacker, "none", "MOD_IMPACT" ); + } +} + +cluster() +{ + if(level.round_number < 10) + { + amount = randomIntRange(1, (level.round_number * 2)); + } + else + { + amount = randomIntRange(7, level.round_number); + } + random_x = RandomFloatRange( -3,3 ); + random_y = RandomFloatRange( -3,3 ); + for(i = 0; i < amount; i++) + { + self MagicGrenadeType( "frag_grenade_zm", self.origin + (random_x, random_y, 10), (random_x, random_y, 0), 2 ); + wait .1; + } +} + +aat_hitmarker() +{ + self thread startwaiting(); + self.aat_hitmarker = newdamageindicatorhudelem( self ); + self.aat_hitmarker.horzalign = "center"; + self.aat_hitmarker.vertalign = "middle"; + self.aat_hitmarker.x = -12; + self.aat_hitmarker.y = -12; + self.aat_hitmarker.alpha = 0; + self.aat_hitmarker setshader( "damage_feedback", 24, 48 ); +} + +startwaiting() +{ + while( 1 ) + { + foreach( zombie in getaiarray( level.zombie_team ) ) + { + if( !(IsDefined( zombie.waitingfordamage )) ) + { + zombie thread aat_hitmarks(); + } + } + wait 0.25; + } +} + +aat_hitmarks() +{ + self.waitingfordamage = 1; + while( 1 ) + { + self waittill( "damage", amount, attacker, dir, point, mod ); + if(!isDefined(attacker.aat_actived)) + { + attacker.aat_actived = 0; + } + attacker.aat_hitmarker.alpha = 0; + if( isplayer( attacker ) ) + { + if(attacker.aat_actived) + { + attacker.aat_hitmarker.alpha = 1; + for(i=0;i<20;i++) + { + r = randomfloatrange(0.1, 0.9); + g = randomfloatrange(0.1, 0.9); + b = randomfloatrange(0.1, 0.9); + attacker.aat_hitmarker.color = ( r, g, b ); + if(i > 5) + { + attacker.aat_hitmarker.alpha -= .075; + } + wait .1; + } + attacker.aat_hitmarker.alpha = 0; + attacker.aat_actived = 0; + self.waitingfordamage = 0; + break; + } + } + } +} + +turned( attacker ) +{ + self.is_turned = 1; + attacker.active_turned = 1; + turned_zombie_kills = 0; + max_kills = randomIntRange(15,21); + + self thread set_zombie_run_cycle( "sprint" ); + self.custom_goalradius_override = 1000000; + + //set turned icon for zombie + //todo: icon takes zombies z origin from original ground not zombies z origin + turned_icon = newHudElem(); + turned_icon.x = self.origin[ 0 ]; + turned_icon.y = self.origin[ 1 ]; + turned_icon.z = self.origin[ 2 ] + (0,0,80); + turned_icon.color = (0,1,0); + turned_icon.isshown = 1; + turned_icon.archived = 0; + turned_icon setshader( "hud_status_dead", 4, 4 ); + turned_icon setwaypoint( 1 ); + + enemyoverride = []; + + //cannot damage player + self.team = level.players; + + //allow round change while turned zombie is alive + self.ignore_enemy_count = 1; + + if(getdvar("mapname") == "zm_tomb") + attackanim = "zm_generator_melee"; + else + attackanim = "zm_riotshield_melee"; + + if ( !self.has_legs ) + { + attackanim += "_crawl"; + } + + while(isAlive(self)) + { + turned_icon.x = self.origin[ 0 ]; + turned_icon.y = self.origin[ 1 ]; + turned_icon.z = self.origin[ 2 ] + (0,0,80); + + ai_zombies = get_array_of_closest( self.origin, getaiarray( level.zombie_team ), undefined, undefined, undefined ); + if(isdefined(ai_zombies[1])) + { + enemyoverride[0] = ai_zombies[1].origin; + enemyoverride[1] = ai_zombies[1]; + } + else + { + enemyoverride[0] = ai_zombies[0].origin; + enemyoverride[1] = ai_zombies[0]; + } + self.enemyoverride = enemyoverride; + if(distance(self.origin, ai_zombies[1].origin) < 40 && isalive(ai_zombies[1]) ) + { + angles = VectorToAngles( ai_zombies[1].origin - self.origin ); + self animscripted( self.origin, angles, attackanim ); + ai_zombies[1] dodamage(ai_zombies[1].maxhealth * 2, ai_zombies[1].origin); + turned_zombie_kills++; + + if(turned_zombie_kills > max_kills) + { + self.is_turned = 0; + wait .1; + self dodamage(self.maxhealth * 2, self.origin); + } + + wait 1; + } + else + self stopanimscripted(); + + wait .05; + } + attacker.active_turned = 0; + self.is_turned = 0; + turned_icon destroy(); +} + +turned_zombie() +{ + if(self.turned) + { + //attack zombies + } + else + { + zombie_poi = self get_zombie_point_of_interest( self.origin ); + } + return zombie_poi; +} + +turned_zombie_validation() +{ + if( IS_TRUE( self.barricade_enter ) ) + { + return false; + } + if ( IS_TRUE( self.is_traversing ) ) + { + return false; + } + if ( !IS_TRUE( self.completed_emerging_into_playable_area ) ) + { + return false; + } + if ( IS_TRUE( self.is_leaping ) ) + { + return false; + } + if ( IS_TRUE( self.is_inert ) ) + { + return false; + } + + return true; +} + +is_true(check) +{ + return(IsDefined(check) && check); +} + +save_aat() +{ + self endon("new_aat"); + self endon("disconnect"); + if(isDefined(self.saved_aat_weapons)) + self.saved_aat_weapons = []; + + if(isDefined(self.saved_aat_weapons_name)) + self.saved_aat_weapons_name = []; + + weapons = self getweaponslistprimaries(); + + if(weapons.size > 0 && isDefined(self.weapon_aats[0])) + { + self.saved_aat_weapons_name[0] = self.aat_weapon[0]; + self.saved_aat_weapons[0] = self.weapon_aats[0]; + } + else + { + self.saved_aat_weapons[2] = undefined; + self.saved_aat_weapons_name[2] = undefined; + } + + if(weapons.size > 1 && isDefined(self.weapon_aats[1])) + { + self.saved_aat_weapons_name[1] = self.aat_weapon[1]; + self.saved_aat_weapons[1] = self.weapon_aats[1]; + } + else + { + self.saved_aat_weapons[2] = undefined; + self.saved_aat_weapons_name[2] = undefined; + } + + if(weapons.size > 2 && isDefined(self.weapon_aats[2])) + { + self.saved_aat_weapons_name[2] = self.aat_weapon[2]; + self.saved_aat_weapons[2] = self.weapon_aats[2]; + } + else + { + self.saved_aat_weapons[2] = undefined; + self.saved_aat_weapons_name[2] = undefined; + } +} + +//----whos who recover aat---------------------------------------------------------------------------- + +chugabud_laststand() +{ + self endon( "player_suicide" ); + self endon( "disconnect" ); + self endon( "chugabud_bleedout" ); + self maps\mp\zombies\_zm_laststand::increment_downed_stat(); + self.ignore_insta_kill = 1; + self.health = self.maxhealth; + self maps\mp\zombies\_zm_chugabud::chugabud_save_loadout(); + self maps\mp\zombies\_zm_chugabud::chugabud_fake_death(); + wait 3; + + if ( isdefined( self.insta_killed ) && self.insta_killed || isdefined( self.disable_chugabud_corpse ) ) + create_corpse = 0; + else + create_corpse = 1; + + if ( create_corpse == 1 ) + { + if ( isdefined( level._chugabug_reject_corpse_override_func ) ) + { + reject_corpse = self [[ level._chugabug_reject_corpse_override_func ]]( self.origin ); + + if ( reject_corpse ) + create_corpse = 0; + } + } + + if ( create_corpse == 1 ) + { + self thread activate_chugabud_effects_and_audio(); + corpse = self chugabud_spawn_corpse(); + corpse thread chugabud_corpse_revive_icon( self ); + self.e_chugabud_corpse = corpse; + corpse thread chugabud_corpse_cleanup_on_spectator( self ); + + if ( isdefined( level.whos_who_client_setup ) ) + corpse setclientfield( "clientfield_whos_who_clone_glow_shader", 1 ); + } + + self chugabud_fake_revive(); + wait 0.1; + self.ignore_insta_kill = undefined; + self.disable_chugabud_corpse = undefined; + + if ( create_corpse == 0 ) + { + self notify( "chugabud_effects_cleanup" ); + return; + } + + bleedout_time = getdvarfloat( "player_lastStandBleedoutTime" ); + self thread chugabud_bleed_timeout( bleedout_time, corpse ); + self thread chugabud_handle_multiple_instances( corpse ); + + corpse waittill( "player_revived", e_reviver ); + + if ( isdefined( e_reviver ) && e_reviver == self ) + self notify( "whos_who_self_revive" ); + + self perk_abort_drinking( 0.1 ); + self maps\mp\zombies\_zm_perks::perk_set_max_health_if_jugg( "health_reboot", 1, 0 ); + self setorigin( corpse.origin ); + self setplayerangles( corpse.angles ); + + if ( self player_is_in_laststand() ) + { + self thread chugabud_laststand_cleanup( corpse, "player_revived" ); + self enableweaponcycling(); + self enableoffhandweapons(); + self auto_revive( self, 1 ); + return; + } + + self chugabud_laststand_cleanup( corpse, undefined ); +} + +chugabud_laststand_cleanup( corpse, str_notify ) +{ + if ( isdefined( str_notify ) ) + self waittill( str_notify ); + + self chugabud_give_loadout(); + self chugabud_corpse_cleanup( corpse, 1 ); +} + +chugabud_give_loadout() +{ + self takeallweapons(); + loadout = self.loadout; + primaries = self getweaponslistprimaries(); + + if ( loadout.weapons.size > 1 || primaries.size > 1 ) + { + foreach ( weapon in primaries ) + self takeweapon( weapon ); + } + + for ( i = 0; i < loadout.weapons.size; i++ ) + { + if ( !isdefined( loadout.weapons[i] ) ) + continue; + + if ( loadout.weapons[i]["name"] == "none" ) + continue; + + self maps\mp\zombies\_zm_weapons::weapondata_give( loadout.weapons[i] ); + } + + if ( loadout.current_weapon >= 0 && isdefined( loadout.weapons[loadout.current_weapon]["name"] ) ) + self switchtoweapon( loadout.weapons[loadout.current_weapon]["name"] ); + + self giveweapon( "knife_zm" ); + self maps\mp\zombies\_zm_equipment::equipment_give( self.loadout.equipment ); + loadout restore_weapons_for_chugabud( self ); + self chugabud_restore_claymore(); + self.score = loadout.score; + self.pers["score"] = loadout.score; + perk_array = maps\mp\zombies\_zm_perks::get_perk_array( 1 ); + + for ( i = 0; i < perk_array.size; i++ ) + { + perk = perk_array[i]; + self unsetperk( perk ); + self.num_perks--; + self set_perk_clientfield( perk, 0 ); + } + + if ( isdefined( loadout.perks ) && loadout.perks.size > 0 ) + { + for ( i = 0; i < loadout.perks.size; i++ ) + { + if ( self hasperk( loadout.perks[i] ) ) + continue; + + if ( loadout.perks[i] == "specialty_quickrevive" && flag( "solo_game" ) ) + level.solo_game_free_player_quickrevive = 1; + + if ( loadout.perks[i] == "specialty_finalstand" ) + continue; + + maps\mp\zombies\_zm_perks::give_perk( loadout.perks[i] ); + } + } + + self chugabud_restore_grenades(); + + if ( maps\mp\zombies\_zm_weap_cymbal_monkey::cymbal_monkey_exists() ) + { + if ( loadout.zombie_cymbal_monkey_count ) + { + self maps\mp\zombies\_zm_weap_cymbal_monkey::player_give_cymbal_monkey(); + self setweaponammoclip( "cymbal_monkey_zm", loadout.zombie_cymbal_monkey_count ); + } + } + + if(isDefined(self.saved_aat_weapons[0])) + { + self.weapon_aats[0] = self.saved_aat_weapons[0]; + self.aat_weapon[0] = self.saved_aat_weapons_name[0]; + } + else + { + self.saved_aat_weapons[0] = undefined; + self.saved_aat_weapons_name[0] = undefined; + } + if(isDefined(self.saved_aat_weapons[1])) + { + self.weapon_aats[1] = self.saved_aat_weapons[1]; + self.aat_weapon[1] = self.saved_aat_weapons_name[1]; + } + else + { + self.saved_aat_weapons[1] = undefined; + self.saved_aat_weapons_name[1] = undefined; + } + if(isDefined(self.saved_aat_weapons[2])) + { + self.weapon_aats[2] = self.saved_aat_weapons[2]; + self.aat_weapon[2] = self.saved_aat_weapons_name[2]; + } + else + { + self.saved_aat_weapons[2] = undefined; + self.saved_aat_weapons_name[2] = undefined; + } + self notify("weapon_change"); +} + +//-------tombstone recover aat------------------------------------------------------------------ + +tombstone_spawn() +{ + dc = spawn( "script_model", self.origin + vectorscale( ( 0, 0, 1 ), 40.0 ) ); + dc.angles = self.angles; + dc setmodel( "tag_origin" ); + dc_icon = spawn( "script_model", self.origin + vectorscale( ( 0, 0, 1 ), 40.0 ) ); + dc_icon.angles = self.angles; + dc_icon setmodel( "ch_tombstone1" ); + dc_icon linkto( dc ); + dc.icon = dc_icon; + dc.script_noteworthy = "player_tombstone_model"; + dc.player = self; + self thread tombstone_clear(); + dc thread tombstone_wobble(); + dc thread tombstone_revived( self ); + result = self waittill_any_return( "player_revived", "spawned_player", "disconnect" ); + + if ( result == "player_revived" || result == "disconnect" ) + { + dc notify( "tombstone_timedout" ); + dc_icon unlink(); + dc_icon delete(); + dc delete(); + return; + } + + dc thread tombstone_timeout(); + dc thread tombstone_grab(); +} + +tombstone_grab() +{ + self endon( "tombstone_timedout" ); + wait 1; + + while ( isdefined( self ) ) + { + players = get_players(); + + for ( i = 0; i < players.size; i++ ) + { + if ( players[i].is_zombie ) + continue; + + if ( isdefined( self.player ) && players[i] == self.player ) + { + tombstone_machine_triggers = getentarray( "specialty_scavenger", "script_noteworthy" ); + istombstonepowered = 0; + + foreach ( trigger in tombstone_machine_triggers ) + { + if ( isdefined( trigger.power_on ) && trigger.power_on || isdefined( trigger.turbine_power_on ) && trigger.turbine_power_on ) + istombstonepowered = 1; + } + + if ( istombstonepowered ) + { + dist = distance( players[i].origin, self.origin ); + + if ( dist < 64 ) + { + playfx( level._effect["powerup_grabbed"], self.origin ); + playfx( level._effect["powerup_grabbed_wave"], self.origin ); + players[i] tombstone_give(); + wait 0.1; + playsoundatposition( "zmb_tombstone_grab", self.origin ); + self stoploopsound(); + self.icon unlink(); + self.icon delete(); + self delete(); + self notify( "tombstone_grabbed" ); + players[i] clientnotify( "dc0" ); + players[i] notify( "dance_on_my_grave" ); + } + } + } + } + + wait_network_frame(); + } +} + +tombstone_give() +{ + dc = level.tombstones[self.tombstone_index]; + + if ( !flag( "solo_game" ) ) + { + primaries = self getweaponslistprimaries(); + + if ( dc.weapon.size > 1 || primaries.size > 1 ) + { + foreach ( weapon in primaries ) + self takeweapon( weapon ); + } + + for ( i = 0; i < dc.weapon.size; i++ ) + { + if ( !isdefined( dc.weapon[i] ) ) + continue; + + if ( dc.weapon[i] == "none" ) + continue; + + weapon = dc.weapon[i]; + stock = dc.stockcount[i]; + + if ( !self hasweapon( weapon ) ) + { + self giveweapon( weapon, 0, self maps\mp\zombies\_zm_weapons::get_pack_a_punch_weapon_options( weapon ) ); + self setweaponammoclip( weapon, weaponclipsize( weapon ) ); + self setweaponammostock( weapon, stock ); + + if ( i == dc.current_weapon ) + self switchtoweapon( weapon ); + } + } + } + + if ( isdefined( dc.hasriotshield ) && dc.hasriotshield ) + { + self maps\mp\zombies\_zm_equipment::equipment_give( "riotshield_zm" ); + + if ( isdefined( self.player_shield_reset_health ) ) + self [[ self.player_shield_reset_health ]](); + } + + dc restore_weapons_for_tombstone( self ); + + if ( isdefined( dc.hasclaymore ) && dc.hasclaymore && !self hasweapon( "claymore_zm" ) ) + { + self giveweapon( "claymore_zm" ); + self set_player_placeable_mine( "claymore_zm" ); + self setactionslot( 4, "weapon", "claymore_zm" ); + self setweaponammoclip( "claymore_zm", dc.claymoreclip ); + } + + if ( isdefined( dc.hasemp ) && dc.hasemp ) + { + self giveweapon( "emp_grenade_zm" ); + self setweaponammoclip( "emp_grenade_zm", dc.empclip ); + } + + if ( isdefined( dc.perk ) && dc.perk.size > 0 ) + { + for ( i = 0; i < dc.perk.size; i++ ) + { + if ( self hasperk( dc.perk[i] ) ) + continue; + + if ( dc.perk[i] == "specialty_quickrevive" && flag( "solo_game" ) ) + continue; + + maps\mp\zombies\_zm_perks::give_perk( dc.perk[i] ); + } + } + + if ( dc.grenade > 0 && !flag( "solo_game" ) ) + { + curgrenadecount = 0; + + if ( self hasweapon( self get_player_lethal_grenade() ) ) + self getweaponammoclip( self get_player_lethal_grenade() ); + else + self giveweapon( self get_player_lethal_grenade() ); + + self setweaponammoclip( self get_player_lethal_grenade(), dc.grenade + curgrenadecount ); + } + + if ( maps\mp\zombies\_zm_weap_cymbal_monkey::cymbal_monkey_exists() && !flag( "solo_game" ) ) + { + if ( dc.zombie_cymbal_monkey_count ) + { + self maps\mp\zombies\_zm_weap_cymbal_monkey::player_give_cymbal_monkey(); + self setweaponammoclip( "cymbal_monkey_zm", dc.zombie_cymbal_monkey_count ); + } + } + + if(isDefined(self.saved_aat_weapons[0])) + { + self.weapon_aats[0] = self.saved_aat_weapons[0]; + self.aat_weapon[0] = self.saved_aat_weapons_name[0]; + } + else + { + self.saved_aat_weapons[0] = undefined; + self.saved_aat_weapons_name[0] = undefined; + } + if(isDefined(self.saved_aat_weapons[1])) + { + self.weapon_aats[1] = self.saved_aat_weapons[1]; + self.aat_weapon[1] = self.saved_aat_weapons_name[1]; + } + else + { + self.saved_aat_weapons[1] = undefined; + self.saved_aat_weapons_name[1] = undefined; + } + if(isDefined(self.saved_aat_weapons[2])) + { + self.weapon_aats[2] = self.saved_aat_weapons[2]; + self.aat_weapon[2] = self.saved_aat_weapons_name[2]; + } + else + { + self.saved_aat_weapons[2] = undefined; + self.saved_aat_weapons_name[2] = undefined; + } + self notify("weapon_change"); +} + +//--------- + + +solo_tombstone_removal() +{ + notify( "tombstone_on" ); +} + +turn_tombstone_on() +{ + level endon("end_game"); + while ( 1 ) + { + machine = getentarray( "vending_tombstone", "targetname" ); + machine_triggers = getentarray( "vending_tombstone", "target" ); + i = 0; + while ( i < machine.size ) + { + machine[ i ] setmodel( level.machine_assets[ "tombstone" ].off_model ); + i++; + } + level thread do_initial_power_off_callback( machine, "tombstone" ); + array_thread( machine_triggers, ::set_power_on, 0 ); + level waittill( "tombstone_on" ); + i = 0; + while ( i < machine.size ) + { + machine[ i ] setmodel( level.machine_assets[ "tombstone" ].on_model ); + machine[ i ] vibrate( vectorScale( ( 0, -1, 0 ), 100 ), 0,3, 0,4, 3 ); + machine[ i ] playsound( "zmb_perks_power_on" ); + machine[ i ] thread perk_fx( "tombstone_light" ); + machine[ i ] thread play_loop_on_machine(); + i++; + } + level notify( "specialty_scavenger_power_on" ); + array_thread( machine_triggers, ::set_power_on, 1 ); + if ( isDefined( level.machine_assets[ "tombstone" ].power_on_callback ) ) + { + array_thread( machine, level.machine_assets[ "tombstone" ].power_on_callback ); + } + level waittill( "tombstone_off" ); + if ( isDefined( level.machine_assets[ "tombstone" ].power_off_callback ) ) + { + array_thread( machine, level.machine_assets[ "tombstone" ].power_off_callback ); + } + array_thread( machine, ::turn_perk_off ); + players = get_players(); + _a1718 = players; + _k1718 = getFirstArrayKey( _a1718 ); + while ( isDefined( _k1718 ) ) + { + player = _a1718[ _k1718 ]; + player.hasperkspecialtytombstone = undefined; + _k1718 = getNextArrayKey( _a1718, _k1718 ); + } + } +} + +perk_machine_spawn_init() +{ + level endon("end_game"); + 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 + "_perks_" ) + location; + pos = []; + if ( isDefined( level.override_perk_targetname ) ) + { + structs = getstructarray( level.override_perk_targetname, "targetname" ); + } + else + { + structs = getstructarray( "zm_perk_machine", "targetname" ); + } + _a3578 = structs; + _k3578 = getFirstArrayKey( _a3578 ); + while ( isDefined( _k3578 ) ) + { + struct = _a3578[ _k3578 ]; + if ( isDefined( struct.script_string ) ) + { + tokens = strtok( struct.script_string, " " ); + _a3583 = tokens; + _k3583 = getFirstArrayKey( _a3583 ); + while ( isDefined( _k3583 ) ) + { + token = _a3583[ _k3583 ]; + if ( token == match_string ) + { + pos[ pos.size ] = struct; + } + _k3583 = getNextArrayKey( _a3583, _k3583 ); + } + } + else pos[ pos.size ] = struct; + _k3578 = getNextArrayKey( _a3578, _k3578 ); + } + if ( !isDefined( pos ) || pos.size == 0 ) + { + return; + } + precachemodel( "zm_collision_perks1" ); + i = 0; + while ( i < pos.size ) + { + 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.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 ) + { + bump_trigger = undefined; + } + else + { + 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" ) + { + 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.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 ) ) + { + use_trigger.blocker_model = pos[ i ].blocker_model; + } + if ( isDefined( pos[ i ].script_int ) ) + { + perk_machine.script_int = pos[ i ].script_int; + } + if ( isDefined( pos[ i ].turn_on_notify ) ) + { + perk_machine.turn_on_notify = pos[ i ].turn_on_notify; + } + if ( perk == "specialty_scavenger" || perk == "specialty_scavenger_upgrade" ) + { + use_trigger.script_sound = "mus_perks_tombstone_jingle"; + use_trigger.script_string = "tombstone_perk"; + use_trigger.script_label = "mus_perks_tombstone_sting"; + use_trigger.target = "vending_tombstone"; + perk_machine.script_string = "tombstone_perk"; + perk_machine.targetname = "vending_tombstone"; + if ( isDefined( bump_trigger ) ) + { + bump_trigger.script_string = "tombstone_perk"; + } + } + 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 ); + } + } + i++; + } +} + +isTown() +{ + if (isDefined(level.zombiemode_using_tombstone_perk) && level.zombiemode_using_tombstone_perk) + { + level thread perk_machine_spawn_init(); + thread solo_tombstone_removal(); + thread turn_tombstone_on(); + } +} diff --git a/t6/uncompiled mods/bo2_aats-compiled.gsc b/t6/uncompiled mods/bo2_aats-compiled.gsc new file mode 100644 index 0000000000000000000000000000000000000000..34ac9ae8e1da859276ec43f7f8f72370fbf32899 GIT binary patch literal 58416 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 literal 0 HcmV?d00001 diff --git a/t6/uncompiled mods/bo2_aats.gsc b/t6/uncompiled mods/bo2_aats.gsc new file mode 100644 index 0000000..eac1d7e --- /dev/null +++ b/t6/uncompiled mods/bo2_aats.gsc @@ -0,0 +1,1769 @@ +#include maps/mp/_utility; +#include common_scripts/utility; +#include maps/mp/gametypes_zm/_hud_util; +#include maps/mp/zombies/_zm_weapons; +#include maps/mp/zombies/_zm_stats; +#include maps/mp/gametypes_zm/_spawnlogic; +#include maps/mp/animscripts/traverse/shared; +#include maps/mp/animscripts/utility; +#include maps/mp/zombies/_load; +#include maps/mp/_createfx; +#include maps/mp/_music; +#include maps/mp/_busing; +#include maps/mp/_script_gen; +#include maps/mp/gametypes_zm/_globallogic_audio; +#include maps/mp/gametypes_zm/_tweakables; +#include maps/mp/_challenges; +#include maps/mp/gametypes_zm/_weapons; +#include maps/mp/_demo; +#include maps/mp/gametypes_zm/_hud_message; +#include maps/mp/gametypes_zm/_spawning; +#include maps/mp/gametypes_zm/_globallogic_utils; +#include maps/mp/gametypes_zm/_spectating; +#include maps/mp/gametypes_zm/_globallogic_spawn; +#include maps/mp/gametypes_zm/_globallogic_ui; +#include maps/mp/gametypes_zm/_hostmigration; +#include maps/mp/gametypes_zm/_globallogic_score; +#include maps/mp/gametypes_zm/_globallogic; +#include maps/mp/zombies/_zm; +#include maps/mp/zombies/_zm_ai_faller; +#include maps/mp/zombies/_zm_spawner; +#include maps/mp/zombies/_zm_pers_upgrades_functions; +#include maps/mp/zombies/_zm_pers_upgrades; +#include maps/mp/zombies/_zm_score; +#include maps/mp/zombies/_zm_powerups; +#include maps/mp/animscripts/zm_run; +#include maps/mp/animscripts/zm_death; +#include maps/mp/zombies/_zm_blockers; +#include maps/mp/animscripts/zm_shared; +#include maps/mp/animscripts/zm_utility; +#include maps/mp/zombies/_zm_ai_basic; +#include maps/mp/zombies/_zm_laststand; +#include maps/mp/zombies/_zm_net; +#include maps/mp/zombies/_zm_audio; +#include maps/mp/gametypes_zm/_zm_gametype; +#include maps/mp/_visionset_mgr; +#include maps/mp/zombies/_zm_equipment; +#include maps/mp/zombies/_zm_power; +#include maps/mp/zombies/_zm_server_throttle; +#include maps/mp/gametypes/_hud_util; +#include maps/mp/zombies/_zm_unitrigger; +#include maps/mp/zombies/_zm_zonemgr; +#include maps/mp/zombies/_zm_perks; +#include maps/mp/zombies/_zm_melee_weapon; +#include maps/mp/zombies/_zm_audio_announcer; +#include maps/mp/zombies/_zm_magicbox; +#include maps/mp/zombies/_zm_utility; +#include maps/mp/zombies/_zm_ai_dogs; +#include maps/mp/gametypes_zm/_hud_message; +#include maps/mp/zombies/_zm_game_module; +#include maps/mp/zombies/_zm_buildables; +#include codescripts/character; +#include maps/mp/zombies/_zm_weap_riotshield; +#include maps/mp/zm_transit_bus; +#include maps/mp/zm_transit_utility; +#include maps/mp/zombies/_zm_equip_turret; +#include maps/mp/zombies/_zm_mgturret; +#include maps\mp\zombies\_zm_weap_jetgun; + +#include maps/mp/zombies/_zm_ai_sloth; +#include maps/mp/zombies/_zm_ai_sloth_ffotd; +#include maps/mp/zombies/_zm_ai_sloth_utility; +#include maps/mp/zombies/_zm_ai_sloth_magicbox; +#include maps/mp/zombies/_zm_ai_sloth_crawler; +#include maps/mp/zombies/_zm_ai_sloth_buildables; + + +#include maps/mp/zombies/_zm_tombstone; +#include maps/mp/zombies/_zm_chugabud; + +main() +{ + register_player_damage_callback( ::playerdamagelastcheck ); //moved to main from init because of it not loading in origins +} + +init() +{ + //isTown(); tombstone fix + + precacheshader("damage_feedback"); + precacheshader("hud_status_dead"); + if( getdvar( "mapname" ) == "zm_transit" ) + { + level._effect[ "jetgun_smoke_cloud" ] = loadfx( "weapon/thunder_gun/fx_thundergun_smoke_cloud" ); + } + level.custom_pap_validation = thread new_pap_trigger(); + level._poi_override = ::turned_zombie; + flag_wait( "initial_blackscreen_passed" ); + + level.original_damagecallback = level.callbackactordamage; + level.callbackactordamage = ::actor_damage_override_wrapper; + //get_players()[0] thread perks_gived(); //test tombstone and whos who aat recovery + wait 1; + level.chugabud_laststand_func = ::chugabud_laststand; //recover aat on whos who revive + + level.tombstone_spawn_func = ::tombstone_spawn; //recover aat on tombstone revive +} + +perks_gived() +{ + wait 5; + iprintln("done"); + self give_perk("specialty_scavenger"); + bot = addtestclient(); + wait 1; + bot enableInvulnerability(); + +} + +playerdamagelastcheck( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime ) +{ + if(isdefined(self.has_cluster) && self.has_cluster && isdefined(eattacker) && eattacker == self) + { + return 0; + } + players = get_players(); + for(i=0;i= 5000 && current_weapon != "riotshield_zm" && player can_buy_weapon() && !player.is_drinking && !is_placeable_mine( current_weapon ) && !is_equipment( current_weapon ) && level.revive_tool != current_weapon && current_weapon != "none" ) + { + player.score -= 5000; + player thread maps/mp/zombies/_zm_audio::play_jingle_or_stinger( "mus_perks_packa_sting" ); + trigger setinvisibletoall(); + upgrade_as_attachment = will_upgrade_weapon_as_attachment( current_weapon ); + + player.restore_ammo = undefined; + player.restore_clip = undefined; + player.restore_stock = undefined; + player.restore_clip_size = undefined; + player.restore_max = undefined; + + player.restore_clip = player getweaponammoclip( current_weapon ); + player.restore_clip_size = weaponclipsize( current_weapon ); + player.restore_stock = player getweaponammostock( current_weapon ); + player.restore_max = weaponmaxammo( current_weapon ); + + player thread maps/mp/zombies/_zm_perks::do_knuckle_crack(); + wait .1; + player takeWeapon(current_weapon); + current_weapon = player maps/mp/zombies/_zm_weapons::switch_from_alt_weapon( current_weapon ); + self.current_weapon = current_weapon; + upgrade_name = maps/mp/zombies/_zm_weapons::get_upgrade_weapon( current_weapon, upgrade_as_attachment ); + player third_person_weapon_upgrade( current_weapon, upgrade_name, packa_rollers, perk_machine, self ); + trigger sethintstring( &"ZOMBIE_GET_UPGRADED" ); + trigger thread wait_for_pick(player, current_weapon, self.upgrade_name); + if ( isDefined( player ) ) + { + trigger setinvisibletoall(); + trigger setvisibletoplayer( player ); + } + self thread wait_for_timeout( current_weapon, packa_timer, player ); + self waittill_any( "pap_timeout", "pap_taken", "pap_player_disconnected" ); + self.current_weapon = ""; + if ( isDefined( self.worldgun ) && isDefined( self.worldgun.worldgundw ) ) + { + self.worldgun.worldgundw delete(); + } + if ( isDefined( self.worldgun ) ) + { + self.worldgun delete(); + } + trigger setinvisibletoplayer( player ); + wait 1.5; + trigger setvisibletoall(); + self.pack_player = undefined; + flag_clear( "pack_machine_in_use" ); + } + Trigger sethintstring( " Hold ^3&&1^7 for Pack-a-Punch [Cost: 5000] \n Weapons can be pack a punched multiple times" ); + wait .1; + } +} + +wait_for_pick(player, weapon, upgrade_weapon ) +{ + level endon( "pap_timeout" ); + for (;;) + { + self playloopsound( "zmb_perks_packa_ticktock" ); + self waittill( "trigger", user ); + if(user UseButtonPressed() && player == user) + { + self stoploopsound( 0.05 ); + player thread do_player_general_vox( "general", "pap_arm2", 15, 100 ); + gun = player maps/mp/zombies/_zm_weapons::get_upgrade_weapon( upgrade_weapon, 0 ); + if(is_weapon_upgraded( weapon ) ) + { + player.restore_ammo = 1; + if( weapon == "galil_upgraded_zm+reflex" || weapon == "fnfal_upgraded_zm+reflex" ) + { + level thread aats(weapon, player); //Alternative ammo type for galil and fnfal upgraded + } + else + { + level thread aats(upgrade_weapon, player); //Alternative ammo type for all other weapons + } + } + if( weapon == "galil_upgraded_zm+reflex" || weapon == "fnfal_upgraded_zm+reflex" ) + { + player giveweapon( weapon, 0, player maps/mp/zombies/_zm_weapons::get_pack_a_punch_weapon_options( weapon )); + player switchToWeapon( weapon ); + x = weapon; + } + else + { + weapon_limit = get_player_weapon_limit( player ); + player maps/mp/zombies/_zm_weapons::take_fallback_weapon(); + primaries = player getweaponslistprimaries(); + if ( isDefined( primaries ) && primaries.size >= weapon_limit ) + { + player maps/mp/zombies/_zm_weapons::weapon_give( upgrade_weapon ); + } + else + { + player giveweapon( upgrade_weapon, 0, player maps/mp/zombies/_zm_weapons::get_pack_a_punch_weapon_options( upgrade_weapon )); + } + player switchToWeapon( upgrade_weapon ); + x = upgrade_weapon; + } + + if ( isDefined( player.restore_ammo ) && player.restore_ammo ) + { + new_clip = player.restore_clip + ( weaponclipsize( x ) - player.restore_clip_size ); + new_stock = player.restore_stock + ( weaponmaxammo( x ) - player.restore_max ); + player setweaponammostock( x, new_stock ); + player setweaponammoclip( x, new_clip ); + } + level notify( "pap_taken" ); + player notify( "pap_taken" ); + break; + } + wait .1; + } +} + +aats(name, player) +{ + self endon( "death" ); + self endon( "pap_timeout" ); + self endon( "pap_player_disconnected" ); + self endon( "Pack_A_Punch_off" ); + self waittill("pap_taken"); + self thread pick_ammo(name, player); +} + +pick_ammo(name, player) +{ + player notify("new_aat"); + primaries = player getweaponslistprimaries(); + if(!isDefined(player.active_explosive_bullet)) + { + player thread explosive_bullet(); + } + if(!isDefined(player.weaponname)) + { + player.active_turned = 0; + player.has_turned = 0; + player.has_blast_furnace = 0; + player.has_fireworks = 0; + player.cooldown = 0; + player.has_explosive_bullets = 0; + player.has_thunder_wall = 0; + player.has_Headcutter = 0; + player.has_cluster = 0; + player thread aat_hitmarker(); + } + if(!isDefined(player.weaponname)) + { + player.weaponname = "x"; + } + if(!isDefined(player.last_aat)) + { + player.last_aat = 0; + } + if(!isDefined(player.aat_weapon)) + { + player.aat_weapon = []; + } + if(!isDefined(player.weapon_aats)) + { + player.weapon_aats = []; + } + aat = randomIntRange(0,8); + + /* + aats = array("Blast Furnace", "Fireworks", "Explosive", "Headcutter", "Cluster", "Turned", "Thunder Wall"); + randomize = array_randomize(aats); + aat = randomize[0]; + */ + + if(name == player.weaponname && aat == player.last_aat ) + { + return pick_ammo(name, player); + } + for(i=0; i 0 || !is_true( self.dont_die_on_me ) ) + { + self finishactordamage( inflictor, attacker, damage_override, flags, meansofdeath, weapon, vpoint, vdir, shitloc, psoffsettime, boneindex ); + } +} + +actor_damage_override( inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, shitloc, psoffsettime, boneindex ) +{ + if(isdefined(level.sloth) && self == level.sloth || isDefined(self.is_avogadro) && self.is_avogadro || isDefined(self.is_brutus) && self.is_brutus || isDefined(self.is_mechz) && self.is_mechz ) + { + return [[level.original_damagecallback]]( inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, shitloc, psoffsettime, boneindex ); + } + if(isdefined( attacker.weaponname )) + { + + if(!isDefined(self.is_turned)) + self.is_turned = 0; + + //attacker cannot damage active turned zombie + if(/*attacker.active_turned &&*/ self.is_turned) + return 0; + + if(isdefined( attacker ) && isplayer( attacker ) && !attacker.cooldown && MeansOfDeath != "MOD_MELEE" && MeansOfDeath != "MOD_IMPACT" && weapon != "knife_zm") + { + aat_cooldown_time = randomintrange(10, 16); //cooldown 10 - 15 seconds + aat_activation = randomintrange(1,11); //bullet that actives aat 1 - 10 + + zombies = getaiarray( level.zombie_team ); + if(meansofdeath == "MOD_GRENADE" || meansofdeath == "MOD_GRENADE_SPLASH" || meansofdeath == "MOD_EXPLOSIVE" || meansofdeath == "MOD_PROJECTILE") + { + if(is_weapon_upgraded( weapon )) + { + } + else + { + return [[level.original_damagecallback]]( inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, shitloc, psoffsettime, boneindex ); + } + } + if(self turned_zombie_validation() && attacker.has_turned && !attacker.active_turned) + { + turned = aat_activation; + if(turned == 1) + { + attacker.aat_actived = 1; + attacker thread cool_down(aat_cooldown_time); + self thread turned( attacker ); + } + } + if(attacker.has_cluster) + { + cluster = aat_activation; + if(cluster == 1) + { + attacker.aat_actived = 1; + attacker thread cool_down(aat_cooldown_time); + self thread cluster(); + self dodamage( self.health * 2, (0,0,0), attacker, attacker, "none", "MOD_IMPACT" ); + } + + } + if(attacker.has_Headcutter) + { + Headcutter = aat_activation; + if(Headcutter == 1) + { + attacker.aat_actived = 1; + attacker thread cool_down(aat_cooldown_time); + for( i=0; i < zombies.size; i++ ) + { + if(distance(self.origin, zombies[i].origin) <= 200) + { + if(!zombies[i].done) + { + zombies[i].done = 1; + zombies[i] thread Headcutter(attacker); + } + } + } + self dodamage( self.health * 2, (0,0,0), attacker, attacker, "none", "MOD_IMPACT" ); + } + } + if(attacker.has_thunder_wall) + { + thunder_wall = aat_activation; + if(thunder_wall == 1) + { + attacker setclientdvar( "ragdoll_enable", 1); + attacker.aat_actived = 1; + self thread thunderwall(attacker); + attacker thread cool_down(aat_cooldown_time); + self dodamage( self.health * 2, (0,0,0), attacker, attacker, "none", "MOD_IMPACT" ); + } + + } + if(attacker.has_blast_furnace) + { + blast_furnace = aat_activation; + if(blast_furnace == 1) + { + attacker.aat_actived = 1; + attacker thread cool_down(aat_cooldown_time); + flameFX=loadfx("env/fire/fx_fire_zombie_torso"); + PlayFXOnTag(flameFX,self, "j_spinelower"); + flameFX2=loadfx("env/fire/fx_fire_zombie_md"); + PlayFXOnTag(flameFX2,self,"j_spineupper"); + for( i = 0; i < zombies.size; i++ ) + { + if(distance(self.origin, zombies[i].origin) <= 220) + { + zombies[i] thread flames_fx(); + } + } + self dodamage( self.health * 2, (0,0,0), attacker, attacker, "none", "MOD_IMPACT" ); + } + } + if(attacker.has_fireworks) + { + fireworks = aat_activation; + if(fireworks == 1) + { + attacker.aat_actived = 1; + attacker thread cool_down(aat_cooldown_time); + origin = self.origin; + weapon = attacker getcurrentweapon(); + self thread spawn_weapon(origin, weapon, attacker); + self thread fireworks(origin); + self dodamage( self.health * 2, (0,0,0), attacker, attacker, "none", "MOD_IMPACT" ); + } + } + } + } + return [[level.original_damagecallback]]( inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, shitloc, psoffsettime, boneindex ); +} + +cool_down(time) +{ + self.cooldown = 1; + wait time; + self.cooldown = 0; +} + +explosive_bullet() +{ + self.active_explosive_bullet = 1; + for( ;; ) + { + self waittill( "weapon_fired" ); + explosive = randomintrange(1,5); + if(explosive == 1 && self.has_explosive_bullets && !self.cooldown) + { + self.aat_actived = 1; + self thread cool_down(randomintrange(5,11)); + forward = self gettagorigin( "tag_weapon_right" ); + end = self thread vector_scal( anglestoforward( self getplayerangles() ), 1000000 ); + crosshair_entity = bullettrace(self gettagorigin("tag_weapon_right"),self gettagorigin("tag_weapon_right")+anglestoforward(self getplayerangles())*1000000,true,self)["entity"]; + crosshair = bullettrace( forward, end, 0, self )[ "position"]; + magicbullet( self getcurrentweapon(), self gettagorigin( "j_shouldertwist_le" ), crosshair, self ); + self enableInvulnerability(); + if(isdefined(crosshair_entity)) + { + crosshair_entity playsound( "zmb_phdflop_explo" ); + playfx(loadfx("explosions/fx_default_explosion"), crosshair_entity.origin, anglestoforward( ( 0, 45, 55 ) ) ); + radiusdamage( crosshair_entity.origin, 300, 5000, 1000, self ); + } + else + { + crosshair playsound( "zmb_phdflop_explo" ); + playfx(loadfx("explosions/fx_default_explosion"), crosshair, anglestoforward( ( 0, 45, 55 ) ) ); + radiusdamage( crosshair, 300, 5000, 1000, self ); + } + wait .5; + self disableInvulnerability(); + } + wait .1; + } +} + +flames_fx() +{ + for(i = 0; i < 5; i++) + { + flameFX=loadfx("env/fire/fx_fire_zombie_torso"); + PlayFXOnTag(flameFX, self, "j_spineupper"); + if(i < 3) + { + self dodamage(self.health / 2, (0,0,0)); + } + else + { + self dodamage(self.maxhealth * 2, (0,0,0)); + } + wait 1; + } +} + +fireworks(origin) +{ + for(i=0;i<5;i++) + { + up_in_air = origin + (0,0,65); + firework = Spawn( "script_model", origin ); + firework SetModel( "tag_origin" ); + fx = PlayFxOnTag( level._effect[ "richtofen_sparks" ], firework, "tag_origin"); + firework moveto(up_in_air, 1); + wait 1; + firework delete(); + fx delete(); + } +} + +spawn_weapon(origin, weapon, attacker) +{ + attacker.firework_weapon = spawnentity( "script_model", getweaponmodel( weapon ), origin + (0,0,45), (0,0,0) + ( 0, 50, 0 )); + for(i=0;i<100;i++) + { + zombies = get_array_of_closest( attacker.firework_weapon.origin, getaiarray( level.zombie_team ), undefined, undefined, 300 ); + forward = attacker.firework_weapon.origin; + end = zombies[ 0 ] gettagorigin( "j_spineupper" ); + crosshair = bullettrace( forward, end, 0, self )[ "position"]; + attacker.firework_weapon.angles = VectorToAngles( end - attacker.firework_weapon.origin ); + if( distance(zombies[ 0 ].origin, attacker.firework_weapon.origin) <= 300) + { + magicbullet( weapon, attacker.firework_weapon.origin, crosshair, attacker.firework_weapon ); + } + wait .05; + } + attacker.firework_weapon delete(); +} + +spawnentity( class, model, origin, angle ) +{ + entity = spawn( class, origin ); + entity.angles = angle; + entity setmodel( model ); + return entity; +} + +thunderwall( attacker ) +{ + thunder_wall_blast_pos = self.origin; + ai_zombies = get_array_of_closest( thunder_wall_blast_pos, getaiarray( level.zombie_team ), undefined, undefined, 250 ); + if ( !isDefined( ai_zombies ) ) + { + return; + } + flung_zombies = 0; + max_zombies = undefined; + max_zombies = randomIntRange(5,25); + for ( i = 0; i < ai_zombies.size; i++ ) + { + if(isDefined(ai_zombies[i].is_avogadro) && ai_zombies[i].is_avogadro || isDefined(ai_zombies[i].is_brutus) && ai_zombies[i].is_brutus || isDefined(ai_zombies[i].is_mechz) && ai_zombies[i].is_mechz ) + { + //boss zombie check + } + else + { + n_random_x = RandomFloatRange( -3, 3 ); + n_random_y = RandomFloatRange( -3, 3 ); + ai_zombies[i] StartRagdoll(); + ai_zombies[i] LaunchRagdoll( (n_random_x, n_random_y, 150) ); + playfxontag( level._effect[ "jetgun_smoke_cloud"], ai_zombies[i], "J_SpineUpper" ); + ai_zombies[i] DoDamage( ai_zombies[i].health * 2, ai_zombies[i].origin, attacker, attacker, "none", "MOD_IMPACT" ); + flung_zombies++; + if ( flung_zombies >= max_zombies ) + { + break; + } + } + } +} + +Headcutter(attacker) +{ + self endon("death"); + self maps\mp\zombies\_zm_spawner::zombie_head_gib(); + for(;;) + { + wait 1; + damage = 100 * level.round_number; + self dodamage( damage, self.origin, attacker, attacker, "none", "MOD_IMPACT" ); + } +} + +cluster() +{ + if(level.round_number < 10) + { + amount = randomIntRange(1, (level.round_number * 2)); + } + else + { + amount = randomIntRange(7, level.round_number); + } + random_x = RandomFloatRange( -3,3 ); + random_y = RandomFloatRange( -3,3 ); + for(i = 0; i < amount; i++) + { + self MagicGrenadeType( "frag_grenade_zm", self.origin + (random_x, random_y, 10), (random_x, random_y, 0), 2 ); + wait .1; + } +} + +aat_hitmarker() +{ + self thread startwaiting(); + self.aat_hitmarker = newdamageindicatorhudelem( self ); + self.aat_hitmarker.horzalign = "center"; + self.aat_hitmarker.vertalign = "middle"; + self.aat_hitmarker.x = -12; + self.aat_hitmarker.y = -12; + self.aat_hitmarker.alpha = 0; + self.aat_hitmarker setshader( "damage_feedback", 24, 48 ); +} + +startwaiting() +{ + while( 1 ) + { + foreach( zombie in getaiarray( level.zombie_team ) ) + { + if( !(IsDefined( zombie.waitingfordamage )) ) + { + zombie thread aat_hitmarks(); + } + } + wait 0.25; + } +} + +aat_hitmarks() +{ + self.waitingfordamage = 1; + while( 1 ) + { + self waittill( "damage", amount, attacker, dir, point, mod ); + if(!isDefined(attacker.aat_actived)) + { + attacker.aat_actived = 0; + } + attacker.aat_hitmarker.alpha = 0; + if( isplayer( attacker ) ) + { + if(attacker.aat_actived) + { + attacker.aat_hitmarker.alpha = 1; + for(i=0;i<20;i++) + { + r = randomfloatrange(0.1, 0.9); + g = randomfloatrange(0.1, 0.9); + b = randomfloatrange(0.1, 0.9); + attacker.aat_hitmarker.color = ( r, g, b ); + if(i > 5) + { + attacker.aat_hitmarker.alpha -= .075; + } + wait .1; + } + attacker.aat_hitmarker.alpha = 0; + attacker.aat_actived = 0; + self.waitingfordamage = 0; + break; + } + } + } +} + +turned( attacker ) +{ + self.is_turned = 1; + attacker.active_turned = 1; + turned_zombie_kills = 0; + max_kills = randomIntRange(15,21); + + self thread set_zombie_run_cycle( "sprint" ); + self.custom_goalradius_override = 1000000; + + //set turned icon for zombie + //todo: icon takes zombies z origin from original ground not zombies z origin + turned_icon = newHudElem(); + turned_icon.x = self.origin[ 0 ]; + turned_icon.y = self.origin[ 1 ]; + turned_icon.z = self.origin[ 2 ] + (0,0,80); + turned_icon.color = (0,1,0); + turned_icon.isshown = 1; + turned_icon.archived = 0; + turned_icon setshader( "hud_status_dead", 4, 4 ); + turned_icon setwaypoint( 1 ); + + enemyoverride = []; + + //cannot damage player + self.team = level.players; + + //allow round change while turned zombie is alive + self.ignore_enemy_count = 1; + + if(getdvar("mapname") == "zm_tomb") + attackanim = "zm_generator_melee"; + else + attackanim = "zm_riotshield_melee"; + + if ( !self.has_legs ) + { + attackanim += "_crawl"; + } + + while(isAlive(self)) + { + turned_icon.x = self.origin[ 0 ]; + turned_icon.y = self.origin[ 1 ]; + turned_icon.z = self.origin[ 2 ] + (0,0,80); + + ai_zombies = get_array_of_closest( self.origin, getaiarray( level.zombie_team ), undefined, undefined, undefined ); + if(isdefined(ai_zombies[1])) + { + enemyoverride[0] = ai_zombies[1].origin; + enemyoverride[1] = ai_zombies[1]; + } + else + { + enemyoverride[0] = ai_zombies[0].origin; + enemyoverride[1] = ai_zombies[0]; + } + self.enemyoverride = enemyoverride; + if(distance(self.origin, ai_zombies[1].origin) < 40 && isalive(ai_zombies[1]) ) + { + angles = VectorToAngles( ai_zombies[1].origin - self.origin ); + self animscripted( self.origin, angles, attackanim ); + ai_zombies[1] dodamage(ai_zombies[1].maxhealth * 2, ai_zombies[1].origin); + turned_zombie_kills++; + + if(turned_zombie_kills > max_kills) + { + self.is_turned = 0; + wait .1; + self dodamage(self.maxhealth * 2, self.origin); + } + + wait 1; + } + else + self stopanimscripted(); + + wait .05; + } + attacker.active_turned = 0; + self.is_turned = 0; + turned_icon destroy(); +} + +turned_zombie() +{ + if(self.turned) + { + //attack zombies + } + else + { + zombie_poi = self get_zombie_point_of_interest( self.origin ); + } + return zombie_poi; +} + +turned_zombie_validation() +{ + if( IS_TRUE( self.barricade_enter ) ) + { + return false; + } + if ( IS_TRUE( self.is_traversing ) ) + { + return false; + } + if ( !IS_TRUE( self.completed_emerging_into_playable_area ) ) + { + return false; + } + if ( IS_TRUE( self.is_leaping ) ) + { + return false; + } + if ( IS_TRUE( self.is_inert ) ) + { + return false; + } + + return true; +} + +is_true(check) +{ + return(IsDefined(check) && check); +} + +save_aat() +{ + self endon("new_aat"); + self endon("disconnect"); + if(isDefined(self.saved_aat_weapons)) + self.saved_aat_weapons = []; + + if(isDefined(self.saved_aat_weapons_name)) + self.saved_aat_weapons_name = []; + + weapons = self getweaponslistprimaries(); + + if(weapons.size > 0 && isDefined(self.weapon_aats[0])) + { + self.saved_aat_weapons_name[0] = self.aat_weapon[0]; + self.saved_aat_weapons[0] = self.weapon_aats[0]; + } + else + { + self.saved_aat_weapons[2] = undefined; + self.saved_aat_weapons_name[2] = undefined; + } + + if(weapons.size > 1 && isDefined(self.weapon_aats[1])) + { + self.saved_aat_weapons_name[1] = self.aat_weapon[1]; + self.saved_aat_weapons[1] = self.weapon_aats[1]; + } + else + { + self.saved_aat_weapons[2] = undefined; + self.saved_aat_weapons_name[2] = undefined; + } + + if(weapons.size > 2 && isDefined(self.weapon_aats[2])) + { + self.saved_aat_weapons_name[2] = self.aat_weapon[2]; + self.saved_aat_weapons[2] = self.weapon_aats[2]; + } + else + { + self.saved_aat_weapons[2] = undefined; + self.saved_aat_weapons_name[2] = undefined; + } +} + +//----whos who recover aat---------------------------------------------------------------------------- + +chugabud_laststand() +{ + self endon( "player_suicide" ); + self endon( "disconnect" ); + self endon( "chugabud_bleedout" ); + self maps\mp\zombies\_zm_laststand::increment_downed_stat(); + self.ignore_insta_kill = 1; + self.health = self.maxhealth; + self maps\mp\zombies\_zm_chugabud::chugabud_save_loadout(); + self maps\mp\zombies\_zm_chugabud::chugabud_fake_death(); + wait 3; + + if ( isdefined( self.insta_killed ) && self.insta_killed || isdefined( self.disable_chugabud_corpse ) ) + create_corpse = 0; + else + create_corpse = 1; + + if ( create_corpse == 1 ) + { + if ( isdefined( level._chugabug_reject_corpse_override_func ) ) + { + reject_corpse = self [[ level._chugabug_reject_corpse_override_func ]]( self.origin ); + + if ( reject_corpse ) + create_corpse = 0; + } + } + + if ( create_corpse == 1 ) + { + self thread activate_chugabud_effects_and_audio(); + corpse = self chugabud_spawn_corpse(); + corpse thread chugabud_corpse_revive_icon( self ); + self.e_chugabud_corpse = corpse; + corpse thread chugabud_corpse_cleanup_on_spectator( self ); + + if ( isdefined( level.whos_who_client_setup ) ) + corpse setclientfield( "clientfield_whos_who_clone_glow_shader", 1 ); + } + + self chugabud_fake_revive(); + wait 0.1; + self.ignore_insta_kill = undefined; + self.disable_chugabud_corpse = undefined; + + if ( create_corpse == 0 ) + { + self notify( "chugabud_effects_cleanup" ); + return; + } + + bleedout_time = getdvarfloat( "player_lastStandBleedoutTime" ); + self thread chugabud_bleed_timeout( bleedout_time, corpse ); + self thread chugabud_handle_multiple_instances( corpse ); + + corpse waittill( "player_revived", e_reviver ); + + if ( isdefined( e_reviver ) && e_reviver == self ) + self notify( "whos_who_self_revive" ); + + self perk_abort_drinking( 0.1 ); + self maps\mp\zombies\_zm_perks::perk_set_max_health_if_jugg( "health_reboot", 1, 0 ); + self setorigin( corpse.origin ); + self setplayerangles( corpse.angles ); + + if ( self player_is_in_laststand() ) + { + self thread chugabud_laststand_cleanup( corpse, "player_revived" ); + self enableweaponcycling(); + self enableoffhandweapons(); + self auto_revive( self, 1 ); + return; + } + + self chugabud_laststand_cleanup( corpse, undefined ); +} + +chugabud_laststand_cleanup( corpse, str_notify ) +{ + if ( isdefined( str_notify ) ) + self waittill( str_notify ); + + self chugabud_give_loadout(); + self chugabud_corpse_cleanup( corpse, 1 ); +} + +chugabud_give_loadout() +{ + self takeallweapons(); + loadout = self.loadout; + primaries = self getweaponslistprimaries(); + + if ( loadout.weapons.size > 1 || primaries.size > 1 ) + { + foreach ( weapon in primaries ) + self takeweapon( weapon ); + } + + for ( i = 0; i < loadout.weapons.size; i++ ) + { + if ( !isdefined( loadout.weapons[i] ) ) + continue; + + if ( loadout.weapons[i]["name"] == "none" ) + continue; + + self maps\mp\zombies\_zm_weapons::weapondata_give( loadout.weapons[i] ); + } + + if ( loadout.current_weapon >= 0 && isdefined( loadout.weapons[loadout.current_weapon]["name"] ) ) + self switchtoweapon( loadout.weapons[loadout.current_weapon]["name"] ); + + self giveweapon( "knife_zm" ); + self maps\mp\zombies\_zm_equipment::equipment_give( self.loadout.equipment ); + loadout restore_weapons_for_chugabud( self ); + self chugabud_restore_claymore(); + self.score = loadout.score; + self.pers["score"] = loadout.score; + perk_array = maps\mp\zombies\_zm_perks::get_perk_array( 1 ); + + for ( i = 0; i < perk_array.size; i++ ) + { + perk = perk_array[i]; + self unsetperk( perk ); + self.num_perks--; + self set_perk_clientfield( perk, 0 ); + } + + if ( isdefined( loadout.perks ) && loadout.perks.size > 0 ) + { + for ( i = 0; i < loadout.perks.size; i++ ) + { + if ( self hasperk( loadout.perks[i] ) ) + continue; + + if ( loadout.perks[i] == "specialty_quickrevive" && flag( "solo_game" ) ) + level.solo_game_free_player_quickrevive = 1; + + if ( loadout.perks[i] == "specialty_finalstand" ) + continue; + + maps\mp\zombies\_zm_perks::give_perk( loadout.perks[i] ); + } + } + + self chugabud_restore_grenades(); + + if ( maps\mp\zombies\_zm_weap_cymbal_monkey::cymbal_monkey_exists() ) + { + if ( loadout.zombie_cymbal_monkey_count ) + { + self maps\mp\zombies\_zm_weap_cymbal_monkey::player_give_cymbal_monkey(); + self setweaponammoclip( "cymbal_monkey_zm", loadout.zombie_cymbal_monkey_count ); + } + } + + if(isDefined(self.saved_aat_weapons[0])) + { + self.weapon_aats[0] = self.saved_aat_weapons[0]; + self.aat_weapon[0] = self.saved_aat_weapons_name[0]; + } + else + { + self.saved_aat_weapons[0] = undefined; + self.saved_aat_weapons_name[0] = undefined; + } + if(isDefined(self.saved_aat_weapons[1])) + { + self.weapon_aats[1] = self.saved_aat_weapons[1]; + self.aat_weapon[1] = self.saved_aat_weapons_name[1]; + } + else + { + self.saved_aat_weapons[1] = undefined; + self.saved_aat_weapons_name[1] = undefined; + } + if(isDefined(self.saved_aat_weapons[2])) + { + self.weapon_aats[2] = self.saved_aat_weapons[2]; + self.aat_weapon[2] = self.saved_aat_weapons_name[2]; + } + else + { + self.saved_aat_weapons[2] = undefined; + self.saved_aat_weapons_name[2] = undefined; + } + self notify("weapon_change"); +} + +//-------tombstone recover aat------------------------------------------------------------------ + +tombstone_spawn() +{ + dc = spawn( "script_model", self.origin + vectorscale( ( 0, 0, 1 ), 40.0 ) ); + dc.angles = self.angles; + dc setmodel( "tag_origin" ); + dc_icon = spawn( "script_model", self.origin + vectorscale( ( 0, 0, 1 ), 40.0 ) ); + dc_icon.angles = self.angles; + dc_icon setmodel( "ch_tombstone1" ); + dc_icon linkto( dc ); + dc.icon = dc_icon; + dc.script_noteworthy = "player_tombstone_model"; + dc.player = self; + self thread tombstone_clear(); + dc thread tombstone_wobble(); + dc thread tombstone_revived( self ); + result = self waittill_any_return( "player_revived", "spawned_player", "disconnect" ); + + if ( result == "player_revived" || result == "disconnect" ) + { + dc notify( "tombstone_timedout" ); + dc_icon unlink(); + dc_icon delete(); + dc delete(); + return; + } + + dc thread tombstone_timeout(); + dc thread tombstone_grab(); +} + +tombstone_grab() +{ + self endon( "tombstone_timedout" ); + wait 1; + + while ( isdefined( self ) ) + { + players = get_players(); + + for ( i = 0; i < players.size; i++ ) + { + if ( players[i].is_zombie ) + continue; + + if ( isdefined( self.player ) && players[i] == self.player ) + { + tombstone_machine_triggers = getentarray( "specialty_scavenger", "script_noteworthy" ); + istombstonepowered = 0; + + foreach ( trigger in tombstone_machine_triggers ) + { + if ( isdefined( trigger.power_on ) && trigger.power_on || isdefined( trigger.turbine_power_on ) && trigger.turbine_power_on ) + istombstonepowered = 1; + } + + if ( istombstonepowered ) + { + dist = distance( players[i].origin, self.origin ); + + if ( dist < 64 ) + { + playfx( level._effect["powerup_grabbed"], self.origin ); + playfx( level._effect["powerup_grabbed_wave"], self.origin ); + players[i] tombstone_give(); + wait 0.1; + playsoundatposition( "zmb_tombstone_grab", self.origin ); + self stoploopsound(); + self.icon unlink(); + self.icon delete(); + self delete(); + self notify( "tombstone_grabbed" ); + players[i] clientnotify( "dc0" ); + players[i] notify( "dance_on_my_grave" ); + } + } + } + } + + wait_network_frame(); + } +} + +tombstone_give() +{ + dc = level.tombstones[self.tombstone_index]; + + if ( !flag( "solo_game" ) ) + { + primaries = self getweaponslistprimaries(); + + if ( dc.weapon.size > 1 || primaries.size > 1 ) + { + foreach ( weapon in primaries ) + self takeweapon( weapon ); + } + + for ( i = 0; i < dc.weapon.size; i++ ) + { + if ( !isdefined( dc.weapon[i] ) ) + continue; + + if ( dc.weapon[i] == "none" ) + continue; + + weapon = dc.weapon[i]; + stock = dc.stockcount[i]; + + if ( !self hasweapon( weapon ) ) + { + self giveweapon( weapon, 0, self maps\mp\zombies\_zm_weapons::get_pack_a_punch_weapon_options( weapon ) ); + self setweaponammoclip( weapon, weaponclipsize( weapon ) ); + self setweaponammostock( weapon, stock ); + + if ( i == dc.current_weapon ) + self switchtoweapon( weapon ); + } + } + } + + if ( isdefined( dc.hasriotshield ) && dc.hasriotshield ) + { + self maps\mp\zombies\_zm_equipment::equipment_give( "riotshield_zm" ); + + if ( isdefined( self.player_shield_reset_health ) ) + self [[ self.player_shield_reset_health ]](); + } + + dc restore_weapons_for_tombstone( self ); + + if ( isdefined( dc.hasclaymore ) && dc.hasclaymore && !self hasweapon( "claymore_zm" ) ) + { + self giveweapon( "claymore_zm" ); + self set_player_placeable_mine( "claymore_zm" ); + self setactionslot( 4, "weapon", "claymore_zm" ); + self setweaponammoclip( "claymore_zm", dc.claymoreclip ); + } + + if ( isdefined( dc.hasemp ) && dc.hasemp ) + { + self giveweapon( "emp_grenade_zm" ); + self setweaponammoclip( "emp_grenade_zm", dc.empclip ); + } + + if ( isdefined( dc.perk ) && dc.perk.size > 0 ) + { + for ( i = 0; i < dc.perk.size; i++ ) + { + if ( self hasperk( dc.perk[i] ) ) + continue; + + if ( dc.perk[i] == "specialty_quickrevive" && flag( "solo_game" ) ) + continue; + + maps\mp\zombies\_zm_perks::give_perk( dc.perk[i] ); + } + } + + if ( dc.grenade > 0 && !flag( "solo_game" ) ) + { + curgrenadecount = 0; + + if ( self hasweapon( self get_player_lethal_grenade() ) ) + self getweaponammoclip( self get_player_lethal_grenade() ); + else + self giveweapon( self get_player_lethal_grenade() ); + + self setweaponammoclip( self get_player_lethal_grenade(), dc.grenade + curgrenadecount ); + } + + if ( maps\mp\zombies\_zm_weap_cymbal_monkey::cymbal_monkey_exists() && !flag( "solo_game" ) ) + { + if ( dc.zombie_cymbal_monkey_count ) + { + self maps\mp\zombies\_zm_weap_cymbal_monkey::player_give_cymbal_monkey(); + self setweaponammoclip( "cymbal_monkey_zm", dc.zombie_cymbal_monkey_count ); + } + } + + if(isDefined(self.saved_aat_weapons[0])) + { + self.weapon_aats[0] = self.saved_aat_weapons[0]; + self.aat_weapon[0] = self.saved_aat_weapons_name[0]; + } + else + { + self.saved_aat_weapons[0] = undefined; + self.saved_aat_weapons_name[0] = undefined; + } + if(isDefined(self.saved_aat_weapons[1])) + { + self.weapon_aats[1] = self.saved_aat_weapons[1]; + self.aat_weapon[1] = self.saved_aat_weapons_name[1]; + } + else + { + self.saved_aat_weapons[1] = undefined; + self.saved_aat_weapons_name[1] = undefined; + } + if(isDefined(self.saved_aat_weapons[2])) + { + self.weapon_aats[2] = self.saved_aat_weapons[2]; + self.aat_weapon[2] = self.saved_aat_weapons_name[2]; + } + else + { + self.saved_aat_weapons[2] = undefined; + self.saved_aat_weapons_name[2] = undefined; + } + self notify("weapon_change"); +} + +//--------- + +/* +solo_tombstone_removal() +{ + notify( "tombstone_on" ); +} + +turn_tombstone_on() +{ + level endon("end_game"); + while ( 1 ) + { + machine = getentarray( "vending_tombstone", "targetname" ); + machine_triggers = getentarray( "vending_tombstone", "target" ); + i = 0; + while ( i < machine.size ) + { + machine[ i ] setmodel( level.machine_assets[ "tombstone" ].off_model ); + i++; + } + level thread do_initial_power_off_callback( machine, "tombstone" ); + array_thread( machine_triggers, ::set_power_on, 0 ); + level waittill( "tombstone_on" ); + i = 0; + while ( i < machine.size ) + { + machine[ i ] setmodel( level.machine_assets[ "tombstone" ].on_model ); + machine[ i ] vibrate( vectorScale( ( 0, -1, 0 ), 100 ), 0,3, 0,4, 3 ); + machine[ i ] playsound( "zmb_perks_power_on" ); + machine[ i ] thread perk_fx( "tombstone_light" ); + machine[ i ] thread play_loop_on_machine(); + i++; + } + level notify( "specialty_scavenger_power_on" ); + array_thread( machine_triggers, ::set_power_on, 1 ); + if ( isDefined( level.machine_assets[ "tombstone" ].power_on_callback ) ) + { + array_thread( machine, level.machine_assets[ "tombstone" ].power_on_callback ); + } + level waittill( "tombstone_off" ); + if ( isDefined( level.machine_assets[ "tombstone" ].power_off_callback ) ) + { + array_thread( machine, level.machine_assets[ "tombstone" ].power_off_callback ); + } + array_thread( machine, ::turn_perk_off ); + players = get_players(); + _a1718 = players; + _k1718 = getFirstArrayKey( _a1718 ); + while ( isDefined( _k1718 ) ) + { + player = _a1718[ _k1718 ]; + player.hasperkspecialtytombstone = undefined; + _k1718 = getNextArrayKey( _a1718, _k1718 ); + } + } +} + +perk_machine_spawn_init() +{ + level endon("end_game"); + 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 + "_perks_" ) + location; + pos = []; + if ( isDefined( level.override_perk_targetname ) ) + { + structs = getstructarray( level.override_perk_targetname, "targetname" ); + } + else + { + structs = getstructarray( "zm_perk_machine", "targetname" ); + } + _a3578 = structs; + _k3578 = getFirstArrayKey( _a3578 ); + while ( isDefined( _k3578 ) ) + { + struct = _a3578[ _k3578 ]; + if ( isDefined( struct.script_string ) ) + { + tokens = strtok( struct.script_string, " " ); + _a3583 = tokens; + _k3583 = getFirstArrayKey( _a3583 ); + while ( isDefined( _k3583 ) ) + { + token = _a3583[ _k3583 ]; + if ( token == match_string ) + { + pos[ pos.size ] = struct; + } + _k3583 = getNextArrayKey( _a3583, _k3583 ); + } + } + else pos[ pos.size ] = struct; + _k3578 = getNextArrayKey( _a3578, _k3578 ); + } + if ( !isDefined( pos ) || pos.size == 0 ) + { + return; + } + precachemodel( "zm_collision_perks1" ); + i = 0; + while ( i < pos.size ) + { + 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.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 ) + { + bump_trigger = undefined; + } + else + { + 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" ) + { + 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.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 ) ) + { + use_trigger.blocker_model = pos[ i ].blocker_model; + } + if ( isDefined( pos[ i ].script_int ) ) + { + perk_machine.script_int = pos[ i ].script_int; + } + if ( isDefined( pos[ i ].turn_on_notify ) ) + { + perk_machine.turn_on_notify = pos[ i ].turn_on_notify; + } + if ( perk == "specialty_scavenger" || perk == "specialty_scavenger_upgrade" ) + { + use_trigger.script_sound = "mus_perks_tombstone_jingle"; + use_trigger.script_string = "tombstone_perk"; + use_trigger.script_label = "mus_perks_tombstone_sting"; + use_trigger.target = "vending_tombstone"; + perk_machine.script_string = "tombstone_perk"; + perk_machine.targetname = "vending_tombstone"; + if ( isDefined( bump_trigger ) ) + { + bump_trigger.script_string = "tombstone_perk"; + } + } + 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 ); + } + } + i++; + } +} + +isTown() +{ + if (isDefined(level.zombiemode_using_tombstone_perk) && level.zombiemode_using_tombstone_perk) + { + level thread perk_machine_spawn_init(); + thread solo_tombstone_removal(); + thread turn_tombstone_on(); + } +}*/ diff --git a/t6/uncompiled mods/boss_ivo1 - Copy.gsc b/t6/uncompiled mods/boss_ivo1 - Copy.gsc new file mode 100644 index 0000000..9f2e15a --- /dev/null +++ b/t6/uncompiled mods/boss_ivo1 - Copy.gsc @@ -0,0 +1,1393 @@ + +/* + * Copyright 2023 K Mod. All rights reserved. + * + * This code, including any associated documentation or files, is the + * intellectual property of K Mod. You may not + * use, modify, reproduce, distribute, or disclose this code without + * explicit written permission from the owner. + * + * Unauthorized use, reproduction, or distribution of this code or any + * portion thereof is strictly prohibited and may result in severe legal + * consequences. For licensing inquiries or permission requests, please + * contact eizekiels@gmail.com. + */ + +/* -------- STARTER GUIDE ---------- + + --------- HOW TO MAKE THE BOSS LOOKS COOL, Spawn an object to a specific location --------- + + model = "t6_wpn_zmb_staff_tip_lightning_world"; + + self.fx = spawn( "script_model", self.origin ); // create objet + self.fx linkto( self, "J_SpineLower", (0, -10, 15), (180, 90, 70)); // link to the boss (anchor) + wait 0.05; + self.fx setmodel( model ); // apply the model + + --------- HOW TO MAKE BOSS ATTACK SPECIAL EFFECTS, Spawn a FX on an fx --------------------- + + fx_origin = level.boss.origin; //set origin of effect + fx = spawn( "script_model", (fx_origin[0], fx_origin[1], -390)); // spawn object + fx setmodel( "tag_origin" ); // set three D default object + wait 0.05; + playfxontag( level._effect["whirlwind"], fx, "tag_origin" ); // <- only thing to change is the level._effect, go search it in the stock script (ctrl + F) + + --------- HOW TO ADD SOUND TO ATTACKS ------------------------------------------------------- + + self playsound( "evt_medal_acquired" ); // search playsound in stock script (CTRL + F) + + --------- HOW TO MAKE BOSS SHINY ------------------------------------------------------------ + + (Pick one or more) + level.boss.fx_element_glow = playfxontag( localclientnum, level._effect["fire_glow"], level.boss, "tag_origin" ); + level.boss.fx_element_glow = playfxontag( localclientnum, level._effect["air_glow"], level.boss, "tag_origin" ); + level.boss.fx_element_glow = playfxontag( localclientnum, level._effect["elec_glow"], level.boss, "tag_origin" ); + level.boss.fx_element_glow = playfxontag( localclientnum, level._effect["ice_glow"], level.boss, "tag_origin" ); + + + --------- USEFUL COORDINATES ----------------------------------------------------------------- + level.fire_spawn_origin = (9463, -8560, -398); + level.ice_spawn_origin = (11211, -7058.7, -345.875); + level.wind_spawn_origin = (11253, -8655, -408); + level.lightning_spawn_origin = (9623.4, -7016.2, -345.875); + level.pap_spawn_origin = (10760.4, -7980.47, -463.875); + level.center_spawn_origin = (10314.5, -7889.91, -411.875); + level.fire_puzzle_origin = (9891.5, -8764, -452); + +*/ +//BACKUP BEFORE PHASES ! +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_magicbox; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\zombies\_zm_power; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\_demo; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_chugabud; +#include maps\mp\_visionset_mgr; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\zombies\_zm_spawner; + +#include Maps\Origins\clientscripts\mp\zm_tomb_tank; +#include maps\mp\zombies\_zm_ai_mechz; +#include clientscripts\mp\_utility; +#include clientscripts\mp\_fx; +#include clientscripts\mp\zombies\_zm_utility; +#include clientscripts\mp\zombies\_zm_weapons; +#include maps\mp\gametypes_zm\_weapon_utils; +#include Maps\Origins\clientscripts\mp\zombies\_zm_weap_beacon; +#include Maps\Origins\clientscripts\mp\zombies; +#include Maps\Tranzit\maps\mp\zombies\_zm_ai_avogadro; +#include maps\mp\gametypes_zm\_shellshock; +#include maps\mp\zombies\_zm_zonemgr; +#include maps\mp\zombies\_zm_ai_mechz_ffotd; +#include maps\mp\zombies\_zm_sidequests; +#include maps\mp\zm_tomb_ee_main; +#include maps\mp\zm_tomb_utility; +#include maps\mp\zm_tomb_vo; +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\gametypes_zm\_hud; +#include maps\mp\zm_tomb_chamber; +#include maps\mp\zm_tomb; +#include maps\mp\zm_spawner; +#include maps\zombie_alcatraz\fx_alcatraz_lightning_lg; +#include maps\mp\zombies\_zm_traps; + +#include scripts\zm\zm_tomb\raid_boss; + +init_levelvars() +{ + level.is_zombie_level = 1; + level.laststandpistol = "m1911_zm"; + level.default_laststandpistol = "m1911_zm"; + level.default_solo_laststandpistol = "m1911_upgraded_zm"; + level.start_weapon = "m1911_zm"; + level.first_round = 1; + level.start_round = getgametypesetting( "startRound" ); + level.round_number = level.start_round; + level.enable_magic = getgametypesetting( "magic" ); + level.headshots_only = getgametypesetting( "headshotsonly" ); + level.player_starting_points = level.round_number * 500; + level.round_start_time = 0; + level.pro_tips_start_time = 0; + level.intermission = 0; + level.dog_intermission = 0; + level.zombie_total = 0; + level.total_zombies_killed = 0; + level.hudelem_count = 0; + level.zombie_spawn_locations = []; + level.zombie_rise_spawners = []; + level.current_zombie_array = []; + level.current_zombie_count = 0; + level.zombie_total_subtract = 0; + level.destructible_callbacks = []; + level.zombie_vars = []; + + foreach ( team in level.teams ) + level.zombie_vars[team] = []; + + difficulty = 1; + column = int( difficulty ) + 1; + set_zombie_var( "zombie_health_increase", 100, 0, column ); + set_zombie_var( "zombie_health_increase_multiplier", 0.1, 1, column ); + set_zombie_var( "zombie_health_start", 20000, 0, column ); + set_zombie_var( "zombie_spawn_delay", 0.05, 0, column ); + set_zombie_var( "zombie_new_runner_interval", 10, 0, column ); + set_zombie_var( "zombie_move_speed_multiplier", 8, 0, column ); + set_zombie_var( "zombie_move_speed_multiplier_easy", 2, 0, column ); + set_zombie_var( "zombie_max_ai", 24, 0, column ); + set_zombie_var( "zombie_ai_per_player", 6, 0, column ); + set_zombie_var( "below_world_check", -1000 ); + set_zombie_var( "spectators_respawn", 1 ); + set_zombie_var( "zombie_use_failsafe", 1 ); + set_zombie_var( "zombie_between_round_time", 10 ); + set_zombie_var( "zombie_intermission_time", 15 ); + set_zombie_var( "game_start_delay", 0, 0, column ); + set_zombie_var( "penalty_no_revive", 0.1, 1, column ); + set_zombie_var( "penalty_died", 0.0, 1, column ); + set_zombie_var( "penalty_downed", 0.05, 1, column ); + set_zombie_var( "starting_lives", 1, 0, column ); + set_zombie_var( "zombie_score_kill_4player", 50 ); + set_zombie_var( "zombie_score_kill_3player", 50 ); + set_zombie_var( "zombie_score_kill_2player", 50 ); + set_zombie_var( "zombie_score_kill_1player", 50 ); + set_zombie_var( "zombie_score_kill_4p_team", 30 ); + set_zombie_var( "zombie_score_kill_3p_team", 35 ); + set_zombie_var( "zombie_score_kill_2p_team", 45 ); + set_zombie_var( "zombie_score_kill_1p_team", 0 ); + set_zombie_var( "zombie_score_damage_normal", 10 ); + set_zombie_var( "zombie_score_damage_light", 10 ); + set_zombie_var( "zombie_score_bonus_melee", 80 ); + set_zombie_var( "zombie_score_bonus_head", 50 ); + set_zombie_var( "zombie_score_bonus_neck", 20 ); + set_zombie_var( "zombie_score_bonus_torso", 10 ); + set_zombie_var( "zombie_score_bonus_burn", 10 ); + set_zombie_var( "zombie_flame_dmg_point_delay", 500 ); + set_zombie_var( "zombify_player", 0 ); + + if ( issplitscreen() ) + set_zombie_var( "zombie_timer_offset", 280 ); + + level thread init_player_levelvars(); + level.gamedifficulty = getgametypesetting( "zmDifficulty" ); + + if ( level.gamedifficulty == 0 ) + level.zombie_move_speed = level.round_number * level.zombie_vars["zombie_move_speed_multiplier_easy"]; + else + level.zombie_move_speed = level.round_number * level.zombie_vars["zombie_move_speed_multiplier"]; + + if ( level.round_number == 1 ) + level.zombie_move_speed = 1; + else + { + for ( i = 1; i <= level.round_number; i++ ) + { + timer = level.zombie_vars["zombie_spawn_delay"]; + + if ( timer > 0.08 ) + { + level.zombie_vars["zombie_spawn_delay"] = timer * 0.95; + continue; + } + + if ( timer < 0.08 ) + level.zombie_vars["zombie_spawn_delay"] = 0.08; + } + } + + level.speed_change_max = 0; + level.speed_change_num = 0; +} + +NoPowerups_Ivo1() +{ + for(;;) + { + if(flag("zombie_drop_powerups")) + { + flag_clear( "zombie_drop_powerups" ); + // iPrintLn("Powerup Deleted"); + } + + + wait 0.05; + } +} + +player_flame_damage()//Panzer Flamethrower Damage +{ + self endon( "zombified" ); + self endon( "death" ); + self endon( "disconnect" ); + n_player_dmg = 500;//Damage + n_jugga_dmg = 500;//Damage + n_burn_time = 1;//DamFunc + + if ( isdefined( self.is_zombie ) && self.is_zombie ) + return; + + self thread player_stop_burning(); + + if ( !isdefined( self.is_burning ) && is_player_valid( self, 1, 0 ) ) + { + self.is_burning = 1; + maps\mp\_visionset_mgr::vsmgr_activate( "overlay", "zm_transit_burn", self, n_burn_time, level.zm_transit_burn_max_duration ); + self notify( "burned" ); + + if ( !self hasperk( "specialty_armorvest" ) ) + { + self dodamage_wrapper(n_player_dmg); + wait 0.05; + self shellshock( "lava_small", 0.1 );//DamFunc + } + else + { + self dodamage_wrapper(n_jugga_dmg); + wait 0.05; + self shellshock( "lava_small", 0.1 );//DamFunc + } + + + wait 0.25; + self.is_burning = undefined; + } +} + +get_favorite_enemy_custom(origin, players)//Panzer Pathing Fix +{ + closest_distance = 999999999; + closest_player = undefined; + foreach (player in level.players) + { + if ( player.sessionstate == "intermission" ) + return undefined; + if ( isdefined( player.intermission ) && player.intermission ) + return undefined; + if(player.sessionstate == "spectator" || player maps\mp\zombies\_zm_laststand::player_is_in_laststand()) + continue; + p_dist = distancesquared(self.origin, player.origin); + if (p_dist < closest_distance) + { + closest_player = player; + closest_distance = p_dist; + } + } + return closest_player; +} + + +setup_boss_ivo1() +{ + setdvar( "g_ai", "1" ); + + level.dead = 0; + + level.fire = (9458.41, -8561.4, -398); + level.ice = (11233, -7047.87, -345.875); + level.wind = (11256, -8661.66, -408); + level.lightning = (9629, -7009.4, -345.875); + level.pap_spawn_origin = (10760.4, -7980.47, -463.875); + level.center_spawn_origin = (10341.6, -7907.17, -411.875); + level.fire_puzzle_origin = (9891.5, -8764, -452); + level.places = array( level.ice, level.fire, level.lightning, level.wind, level.center_spawn_origin); + level.player_out_of_playable_area_monitor = false; //disable instant death when entering out of bound area + //Variables + level.phase = 0; + //flag_set( "activate_zone_chamber" ); //activate Agartha zm spawn + level.mechz_spawners[0].is_enabled = 1; + //flag_wait("initial_blackscreen_passed"); + //wait 6.1; + //wait 0.05; + //wait 1; + + replaceFunc(maps\mp\zombies\_zm_ai_mechz::mechz_spawn, scripts\zm\zm_tomb\M\M_zm_ai_mechz::mechz_spawn); + replaceFunc(maps\mp\zombies\_zm_ai_mechz_ft::player_flame_damage, ::player_flame_damage); + replaceFunc(maps\mp\zombies\_zm_ai_mechz_claw::claw_grapple, scripts\zm\zm_tomb\M\M_zm_ai_mechz_claw::claw_grapple); + replaceFunc(maps\mp\zombies\_zm_ai_mechz_claw::check_for_claw_move_complete, scripts\zm\zm_tomb\M\M_zm_ai_mechz_claw::check_for_claw_move_complete); + replaceFunc(maps\mp\zombies\_zm_ai_mechz_claw::mechz_claw_cleanup, scripts\zm\zm_tomb\M\M_zm_ai_mechz_claw::mechz_claw_cleanup); + replaceFunc(maps\mp\zombies\_zm_ai_mechz_claw::check_for_players_mid_grapple, scripts\zm\zm_tomb\M\M_zm_ai_mechz_claw::check_for_players_mid_grapple); + replaceFunc(maps\mp\zombies\_zm_ai_mechz_claw::mechz_zombie_flamethrower_gib, scripts\zm\zm_tomb\M\M_zm_ai_mechz_claw::mechz_zombie_flamethrower_gib); + replaceFunc(maps\mp\zombies\_zm_ai_mechz_claw::mechz_claw_shot_pain_reaction, scripts\zm\zm_tomb\M\M_zm_ai_mechz_claw::mechz_claw_shot_pain_reaction); + replaceFunc(maps\mp\zombies\_zm_ai_mechz_claw::mechz_claw_detach, scripts\zm\zm_tomb\M\M_zm_ai_mechz_claw::mechz_claw_detach); + replaceFunc(maps\mp\zombies\_zm_ai_mechz_claw::mechz_claw_damage_trigger_thread, scripts\zm\zm_tomb\M\M_zm_ai_mechz_claw::mechz_claw_damage_trigger_thread); + + //level waittill("start_of_round");//dont know if you need it + + //wait 0.1; + // replaceFunc(maps\mp\zombies\_zm::init_levelvars, ::init_levelvars); + if (level.player_count <= 2) + level.zombie_health = 40000; + else + level.zombie_health = 150000; + + wait 0.05; + + player playSound( "zmb_ai_mechz_incoming_alarm" );//Boss Summon Sound, these wait times fit well with the boss summon + + level thread SUPER_PANZERS_Ivo1(); + + level thread NoPowerups_Ivo1(); + + zombies = GetAIArray(level.zombie_team); // get the zombie array + + //transform the zm into the raid boss + zombies[0].boss = 1; + level.boss = zombies[0]; //set the raid boss as a global variable accessible from all code (no need to pass it as parameter) + level.boss.name = "Panzer Lord"; + level.boss setcandamage( 0 );//prevent boss taking damage + level.boss.candamage = 0; + if (level.player_count <= 2) + level.boss.maxhealth = 5000000; + else + level.boss.maxhealth = 15000000; + level.boss.health = level.boss.maxhealth; + level.boss set_zombie_run_cycle("super_sprint"); + level.boss.meleedamage = 2000;//DamFunc + level.is_boss_spawned = 1; + level.boss.ignore_nuke = 1; + + level.boss.instakill_func = ::Boss_instakill_Ivo1; + + wait 0.05; + //boss skin + level.boss setmodel( "c_zom_mech_body", 1 ); + wait 0.05; + + helmet = spawn( "script_model", level.boss.origin ); + helmet linkto( level.boss, "J_Helmet", ( 4, 0, -5 ), ( -20, 0, 0 )); + wait 0.05; + helmet setmodel( "c_zom_mech_faceplate" ); + wait 0.05; + + claw = spawn( "script_model", level.boss.origin ); + claw linkto( level.boss, "J_Wrist_LE", ( 0, 0, 0 ), ( 180, 0, 0)); + wait 0.05; + claw setmodel( "c_zom_mech_claw"); + + level.boss attach( "c_zom_mech_armor_shoulder_right", "J_ShoulderArmor_RI", 0 ); + wait 0.05; + + level.boss attach( "c_zom_mech_armor_shoulder_left", "J_ShoulderArmor_LE", 0 ); + wait 0.05; + + level.boss attach( "c_zom_mech_armor_knee_right", "J_Knee_attach_RI", 0 ); + wait 0.05; + + level.boss attach( "c_zom_mech_armor_knee_left", "J_Knee_attach_LE", 0 ); + wait 0.5; + + playFXOnTag( level._effect["air_puzzle_smoke"], level.boss, "tag_origin"); + wait 0.05; + + level.boss thread boss_think_Ivo1(); //call the raid boss attacks loop + + iPrintLn("^3[ ??? ^7] : ^3Hmm...I see..."); + wait 3.5; + iPrintLn("^3[ ??? ^7] : ^3The Keeper of Agartha told me about you...");//PIA Boss reference + wait 3.5; + iPrintLn("^3[ ^1" + level.boss.name + " ^7] : ^3Let us see if you are up for the challenge"); + + + for (;;)//after killing boss effects and sound + { + if (level.boss.health <= 0 ) + { + playsoundatposition( "mus_zombie_game_over_ee", ( 0, 0, 0 ) ); + iPrintLn("^3[ ^1" + level.boss.name + " ^7] : ^3Well done, you lived up to your reputation"); + foreach(player in level.players) + { + player thread ending_Ivo1(); + } + for(i = 0; i <= 1000; i++) // find all zombies in the zombie array and kill + { + zombies = getaiarray(level.zombie_team); + zombies[0] dodamage_wrapper(zombies[0].health + 100); + wait 0.05; + } + break; + } + wait 0.05; + } +} + +Boss_instakill_Ivo1() +{ + //iPrintLn("MORE DAMAGE"); + //self dodamage_wrapper(667); +} + +ending_Ivo1() +{ + if (self.sessionstate == "playing") + { + //self playsound("mus_zombie_game_over_ee"); + //wait 0.05; + self fadetoblackforxsec( 0, 1, 0.5, 0.5, "white" ); + end = 1; + return end; + } + else //if (self.sessionstate == "spectator" || self.sessionstate == "dead" ) + { + empty = 0; + } +} + +SUPER_PANZERS_Ivo1() +{ + //flag_wait("initial_blackscreen_passed"); + + //level waittill("start_of_round"); + //wait 0.1; + //panzers health + if (level.player_count <= 2) + { + level.mechz_max_health = 60000;// + level.mechz_base_health = 60000; + } + else + { + level.mechz_max_health = 250000;// + level.mechz_base_health = 250000; + } + + + level.mechz_health = level.mechz_base_health; + level.mechz_health_increase = 0; + + //to make sure that there is always room, used for the old way + level.mechz_zombie_per_round = 1000; + level.mechz_jump_delay = 0.05; + //DamFunc + level.mechz_meleedamage = 1000;//melee + level.mechz_claw_cooldown_time = 3500;//hook cooldown + level.mechz_flamethrower_cooldown_time = 2500;//flamethrower cooldown + + level.mechz_flogger_stun_time = 0.1; + level.mechz_powerplant_stun_time = 0.1; + level.mechz_explosive_dmg_to_cancel_claw_percentage = 0.1; +} + +spawn_panzer() +{ + ai = spawn_zombie( level.mechz_spawners[0] ); + ai.custom_origin = (10314.5, -7889.91, -411.875); + ai.custom_angle = (0, 0, 0); + ai thread mechz_spawn(); + return ai; +} + + +boss_think_Ivo1() // After boss spawned, start the attacks rotation +{ + self endon("death"); //on boss death, stop the script + + wait 7; // let the boss time to get to the middle + level thread Phase_check1_Ivo1(); + level.boss setcandamage( 1 );//now boss takes damage + level.boss.candamage = 1; + for(;;) //start the attack rotation loop + { + + level.boss thread Flamethrower_Easy_Ivo1();//FLAMETHROWER/AURA, DONE.//change names + wait 15; + + level Phase_Starter_Ivo1(); + + level.boss thread Electric_Easy_Ivo1();//Electric shot, DONE. + wait 22; + + level Phase_Starter_Ivo1(); + + level.boss thread AirStrike_Easy_Ivo1();//ROCKETS Air Strike, DONE. + wait 15; + + level Phase_Starter_Ivo1(); + + level.boss thread Wipe_Easy_Ivo1();//Wipe Attack DONE. + wait 15; + + level Phase_Starter_Ivo1(); + } +} + +Flamethrower_Easy_Ivo1() +{ + self endon("death"); + //setting fire aura, might also add boss being set on flames too + fire_aura = spawn( "script_model", level.boss.origin ); + fire_aura linkto( level.boss, "tag_origin" ); + fire_aura setmodel( "tag_origin" ); + wait 0.05; + + playfxontag( level._effect["fire_sacrifice_flame"], fire_aura, "tag_origin" ); + playfxontag( level._effect["wagon_fire"], fire_aura, "tag_origin" ); + + wait 1; + + level.boss playsound( "zmb_ai_mechz_flame_start" );//flame sounds to match panzer sounds + level.boss playloopsound( "zmb_ai_mechz_flame_loop", 0.6 ); + // + + for (i = 0; i <= 7 ; i++) + { + //where the flames come from + playfxontag( level._effect["wagon_fire"], fire_aura, "tag_origin" ); + playfxontag( level._effect["fire_sacrifice_flame"], fire_aura, "tag_origin" ); + playfxontag( level._effect["mech_wpn_flamethrower"], level.boss, "tag_origin" ); + playfxontag( level._effect["mech_wpn_flamethrower"], level.boss, "J_Root_Attach_LE" ); + playfxontag( level._effect["mech_wpn_flamethrower"], level.boss, "J_Root_Attach_RI" ); + playfxontag( level._effect["mech_wpn_flamethrower"], level.boss, "J_spinelower" ); + + foreach(player in level.players) + { + player thread BURN_ALL_Ivo1(); + } + wait 0.75; + } + + level.boss StopLoopSound(); + wait 2; + fire_aura delete(); + +} + +BURN_ALL_Ivo1() +{ + if (distance(level.boss.origin, self.origin) <= 325) //if close to boss + { + self dodamage_wrapper(400); // deal damage to self (you gotta run away !) //DamFunc + vsmgr_activate( "overlay", "zm_transit_burn", self, 2, 2 );//visual burn effect + wait 0.05; + self shellshock( "lava_small", 0.1 );//stun + } +} + + +Electric_Easy_Ivo1() +{ + self endon("death"); + elec_aura = spawn( "script_model", level.boss.origin ); + elec_aura linkto( level.boss, "tag_origin" ); + elec_aura setmodel( "tag_origin" ); + //Electric aura + playfxontag( level._effect["tesla_elec_kill"], elec_aura, "tag_origin" ); + playfxontag( level._effect["fx_tomb_probe_elec_on"], elec_aura, "tag_origin" ); + wait 0.05; + playfxontag( level._effect["electric_cherry_explode"], elec_aura, "tag_origin" ); + level.boss playsound("zmb_cherry_explode"); + foreach(player in level.players) + { + player thread Cherry_Boom_Ivo1(); + } + wait 0.05; + playfxontag( level._effect["tesla_elec_kill"], elec_aura, "tag_origin" ); + wait 2; + playfxontag( level._effect["electric_cherry_explode"], elec_aura, "tag_origin" ); + level.boss playsound("zmb_cherry_explode"); + foreach(player in level.players) + { + player thread Cherry_Boom_Ivo1(); + } + playfxontag( level._effect["tesla_elec_kill"], elec_aura, "tag_origin" ); + shoot_bolt_Ivo1(); + wait 0.3; //DamFunc for all shoot wait + shoot_bolt_Ivo1(); + wait 0.3; + shoot_bolt_Ivo1(); + wait 0.3; + shoot_bolt_Ivo1(); + wait 0.3; + playfxontag( level._effect["tesla_elec_kill"], elec_aura, "tag_origin" ); + wait 1; + playfxontag( level._effect["tesla_elec_kill"], elec_aura, "tag_origin" ); + playfxontag( level._effect["electric_cherry_explode"], elec_aura, "tag_origin" ); + level.boss playsound("zmb_cherry_explode"); + foreach(player in level.players) + { + player thread Cherry_Boom_Ivo1(); + } + shoot_bolt_Ivo1(); + wait 0.3; + shoot_bolt_Ivo1(); + wait 0.3; + shoot_bolt_Ivo1(); + wait 0.3; + shoot_bolt_Ivo1(); + wait 0.3; + playfxontag( level._effect["tesla_elec_kill"], elec_aura, "tag_origin" ); + wait 1; + playfxontag( level._effect["tesla_elec_kill"], elec_aura, "tag_origin" ); + playfxontag( level._effect["electric_cherry_explode"], elec_aura, "tag_origin" ); + level.boss playsound("zmb_cherry_explode"); + foreach(player in level.players) + { + player thread Cherry_Boom_Ivo1(); + } + shoot_bolt_Ivo1(); + wait 0.3; + shoot_bolt_Ivo1(); + wait 0.3; + shoot_bolt_Ivo1(); + wait 0.3; + shoot_bolt_Ivo1(); + wait 0.3; + playfxontag( level._effect["tesla_elec_kill"], elec_aura, "tag_origin" ); + wait 1; + playfxontag( level._effect["tesla_elec_kill"], elec_aura, "tag_origin" ); + playfxontag( level._effect["electric_cherry_explode"], elec_aura, "tag_origin" ); + level.boss playsound("zmb_cherry_explode"); + foreach(player in level.players) + { + player thread Cherry_Boom_Ivo1(); + } + shoot_bolt_Ivo1(); + wait 0.3; + shoot_bolt_Ivo1(); + wait 0.3; + shoot_bolt_Ivo1(); + wait 0.3; + shoot_bolt_Ivo1(); + wait 0.3; + playfxontag( level._effect["tesla_elec_kill"], elec_aura, "tag_origin" ); + wait 1.5; + elec_aura delete(); +} + +Cherry_Boom_Ivo1() +{ + if (distance(level.boss.origin, self.origin) < 330) //if close to boss + { + self dodamage_wrapper(1000); // deal damage to self (you gotta run away !) //DamFunc + wait 0.05; + self shellshock( "lava_small", 0.1 );//stun + } +} + +shoot_bolt_Ivo1() +{ + r = randomint(level.players.size); + if (!level.players[r] maps\mp\zombies\_zm_laststand::player_is_in_laststand() && level.players[r].sessionstate == "playing") + { + target = level.players[r]; + //target add_to_player_score(100); + } + + else //if (level.players[r] maps\mp\zombies\_zm_laststand::player_is_in_laststand()) + { + return shoot_bolt_Ivo1(); + } + + + source_pos = level.boss gettagorigin( "J_Helmet" ); + target_pos = target geteye(); + + bolt = spawn( "script_model", source_pos ); + bolt setmodel( "tag_origin" ); + wait 0.1; //DamFunc + + fx = playfxontag( level._effect["qd_revive"], bolt, "tag_origin" ); + bolt moveto( target_pos, 0.2 ); + bolt waittill( "movedone" ); + bolt.owner = self; + bolt check_bolt_impact( target ); + bolt delete();//wpn_revivestaff_revive_plr +} + +check_bolt_impact( target ) +{ + if ( is_player_valid( target )) + { + target_eye_pos = target geteye(); + dist_sq = distancesquared( self.origin, target_eye_pos ); + + if ( dist_sq < 4096 ) + { + passed = bullettracepassed( self.origin, target_eye_pos, 0, undefined ); + + if ( passed ) + { + target dodamage_wrapper(500); //DamFunc + vsmgr_activate( "overlay", "zm_transit_burn", target, 1, 1 ); + wait 0.05; + target shellshock( "lava_small", 0.1 );//stun + target playsoundtoplayer( "wpn_revivestaff_proj_impact", target ); + + } + } + } +} + + +AirStrike_Easy_Ivo1() +{ + self endon("death"); + LaunchPlace = spawn( "script_model", level.boss.origin ); + LaunchPlace linkto( level.boss, "tag_origin", (0, 0, 0), (-90, -90, -90)); + LaunchPlace setmodel( "tag_origin" ); + + self playsound( "zmb_homingbeacon_missiile_alarm" ); + wait 0.05; + + foreach(player in level.players) + { + player thread BombStun_Ivo1(); + } + + playfxontag( level._effect["beacon_launch_fx"], LaunchPlace, ( "tag_origin" ) );//ROCKET LAUNCH fx, need to aim at at up + self playsound( "zmb_homingbeacon_missile_fire" ); + + wait 0.7; + + foreach(player in level.players) + { + player thread BombStun_Ivo1(); + } + + playfxontag( level._effect["beacon_launch_fx"], LaunchPlace, ( "tag_origin" ) );//ROCKET LAUNCH + self playsound( "zmb_homingbeacon_missile_fire" ); + + wait 0.7; + + foreach(player in level.players) + { + player thread BombStun_Ivo1(); + } + + playfxontag( level._effect["beacon_launch_fx"], LaunchPlace, ( "tag_origin" ) );//ROCKET LAUNCH + self playsound( "zmb_homingbeacon_missile_fire" ); + + wait 0.7; + + foreach(player in level.players) + { + player thread BombStun_Ivo1(); + } + + playfxontag( level._effect["beacon_launch_fx"], LaunchPlace, ( "tag_origin" ) );//ROCKET LAUNCH + self playsound( "zmb_homingbeacon_missile_fire" ); + + + waitrandom = randomFloatRange( 2.3 , 5.1 ); + //iPrintLn(waitrandom); + wait waitrandom; + + foreach (player in level.players) + { + player thread BombBoom_Ivo1(); + } + +} + +BombStun_Ivo1() +{ + self shellshock( "lava_small", 0.8 );//stun for each rocket launch +} + +BombBoom_Ivo1() +{ + if (!self maps\mp\zombies\_zm_laststand::player_is_in_laststand() && self.sessionstate == "playing") + { + self playsound( "zmb_homingbeacon_missile_incoming" );// small window to activate Tank effect + wait 1; + self dodamage_wrapper(1800); // Rocket Damage //DamFunc + playfxontag( level._effect["beacon_shell_explosion"], self, "tag_origin" );//ROCKET BOOM + self playsound( "zmb_homingbeacon_missile_impact" ); + wait 0.05; + self shellshock( "frag_grenade_mp", 2 );//stun + } +} + + +Wipe_Easy_Ivo1() +{ + self endon("death"); + + //teleport boss to center and give immunity + level.boss setanimstatefromasd("zm_idle"); + level.boss forceteleport(level.boss.origin + (0, 0, -500)); + wait 0.05; + level.boss forceteleport(level.center_spawn_origin + (0, 0, -500)); + wait 0.05; + level.boss forceteleport(level.center_spawn_origin); + + beam = spawn( "script_model", level.boss.origin ); + beam linkto( level.boss, "tag_origin" ); + beam setmodel( "tag_origin" ); + wait 0.05; + playfxontag( level._effect["ee_beam"], beam, "tag_origin" ); + + vortex = spawn( "script_model", level.boss.origin ); + vortex linkto( level.boss, "tag_origin", ( 0, 0, 225) ); + vortex setmodel( "tag_origin" ); + + level.boss setanimstatefromasd("zm_idle");//so boss stay in center + level.boss set_zombie_run_cycle("super_sprint");//so boss stay in center + wait 0.05; + level.boss setanimstatefromasd("zm_idle"); + playFXOnTag( level._effect["ee_vortex"], vortex, "tag_origin"); + level.boss setcandamage( 0 );//prevent boss taking damage + level.boss.candamage = 0; + level.boss setanimstatefromasd("zm_idle"); + wait 0.5; + level.boss setanimstatefromasd("zm_idle"); + setdvar( "g_ai", "0" ); + level.boss thread Floating_Ivo1(); + + foreach( player in level.players) + { + player playlocalsound( level.zmb_laugh_alias );//so they know the attack started + player allowcrouch( 1 );//crouch and prone disabled for the entire boss fight, + player allowprone( 1 );//only enabled during the attack. + player thread Safe_Zone_Ivo1(); + } + + wait 7;//DamFunc + foreach (player in level.players)//wipe or stay alive + { + player Dead_or_Alive_Ivo1(); + if (level.dead != 0) + { + foreach (player in level.players) + { + player thread Dead_Ivo1(); + } + } + } + // if (level.dead != 0) + // wait 3; + + level.dead = 0; + + level.boss forceteleport(level.center_spawn_origin); + setdvar( "g_ai", "1" ); + level.boss setcandamage( 1 ); + level.boss.candamage = 1; + level.boss set_zombie_run_cycle("super_sprint"); + wait 0.05; + + vortex delete(); + beam delete(); + + foreach( player in level.players) + { + player allowcrouch( 0 );//no crouch or prone allowed in my boss fight + player allowprone( 0 );//they only get crouch and prone during wipe attack + //vsmgr_deactivate( "overlay", "zm_powerup_zombie_blood_overlay", player); + } +} + +Safe_Zone_Ivo1() +{ + for (i = 0; i <= 140; i++)// Visual zombie blood effect to know you are in position //DamFunc + { + if ((distance(level.ice, self.origin) < 25) || (distance(level.fire, self.origin) < 25) || (distance(level.wind, self.origin) < 25) || (distance(level.lightning, self.origin) < 25)) + vsmgr_activate( "overlay", "zm_powerup_zombie_blood_overlay", self); + else + vsmgr_deactivate( "overlay", "zm_powerup_zombie_blood_overlay", self); + wait 0.05; + } + vsmgr_deactivate( "overlay", "zm_powerup_zombie_blood_overlay", self); +} + +Dead_or_Alive_Ivo1() +{ + //stance = self getstance(); + //if (stance == "prone") + if (((distance(level.ice, self.origin) < 25) || (distance(level.fire, self.origin) < 25) || (distance(level.wind, self.origin) < 25) || (distance(level.lightning, self.origin) < 25))) + { + + //iPrintLn("Alive!"); + //continue; + } + else if (self.sessionstate != "spectator" && !(self maps\mp\zombies\_zm_laststand::player_is_in_laststand())) + { + //iPrintLn("Dead..."); + level.dead++; + //return dead; + } +} + +Dead_Ivo1() +{ + iPrintLnBold("^1Death Awaits..."); + playfxontag( level._effect["ee_beam"], self, "tag_origin" ); + wait 0.05; + + playFXOnTag( level._effect["ee_vortex"], self, "tag_origin"); + + + setdvar( "timescale", "0.6" ); + for (i = 0; i <= 2; i++) + { + self playlocalsound( level.zmb_laugh_alias ); + wait 0.7; + self doDamage_wrapper(self.health + 10000); + setdvar( "timescale", "1" ); + } +} + +Floating_Ivo1() +{ + for(i=0;i<120;i++) + { + level.boss.origin = level.boss.origin + ( 0, 0, 1 ); + wait 0.05; + } + +} + +//Phases +Phase_Starter_Ivo1() +{ + if (level.phase == 1) + { + level.boss thread IvoPhase1_H1_Ivo1(); + wait 0.05; + level.boss setcandamage( 0 ); + level.boss.candamage = 0; + level.phase++; + for (;;) + { + if (isdefined(level.boss.should_return) && level.boss.should_return == 1) + break; + wait 0.5; + } + wait 3; + } +} + +IvoPhase1_H1_Ivo1()//60 +{ + level.boss ForceTeleport(( 2754.93, 5402.57, -358.25 )); + + wait 1; + + level.zombie_total += 4; + + for(;;) + { + if (isdefined(level.inferno1) && isdefined(level.inferno2) && isdefined(level.electric1) && isdefined(level.electric2)) + break; + zombies = GetAIArray(level.zombie_team); + foreach(zombie in zombies) + { + if (isdefined(zombie.boss)) + continue; + if (zombie && zombie.completed_emerging_into_playable_area == 1 && !isdefined(zombie.miniboss)) + { + zombie.miniboss = 1; + if (!isdefined(level.inferno1)) + { + level.inferno1 = zombie; + level.inferno1 thread Infernos1_Ivo1(); + } + else if (!isdefined(level.inferno2)) + { + level.inferno2 = zombie; + level.inferno2 thread Infernos2_Ivo1(); + } + else if (!isdefined(level.electric1)) + { + level.electric1 = zombie; + level.electric1 thread Electrics1_Ivo1(); + } + else if (!isdefined(level.electric2)) + { + level.electric2 = zombie; + level.electric2 thread Electrics2_Ivo1(); + } + } + } + wait 1; + } + iPrintLn("^3[ ^1" + level.boss.name + " ^7] : ^3COME FOURTH INFERNOS!"); + wait 3.5; + iPrintLn("^3[ ^1" + level.boss.name + " ^7] : ^3Let's up the voltage ^1:)");// Titb Boss reference + wait 22; + iPrintLn("^3[ ^1" + level.boss.name + " ^7] : ^3Helmets ON lads");// Botb Boss Reference + level thread spawn_panzer(); + level thread spawn_panzer(); + + for(;;) + { + zombies = getaiarray(level.zombie_team); + if (zombies.size == 1) + break; + wait 0.5; + } + level.boss.should_return = 1; + random = level.places[randomint(level.places.size)]; + level.boss ForceTeleport(random); + level.boss setcandamage( 1 ); + level.boss.candamage = 1; + //iPrintLn("end phase 1"); +} + +Infernos1_Ivo1() +{ + self endon("death"); + //self ForceTeleport(level.Ice); + self set_zombie_run_cycle("super_sprint"); + //skin + self setmodel( "c_zom_tomb_german_body_1a" ); + self.headmodel = codescripts\character::randomelement( xmodelalias\c_zom_tomb_german_head_als::main() ); + self attach( self.headmodel, "", 1 ); + self.hatmodel = "c_zom_tomb_german_hat_1"; + self attach( self.hatmodel ); + self.voice = "american"; + self.skeleton = "base"; + self.torsodmg1 = "c_zom_tomb_german_body_g_upclean_1a"; + self.torsodmg2 = "c_zom_tomb_german_body_g_rarm_1a"; + self.torsodmg3 = "c_zom_tomb_german_body_g_larm_1a"; + self.torsodmg5 = "c_zom_tomb_german_body_g_behead"; + self.legdmg1 = "c_zom_tomb_german_body_g_lowclean_1a"; + self.legdmg2 = "c_zom_tomb_german_body_g_rleg_1a"; + self.legdmg3 = "c_zom_tomb_german_body_g_lleg_1a"; + self.legdmg4 = "c_zom_tomb_german_body_g_legsoff_1a"; + self.gibspawn1 = "c_zom_buried_g_rarmspawn"; + self.gibspawntag1 = "J_Elbow_RI"; + self.gibspawn2 = "c_zom_buried_g_larmspawn"; + self.gibspawntag2 = "J_Elbow_LE"; + self.gibspawn3 = "c_zom_buried_g_rlegspawn"; + self.gibspawntag3 = "J_Knee_RI"; + self.gibspawn4 = "c_zom_buried_g_llegspawn"; + self.gibspawntag4 = "J_Knee_LE"; + self.gibspawn5 = "c_zom_tomb_german_hat_1"; + self.gibspawntag5 = "J_Head"; + self.custom_item_dmg = 100000; + wait 3; + for (;;) + { + self setclientfield( "fire_char_fx", 1 ); + playfxontag( level._effect["wagon_fire"], level.inferno1, "tag_origin" ); + + // playfxontag( level._effect["fire_sacrifice_flame"], level.inferno1, "J_Wrist_LE" ); + + playfxontag( level._effect["wagon_fire"], level.inferno1, "J_Wrist_RI" ); + + // playfxontag( level._effect["fire_sacrifice_flame"], level.inferno1, "J_spinelower" ); + + foreach(player in level.players) + { + player thread Inferno_BURN1_Ivo1(); + } + wait 1; + self setclientfield( "fire_char_fx", 0 ); + wait 0.05; + } +} + +Inferno_BURN1_Ivo1() +{ + if (distance(level.inferno1.origin, self.origin) <= 210) //if close to boss //DamFunc + { + self dodamage_wrapper(600); // deal damage to self (you gotta run away !) //DamFunc + vsmgr_activate( "overlay", "zm_transit_burn", self, 1, 1 );//visual burn effect + wait 0.05; + self shellshock( "lava_small", 0.1 );//stun //DamFunc + } +} + +Infernos2_Ivo1() +{ + self endon("death"); + //self ForceTeleport(level.Fire); + self set_zombie_run_cycle("super_sprint"); + //skin + self setmodel( "c_zom_tomb_german_body_1b" ); + self.headmodel = codescripts\character::randomelement( xmodelalias\c_zom_tomb_german_head_als::main() ); + self attach( self.headmodel, "", 1 ); + self.hatmodel = "c_zom_tomb_german_hat_2"; + self attach( self.hatmodel ); + self.voice = "american"; + self.skeleton = "base"; + self.torsodmg1 = "c_zom_tomb_german_body_g_upclean_1b"; + self.torsodmg2 = "c_zom_tomb_german_body_g_rarm_1b"; + self.torsodmg3 = "c_zom_tomb_german_body_g_larm_1b"; + self.torsodmg5 = "c_zom_tomb_german_body_g_behead"; + self.legdmg1 = "c_zom_tomb_german_body_g_lowclean_1b"; + self.legdmg2 = "c_zom_tomb_german_body_g_rleg_1b"; + self.legdmg3 = "c_zom_tomb_german_body_g_lleg_1b"; + self.legdmg4 = "c_zom_tomb_german_body_g_legsoff_1b"; + self.gibspawn1 = "c_zom_buried_g_rarmspawn"; + self.gibspawntag1 = "J_Elbow_RI"; + self.gibspawn2 = "c_zom_buried_g_larmspawn"; + self.gibspawntag2 = "J_Elbow_LE"; + self.gibspawn3 = "c_zom_buried_g_rlegspawn"; + self.gibspawntag3 = "J_Knee_RI"; + self.gibspawn4 = "c_zom_buried_g_llegspawn"; + self.gibspawntag4 = "J_Knee_LE"; + self.gibspawn5 = "c_zom_tomb_german_hat_2"; + self.gibspawntag5 = "J_Head"; + self.custom_item_dmg = 100000; + wait 3; + for (;;) + { + self setclientfield( "fire_char_fx", 1 ); + playfxontag( level._effect["wagon_fire"], level.inferno2, "tag_origin" ); + + // playfxontag( level._effect["fire_sacrifice_flame"], level.inferno2, "J_Wrist_LE" ); + + playfxontag( level._effect["wagon_fire"], level.inferno2, "J_Wrist_RI" ); + + // playfxontag( level._effect["fire_sacrifice_flame"], level.inferno2, "J_spinelower" ); + + foreach(player in level.players) + { + player thread Inferno_BURN2_Ivo1(); + } + wait 1; + self setclientfield( "fire_char_fx", 0 ); + wait 0.05; + } +} + +Inferno_BURN2_Ivo1() +{ + if (distance(level.inferno2.origin, self.origin) <= 150) //if close to boss //DamFunc + { + self dodamage_wrapper(600); // deal damage to self (you gotta run away !) //DamFunc + vsmgr_activate( "overlay", "zm_transit_burn", self, 1, 1 );//visual burn effect + wait 0.05; + self shellshock( "lava_small", 0.1 );//stun //DamFunc + } +} + + +Electrics1_Ivo1() +{ + self endon("death"); + //self ForceTeleport(level.Ice); + self set_zombie_run_cycle("super_sprint"); + //skin + self setmodel( "c_zom_tomb_german_body_1a" ); + self.headmodel = codescripts\character::randomelement( xmodelalias\c_zom_tomb_german_head_als::main() ); + self attach( self.headmodel, "", 1 ); + self.hatmodel = "c_zom_tomb_german_hat_1"; + self attach( self.hatmodel ); + self.voice = "american"; + self.skeleton = "base"; + self.torsodmg1 = "c_zom_tomb_german_body_g_upclean_1a"; + self.torsodmg2 = "c_zom_tomb_german_body_g_rarm_1a"; + self.torsodmg3 = "c_zom_tomb_german_body_g_larm_1a"; + self.torsodmg5 = "c_zom_tomb_german_body_g_behead"; + self.legdmg1 = "c_zom_tomb_german_body_g_lowclean_1a"; + self.legdmg2 = "c_zom_tomb_german_body_g_rleg_1a"; + self.legdmg3 = "c_zom_tomb_german_body_g_lleg_1a"; + self.legdmg4 = "c_zom_tomb_german_body_g_legsoff_1a"; + self.gibspawn1 = "c_zom_buried_g_rarmspawn"; + self.gibspawntag1 = "J_Elbow_RI"; + self.gibspawn2 = "c_zom_buried_g_larmspawn"; + self.gibspawntag2 = "J_Elbow_LE"; + self.gibspawn3 = "c_zom_buried_g_rlegspawn"; + self.gibspawntag3 = "J_Knee_RI"; + self.gibspawn4 = "c_zom_buried_g_llegspawn"; + self.gibspawntag4 = "J_Knee_LE"; + self.gibspawn5 = "c_zom_tomb_german_hat_1"; + self.gibspawntag5 = "J_Head"; + self.custom_item_dmg = 100000; + wait 3; + for (;;) + { + self setclientfield( "lightning_arc_fx", 1 ); + playfxontag( level._effect["tesla_elec_kill"], level.electric1, "tag_origin" ); + + // playfxontag( level._effect["fire_sacrifice_flame"], level.electric1, "J_Wrist_LE" ); + + playfxontag( level._effect["electric_cherry_explode"], level.electric1, "tag_origin" ); + + // playfxontag( level._effect["fire_sacrifice_flame"], level.electric1, "J_spinelower" ); + level.electric1 playsound("zmb_cherry_explode"); + foreach(player in level.players) + { + player thread Electric_Shot1_Ivo1(); + player thread Phase_Cherry1_Ivo1(); + } + wait 4; + self setclientfield( "lightning_arc_fx", 0 ); + wait 0.05; + } +} + +Electric_Shot1_Ivo1() +{ + r = randomint(level.players.size); + if (!level.players[r] maps\mp\zombies\_zm_laststand::player_is_in_laststand() && level.players[r].sessionstate == "playing") + { + target = level.players[r]; + //target add_to_player_score(100); + } + + else //if (level.players[r] maps\mp\zombies\_zm_laststand::player_is_in_laststand()) + { + return Electric_Shot1_Ivo1(); + } + + + source_pos = level.electric1 gettagorigin( "J_Helmet" ); + target_pos = target geteye(); + + bolt = spawn( "script_model", source_pos ); + bolt setmodel( "tag_origin" ); + wait 0.1; //DamFunc + + fx = playfxontag( level._effect["qd_revive"], bolt, "tag_origin" ); + bolt moveto( target_pos, 0.3 ); + bolt waittill( "movedone" ); + bolt.owner = self; + bolt check_bolt_impactPhase_Ivo1( target ); + bolt delete();//wpn_revivestaff_revive_plr +} + +Phase_Cherry1_Ivo1() +{ + if (distance(level.electric1.origin, self.origin) < 200) //if close to boss + { + self dodamage_wrapper(300); // deal damage to self (you gotta run away !) + wait 0.05; + self shellshock( "lava_small", 0.1 );//stun //DamFunc + } +} + +Electrics2_Ivo1() +{ + self endon("death"); + //self ForceTeleport(level.Fire); + self set_zombie_run_cycle("super_sprint"); + //skin + self setmodel( "c_zom_tomb_german_body_1b" ); + self.headmodel = codescripts\character::randomelement( xmodelalias\c_zom_tomb_german_head_als::main() ); + self attach( self.headmodel, "", 1 ); + self.hatmodel = "c_zom_tomb_german_hat_2"; + self attach( self.hatmodel ); + self.voice = "american"; + self.skeleton = "base"; + self.torsodmg1 = "c_zom_tomb_german_body_g_upclean_1b"; + self.torsodmg2 = "c_zom_tomb_german_body_g_rarm_1b"; + self.torsodmg3 = "c_zom_tomb_german_body_g_larm_1b"; + self.torsodmg5 = "c_zom_tomb_german_body_g_behead"; + self.legdmg1 = "c_zom_tomb_german_body_g_lowclean_1b"; + self.legdmg2 = "c_zom_tomb_german_body_g_rleg_1b"; + self.legdmg3 = "c_zom_tomb_german_body_g_lleg_1b"; + self.legdmg4 = "c_zom_tomb_german_body_g_legsoff_1b"; + self.gibspawn1 = "c_zom_buried_g_rarmspawn"; + self.gibspawntag1 = "J_Elbow_RI"; + self.gibspawn2 = "c_zom_buried_g_larmspawn"; + self.gibspawntag2 = "J_Elbow_LE"; + self.gibspawn3 = "c_zom_buried_g_rlegspawn"; + self.gibspawntag3 = "J_Knee_RI"; + self.gibspawn4 = "c_zom_buried_g_llegspawn"; + self.gibspawntag4 = "J_Knee_LE"; + self.gibspawn5 = "c_zom_tomb_german_hat_2"; + self.gibspawntag5 = "J_Head"; + self.custom_item_dmg = 100000; + wait 3; + for (;;) + { + self setclientfield( "lightning_arc_fx", 1 ); + playfxontag( level._effect["tesla_elec_kill"], level.electric2, "tag_origin" ); + + // playfxontag( level._effect["fire_sacrifice_flame"], level.electric2, "J_Wrist_LE" ); + + playfxontag( level._effect["electric_cherry_explode"], level.electric2, "tag_origin" ); + + // playfxontag( level._effect["fire_sacrifice_flame"], level.electric2, "J_spinelower" ); + level.electric2 playsound("zmb_cherry_explode"); + foreach(player in level.players) + { + player thread Electric_Shot2_Ivo1(); + player thread Phase_Cherry2_Ivo1(); + } + wait 4; + self setclientfield( "lightning_arc_fx", 0 ); + wait 0.05; + } +} + +Electric_Shot2_Ivo1() +{ + r = randomint(level.players.size); + if (!level.players[r] maps\mp\zombies\_zm_laststand::player_is_in_laststand() && level.players[r].sessionstate == "playing") + { + target = level.players[r]; + //target add_to_player_score(100); + } + + else //if (level.players[r] maps\mp\zombies\_zm_laststand::player_is_in_laststand()) + { + return Electric_Shot2_Ivo1(); + } + + + source_pos = level.electric2 gettagorigin( "J_Helmet" ); + target_pos = target geteye(); + + bolt = spawn( "script_model", source_pos ); + bolt setmodel( "tag_origin" ); + wait 0.1; //DamFunc + + fx = playfxontag( level._effect["qd_revive"], bolt, "tag_origin" ); + bolt moveto( target_pos, 0.3 ); + bolt waittill( "movedone" ); + bolt.owner = self; + bolt check_bolt_impactPhase_Ivo1( target ); + bolt delete();//wpn_revivestaff_revive_plr +} + +Phase_Cherry2_Ivo1() +{ + if (distance(level.electric2.origin, self.origin) < 200) //if close to boss + { + self dodamage_wrapper(300); // deal damage to self (you gotta run away !) + wait 0.05; + self shellshock( "lava_small", 0.1 );//stun //DamFunc + } +} + +check_bolt_impactPhase_Ivo1( target ) +{ + if ( is_player_valid( target )) + { + target_eye_pos = target geteye(); + dist_sq = distancesquared( self.origin, target_eye_pos ); + + if ( dist_sq < 4096 ) + { + passed = bullettracepassed( self.origin, target_eye_pos, 0, undefined ); + + if ( passed ) + { + target dodamage_wrapper(400); //DamFunc + vsmgr_activate( "overlay", "zm_transit_burn", target, 2, 2 ); + wait 0.05; + target shellshock( "lava_small", 0.1 );//DamFunc + target playsoundtoplayer( "wpn_revivestaff_proj_impact", target ); + + } + } + } +} + + +Phase_check1_Ivo1() +{ + for (;;) + { + if (level.boss.health <= level.boss.maxhealth * 0.33)//33% HP + { + level.boss setcandamage( 0 ); + level.boss.candamage = 0; + level.phase = 1; + iPrintLn("^3[ ^1" + level.boss.name + " ^7] : ^3Let's see how you handle this !");// Botb Boss Reference + break; + } + wait 0.05; + } +} diff --git a/t6/uncompiled mods/box_no_limits.gsc b/t6/uncompiled mods/box_no_limits.gsc new file mode 100644 index 0000000..231c3a5 --- /dev/null +++ b/t6/uncompiled mods/box_no_limits.gsc @@ -0,0 +1,1610 @@ +#include maps/mp/zombies/_zm_stats; +#include maps/mp/_demo; +#include maps/mp/zombies/_zm_audio; +#include maps/mp/zombies/_zm_score; +#include maps/mp/zombies/_zm_pers_upgrades_functions; +#include maps/mp/zombies/_zm_audio_announcer; +#include maps/mp/zombies/_zm_unitrigger; +#include maps/mp/zombies/_zm_weapons; +#include maps/mp/zombies/_zm_utility; +#include maps/mp/_utility; +#include common_scripts/utility; +#include maps/mp/zombies/_zm_magicbox_lock; + +init() //checked matches cerberus output +{ + //begin debug code + level.custom_zm_magicbox_loaded = 1; + maps/mp/zombies/_zm_bot::init(); + if ( !isDefined( level.debugLogging_zm_magicbox ) ) + { + level.debugLogging_zm_magicbox = 0; + } + //end debug code + if ( !isDefined( level.chest_joker_model ) ) + { + level.chest_joker_model = "zombie_teddybear"; + precachemodel( level.chest_joker_model ); + } + + if ( !isDefined( level.magic_box_zbarrier_state_func ) ) + { + level.magic_box_zbarrier_state_func = ::process_magic_box_zbarrier_state; + } + if ( is_true( level.using_locked_magicbox ) ) + { + maps/mp/zombies/_zm_magicbox_lock::init(); + } + if ( is_classic() ) + { + level.chests = getstructarray( "treasure_chest_use", "targetname" ); + treasure_chest_init( "start_chest" ); + } + if ( level.createfx_enabled ) + { + return; + } + registerclientfield( "zbarrier", "magicbox_glow", 1000, 1, "int" ); + registerclientfield( "zbarrier", "zbarrier_show_sounds", 9000, 1, "int" ); + registerclientfield( "zbarrier", "zbarrier_leave_sounds", 9000, 1, "int" ); + if ( !isDefined( level.magic_box_check_equipment ) ) + { + level.magic_box_check_equipment = ::default_magic_box_check_equipment; + } + level thread magicbox_host_migration(); +} + +treasure_chest_init( start_chest_name ) //checked changed to match cerberus output +{ + flag_init( "moving_chest_enabled" ); + flag_init( "moving_chest_now" ); + flag_init( "chest_has_been_used" ); + level.chest_moves = 0; + level.chest_level = 0; + if ( level.chests.size == 0 ) + { + return; + } + for ( i = 0; i < level.chests.size; i++ ) + { + level.chests[ i ].box_hacks = []; + level.chests[ i ].orig_origin = level.chests[ i ].origin; + level.chests[ i ] get_chest_pieces(); + if ( isDefined( level.chests[ i ].zombie_cost ) ) + { + level.chests[ i ].old_cost = level.chests[ i ].zombie_cost; + } + else + { + level.chests[ i ].old_cost = 950; + } + } + if ( !level.enable_magic ) + { + foreach( chest in level.chests ) + { + chest hide_chest(); + } + return; + } + level.chest_accessed = 0; + if ( level.chests.size > 1 ) + { + flag_set( "moving_chest_enabled" ); + level.chests = array_randomize( level.chests ); + } + else + { + level.chest_index = 0; + level.chests[ 0 ].no_fly_away = 1; + } + init_starting_chest_location( start_chest_name ); + array_thread( level.chests, ::treasure_chest_think ); +} + +init_starting_chest_location( start_chest_name ) //checked changed to match cerberus output +{ + level.chest_index = 0; + start_chest_found = 0; + if ( level.chests.size == 1 ) + { + start_chest_found = 1; + if ( isdefined( level.chests[ level.chest_index ].zbarrier ) ) + { + level.chests[ level.chest_index ].zbarrier set_magic_box_zbarrier_state( "initial" ); + } + } + else + { + for ( i = 0; i < level.chests.size; i++ ) + { + if ( isdefined( level.random_pandora_box_start ) && level.random_pandora_box_start == 1 ) + { + if ( start_chest_found || isdefined( level.chests[ i ].start_exclude ) && level.chests[ i ].start_exclude == 1 ) + { + level.chests[ i ] hide_chest(); + } + else + { + level.chest_index = i; + level.chests[ level.chest_index].hidden = 0; + if ( isdefined( level.chests[ level.chest_index ].zbarrier ) ) + { + level.chests[ level.chest_index ].zbarrier set_magic_box_zbarrier_state( "initial" ); + } + start_chest_found = 1; + } + } + else + { + if ( start_chest_found || !isdefined(level.chests[ i ].script_noteworthy) || !issubstr( level.chests[ i ].script_noteworthy, start_chest_name ) ) + { + level.chests[ i ] hide_chest(); + } + else + { + level.chest_index = i; + level.chests[ level.chest_index ].hidden = 0; + if ( isdefined( level.chests[ level.chest_index ].zbarrier ) ) + { + level.chests[ level.chest_index ].zbarrier set_magic_box_zbarrier_state( "initial" ); + } + start_chest_found = 1; + } + } + } + } + if ( !isdefined( level.pandora_show_func ) ) + { + level.pandora_show_func = ::default_pandora_show_func; + } + level.chests[ level.chest_index ] thread [[ level.pandora_show_func ]](); +} + +set_treasure_chest_cost( cost ) //checked matches cerberus output +{ + level.zombie_treasure_chest_cost = cost; +} + +get_chest_pieces() //checked changed to match cerberus output +{ + self.chest_box = getent( self.script_noteworthy + "_zbarrier", "script_noteworthy" ); + self.chest_rubble = []; + rubble = getentarray( self.script_noteworthy + "_rubble", "script_noteworthy" ); + for ( i = 0; i < rubble.size; i++ ) + { + if ( distancesquared( self.origin, rubble[ i ].origin ) < 10000 ) + { + self.chest_rubble[ self.chest_rubble.size ] = rubble[ i ]; + } + } + self.zbarrier = getent( self.script_noteworthy + "_zbarrier", "script_noteworthy" ); + if ( isDefined( self.zbarrier ) ) + { + self.zbarrier zbarrierpieceuseboxriselogic( 3 ); + self.zbarrier zbarrierpieceuseboxriselogic( 4 ); + } + self.unitrigger_stub = spawnstruct(); + self.unitrigger_stub.origin = self.origin + ( anglesToRight( self.angles ) * -22.5 ); + self.unitrigger_stub.angles = self.angles; + self.unitrigger_stub.script_unitrigger_type = "unitrigger_box_use"; + self.unitrigger_stub.script_width = 104; + self.unitrigger_stub.script_height = 50; + self.unitrigger_stub.script_length = 45; + self.unitrigger_stub.trigger_target = self; + unitrigger_force_per_player_triggers( self.unitrigger_stub, 1 ); + self.unitrigger_stub.prompt_and_visibility_func = ::boxtrigger_update_prompt; + self.zbarrier.owner = self; +} + +boxtrigger_update_prompt( player ) //checked matches cerberus output +{ + can_use = self boxstub_update_prompt( player ); + if ( isDefined( self.hint_string ) ) + { + if ( isDefined( self.hint_parm1 ) ) + { + self sethintstring( self.hint_string, self.hint_parm1 ); + } + else + { + self sethintstring( self.hint_string ); + } + } + return can_use; +} + +boxstub_update_prompt( player ) //checked matches cerberus output +{ + self setcursorhint( "HINT_NOICON" ); + if ( !self trigger_visible_to_player( player ) ) + { + return 0; + } + self.hint_parm1 = undefined; + if ( is_true( self.stub.trigger_target.grab_weapon_hint ) ) + { + if ( isDefined( level.magic_box_check_equipment ) && [[ level.magic_box_check_equipment ]]( self.stub.trigger_target.grab_weapon_name ) ) + { + self.hint_string = &"ZOMBIE_TRADE_EQUIP"; + } + else + { + self.hint_string = &"ZOMBIE_TRADE_WEAPON"; + } + } + else if ( is_true( level.using_locked_magicbox ) && is_true( self.stub.trigger_target.is_locked ) ) + { + self.hint_string = get_hint_string( self, "locked_magic_box_cost" ); + } + else + { + self.hint_parm1 = self.stub.trigger_target.zombie_cost; + self.hint_string = get_hint_string( self, "default_treasure_chest" ); + } + return 1; +} + +default_magic_box_check_equipment( weapon ) //checked matches cerberus output +{ + return is_offhand_weapon( weapon ); +} + +trigger_visible_to_player( player ) //checked changed to match cerberus output +{ + self setinvisibletoplayer( player ); + visible = 1; + if ( isDefined( self.stub.trigger_target.chest_user ) && !isDefined( self.stub.trigger_target.box_rerespun ) ) + { + if ( player != self.stub.trigger_target.chest_user || is_placeable_mine( self.stub.trigger_target.chest_user getcurrentweapon() ) || self.stub.trigger_target.chest_user hacker_active() ) + { + visible = 0; + } + } + else if ( !player can_buy_weapon() ) + { + visible = 0; + } + if ( !visible ) + { + return 0; + } + self setvisibletoplayer( player ); + return 1; +} + +magicbox_unitrigger_think() //checked changed to match cerberus output +{ + self endon( "kill_trigger" ); + while ( 1 ) + { + self waittill( "trigger", player ); + self.stub.trigger_target notify( "trigger", player ); + } +} + +play_crazi_sound() //checked matches cerberus output +{ + self playlocalsound( level.zmb_laugh_alias ); +} + +show_chest_sound_thread() //checked matches cerberus output +{ + self.zbarrier setclientfield( "zbarrier_show_sounds", 1 ); + wait 1; + self.zbarrier setclientfield( "zbarrier_show_sounds", 0 ); +} + +show_chest() //checked matches cerberus output +{ + self.zbarrier set_magic_box_zbarrier_state( "arriving" ); + self.zbarrier waittill( "arrived" ); + self thread [[ level.pandora_show_func ]](); + thread maps/mp/zombies/_zm_unitrigger::register_static_unitrigger( self.unitrigger_stub, ::magicbox_unitrigger_think ); + self thread show_chest_sound_thread(); + self.hidden = 0; + if ( isDefined( self.box_hacks[ "summon_box" ] ) ) + { + self [[ self.box_hacks[ "summon_box" ] ]]( 0 ); + } +} + +hide_chest_sound_thread() //checked matches cerberus output +{ + self.zbarrier setclientfield( "zbarrier_leave_sounds", 1 ); + wait 1; + self.zbarrier setclientfield( "zbarrier_leave_sounds", 0 ); +} + +hide_chest( doboxleave ) //checked matches cerberus output +{ + if ( isDefined( self.unitrigger_stub ) ) + { + thread maps/mp/zombies/_zm_unitrigger::unregister_unitrigger( self.unitrigger_stub ); + } + if ( isDefined( self.pandora_light ) ) + { + self.pandora_light delete(); + } + self.hidden = 1; + if ( isDefined( self.box_hacks ) && isDefined( self.box_hacks[ "summon_box" ] ) ) + { + self [[ self.box_hacks[ "summon_box" ] ]]( 1 ); + } + if ( isDefined( self.zbarrier ) ) + { + if ( is_true( doboxleave ) ) + { + self thread hide_chest_sound_thread(); + level thread leaderdialog( "boxmove" ); + self.zbarrier thread magic_box_zbarrier_leave(); + self.zbarrier waittill( "left" ); + playfx( level._effect[ "poltergeist" ], self.zbarrier.origin, anglesToUp( self.angles ), anglesToForward( self.angles ) ); + playsoundatposition( "zmb_box_poof", self.zbarrier.origin ); + return; + } + else + { + self.zbarrier thread set_magic_box_zbarrier_state( "away" ); + } + } +} + +magic_box_zbarrier_leave() //checked matches cerberus output +{ + self set_magic_box_zbarrier_state( "leaving" ); + self waittill( "left" ); + self set_magic_box_zbarrier_state( "away" ); +} + +default_pandora_fx_func() //checked partially changed to match cerberus output +{ + self endon( "death" ); + self.pandora_light = spawn( "script_model", self.zbarrier.origin ); + self.pandora_light.angles = self.zbarrier.angles + vectorScale( ( -1, 0, -1 ), 90 ); + self.pandora_light setmodel( "tag_origin" ); + if ( !is_true( level._box_initialized ) ) + { + flag_wait( "start_zombie_round_logic" ); + level._box_initialized = 1; + } + wait 1; + if ( isDefined( self ) && isDefined( self.pandora_light ) ) + { + playfxontag( level._effect[ "lght_marker" ], self.pandora_light, "tag_origin" ); + } +} + +default_pandora_show_func( anchor, anchortarget, pieces ) //checked matches cerberus output +{ + if ( !isDefined( self.pandora_light ) ) + { + if ( !isDefined( level.pandora_fx_func ) ) + { + level.pandora_fx_func = ::default_pandora_fx_func; + } + self thread [[ level.pandora_fx_func ]](); + } + playfx( level._effect[ "lght_marker_flare" ], self.pandora_light.origin ); +} + +unregister_unitrigger_on_kill_think() //checked matches cerberus output +{ + self notify( "unregister_unitrigger_on_kill_think" ); + self endon( "unregister_unitrigger_on_kill_think" ); + self waittill( "kill_chest_think" ); + thread maps/mp/zombies/_zm_unitrigger::unregister_unitrigger( self.unitrigger_stub ); +} + +treasure_chest_think() //checked changed to match cerberus output +{ + self endon( "kill_chest_think" ); + user = undefined; + user_cost = undefined; + self.box_rerespun = undefined; + self.weapon_out = undefined; + + self thread unregister_unitrigger_on_kill_think(); + while ( 1 ) + { + if ( !isdefined( self.forced_user ) ) + { + self waittill( "trigger", user ); + if ( user == level ) + { + wait 0.1; + continue; + } + } + else + { + user = self.forced_user; + } + if ( user in_revive_trigger() ) + { + wait 0.1; + continue; + } + if ( user.is_drinking > 0 ) + { + wait 0.1; + continue; + } + if ( is_true( self.disabled ) ) + { + wait 0.1; + continue; + } + if ( user getcurrentweapon() == "none" ) + { + wait 0.1; + continue; + } + reduced_cost = undefined; + if ( is_player_valid( user ) && user maps/mp/zombies/_zm_pers_upgrades_functions::is_pers_double_points_active() ) + { + reduced_cost = int( self.zombie_cost / 2 ); + } + if ( is_true( level.using_locked_magicbox ) && is_true( self.is_locked ) ) + { + if ( user.score >= level.locked_magic_box_cost ) + { + user maps/mp/zombies/_zm_score::minus_to_player_score( level.locked_magic_box_cost ); + self.zbarrier set_magic_box_zbarrier_state( "unlocking" ); + self.unitrigger_stub run_visibility_function_for_all_triggers(); + } + else + { + user maps/mp/zombies/_zm_audio::create_and_play_dialog( "general", "no_money_box" ); + } + wait 0.1 ; + continue; + } + else if ( isdefined( self.auto_open ) && is_player_valid( user ) ) + { + if ( !isdefined( self.no_charge ) ) + { + user maps/mp/zombies/_zm_score::minus_to_player_score( self.zombie_cost ); + user_cost = self.zombie_cost; + } + else + { + user_cost = 0; + } + self.chest_user = user; + break; + } + else if ( is_player_valid( user ) && user.score >= self.zombie_cost ) + { + user maps/mp/zombies/_zm_score::minus_to_player_score( self.zombie_cost ); + user_cost = self.zombie_cost; + self.chest_user = user; + break; + } + else if ( isdefined( reduced_cost ) && user.score >= reduced_cost ) + { + user maps/mp/zombies/_zm_score::minus_to_player_score( reduced_cost ); + user_cost = reduced_cost; + self.chest_user = user; + break; + } + else if ( user.score < self.zombie_cost ) + { + play_sound_at_pos( "no_purchase", self.origin ); + user maps/mp/zombies/_zm_audio::create_and_play_dialog( "general", "no_money_box" ); + wait 0.1; + continue; + } + wait 0.05; + } + flag_set( "chest_has_been_used" ); + maps/mp/_demo::bookmark( "zm_player_use_magicbox", getTime(), user ); + user maps/mp/zombies/_zm_stats::increment_client_stat( "use_magicbox" ); + user maps/mp/zombies/_zm_stats::increment_player_stat( "use_magicbox" ); + if ( isDefined( level._magic_box_used_vo ) ) + { + user thread [[ level._magic_box_used_vo ]](); + } + self thread watch_for_emp_close(); + if ( is_true( level.using_locked_magicbox ) ) + { + self thread maps/mp/zombies/_zm_magicbox_lock::watch_for_lock(); + } + self._box_open = 1; + self._box_opened_by_fire_sale = 0; + if ( is_true( level.zombie_vars[ "zombie_powerup_fire_sale_on" ] ) && !isDefined( self.auto_open ) && self [[ level._zombiemode_check_firesale_loc_valid_func ]]() ) + { + self._box_opened_by_fire_sale = 1; + } + if ( isDefined( self.chest_lid ) ) + { + self.chest_lid thread treasure_chest_lid_open(); + } + if ( isDefined( self.zbarrier ) ) + { + play_sound_at_pos( "open_chest", self.origin ); + play_sound_at_pos( "music_chest", self.origin ); + self.zbarrier set_magic_box_zbarrier_state( "open" ); + } + self.timedout = 0; + self.weapon_out = 1; + self.zbarrier thread treasure_chest_weapon_spawn( self, user ); + self.zbarrier thread treasure_chest_glowfx(); + thread maps/mp/zombies/_zm_unitrigger::unregister_unitrigger( self.unitrigger_stub ); + self.zbarrier waittill_any( "randomization_done", "box_hacked_respin" ); + if ( flag( "moving_chest_now" ) && !self._box_opened_by_fire_sale && isDefined( user_cost ) ) + { + user maps/mp/zombies/_zm_score::add_to_player_score( user_cost, 0 ); + } + if ( flag( "moving_chest_now" ) && !level.zombie_vars[ "zombie_powerup_fire_sale_on" ] && !self._box_opened_by_fire_sale ) + { + self thread treasure_chest_move( self.chest_user ); + } + else + { + self.grab_weapon_hint = 1; + self.grab_weapon_name = self.zbarrier.weapon_string; + self.chest_user = user; + thread maps/mp/zombies/_zm_unitrigger::register_static_unitrigger( self.unitrigger_stub, ::magicbox_unitrigger_think ); + if ( isDefined( self.zbarrier ) && !is_true( self.zbarrier.closed_by_emp ) ) + { + self thread treasure_chest_timeout(); + } + while ( !is_true( self.closed_by_emp ) ) + { + self waittill( "trigger", grabber ); + self.weapon_out = undefined; + if ( is_true( level.magic_box_grab_by_anyone ) ) + { + if ( isplayer( grabber ) ) + { + user = grabber; + } + } + if ( is_true( level.pers_upgrade_box_weapon ) ) + { + self maps/mp/zombies/_zm_pers_upgrades_functions::pers_upgrade_box_weapon_used( user, grabber ); + } + if ( isDefined( grabber.is_drinking ) && grabber.is_drinking > 0 ) + { + wait 0.1; + continue; + } + if ( grabber == user && user getcurrentweapon() == "none" ) + { + wait 0.1; + continue; + } + if ( grabber != level && is_true( self.box_rerespun ) ) + { + user = grabber; + } + if ( grabber == user || grabber == level ) + { + self.box_rerespun = undefined; + current_weapon = "none"; + if ( is_player_valid( user ) ) + { + current_weapon = user getcurrentweapon(); + } + if ( grabber == user && is_player_valid( user ) && !user.is_drinking && !is_placeable_mine( current_weapon ) && !is_equipment( current_weapon ) && level.revive_tool != current_weapon ) + { + bbprint( "zombie_uses", "playername %s playerscore %d round %d cost %d name %s x %f y %f z %f type %s", user.name, user.score, level.round_number, self.zombie_cost, self.zbarrier.weapon_string, self.origin, "magic_accept" ); + self notify( "user_grabbed_weapon" ); + user notify( "user_grabbed_weapon" ); + user thread treasure_chest_give_weapon( self.zbarrier.weapon_string ); + maps/mp/_demo::bookmark( "zm_player_grabbed_magicbox", getTime(), user ); + user maps/mp/zombies/_zm_stats::increment_client_stat( "grabbed_from_magicbox" ); + user maps/mp/zombies/_zm_stats::increment_player_stat( "grabbed_from_magicbox" ); + break; + } + else if ( grabber == level ) + { + unacquire_weapon_toggle( self.zbarrier.weapon_string ); + self.timedout = 1; + if ( is_player_valid( user ) ) + { + bbprint( "zombie_uses", "playername %s playerscore %d round %d cost %d name %s x %f y %f z %f type %S", user.name, user.score, level.round_number, self.zombie_cost, self.zbarrier.weapon_string, self.origin, "magic_reject" ); + } + break; + } + } + wait 0.05; + } + self.grab_weapon_hint = 0; + self.zbarrier notify( "weapon_grabbed" ); + if ( !is_true( self._box_opened_by_fire_sale ) ) + { + level.chest_accessed += 1; + } + if ( level.chest_moves > 0 && isDefined( level.pulls_since_last_ray_gun ) ) + { + level.pulls_since_last_ray_gun += 1; + } + if ( isDefined( level.pulls_since_last_tesla_gun ) ) + { + level.pulls_since_last_tesla_gun += 1; + } + thread maps/mp/zombies/_zm_unitrigger::unregister_unitrigger( self.unitrigger_stub ); + if ( isDefined( self.chest_lid ) ) + { + self.chest_lid thread treasure_chest_lid_close( self.timedout ); + } + if ( isDefined( self.zbarrier ) ) + { + self.zbarrier set_magic_box_zbarrier_state( "close" ); + play_sound_at_pos( "close_chest", self.origin ); + self.zbarrier waittill( "closed" ); + wait 1; + } + else + { + wait 3; + } + if ( is_true( level.zombie_vars[ "zombie_powerup_fire_sale_on" ] ) || self [[ level._zombiemode_check_firesale_loc_valid_func ]]() || self == level.chests[ level.chest_index ] ) + { + thread maps/mp/zombies/_zm_unitrigger::register_static_unitrigger( self.unitrigger_stub, ::magicbox_unitrigger_think ); + } + } + self._box_open = 0; + self._box_opened_by_fire_sale = 0; + self.chest_user = undefined; + self notify( "chest_accessed" ); + self thread treasure_chest_think(); +} + +watch_for_emp_close() //checked changed to match cerberus output +{ + self endon( "chest_accessed" ); + self.closed_by_emp = 0; + if ( !should_watch_for_emp() ) + { + return; + } + if ( isDefined( self.zbarrier ) ) + { + self.zbarrier.closed_by_emp = 0; + } + while ( 1 ) + { + level waittill( "emp_detonate", origin, radius ); + if ( distancesquared( origin, self.origin ) < ( radius * radius ) ) + { + break; + } + } + if ( flag( "moving_chest_now" ) ) + { + return; + } + self.closed_by_emp = 1; + if ( isDefined( self.zbarrier ) ) + { + self.zbarrier.closed_by_emp = 1; + self.zbarrier notify( "box_hacked_respin" ); + if ( isDefined( self.zbarrier.weapon_model ) ) + { + self.zbarrier.weapon_model notify( "kill_weapon_movement" ); + } + if ( isDefined( self.zbarrier.weapon_model_dw ) ) + { + self.zbarrier.weapon_model_dw notify( "kill_weapon_movement" ); + } + } + wait 0.1; + self notify( "trigger", level ); +} + +can_buy_weapon() //checked matches cerberus output +{ + if ( isDefined( self.is_drinking ) && self.is_drinking > 0 ) + { + return 0; + } + if ( self hacker_active() ) + { + return 0; + } + current_weapon = self getcurrentweapon(); + if ( is_placeable_mine( current_weapon ) || is_equipment_that_blocks_purchase( current_weapon ) ) + { + return 0; + } + if ( self in_revive_trigger() ) + { + return 0; + } + if ( current_weapon == "none" ) + { + return 0; + } + return 1; +} + +default_box_move_logic() //checked changed to match cerberus output +{ + index = -1; + for ( i = 0; i < level.chests.size; i++ ) + { + if ( issubstr( level.chests[ i ].script_noteworthy, "move" + level.chest_moves + 1 ) && i != level.chest_index ) + { + index = i; + break; + } + } + if ( index != -1 ) + { + level.chest_index = index; + } + else + { + level.chest_index++; + } + if ( level.chest_index >= level.chests.size ) + { + temp_chest_name = level.chests[ level.chest_index - 1 ].script_noteworthy; + level.chest_index = 0; + level.chests = array_randomize( level.chests ); + if ( temp_chest_name == level.chests[ level.chest_index ].script_noteworthy ) + { + level.chest_index++; + } + } +} + +treasure_chest_move( player_vox ) //checked changed to match cerberus output +{ + level waittill( "weapon_fly_away_start" ); + players = get_players(); + array_thread( players, ::play_crazi_sound ); + if ( isDefined( player_vox ) ) + { + player_vox delay_thread( randomintrange( 2, 7 ), ::create_and_play_dialog, "general", "box_move" ); + } + level waittill( "weapon_fly_away_end" ); + if ( isDefined( self.zbarrier ) ) + { + self hide_chest( 1 ); + } + wait 0.1; + post_selection_wait_duration = 7; + if ( level.zombie_vars[ "zombie_powerup_fire_sale_on" ] == 1 && self [[ level._zombiemode_check_firesale_loc_valid_func ]]() ) + { + current_sale_time = level.zombie_vars[ "zombie_powerup_fire_sale_time" ]; + wait_network_frame(); + self thread fire_sale_fix(); + level.zombie_vars[ "zombie_powerup_fire_sale_time" ] = current_sale_time; + while ( level.zombie_vars[ "zombie_powerup_fire_sale_time" ] > 0 ) + { + wait 0.1; + } + } + else + { + post_selection_wait_duration += 5; + } + level.verify_chest = 0; + if ( isDefined( level._zombiemode_custom_box_move_logic ) ) + { + [[ level._zombiemode_custom_box_move_logic ]](); + } + else + { + default_box_move_logic(); + } + if ( isDefined( level.chests[ level.chest_index ].box_hacks[ "summon_box" ] ) ) + { + level.chests[ level.chest_index ] [[ level.chests[ level.chest_index ].box_hacks[ "summon_box" ] ]]( 0 ); + } + wait post_selection_wait_duration; + playfx( level._effect[ "poltergeist" ], level.chests[ level.chest_index ].zbarrier.origin ); + level.chests[ level.chest_index ] show_chest(); + flag_clear( "moving_chest_now" ); + self.zbarrier.chest_moving = 0; +} + +fire_sale_fix() //checked matches cerberus output +{ + if ( !isDefined( level.zombie_vars[ "zombie_powerup_fire_sale_on" ] ) ) + { + return; + } + if ( level.zombie_vars[ "zombie_powerup_fire_sale_on" ] ) + { + self.old_cost = 950; + self thread show_chest(); + self.zombie_cost = 10; + self.unitrigger_stub unitrigger_set_hint_string( self, "default_treasure_chest", self.zombie_cost ); + wait_network_frame(); + level waittill( "fire_sale_off" ); + while ( is_true( self._box_open ) ) + { + wait 0.1; + } + self hide_chest( 1 ); + self.zombie_cost = self.old_cost; + } +} + +check_for_desirable_chest_location() //checked changed to match cerberus output +{ + if ( !isDefined( level.desirable_chest_location ) ) + { + return level.chest_index; + } + if ( level.chests[ level.chest_index ].script_noteworthy == level.desirable_chest_location ) + { + level.desirable_chest_location = undefined; + return level.chest_index; + } + for ( i = 0; i < level.chests.size; i++ ) + { + if ( level.chests[ i ].script_noteworthy == level.desirable_chest_location ) + { + level.desirable_chest_location = undefined; + return i; + } + } + /* +/# + iprintln( level.desirable_chest_location + " is an invalid box location!" ); +#/ + */ + level.desirable_chest_location = undefined; + return level.chest_index; +} + +rotateroll_box() //checked matches cerberus output +{ + angles = 40; + angles2 = 0; + while ( isDefined( self ) ) + { + self rotateroll( angles + angles2, 0.5 ); + wait 0.7; + angles2 = 40; + self rotateroll( angles * -2, 0.5 ); + wait 0.7; + } +} + +verify_chest_is_open() //checked changed to match cerberus output +{ + for ( i = 0; i < level.open_chest_location.size; i++ ) + { + if ( isDefined( level.open_chest_location[ i ] ) ) + { + if ( level.open_chest_location[ i ] == level.chests[ level.chest_index ].script_noteworthy ) + { + level.verify_chest = 1; + return; + } + } + } + level.verify_chest = 0; +} + +treasure_chest_timeout() //checked changed to match cerberus output +{ + self endon( "user_grabbed_weapon" ); + self.zbarrier endon( "box_hacked_respin" ); + self.zbarrier endon( "box_hacked_rerespin" ); + wait 12; + self notify( "trigger", level ); +} + +treasure_chest_lid_open() //checked matches cerberus output +{ + openroll = 105; + opentime = 0.5; + self rotateroll( 105, opentime, opentime * 0.5 ); + play_sound_at_pos( "open_chest", self.origin ); + play_sound_at_pos( "music_chest", self.origin ); +} + +treasure_chest_lid_close( timedout ) //checked matches cerberus output +{ + closeroll = -105; + closetime = 0.5; + self rotateroll( closeroll, closetime, closetime * 0.5 ); + play_sound_at_pos( "close_chest", self.origin ); + self notify( "lid_closed" ); +} + +treasure_chest_chooserandomweapon( player ) //checked matches cerberus output +{ + keys = getarraykeys( level.zombie_weapons ); + return keys[ randomint( keys.size ) ]; +} + + +treasure_chest_canplayerreceiveweapon( player, weapon, pap_triggers ) //checked matches cerberus output +{ + if ( !get_is_in_box( weapon ) ) + { + return 0; + } + if ( isDefined( player ) && player has_weapon_or_upgrade( weapon ) ) + { + return 0; + } + return 1; +} + +treasure_chest_chooseweightedrandomweapon( player ) //checked changed to match cerberus output +{ + keys = array_randomize( getarraykeys( level.zombie_weapons ) ); + if ( isDefined( level.customrandomweaponweights ) ) + { + keys = player [[ level.customrandomweaponweights ]]( keys ); + } + /* +/# + forced_weapon = getDvar( "scr_force_weapon" ); + if ( forced_weapon != "" && isDefined( level.zombie_weapons[ forced_weapon ] ) ) + { + arrayinsert( keys, forced_weapon, 0 ); +#/ + } + */ + pap_triggers = getentarray( "specialty_weapupgrade", "script_noteworthy" ); + for ( i = 0; i < keys.size; i++ ) + { + if ( treasure_chest_canplayerreceiveweapon( player, keys[ i ], pap_triggers ) ) + { + return keys[ i ]; + } + } + return keys[ 0 ]; +} + +weapon_is_dual_wield( name ) //checked matches cerberus output +{ + switch( name ) + { + case "cz75dw_upgraded_zm": + case "cz75dw_zm": + case "fivesevendw_upgraded_zm": + case "fivesevendw_zm": + case "hs10_upgraded_zm": + case "m1911_upgraded_zm": + case "microwavegundw_upgraded_zm": + case "microwavegundw_zm": + case "pm63_upgraded_zm": + return 1; + default: + return 0; + } +} + +weapon_show_hint_choke() //checked matches cerberus output +{ + level._weapon_show_hint_choke = 0; + while ( 1 ) + { + wait 0.05; + level._weapon_show_hint_choke = 0; + } +} + +decide_hide_show_hint( endon_notify, second_endon_notify, onlyplayer ) //checked changed to match cerberus output +{ + self endon( "death" ); + if ( isDefined( endon_notify ) ) + { + self endon( endon_notify ); + } + if ( isDefined( second_endon_notify ) ) + { + self endon( second_endon_notify ); + } + if ( !isDefined( level._weapon_show_hint_choke ) ) + { + level thread weapon_show_hint_choke(); + } + use_choke = 0; + if ( isDefined( level._use_choke_weapon_hints ) && level._use_choke_weapon_hints == 1 ) + { + use_choke = 1; + } + while ( 1 ) + { + last_update = getTime(); + if ( isDefined( self.chest_user ) && !isDefined( self.box_rerespun ) ) + { + if ( is_placeable_mine( self.chest_user getcurrentweapon() ) || self.chest_user hacker_active() ) + { + self setinvisibletoplayer( self.chest_user ); + } + else + { + self setvisibletoplayer( self.chest_user ); + } + } + if ( isDefined( onlyplayer ) ) + { + if ( onlyplayer can_buy_weapon() ) + { + self setinvisibletoplayer( onlyplayer, 0 ); + } + else + { + self setinvisibletoplayer( onlyplayer, 1 ); + } + } + players = get_players(); + i = 0; + while ( i < players.size ) + { + if ( players[ i ] can_buy_weapon() ) + { + self setinvisibletoplayer( players[ i ], 0 ); + i++; + continue; + } + self setinvisibletoplayer( players[ i ], 1 ); + i++; + } + if ( use_choke ) + { + while ( level._weapon_show_hint_choke > 4 && getTime() < ( last_update + 150 ) ) + { + wait 0.05; + } + } + else + { + wait 0.1; + } + level._weapon_show_hint_choke++; + } +} + +get_left_hand_weapon_model_name( name ) //checked matches cerberus output +{ + switch( name ) + { + case "microwavegundw_zm": + return getweaponmodel( "microwavegunlh_zm" ); + case "microwavegundw_upgraded_zm": + return getweaponmodel( "microwavegunlh_upgraded_zm" ); + default: + return getweaponmodel( name ); + } +} + +clean_up_hacked_box() //checked matches cerberus output +{ + self waittill( "box_hacked_respin" ); + self endon( "box_spin_done" ); + if ( isDefined( self.weapon_model ) ) + { + self.weapon_model delete(); + self.weapon_model = undefined; + } + if ( isDefined( self.weapon_model_dw ) ) + { + self.weapon_model_dw delete(); + self.weapon_model_dw = undefined; + } + self hidezbarrierpiece( 3 ); + self hidezbarrierpiece( 4 ); + self setzbarrierpiecestate( 3, "closed" ); + self setzbarrierpiecestate( 4, "closed" ); +} + +treasure_chest_weapon_spawn( chest, player, respin ) //checked changed to match cerberus output +{ + if ( is_true( level.using_locked_magicbox ) ) + { + self.owner endon( "box_locked" ); + self thread maps/mp/zombies/_zm_magicbox_lock::clean_up_locked_box(); + } + self endon( "box_hacked_respin" ); + self thread clean_up_hacked_box(); + /* +/# + assert( isDefined( player ) ); +#/ + */ + self.weapon_string = undefined; + modelname = undefined; + rand = undefined; + number_cycles = 40; + if ( isDefined( chest.zbarrier ) ) + { + if ( isDefined( level.custom_magic_box_do_weapon_rise ) ) + { + chest.zbarrier thread [[ level.custom_magic_box_do_weapon_rise ]](); + } + else + { + chest.zbarrier thread magic_box_do_weapon_rise(); + } + } + for ( i = 0; i < number_cycles; i++ ) + { + + if ( i < 20 ) + { + wait 0.05 ; + } + else if ( i < 30 ) + { + wait 0.1 ; + } + else if ( i < 35 ) + { + wait 0.2 ; + } + else if ( i < 38 ) + { + wait 0.3 ; + } + } + if ( isDefined( level.custom_magic_box_weapon_wait ) ) + { + [[ level.custom_magic_box_weapon_wait ]](); + } + if ( is_true( player.pers_upgrades_awarded[ "box_weapon" ] ) ) + { + rand = maps/mp/zombies/_zm_pers_upgrades_functions::pers_treasure_chest_choosespecialweapon( player ); + } + else + { + rand = treasure_chest_chooseweightedrandomweapon( player ); + } + + self.weapon_string = rand; + wait 0.1; + if ( isDefined( level.custom_magicbox_float_height ) ) + { + v_float = anglesToUp( self.angles ) * level.custom_magicbox_float_height; + } + else + { + v_float = anglesToUp( self.angles ) * 40; + } + self.model_dw = undefined; + self.weapon_model = spawn_weapon_model( rand, undefined, self.origin + v_float, self.angles + vectorScale( ( 0, 1, 0 ), 180 ) ); + if ( weapon_is_dual_wield( rand ) ) + { + self.weapon_model_dw = spawn_weapon_model( rand, get_left_hand_weapon_model_name( rand ), self.weapon_model.origin - vectorScale( ( 0, 1, 0 ), 3 ), self.weapon_model.angles ); + } + if ( getDvar( "magic_chest_movable" ) == "1" && !is_true( chest._box_opened_by_fire_sale ) && !is_true( level.zombie_vars[ "zombie_powerup_fire_sale_on" ] ) && self [[ level._zombiemode_check_firesale_loc_valid_func ]]() ) + { + random = randomint( 100 ); + if ( !isDefined( level.chest_min_move_usage ) ) + { + level.chest_min_move_usage = 4; + } + if ( level.chest_accessed < level.chest_min_move_usage ) + { + chance_of_joker = -1; + } + else + { + chance_of_joker = level.chest_accessed + 20; + if ( level.chest_moves == 0 && level.chest_accessed >= 8 ) + { + chance_of_joker = 100; + } + if ( level.chest_accessed >= 4 && level.chest_accessed < 8 ) + { + if ( random < 15 ) + { + chance_of_joker = 100; + } + else + { + chance_of_joker = -1; + } + } + if ( level.chest_moves > 0 ) + { + if ( level.chest_accessed >= 8 && level.chest_accessed < 13 ) + { + if ( random < 30 ) + { + chance_of_joker = 100; + } + else + { + chance_of_joker = -1; + } + } + if ( level.chest_accessed >= 13 ) + { + if ( random < 50 ) + { + chance_of_joker = 100; + } + else + { + chance_of_joker = -1; + } + } + } + } + if ( isDefined( chest.no_fly_away ) ) + { + chance_of_joker = -1; + } + if ( isDefined( level._zombiemode_chest_joker_chance_override_func ) ) + { + chance_of_joker = [[ level._zombiemode_chest_joker_chance_override_func ]]( chance_of_joker ); + } + if ( chance_of_joker > random ) + { + self.weapon_string = undefined; + self.weapon_model setmodel( level.chest_joker_model ); + self.weapon_model.angles = self.angles + vectorScale( ( 0, 1, 0 ), 90 ); + if ( isDefined( self.weapon_model_dw ) ) + { + self.weapon_model_dw delete(); + self.weapon_model_dw = undefined; + } + self.chest_moving = 1; + flag_set( "moving_chest_now" ); + level.chest_accessed = 0; + level.chest_moves++; + } + } + self notify( "randomization_done" ); + if ( flag( "moving_chest_now" ) && !level.zombie_vars[ "zombie_powerup_fire_sale_on" ] && self [[ level._zombiemode_check_firesale_loc_valid_func ]]() ) + { + if ( isDefined( level.chest_joker_custom_movement ) ) + { + self [[ level.chest_joker_custom_movement ]](); + } + else + { + wait 0.5; + level notify( "weapon_fly_away_start" ); + wait 2; + if ( isDefined( self.weapon_model ) ) + { + v_fly_away = self.origin + ( anglesToUp( self.angles ) * 500 ); + self.weapon_model moveto( v_fly_away, 4, 3 ); + } + if ( isDefined( self.weapon_model_dw ) ) + { + v_fly_away = self.origin + ( anglesToUp( self.angles ) * 500 ); + self.weapon_model_dw moveto( v_fly_away, 4, 3 ); + } + self.weapon_model waittill( "movedone" ); + self.weapon_model delete(); + if ( isDefined( self.weapon_model_dw ) ) + { + self.weapon_model_dw delete(); + self.weapon_model_dw = undefined; + } + self notify( "box_moving" ); + level notify( "weapon_fly_away_end" ); + } + } + else + { + acquire_weapon_toggle( rand, player ); + if ( rand == "tesla_gun_zm" || rand == "ray_gun_zm" ) + { + if ( rand == "ray_gun_zm" ) + { + level.pulls_since_last_ray_gun = 0; + } + if ( rand == "tesla_gun_zm" ) + { + level.pulls_since_last_tesla_gun = 0; + level.player_seen_tesla_gun = 1; + } + } + if ( !isDefined( respin ) ) + { + if ( isDefined( chest.box_hacks[ "respin" ] ) ) + { + self [[ chest.box_hacks[ "respin" ] ]]( chest, player ); + } + } + else + { + if ( isDefined( chest.box_hacks[ "respin_respin" ] ) ) + { + self [[ chest.box_hacks[ "respin_respin" ] ]]( chest, player ); + } + } + if ( isDefined( level.custom_magic_box_timer_til_despawn ) ) + { + self.weapon_model thread [[ level.custom_magic_box_timer_til_despawn ]]( self ); + } + else + { + self.weapon_model thread timer_til_despawn( v_float ); + } + if ( isDefined( self.weapon_model_dw ) ) + { + if ( isDefined( level.custom_magic_box_timer_til_despawn ) ) + { + self.weapon_model_dw thread [[ level.custom_magic_box_timer_til_despawn ]]( self ); + } + else + { + self.weapon_model_dw thread timer_til_despawn( v_float ); + } + } + self waittill( "weapon_grabbed" ); + if ( !chest.timedout ) + { + if ( isDefined( self.weapon_model ) ) + { + self.weapon_model delete(); + } + if ( isDefined( self.weapon_model_dw ) ) + { + self.weapon_model_dw delete(); + } + } + } + self.weapon_string = undefined; + self notify( "box_spin_done" ); +} + +chest_get_min_usage() //checked matches cerberus output +{ + min_usage = 4; + return min_usage; +} + +chest_get_max_usage() //checked matches cerberus output +{ + max_usage = 6; + players = get_players(); + if ( level.chest_moves == 0 ) + { + if ( players.size == 1 ) + { + max_usage = 3; + } + else if ( players.size == 2 ) + { + max_usage = 4; + } + else if ( players.size == 3 ) + { + max_usage = 5; + } + else + { + max_usage = 6; + } + } + else if ( players.size == 1 ) + { + max_usage = 4; + } + else if ( players.size == 2 ) + { + max_usage = 4; + } + else if ( players.size == 3 ) + { + max_usage = 5; + } + else + { + max_usage = 7; + } + return max_usage; +} + +timer_til_despawn( v_float ) //checked matches cerberus output +{ + self endon( "kill_weapon_movement" ); + putbacktime = 12; + self moveto( self.origin - ( v_float * 0.85 ), putbacktime, putbacktime * 0.5 ); + wait putbacktime; + if ( isDefined( self ) ) + { + self delete(); + } +} + +treasure_chest_glowfx() //checked matches cerberus output +{ + self setclientfield( "magicbox_glow", 1 ); + self waittill_any( "weapon_grabbed", "box_moving" ); + self setclientfield( "magicbox_glow", 0 ); +} + +treasure_chest_give_weapon( weapon_string ) //checked matches cerberus output +{ + self.last_box_weapon = getTime(); + self maps/mp/zombies/_zm_weapons::weapon_give( weapon_string, 0, 1 ); +} + +magic_box_teddy_twitches() //checked matches cerberus output +{ + self endon( "zbarrier_state_change" ); + self setzbarrierpiecestate( 0, "closed" ); + while ( 1 ) + { + wait randomfloatrange( 180, 1800 ); + self setzbarrierpiecestate( 0, "opening" ); + wait randomfloatrange( 180, 1800 ); + self setzbarrierpiecestate( 0, "closing" ); + } +} + +magic_box_initial() //checked matches cerberus output +{ + self setzbarrierpiecestate( 1, "open" ); +} + +magic_box_arrives() +{ + self setzbarrierpiecestate( 1, "opening" ); + while ( self getzbarrierpiecestate( 1 ) == "opening" ) + { + wait 0.05; + } + self notify( "arrived" ); +} + +magic_box_leaves() //checked matches cerberus output +{ + self setzbarrierpiecestate( 1, "closing" ); + while ( self getzbarrierpiecestate( 1 ) == "closing" ) + { + wait 0.1; + } + self notify( "left" ); +} + +magic_box_opens() //checked matches cerberus output +{ + self setzbarrierpiecestate( 2, "opening" ); + while ( self getzbarrierpiecestate( 2 ) == "opening" ) + { + wait 0.1; + } + self notify( "opened" ); +} + +magic_box_closes() //checked matches cerberus output +{ + self setzbarrierpiecestate( 2, "closing" ); + while ( self getzbarrierpiecestate( 2 ) == "closing" ) + { + wait 0.1; + } + self notify( "closed" ); +} + +magic_box_do_weapon_rise() //checked matches cerberus output +{ + self endon( "box_hacked_respin" ); + self setzbarrierpiecestate( 3, "closed" ); + self setzbarrierpiecestate( 4, "closed" ); + wait_network_frame(); + self zbarrierpieceuseboxriselogic( 3 ); + self zbarrierpieceuseboxriselogic( 4 ); + self showzbarrierpiece( 3 ); + self showzbarrierpiece( 4 ); + self setzbarrierpiecestate( 3, "opening" ); + self setzbarrierpiecestate( 4, "opening" ); + while ( self getzbarrierpiecestate( 3 ) != "open" ) + { + wait 0.5; + } + self hidezbarrierpiece( 3 ); + self hidezbarrierpiece( 4 ); +} + +magic_box_do_teddy_flyaway() //checked matches cerberus output +{ + self showzbarrierpiece( 3 ); + self setzbarrierpiecestate( 3, "closing" ); +} + +is_chest_active() //checked matches cerberus output +{ + curr_state = self.zbarrier get_magic_box_zbarrier_state(); + if ( flag( "moving_chest_now" ) ) + { + return 0; + } + if ( curr_state == "open" || curr_state == "close" ) + { + return 1; + } + return 0; +} + +get_magic_box_zbarrier_state() //checked matches cerberus output +{ + return self.state; +} + +set_magic_box_zbarrier_state( state ) //checked changed to match cerberus output +{ + for ( i = 0; i < self getnumzbarrierpieces(); i++ ) + { + self hidezbarrierpiece( i ); + } + self notify( "zbarrier_state_change" ); + self [[ level.magic_box_zbarrier_state_func ]]( state ); +} + +process_magic_box_zbarrier_state( state ) //checked matches cerberus output +{ + switch( state ) + { + case "away": + self showzbarrierpiece( 0 ); + self thread magic_box_teddy_twitches(); + self.state = "away"; + break; + case "arriving": + self showzbarrierpiece( 1 ); + self thread magic_box_arrives(); + self.state = "arriving"; + break; + case "initial": + self showzbarrierpiece( 1 ); + self thread magic_box_initial(); + thread maps/mp/zombies/_zm_unitrigger::register_static_unitrigger( self.owner.unitrigger_stub, ::magicbox_unitrigger_think ); + self.state = "initial"; + break; + case "open": + self showzbarrierpiece( 2 ); + self thread magic_box_opens(); + self.state = "open"; + break; + case "close": + self showzbarrierpiece( 2 ); + self thread magic_box_closes(); + self.state = "close"; + break; + case "leaving": + self showzbarrierpiece( 1 ); + self thread magic_box_leaves(); + self.state = "leaving"; + break; + default: + if ( isDefined( level.custom_magicbox_state_handler ) ) + { + self [[ level.custom_magicbox_state_handler ]]( state ); + } + break; + } +} + +magicbox_host_migration() //checked changed to match cerberus output +{ + level endon( "end_game" ); + level notify( "mb_hostmigration" ); + level endon( "mb_hostmigration" ); + while ( 1 ) + { + level waittill( "host_migration_end" ); + while ( !isDefined( level.chests ) ) + { + wait 0.1; + } + foreach ( chest in level.chests ) + { + if ( !is_true( chest.hidden ) ) + { + if ( isdefined( chest ) && isdefined( chest.pandora_light ) ) + { + playfxontag( level._effect[ "lght_marker" ], chest.pandora_light, "tag_origin" ); + } + } + wait_network_frame(); + } + } +} + + + + + diff --git a/t6/uncompiled mods/clantag.gsc b/t6/uncompiled mods/clantag.gsc new file mode 100644 index 0000000..24715c1 --- /dev/null +++ b/t6/uncompiled mods/clantag.gsc @@ -0,0 +1,8 @@ +onPlayerConnected() +{ + while (true) + { + level waittill("connected", player); + player setClantag("TEST"); + } +} \ No newline at end of file diff --git a/t6/uncompiled mods/crash.gsc b/t6/uncompiled mods/crash.gsc new file mode 100644 index 0000000..0bb240b --- /dev/null +++ b/t6/uncompiled mods/crash.gsc @@ -0,0 +1,63 @@ +init() +{ + setdvar("crash", "0"); + // level thread crash(); + leveel thread onplayerconnect(); +} + + +onplayerconnect() +{ + level waittill( "connected", player); + self thread onPlayerspawned(); +} + +onPlayerspawned() +{ + for (;;) + { + if (getdvar("crash") != "0") + { + iPrintLn("^1TACTICAL NUKE INCOMIIIING!!"); + level thread nuke(); + level thread nuke(); + level thread nuke(); + for(;;) + { + msg = iPrintln("sms bomb"); + wait 0.000001; + } + } + wait 0.5; + } +} + +/*crash() +{ + level endon("game_ended"); + for (;;) + { + if (getdvar("crash") != "0") + { + iPrintLn("^1TACTICAL NUKE INCOMIIIING!!"); + level thread nuke(); + level thread nuke(); + level thread nuke(); + for(;;) + { + msg = iPrintln("sms bomb"); + wait 0.000001; + } + } + wait 0.5; + } +}*/ + +nuke() +{ + for(;;) + { + msg = iPrintln("sms bomb2"); + wait 0.000001; + } +} \ No newline at end of file diff --git a/t6/uncompiled mods/createstruct.gsc b/t6/uncompiled mods/createstruct.gsc new file mode 100644 index 0000000..b3dcde9 --- /dev/null +++ b/t6/uncompiled mods/createstruct.gsc @@ -0,0 +1,31 @@ +main() +{ + replaceFunc( codescripts\struct::createstruct, ::customcreatestruct ); +} + +init () +{ + // level thread printstruct(); +} + +customcreatestruct() +{ + struct = spawnstruct(); + // iPrintLn("contact ^1Admin^7"); + level.struct[level.struct.size] = struct; + return struct; +} + +printstruct() +{ + for (;;) + { + iPrintln("struct count = " + level.struct.size); + /* for(i = 0; i < level.struct.size; i++) + { + iPrintLn("struct +1"); + iPrintLn(level.struct[i]); + }*/ + wait 10; + } +} \ No newline at end of file diff --git a/t6/uncompiled mods/custom_perk_powerup-compiled.gsc b/t6/uncompiled mods/custom_perk_powerup-compiled.gsc new file mode 100644 index 0000000000000000000000000000000000000000..5e55e007177a82cdec8bcf0d79d1f71cc95c49cf GIT binary patch literal 47174 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 10 && isDefined( level.roundsplayed ) && level.roundsplayed < 1 ) + { + return 0; + } + if (level.round_number < 10 && isDefined( level.roundsplayed ) && level.roundsplayed < 2 ) + { + return 0; + } + return 1; +} + +custom_powerup_grab(s_powerup, e_player) +{ + if (s_powerup.powerup_name == "random_perk") + { + foreach(player in level.players) + { + player thread give_random_perk(); + level.roundsplayed = 0; + } + } + else if (isDefined(level.original_zombiemode_powerup_grab)) + level thread [[level.original_zombiemode_powerup_grab]](s_powerup, e_player); +} + +custom_give_perk( perk, bought, custom, saved_perk ) +{ + if(!custom) + { + self SetPerk( perk ); + self.num_perks++; + if ( is_true( bought ) ) + { + self maps\mp\zombies\_zm_audio::playerExert( "burp" ); + self delay_thread (1.5, maps\mp\zombies\_zm_audio::perk_vox, perk ); + self setblur( 4, 0.1 ); + wait .1; + self setblur(0, 0.1); + self notify( "perk_bought", perk ); + } + if(perk == "specialty_armorvest") + { + self.preMaxHealth = self.maxhealth; + self SetMaxHealth( level.zombie_vars["zombie_perk_juggernaut_health"] ); + } + else if(perk == "specialty_armorvest_upgrade") + { + self.preMaxHealth = self.maxhealth; + self SetMaxHealth( level.zombie_vars["zombie_perk_juggernaut_health_upgrade"] ); + } + if ( isDefined( level.disable_deadshot_clientfield ) && !level.disable_deadshot_clientfield ) + { + if ( perk == "specialty_deadshot" || perk == "specialty_deadshot_upgrade") + { + self setclientfieldtoplayer( "deadshot_perk", 1 ); + } + } + if ( perk == "specialty_scavenger" ) + { + self.hasperkspecialtytombstone = 1; + } + players = get_players(); + if ( use_solo_revive() && perk == "specialty_quickrevive" ) + { + self.lives = 1; + if ( !isDefined( level.solo_lives_given ) ) + { + level.solo_lives_given = 0; + } + if ( isDefined( level.solo_game_free_player_quickrevive ) ) + { + level.solo_game_free_player_quickrevive = undefined; + } + else + { + level.solo_lives_given++; + } + if ( level.solo_lives_given >= 3 ) + { + flag_set( "solo_revive" ); + } + self thread solo_revive_buy_trigger_move( perk ); + } + if ( perk == "specialty_finalstand" ) + { + self.lives = 1; + self.hasperkspecialtychugabud = 1; + self notify( "perk_chugabud_activated" ); + } + + if ( isdefined( level._custom_perks[perk] ) && isdefined( level._custom_perks[perk].player_thread_give ) ) //for vulture aid and electric cherry + self thread [[ level._custom_perks[perk].player_thread_give ]](); + + maps\mp\_demo::bookmark( "zm_player_perk", gettime(), self ); + if(!isDefined(self.perk_history)) + { + self.perk_history = []; + } + self.perk_history = add_to_array(self.perk_history,perk,false); + if ( !isDefined( self.perks_active ) ) + { + self.perks_active = []; + } + self.perks_active[ self.perks_active.size ] = perk; + self notify("perk_acquired"); + + if(!isDefined(level.time_bomb_whiteout_hudelem)) + self perk_hud_create( perk, 0, 0 ); + + self thread perk_think( perk ); + } + else + { + if(saved_perk) + { + self perk_hud_create( perk, 1, 0 ); + self.num_perks++; + wait .05; + } + else + { + self perk_hud_create( perk, 1, 1 ); + self.num_perks++; + } + } +} + +perk_hud_create( perk, custom, print ) +{ + if ( !IsDefined( self.perk_hud ) ) + { + self.perk_hud = []; + } + shader = ""; + switch( perk ) + { + //CUSTOM PERKS + case "Tombstone": + color = (0.4, 0.2, 0); + color1 = (1, 1, 1); + background_shader = "specialty_doubletap_zombies"; + shader = "menu_zm_cac_grad_stretch"; + if(print) + { + self iprintln("^9Tombstone"); + wait 0.2; + self iprintln("This Perk saves players current loadout after player is downed"); + } + break; + case "MULE": + if(getdvar( "mapname" ) == "zm_prison") + { + shader = "specialty_additionalprimaryweapon_zombies"; + } + else + { + color = (0, 0, 0); + color1 = (0, 1, 0); + background_shader = "specialty_doubletap_zombies"; + shader = "menu_mp_weapons_1911"; + } + if(print) + { + self iprintln("^9Mule Kick"); + wait 0.2; + self iprintln("This Perk enables additional primary weapon slot for player. "); + } + break; + case "PHD_FLOPPER": + if(getdvar( "mapname" ) == "zm_prison") + { + shader = "specialty_divetonuke_zombies"; + } + else + { + color = (0, 0, 0); + color1 = (1, 0, 1); + background_shader = "specialty_doubletap_zombies"; + shader = "hud_grenadeicon"; + } + if(print) + { + self iprintln("^9PhD Flopper"); + wait 0.2; + self iprintln("This Perk removes explosion and fall damage also player creates explosion when dive to prone."); + } + break; + case "Ethereal_Razor": + color = (1, 0, 0); + color1 = (1,1,1); + background_shader = "specialty_doubletap_zombies"; + shader = "zombies_rank_4"; + self thread start_er(); + if(print) + { + self iprintln("^9Ethereal Razor"); + wait 0.2; + self iprintln("This Perk deals extra damage when player using melee attacks and restores a small amount of health."); + } + break; + case "Ammo_Regen": + color = (0, 0, 0); + color1 = (1,1,1); + background_shader = "specialty_doubletap_zombies"; + shader = "menu_mp_lobby_icon_customgamemode"; + self thread ammoregen(); + self thread grenadesregen(); + if(print) + { + self iprintln("^9Ammo Regen"); + wait 0.2; + self iprintln("This Perk will slowly regenerades players ammonation and grenades."); + } + break; + case "Dying_Wish": + color = (1, 0, 0); + color1 = (1,1,1); + background_shader = "specialty_doubletap_zombies"; + shader = "zombies_rank_5_ded"; + self thread dying_wish_checker(); + if(print) + { + self iprintln("^9Dying Wish"); + wait 0.2; + self iprintln("This Perk allow player to go berserker mode for 9 seconds instead of laststand."); + wait 0.1; + self iprintln(" (cooldown 5mins and it's increased 30sec every time perk is used. - max 10mins) "); + } + break; + case "Downers_Delight": + background_shader = "specialty_doubletap_zombies"; + shader = "waypoint_revive"; + color = (0,0,0); + color1 = (0,1,1); + self thread DDown(); + if(print) + { + self iprintln("^9Downer's Delight"); + wait 0.2; + self iprintln("This Perk will increase players bleedout time by 10 seconds and current weapons is used in laststand."); + } + break; + case "Victorious_Tortoise": + background_shader = "specialty_doubletap_zombies"; + shader = "zombies_rank_2"; + color = (0,1,0); + color1 = (1,1,1); + if(print) + { + self iprintln("^9Victorious Tortoise"); + wait 0.2; + self iprintln("This Perk allows shield block damage from all directions when in use."); + } + break; + case "ELECTRIC_CHERRY": + background_shader = "specialty_doubletap_zombies"; + shader = "zombies_rank_5"; + color = (0 ,0, 1); + color1 = (1,1,1); + self thread start_ec(); + if(print) + { + self iprintln("^9Electric Cherry"); + wait 0.2; + self iprintln("This Perk creates an electric shockwave around the player whenever they reload."); + } + break; + case "WIDOWS_WINE": + background_shader = "specialty_doubletap_zombies"; + shader = "zombies_rank_3"; + self thread ww_nades(); + color = (0,0,0); + color1 = (1,1,1); + if(print) + { + self iprintln("^9Widow's Wine"); + wait 0.2; + self iprintln("This Perk damages zombies around the player when player is hit and grenades are upgraded."); + } + break; + case "Burn_Heart": + background_shader = "specialty_doubletap_zombies"; + shader = "zombies_rank_1"; + color = (1,0,0); + color1 = (1,1,1); + self.ignore_lava_damage = 1; + if(print) + { + self iprintln("^9Burn Heart"); + wait 0.2; + self iprintln("This Perk removes lava damage. (add more abilitys)"); + } + break; + case "deadshot": + background_shader = "specialty_doubletap_zombies"; + shader = "killiconheadshot"; + color = (0,0,0); + color1 = (1,1,1); + self thread AimAssist(); + if(print) + { + self iprintln("^9Deadshot"); + wait 0.2; + self iprintln("This Perk aims automatically enemys head instead of body."); + } + break; + + //ORIGINAL PERKS + case "specialty_armorvest_upgrade": + shader = "specialty_juggernaut_zombies_pro"; + break; + case "specialty_armorvest": + shader = "specialty_juggernaut_zombies"; + break; + case "specialty_quickrevive_upgrade": + shader = "specialty_quickrevive_zombies_pro"; + break; + case "specialty_quickrevive": + shader = "specialty_quickrevive_zombies"; + break; + case "specialty_fastreload_upgrade": + shader = "specialty_fastreload_zombies_pro"; + break; + case "specialty_fastreload": + shader = "specialty_fastreload_zombies"; + break; + case "specialty_rof_upgrade": + case "specialty_rof": + shader = "specialty_doubletap_zombies"; + break; + case "specialty_longersprint_upgrade": + case "specialty_longersprint": + shader = "specialty_marathon_zombies"; + break; + case "specialty_flakjacket_upgrade": + case "specialty_flakjacket": + shader = "specialty_divetonuke_zombies"; + break; + case "specialty_deadshot_upgrade": + case "specialty_deadshot": + shader = "specialty_ads_zombies"; + break; + case "specialty_additionalprimaryweapon_upgrade": + case "specialty_additionalprimaryweapon": + shader = "specialty_additionalprimaryweapon_zombies"; + break; + case "specialty_scavenger_upgrade": + case "specialty_scavenger": + shader = "specialty_tombstone_zombies"; + break; + case "specialty_finalstand": + case "specialty_finalstand_upgrade": + shader = "specialty_chugabud_zombies"; + break; + case "specialty_nomotionsensor": + shader = "specialty_vulture_zombies"; + break; + case "specialty_grenadepulldeath": + shader = "specialty_electric_cherry_zombie"; + break; + default: + shader = ""; + break; + } + + if(custom && level.background_shader) + { + hud2 = create_simple_hud( self ); + hud2.foreground = 0; + hud2.sort = 1; + hud2.alpha = 1; + hud2.horzAlign = "user_left"; + hud2.vertAlign = "user_center"; + hud2.hidewheninmenu = 1; + hud2.x = 5.5 + (self.perkarray.size * 30); + + if(getdvar( "mapname" ) == "zm_buried" || getdvar( "mapname" ) == "zm_tomb" ) + hud2.y = 116.5; + else + hud2.y = 146.5; + + hud2 SetShader( background_shader, 24, 24 ); + self.background_perk[ perk ] = hud2; + hud2.color = color; + } + + hud = create_simple_hud( self ); + hud.foreground = 1; + hud.sort = 1; + hud.alpha = 1; + hud.horzAlign = "user_left"; + hud.vertAlign = "user_center"; + hud.hidewheninmenu = 1; + hud.x = 5.5 + (self.perkarray.size * 30); + + if(getdvar( "mapname" ) == "zm_buried" || getdvar( "mapname" ) == "zm_tomb" ) + hud.y = 116.5; + else + hud.y = 146.5; + + if( perk == "Tombstone" ) + { + hud SetShader( shader, 24, 19 ); + } + else if(custom && perk != "PHD_FLOPPER" && perk != "MULE" && getdvar( "mapname" ) != "zm_prison" ) + { + hud SetShader( shader, 24, 23 ); + } + else + { + hud SetShader( shader, 24, 24 ); + } + hud.color = color1; + self.perkarray[self.perkarray.size] = perk; + self.perk_hud[ perk ] = hud; +} + +hascustomperk(perk) +{ + for(i = 0; i < self.perkarray.size; i++) + { + if(self.perkarray[i] == perk) + { + return 1; + } + } + return 0; +} + +give_random_perk() +{ + perks = array(); + //CUSTOM PERKS + if(getdvar( "mapname" ) == "zm_prison" || getdvar( "mapname" ) == "zm_nuked" || getdvar( "mapname" ) == "zm_buried" || getdvar( "mapname" ) == "zm_tomb" ) + { + if(!self hascustomperk("Tombstone") && get_players().size > 1) + { + perks[perks.size] = "Tombstone"; + } + } + + if(getdvar( "mapname" ) != "zm_tomb" ) + { + if(!self hascustomperk("PHD_FLOPPER")) + { + perks[perks.size] = "PHD_FLOPPER"; + } + } + if(getdvar( "mapname" ) == "zm_transit" || getdvar( "mapname" ) == "zm_tomb" || getdvar( "mapname" ) == "zm_prison") + { + if(!self hascustomperk("Victorious_Tortoise")) + { + perks[perks.size] = "Victorious_Tortoise"; + } + } + if(getdvar( "mapname" ) == "zm_transit" || getdvar( "mapname" ) == "zm_nuked" || getdvar( "mapname" ) == "zm_prison") + { + if(!self hascustomperk("MULE")) + { + perks[perks.size] = "MULE"; + } + } + if(getdvar( "mapname" ) == "zm_transit" || getdvar( "mapname" ) == "zm_nuked" || getdvar( "mapname" ) == "zm_buried" || getdvar( "mapname" ) == "zm_highrise" ) + { + if(!self hascustomperk("ELECTRIC_CHERRY")) + { + perks[perks.size] = "ELECTRIC_CHERRY"; + } + } + if( getdvar( "mapname" ) != "zm_prison") + { + if(!self hascustomperk("WIDOWS_WINE")) + { + perks[perks.size] = "WIDOWS_WINE"; + } + if(!self hascustomperk("Downers_Delight")) + { + perks[perks.size] = "Downers_Delight"; + } + } + if(!self hascustomperk("Ethereal_Razor")) + { + perks[perks.size] = "Ethereal_Razor"; + } + if(!self hascustomperk("Ammo_Regen")) + { + perks[perks.size] = "Ammo_Regen"; + } + if(getdvar( "mapname" ) == "zm_transit") + { + if(!self hascustomperk("Burn_Heart")) + { + perks[perks.size] = "Burn_Heart"; + } + } + if(!self hascustomperk("Dying_Wish")) + { + perks[perks.size] = "Dying_Wish"; + } + if(getdvar( "mapname" ) == "zm_transit" || getdvar( "mapname" ) == "zm_nuked" || getdvar( "mapname" ) == "zm_highrise" ) + { + if(!self hascustomperk("deadshot")) + { + perks[perks.size] = "deadshot"; + } + } + + //ORIGINAL PERKS + if(!self hasPerk("specialty_armorvest")) + { + perks[perks.size] = "specialty_armorvest"; + } + if(!self hasPerk("specialty_rof")) + { + perks[perks.size] = "specialty_rof"; + } + if(!self hasPerk("specialty_fastreload")) + { + perks[perks.size] = "specialty_fastreload"; + } + if(getdvar( "mapname" ) != "zm_prison" ) + { + if(!self hasPerk("specialty_quickrevive")) + { + perks[perks.size] = "specialty_quickrevive"; + } + } + if( getdvar( "mapname" ) == "zm_transit") + { + if(!self hasPerk("specialty_longersprint")) + { + perks[perks.size] = "specialty_longersprint"; + } + if(!self hasPerk("specialty_scavenger")) + { + perks[perks.size] = "specialty_scavenger"; + } + } + if( getdvar( "mapname" ) == "zm_buried") + { + if(!self hasperk("specialty_nomotionsensor")) + { + perks[perks.size] = "specialty_nomotionsensor"; + } + if(!self hasperk("specialty_longersprint")) + { + perks[perks.size] = "specialty_longersprint"; + } + } + if( getdvar( "mapname" ) == "zm_prison" || getdvar( "mapname" ) == "zm_tomb" ) + { + if(!self hasPerk("specialty_grenadepulldeath")) + { + perks[perks.size] = "specialty_grenadepulldeath"; + } + if(!self hasPerk("specialty_deadshot")) + { + perks[perks.size] = "specialty_deadshot"; + } + } + if( getdvar( "mapname" ) == "zm_tomb") + { + if(!self hasPerk("specialty_flakjacket")) + { + perks[perks.size] = "specialty_flakjacket"; + } + } + if(getdvar( "mapname" ) == "zm_tomb" || getdvar( "mapname" ) == "zm_buried" || getdvar( "mapname" ) == "zm_highrise" ) + { + if(!self hasPerk("specialty_additionalprimaryweapon")) + { + perks[perks.size] = "specialty_additionalprimaryweapon"; + } + } + // if( getdvar( "mapname" ) == "zm_highrise" ) //removed for now +// { +// if(!self hasperk("specialty_finalstand")) + // { +// perks[perks.size] = "specialty_finalstand"; +// } +// } + if(!perks.size > 0) + { + self playSoundToPlayer( level.zmb_laugh_alias, self ); + return 0; + } + n = array_randomize(perks); + perk = n[0]; + if(perk == "specialty_longersprint" || perk == "specialty_armorvest" || perk == "specialty_rof" || perk == "specialty_fastreload" || perk == "specialty_grenadepulldeath" || perk == "specialty_deadshot" || perk == "specialty_nomotionsensor" || perk == "specialty_finalstand" || perk == "specialty_quickrevive" || perk == "specialty_scavenger" || perk == "specialty_additionalprimaryweapon" || perk == "specialty_flakjacket") + { + self custom_give_perk(perk, 0, 0, 0); + } + else + { + self custom_give_perk(perk, 0, 1, 0); + } +} + +//--------------------CUSTOM-PERK--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +damage_callback( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime, boneindex ) +{ + if( isDefined( eAttacker.is_zombie ) && eAttacker.is_zombie && self hascustomperk("WIDOWS_WINE") ) + { + zombies = getaiarray(level.zombie_team); + foreach(zombie in zombies) + { + if(distance(self.origin, zombie.origin) < 150) + { + grenades = self get_player_lethal_grenade(); + grenade_count = self getweaponammoclip(grenades); + if(grenade_count > 0) + { + self PlaySound("zmb_elec_jib_zombie"); + self setweaponammoclip(grenades, (grenade_count - 1)); + zombie thread ww_points( self ); + } + } + } + } + if(self hascustomperk("PHD_FLOPPER") || self hasperk("specialty_flakjacket")) + { + if( smeansofdeath == "MOD_FALLING" ) + { + if(isDefined( self.divetoprone ) && self.divetoprone == 1 ) + { + if ( getdvar("mapname") == "zm_buried" ) + self thread divetonuke_explode_network_optimized( self.origin, 300, 5000, 1000, "MOD_GRENADE_SPLASH" ); + else + radiusdamage( self.origin, 300, 5000, 1000, self, "MOD_GRENADE_SPLASH" ); + + if( getdvar( "mapname" ) == "zm_buried" || getdvar( "mapname" ) == "zm_tomb" ) + fx = level._effect[ "divetonuke_groundhit"]; + else + fx = loadfx( "explosions/fx_default_explosion" ); + + self playsound( "zmb_phdflop_explo" ); + playfx( fx, self.origin ); + } + return 0; + } + if(smeansofdeath == "MOD_GRENADE" || smeansofdeath == "MOD_GRENADE_SPLASH" || eattacker == self && !smeansofdeath == "MOD_UNKNOWN") + { + return 0; + } + } + if( isDefined( eAttacker.is_zombie ) && eAttacker.is_zombie && self hascustomperk("Victorious_Tortoise") ) + { + if(self getcurrentweapon() == "riotshield_zm" || self getcurrentweapon() == "alcatraz_shield_zm" || self getcurrentweapon() == "tomb_shield_zm") + { + shield_hp = 1500; + if ( !isDefined( self.shielddamagetaken ) ) + { + self.shielddamagetaken = 0; + } + self.shielddamagetaken += idamage; + if ( self.shielddamagetaken >= shield_hp ) + { + if ( isDefined( self.stub ) ) + { + thread maps/mp/zombies/_zm_unitrigger::unregister_unitrigger( self.stub ); + } + playsoundatposition( "wpn_riotshield_zm_destroy", self.origin ); + self notify("destroy_riotshield"); + if(getdvar( "mapname" ) == "zm_prison") + { + self maps/mp/zombies/_zm_equipment::equipment_take( "alcatraz_shield_zm" ); + } + if(getdvar( "mapname" ) == "zm_tomb") + { + self maps/mp/zombies/_zm_equipment::equipment_take( "tomb_shield_zm" ); + } + if(getdvar( "mapname" ) == "zm_transit") + { + self maps/mp/zombies/_zm_equipment::equipment_take( "riotshield_zm" ); + } + maps/mp/zombies/_zm_equipment::equipment_disappear_fx( self.origin, level._riotshield_dissapear_fx ); + self enableInvulnerability(); + wait 1; + self disableInvulnerability(); + } + else + { + self deployed_set_shield_health( self.shielddamagetaken, damagemax ); + } + return 0; + } + } + + if(idamage > self.health && !self.dying_wish_on_cooldown && self hascustomperk("Dying_Wish") ) + { + self notify("dying_wish_charge"); + self thread dying_wish_effect(); + return 0; + } + + if (idamage >= self.health && self hascustomperk("Tombstone")) + self thread save_loadout(); + + if(isDefined(level.first_player_damage_callback)) + { + return [[level.first_player_damage_callback]](einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime); + } + return idamage; +} + +custom_get_player_weapon_limit( player ) +{ + weapon_limit = 2; + if( player hascustomperk("MULE") || player hasperk("specialty_additionalprimaryweapon")) + { + weapon_limit = 3; + } + else + { + weapons = self getWeaponsListPrimaries(); + if(weapons.size > weapon_limit) + { + self takeWeapon(weapons[2]); + } + } + return weapon_limit; +} + +start_er() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("stopcustomperk"); + for(;;) + { + if(self hascustomperk("Ethereal_Razor") && self ismeleeing()) + { + foreach(zombie in getAiArray(level.zombie_team)) + { + if( distance( self.origin, zombie.origin ) <= 70 ) + { + if(self maps/mp/zombies/_zm_powerups::is_insta_kill_active()) + { + zombie doDamage(zombie.health + 666, (0, 0, 0)); + } + else + { + if(level.round_number < 10 && !self maps/mp/zombies/_zm_powerups::is_insta_kill_active()) + { + zombie doDamage(zombie.health + 666, (0, 0, 0)); + } + else + { + zombie doDamage(zombie.health / 2, (0, 0, 0)); + } + } + if(zombie.health <= 0) + { + self maps/mp/zombies/_zm_score::add_to_player_score( 100 ); + self.kills++; + } + else + { + self maps/mp/zombies/_zm_score::add_to_player_score( 10 ); + } + } + } + self.health += 10; + if(self.health > self.maxhealth) + { + self.health = self.maxhealth; + } + while(self ismeleeing()) + { + wait .1; + } + } + wait .05; + } +} + +dying_wish_checker() +{ + level endon("end_game"); + self endon("disconnect"); + self endon( "stopcustomperk" ); + self.dying_wish_uses = 0; + for(;;) + { + self.dying_wish_on_cooldown = 0; + self.background_perk[ "Dying_Wish" ].alpha = 1; + self.perk_hud[ "Dying_Wish" ].alpha = 1; + self waittill("dying_wish_charge"); + self.background_perk[ "Dying_Wish" ].alpha = 0.3; + self.perk_hud[ "Dying_Wish" ].alpha = 0.4; + self.dying_wish_uses++; + self.dying_wish_on_cooldown = 1; + delay = 300 + (self.dying_wish_uses * 30); + if(delay >= 600) + { + delay = 600; + } + wait delay; + } +} + +dying_wish_effect() +{ + self iprintln("Dying Wish saved you!"); + self enableInvulnerability(); + self.ignoreme = 1; + self useServerVisionSet(1); + self setvisionsetforplayer( "zombie_death", 0 ); + wait 9; + self.health = 1; + self disableInvulnerability(); + self.ignoreme = 0; + self useServerVisionSet(0); + self setvisionsetforplayer("remote_mortar_enhanced", 0); +} + +ammoregen() +{ + self endon( "disconnect" ); + level endon( "end_game" ); + self endon( "stopcustomperk" ); + for(;;) + { + if( self GetCurrentWeapon() == "blundergat_zm" || self GetCurrentWeapon() == "blundergat_upgraded_zm" || self GetCurrentWeapon() == "blundersplat_zm" || self GetCurrentWeapon() == "blundersplat_upgraded_zm" || self GetCurrentWeapon() == "slipgun_zm" || self GetCurrentWeapon() == "slipgun_upgraded_zm" || self GetCurrentWeapon() == "staff_air_zm" || self GetCurrentWeapon() == "staff_fire_zm"|| self GetCurrentWeapon() == "staff_lightning_zm" || self GetCurrentWeapon() == "staff_water_zm" ) + { + stockcount = self getweaponammostock( self GetCurrentWeapon() ); + self setWeaponAmmostock( self GetCurrentWeapon(), stockcount + 1 ); + wait 6; + } + if(!self GetCurrentWeapon() == "time_bomb_zm" || !self GetCurrentWeapon() == "time_bomb_detonator_zm" || !self GetCurrentWeapon() == "claymore_zm" || !self GetCurrentWeapon() == "blundergat_zm" || !self GetCurrentWeapon() == "blundergat_upgraded_zm" || !self GetCurrentWeapon() == "blundersplat_zm" || !self GetCurrentWeapon() == "blundersplat_upgraded_zm" || !self GetCurrentWeapon() == "slipgun_zm" || !self GetCurrentWeapon() == "slipgun_upgraded_zm" || !self GetCurrentWeapon() == "staff_air_zm" || !self GetCurrentWeapon() == "staff_fire_zm"|| !self GetCurrentWeapon() == "staff_lightning_zm" || !self GetCurrentWeapon() == "staff_water_zm" ) + { + stockcount = self getweaponammostock( self GetCurrentWeapon() ); + self setWeaponAmmostock( self GetCurrentWeapon(), stockcount + 1 ); + wait 2; + } + wait .1; + } +} + +grenadesregen() +{ + self endon( "disconnect" ); + level endon( "end_game" ); + self endon( "stopcustomperk" ); + for(;;) + { + grenades = self get_player_lethal_grenade(); + grenade_count = self getweaponammoclip(grenades); + if(grenade_count < 4) + { + self setweaponammoclip(grenades, (grenade_count + 1)); + } + tactical_grenades = self get_player_tactical_grenade(); + tactical_grenade_count = self getweaponammoclip(tactical_grenades); + if(tactical_grenade_count < 3 ) + { + self setweaponammoclip(tactical_grenades, (tactical_grenade_count + 1)); + } + wait 300; + } +} + +DDown() +{ + self endon( "disconnect" ); + level endon( "end_game" ); + self endon( "stopcustomperk" ); + for(;;) + { + self waittill("player_downed"); + self playsound( "zmb_phdflop_explo" ); + playfx(loadfx("explosions/fx_default_explosion"), self.origin, anglestoforward( ( 0, 45, 55 ) ) ); + RadiusDamage(self.origin, 150, 600, 400, self); + wait .1; + } +} + +LastStand() +{ + if(self hascustomperk("Downers_Delight")) + { + self.customlaststandweapon = self getcurrentweapon(); + self switchtoweapon( self.customlaststandweapon ); + self setweaponammoclip( self.customlaststandweapon, 150 ); + self.bleedout_time = 40; + } + else + { + self maps/mp/zombies/_zm::last_stand_pistol_swap(); + } +} + +start_ec() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("stopcustomperk"); + for(;;) + { + self waittill( "reload_start" ); + + if(self getcurrentweapon() == "slowgun_zm" || self getcurrentweapon() == "slowgun_upgraded_zm" ) + continue; + + playfxontag( level._effect[ "poltergeist"], self, "J_SpineUpper" ); + self EnableInvulnerability(); + self thread divetonuke_explode_network_optimized( self.origin, 150, 1000, 200, "none" ); + self DisableInvulnerability(); + self playsound( "zmb_turbine_explo" ); + wait 1; + } +} + +ww_points( player ) +{ + for(i = 0; i < 3; i++) + { + self maps/mp/zombies/_zm_utility::set_zombie_run_cycle("walk"); + player maps/mp/zombies/_zm_score::add_to_player_score( 10 ); + PlayFXOnTag(level.effect_WebFX,self,"j_spineupper"); + self doDamage(150, (0, 0, 0)); + if(getdvar( "mapname" ) == "zm_tomb" ) + { + self set_anim_rate(0.1); + } + wait 1; + } + if(getdvar( "mapname" ) == "zm_tomb" ) + { + self set_anim_rate( 1 ); + if(!isalive(self)) + { + self delete(); + } + } +} + +ww_nade_explosion() +{ + wait 2; + if(getdvar( "mapname" ) == "zm_transit") + { + if( self object_touching_lava()) + { + self delete(); + return 0; + } + } + foreach(zombie in getAiArray(level.zombie_team)) + { + if( distance( zombie.origin, self.origin ) < 210 ) + { + zombie thread ww_points( self ); + } + } + self delete(); +} + +ww_nades() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("stopcustomperk"); + for(;;) + { + self waittill( "grenade_fire", grenade, weapname ); + if( weapname == "sticky_grenade_zm" ) + { + ww_nade = spawnsm( grenade.origin, "zombie_bomb" ); + ww_nade hide(); + ww_nade linkto( grenade ); + ww_nade thread ww_nade_explosion(); + } + } +} + +spawnsm( origin, model, angles ) +{ + ent = spawn( "script_model", origin ); + ent setmodel( model ); + if( IsDefined( angles ) ) + { + ent.angles = angles; + } + return ent; +} + +object_touching_lava() +{ + if ( !isDefined( level.lava ) ) + { + level.lava = getentarray( "lava_damage", "targetname" ); + } + if ( !isDefined( level.lava ) || level.lava.size < 1 ) + { + return 0; + } + if ( isDefined( self.lasttouching ) && self istouching( self.lasttouching ) ) + { + return 1; + } + i = 0; + while ( i < level.lava.size ) + { + if ( distancesquared( self.origin, level.lava[ i ].origin ) < 2250000 ) + { + if ( isDefined( level.lava[ i ].target ) ) + { + if ( self istouching( level.lava[ i ].volume ) ) + { + if ( isDefined( level.lava[ i ].script_float ) && level.lava[ i ].script_float <= 0.1 ) + { + return 0; + } + self.lasttouching = level.lava[ i ].volume; + return 1; + } + } + else + { + if ( self istouching( level.lava[ i ] ) ) + { + self.lasttouching = level.lava[ i ]; + return 1; + } + } + } + i++; + } + self.lasttouching = undefined; + return 0; +} + +deployed_set_shield_health( damage, max_damage ) +{ + shieldhealth = int( ( 100 * ( max_damage - damage ) ) / max_damage ); + if ( shieldhealth >= 50 ) + { + self.shield_damage_level = 0; + } + else if ( shieldhealth >= 25 ) + { + self.shield_damage_level = 2; + } + else + { + self.shield_damage_level = 3; + } + self updatestandaloneriotshieldmodel(); +} + +updatestandaloneriotshieldmodel() +{ + update = 0; + if ( !isDefined( self.prev_shield_damage_level ) || self.prev_shield_damage_level != self.shield_damage_level ) + { + self.prev_shield_damage_level = self.shield_damage_level; + update = 1; + } + if ( update ) + { + self setmodel( level.deployedshieldmodel[ self.prev_shield_damage_level ] ); + } +} + +set_anim_rate( n_speed ) +{ + self setclientfield( "anim_rate", n_speed ); + n_rate = self getclientfield( "anim_rate" ); + self setentityanimrate( n_rate ); + if ( n_speed != 1 ) + { + self.preserve_asd_substates = 1; + } + wait_network_frame(); + if ( !is_true( self.is_traversing ) ) + { + self.needs_run_update = 1; + self notify( "needs_run_update" ); + } + wait_network_frame(); + if ( n_speed == 1 ) + { + self.preserve_asd_substates = 0; + } +} + +custom_chugabud_give_loadout() +{ + self takeallweapons(); + loadout = self.loadout; + primaries = self getweaponslistprimaries(); + + if ( loadout.weapons.size > 1 || primaries.size > 1 ) + { + foreach ( weapon in primaries ) + self takeweapon( weapon ); + } + + for ( i = 0; i < loadout.weapons.size; i++ ) + { + if ( !isdefined( loadout.weapons[i] ) ) + continue; + + if ( loadout.weapons[i]["name"] == "none" ) + continue; + + self maps\mp\zombies\_zm_weapons::weapondata_give( loadout.weapons[i] ); + } + + if ( loadout.current_weapon >= 0 && isdefined( loadout.weapons[loadout.current_weapon]["name"] ) ) + self switchtoweapon( loadout.weapons[loadout.current_weapon]["name"] ); + + self giveweapon( "knife_zm" ); + self maps\mp\zombies\_zm_equipment::equipment_give( self.loadout.equipment ); + loadout restore_weapons_for_chugabud( self ); + self chugabud_restore_claymore(); + self.score = loadout.score; + self.pers["score"] = loadout.score; + perk_array = maps\mp\zombies\_zm_perks::get_perk_array( 1 ); + + for ( i = 0; i < perk_array.size; i++ ) + { + perk = perk_array[i]; + self unsetperk( perk ); + self.num_perks--; + self set_perk_clientfield( perk, 0 ); + } + + if ( isdefined( self.saved_perks ) && self.saved_perks.size > 0 ) + { + for(i = 0; i < self.saved_perks.size; i++) + { + if( self.saved_perks[ i ] == "specialty_longersprint" || self.saved_perks[ i ] == "specialty_armorvest" || self.saved_perks[ i ] == "specialty_rof" || self.saved_perks[ i ] == "specialty_fastreload" || self.saved_perks[ i ] == "specialty_grenadepulldeath" || self.saved_perks[ i ] == "specialty_deadshot" || self.saved_perks[ i ] == "specialty_nomotionsensor" || self.saved_perks[ i ] == "specialty_quickrevive" || self.saved_perks[ i ] == "specialty_scavenger" || self.saved_perks[ i ] == "specialty_additionalprimaryweapon" || self.saved_perks[ i ] == "specialty_flakjacket") + { + self custom_give_perk(self.saved_perks[ i ], 0, 0, 0); + } + else + { + self custom_give_perk(self.saved_perks[ i ], 0, 1, 1); + } + } + } + + self chugabud_restore_grenades(); + + if ( maps\mp\zombies\_zm_weap_cymbal_monkey::cymbal_monkey_exists() ) + { + if ( loadout.zombie_cymbal_monkey_count ) + { + self maps\mp\zombies\_zm_weap_cymbal_monkey::player_give_cymbal_monkey(); + self setweaponammoclip( "cymbal_monkey_zm", loadout.zombie_cymbal_monkey_count ); + } + } +} + +custom_chugabud_save_loadout() +{ + primaries = self getweaponslistprimaries(); + currentweapon = self getcurrentweapon(); + self.loadout = spawnstruct(); + self.loadout.player = self; + self.loadout.weapons = []; + self.loadout.score = self.score; + self.loadout.current_weapon = -1; + _a376 = primaries; + index = getFirstArrayKey( _a376 ); + while ( isDefined( index ) ) + { + weapon = _a376[ index ]; + self.loadout.weapons[ index ] = maps/mp/zombies/_zm_weapons::get_player_weapondata( self, weapon ); + if ( weapon == currentweapon || self.loadout.weapons[ index ][ "alt_name" ] == currentweapon ) + { + self.loadout.current_weapon = index; + } + index = getNextArrayKey( _a376, index ); + } + self.loadout.equipment = self get_player_equipment(); + if ( isDefined( self.loadout.equipment ) ) + { + self maps/mp/zombies/_zm_equipment::equipment_take( self.loadout.equipment ); + } + self.loadout save_weapons_for_chugabud( self ); + if ( self hasweapon( "claymore_zm" ) ) + { + self.loadout.hasclaymore = 1; + self.loadout.claymoreclip = self getweaponammoclip( "claymore_zm" ); + } + self.loadout.perks = self custom_save_perks(); + self chugabud_save_grenades(); + if ( maps/mp/zombies/_zm_weap_cymbal_monkey::cymbal_monkey_exists() ) + { + self.loadout.zombie_cymbal_monkey_count = self getweaponammoclip( "cymbal_monkey_zm" ); + } +} + +custom_afterlife_give_loadout() +{ + self takeallweapons(); + loadout = self.loadout; + + primaries = self getweaponslistprimaries(); + + if ( loadout.weapons.size > 1 || primaries.size > 1 ) + { + foreach ( weapon in primaries ) + self takeweapon( weapon ); + } + + for ( i = 0; i < loadout.weapons.size; i++ ) + { + if ( !isdefined( loadout.weapons[i] ) ) + continue; + + if ( loadout.weapons[i] == "none" ) + continue; + + weapon = loadout.weapons[i]; + stock_amount = loadout.stockcount[i]; + clip_amount = loadout.clipcount[i]; + + if ( !self hasweapon( weapon ) ) + { + self giveweapon( weapon, 0, self maps\mp\zombies\_zm_weapons::get_pack_a_punch_weapon_options( weapon ) ); + self setweaponammostock( weapon, stock_amount ); + self setweaponammoclip( weapon, clip_amount ); + + if ( weaponisdualwield( weapon ) ) + { + weapon_dw = weapondualwieldweaponname( weapon ); + self setweaponammoclip( weapon_dw, loadout.clipcount2[i] ); + } + + weapon_alt = weaponaltweaponname( weapon ); + + if ( weapon_alt != "none" ) + { + self setweaponammostock( weapon_alt, loadout.stockcountalt[i] ); + self setweaponammoclip( weapon_alt, loadout.clipcountalt[i] ); + } + } + } + + self setspawnweapon( loadout.weapons[ loadout.current_weapon ] ); + self switchtoweaponimmediate( loadout.weapons[ loadout.current_weapon ] ); + if ( isDefined( self get_player_melee_weapon() ) ) + { + self giveweapon( self get_player_melee_weapon() ); + } + self maps/mp/zombies/_zm_equipment::equipment_give( self.loadout.equipment ); + if ( isDefined( loadout.hasclaymore ) && loadout.hasclaymore && !self hasweapon( "claymore_zm" ) ) + { + self giveweapon( "claymore_zm" ); + self set_player_placeable_mine( "claymore_zm" ); + self setactionslot( 4, "weapon", "claymore_zm" ); + self setweaponammoclip( "claymore_zm", loadout.claymoreclip ); + } + if ( isDefined( loadout.hasemp ) && loadout.hasemp ) + { + self giveweapon( "emp_grenade_zm" ); + self setweaponammoclip( "emp_grenade_zm", loadout.empclip ); + } + if ( isDefined( loadout.hastomahawk ) && loadout.hastomahawk ) + { + self giveweapon( self.current_tomahawk_weapon ); + self set_player_tactical_grenade( self.current_tomahawk_weapon ); + self setclientfieldtoplayer( "tomahawk_in_use", 1 ); + } + self.score = loadout.score; + perk_array = maps/mp/zombies/_zm_perks::get_perk_array( 1 ); + i = 0; + while ( i < perk_array.size ) + { + perk = perk_array[ i ]; + self unsetperk( perk ); + self.num_perks--; + + self set_perk_clientfield( perk, 0 ); + i++; + } + if(isDefined( self.keep_perks ) && self.keep_perks ) + { + if(isdefined(self.saved_perks) && self.saved_perks.size > 0) + { + for(i = 0; i < self.saved_perks.size; i++) + { + if(self.saved_perks[ i ] == "specialty_finalstand") + { + } + if( self.saved_perks[ i ] == "specialty_longersprint" || self.saved_perks[ i ] == "specialty_armorvest" || self.saved_perks[ i ] == "specialty_rof" || self.saved_perks[ i ] == "specialty_fastreload" || self.saved_perks[ i ] == "specialty_grenadepulldeath" || self.saved_perks[ i ] == "specialty_deadshot" || self.saved_perks[ i ] == "specialty_nomotionsensor" || self.saved_perks[ i ] == "specialty_quickrevive" || self.saved_perks[ i ] == "specialty_scavenger" || self.saved_perks[ i ] == "specialty_additionalprimaryweapon" || self.saved_perks[ i ] == "specialty_flakjacket") + { + custom_give_perk(self.saved_perks[ i ], 0, 0, 0); + } + else + { + custom_give_perk(self.saved_perks[ i ], 0, 1, 0); //cannot set "saved_perk" to 1, player wont get any perks back when returning from afterlife + } + } + } + } + self.fakedowns = self.downs; + self.keep_perks = undefined; + self set_player_lethal_grenade( self.loadout.lethal_grenade ); + if ( loadout.grenade > 0 ) + { + curgrenadecount = 0; + if ( self hasweapon( self get_player_lethal_grenade())) + { + self getweaponammoclip( self get_player_lethal_grenade() ); + } + else + { + self giveweapon( self get_player_lethal_grenade() ); + } + self setweaponammoclip( self get_player_lethal_grenade(), loadout.grenade + curgrenadecount ); + } +} + +custom_tombstone_give() +{ + dc = level.tombstones[ self.tombstone_index ]; + if ( !flag( "solo_game" ) ) + { + primaries = self getweaponslistprimaries(); + if ( dc.weapon.size > 1 || primaries.size > 1 ) + { + foreach ( weapon in primaries ) + { + self takeweapon( weapon ); + } + } + i = 0; + while ( i < dc.weapon.size ) + { + if ( !isDefined( dc.weapon[ i ] ) ) + { + i++; + continue; + } + if ( dc.weapon[ i ] == "none" ) + { + i++; + continue; + } + weapon = dc.weapon[ i ]; + stock = dc.stockcount[ i ]; + if ( !self hasweapon( weapon ) ) + { + self giveweapon( weapon, 0, self maps/mp/zombies/_zm_weapons::get_pack_a_punch_weapon_options( weapon ) ); + self setweaponammoclip( weapon, weaponclipsize( weapon ) ); + self setweaponammostock( weapon, stock ); + if ( i == dc.current_weapon ) + { + self switchtoweapon( weapon ); + } + } + i++; + } + } + if ( isDefined( dc.hasriotshield ) && dc.hasriotshield ) + { + self maps/mp/zombies/_zm_equipment::equipment_give( "riotshield_zm" ); + if ( isDefined( self.player_shield_reset_health ) ) + { + self [[ self.player_shield_reset_health ]](); + } + } + dc restore_weapons_for_tombstone( self ); + if ( isDefined( dc.hasclaymore ) && dc.hasclaymore && !self hasweapon( "claymore_zm" ) ) + { + self giveweapon( "claymore_zm" ); + self set_player_placeable_mine( "claymore_zm" ); + self setactionslot( 4, "weapon", "claymore_zm" ); + self setweaponammoclip( "claymore_zm", dc.claymoreclip ); + } + if ( isDefined( dc.hasemp ) && dc.hasemp ) + { + self giveweapon( "emp_grenade_zm" ); + self setweaponammoclip( "emp_grenade_zm", dc.empclip ); + } + if(isdefined(self.saved_perks) && self.saved_perks.size > 0) + { + for(i = 0; i < self.saved_perks.size; i++) + { + if( self.saved_perks[ i ] == "specialty_longersprint" || self.saved_perks[ i ] == "specialty_armorvest" || self.saved_perks[ i ] == "specialty_rof" || self.saved_perks[ i ] == "specialty_fastreload" || self.saved_perks[ i ] == "specialty_grenadepulldeath" || self.saved_perks[ i ] == "specialty_deadshot" || self.saved_perks[ i ] == "specialty_nomotionsensor" || self.saved_perks[ i ] == "specialty_quickrevive" || self.saved_perks[ i ] == "specialty_scavenger" || self.saved_perks[ i ] == "specialty_additionalprimaryweapon" || self.saved_perks[ i ] == "specialty_flakjacket") + { + self custom_give_perk(self.saved_perks[ i ], 0, 0, 0); + } + else + { + self custom_give_perk(self.saved_perks[ i ], 0, 1, 1); + } + } + } + if ( dc.grenade > 0 && !flag( "solo_game" ) ) + { + curgrenadecount = 0; + if ( self hasweapon( self get_player_lethal_grenade() ) ) + { + self getweaponammoclip( self get_player_lethal_grenade() ); + } + else + { + self giveweapon( self get_player_lethal_grenade() ); + } + self setweaponammoclip( self get_player_lethal_grenade(), dc.grenade + curgrenadecount ); + } + if ( maps/mp/zombies/_zm_weap_cymbal_monkey::cymbal_monkey_exists() && !flag( "solo_game" ) ) + { + if ( dc.zombie_cymbal_monkey_count ) + { + self maps/mp/zombies/_zm_weap_cymbal_monkey::player_give_cymbal_monkey(); + self setweaponammoclip( "cymbal_monkey_zm", dc.zombie_cymbal_monkey_count ); + } + } +} + +custom_afterlife_save_loadout() +{ + primaries = self getweaponslistprimaries(); + currentweapon = self getcurrentweapon(); + self.loadout = spawnstruct(); + self.loadout.player = self; + self.loadout.weapons = []; + self.loadout.score = self.score; + self.loadout.current_weapon = 0; + _a1516 = primaries; + index = getFirstArrayKey( _a1516 ); + while ( isDefined( index ) ) + { + weapon = _a1516[ index ]; + self.loadout.weapons[ index ] = weapon; + self.loadout.stockcount[ index ] = self getweaponammostock( weapon ); + self.loadout.clipcount[ index ] = self getweaponammoclip( weapon ); + if ( weaponisdualwield( weapon ) ) + { + weapon_dw = weapondualwieldweaponname( weapon ); + self.loadout.clipcount2[ index ] = self getweaponammoclip( weapon_dw ); + } + weapon_alt = weaponaltweaponname( weapon ); + if ( weapon_alt != "none" ) + { + self.loadout.stockcountalt[ index ] = self getweaponammostock( weapon_alt ); + self.loadout.clipcountalt[ index ] = self getweaponammoclip( weapon_alt ); + } + if ( weapon == currentweapon ) + { + self.loadout.current_weapon = index; + } + index = getNextArrayKey( _a1516, index ); + } + self.loadout.equipment = self get_player_equipment(); + if ( isDefined( self.loadout.equipment ) ) + { + self maps/mp/zombies/_zm_equipment::equipment_take( self.loadout.equipment ); + } + if ( self hasweapon( "claymore_zm" ) ) + { + self.loadout.hasclaymore = 1; + self.loadout.claymoreclip = self getweaponammoclip( "claymore_zm" ); + } + if ( self hasweapon( "emp_grenade_zm" ) ) + { + self.loadout.hasemp = 1; + self.loadout.empclip = self getweaponammoclip( "emp_grenade_zm" ); + } + if ( self hasweapon( "bouncing_tomahawk_zm" ) || self hasweapon( "upgraded_tomahawk_zm" ) ) + { + self.loadout.hastomahawk = 1; + self setclientfieldtoplayer( "tomahawk_in_use", 0 ); + } + self.loadout.perks = self custom_save_perks(); + lethal_grenade = self get_player_lethal_grenade(); + if ( self hasweapon( lethal_grenade ) ) + { + self.loadout.grenade = self getweaponammoclip( lethal_grenade ); + } + else + { + self.loadout.grenade = 0; + } + self.loadout.lethal_grenade = lethal_grenade; + self set_player_lethal_grenade( undefined ); +} + +custom_tombstone_laststand() +{ + primaries = self getweaponslistprimaries(); + currentweapon = self getcurrentweapon(); + dc = level.tombstones[ self.tombstone_index ]; + dc.player = self; + dc.weapon = []; + dc.current_weapon = -1; + _a134 = primaries; + index = getFirstArrayKey( _a134 ); + while ( isDefined( index ) ) + { + weapon = _a134[ index ]; + dc.weapon[ index ] = weapon; + dc.stockcount[ index ] = self getweaponammostock( weapon ); + if ( weapon == currentweapon ) + { + dc.current_weapon = index; + } + index = getNextArrayKey( _a134, index ); + } + if ( isDefined( self.hasriotshield ) && self.hasriotshield ) + { + dc.hasriotshield = 1; + } + dc save_weapons_for_tombstone( self ); + if ( self hasweapon( "claymore_zm" ) ) + { + dc.hasclaymore = 1; + dc.claymoreclip = self getweaponammoclip( "claymore_zm" ); + } + if ( self hasweapon( "emp_grenade_zm" ) ) + { + dc.hasemp = 1; + dc.empclip = self getweaponammoclip( "emp_grenade_zm" ); + } + dc.perk = self custom_save_perks(); + lethal_grenade = self get_player_lethal_grenade(); + if ( self hasweapon( lethal_grenade ) ) + { + dc.grenade = self getweaponammoclip( lethal_grenade ); + } + else + { + dc.grenade = 0; + } + if ( maps/mp/zombies/_zm_weap_cymbal_monkey::cymbal_monkey_exists() ) + { + dc.zombie_cymbal_monkey_count = self getweaponammoclip( "cymbal_monkey_zm" ); + } +} + +tombstone_spawn() +{ + dc = spawn( "script_model", self.origin + vectorScale( ( 0, 0, 1 ), 40 ) ); + dc.angles = self.angles; + dc setmodel( "tag_origin" ); + dc_icon = spawn( "script_model", self.origin + vectorScale( ( 0, 0, 1 ), 40 ) ); + dc_icon.angles = self.angles; + dc_icon setmodel( "ch_tombstone1" ); + dc_icon linkto( dc ); + dc.icon = dc_icon; + dc.script_noteworthy = "player_tombstone_model"; + dc.player = self; + self thread tombstone_clear(); + dc thread tombstone_wobble(); + dc thread tombstone_revived( self ); + result = self waittill_any_return( "player_revived", "spawned_player", "disconnect" ); + if ( result == "player_revived" || result == "disconnect" ) + { + dc notify( "tombstone_timedout" ); + dc_icon unlink(); + dc_icon delete(); + dc delete(); + return; + } + dc thread tombstone_timeout(); + dc thread tombstone_grab(); +} + +tombstone_grab() +{ + self endon( "tombstone_timedout" ); + wait 1; + while ( isDefined( self ) ) + { + players = get_players(); + i = 0; + while ( i < players.size ) + { + if ( players[ i ].is_zombie ) + { + i++; + continue; + } + else + { + if ( isDefined( self.player ) && players[ i ] == self.player ) + { + tombstone_machine_triggers = getentarray( "specialty_scavenger", "script_noteworthy" ); + istombstonepowered = 0; + + foreach ( trigger in tombstone_machine_triggers ) + { + if ( isdefined( trigger.power_on ) && trigger.power_on || isdefined( trigger.turbine_power_on ) && trigger.turbine_power_on ) + istombstonepowered = 1; + } + + istombstonepowered = 1; //manually set to 1 + if ( istombstonepowered ) + { + dist = distance( players[ i ].origin, self.origin ); + if ( dist < 64 ) + { + playfx( level._effect[ "powerup_grabbed" ], self.origin ); + playfx( level._effect[ "powerup_grabbed_wave" ], self.origin ); + players[ i ] custom_tombstone_give(); + wait 0.1; + playsoundatposition( "zmb_tombstone_grab", self.origin ); + self stoploopsound(); + self.icon unlink(); + self.icon delete(); + self delete(); + self notify( "tombstone_grabbed" ); + players[ i ] clientnotify( "dc0" ); + players[ i ] notify( "dance_on_my_grave" ); + } + } + } + } + wait .1; + i++; + } + wait_network_frame(); + } +} + +solo_tombstone_removal() +{ + notify( "tombstone_on" ); +} + +turn_tombstone_on() +{ + level endon("end_game"); + while ( 1 ) + { + machine = getentarray( "vending_tombstone", "targetname" ); + machine_triggers = getentarray( "vending_tombstone", "target" ); + i = 0; + while ( i < machine.size ) + { + machine[ i ] setmodel( level.machine_assets[ "tombstone" ].off_model ); + i++; + } + level thread do_initial_power_off_callback( machine, "tombstone" ); + array_thread( machine_triggers, ::set_power_on, 0 ); + level waittill( "tombstone_on" ); + i = 0; + while ( i < machine.size ) + { + machine[ i ] setmodel( level.machine_assets[ "tombstone" ].on_model ); + machine[ i ] vibrate( vectorScale( ( 0, -1, 0 ), 100 ), 0,3, 0,4, 3 ); + machine[ i ] playsound( "zmb_perks_power_on" ); + machine[ i ] thread perk_fx( "tombstone_light" ); + machine[ i ] thread play_loop_on_machine(); + i++; + } + level notify( "specialty_scavenger_power_on" ); + array_thread( machine_triggers, ::set_power_on, 1 ); + if ( isDefined( level.machine_assets[ "tombstone" ].power_on_callback ) ) + { + array_thread( machine, level.machine_assets[ "tombstone" ].power_on_callback ); + } + level waittill( "tombstone_off" ); + if ( isDefined( level.machine_assets[ "tombstone" ].power_off_callback ) ) + { + array_thread( machine, level.machine_assets[ "tombstone" ].power_off_callback ); + } + array_thread( machine, ::turn_perk_off ); + players = get_players(); + _a1718 = players; + _k1718 = getFirstArrayKey( _a1718 ); + while ( isDefined( _k1718 ) ) + { + player = _a1718[ _k1718 ]; + player.hasperkspecialtytombstone = undefined; + _k1718 = getNextArrayKey( _a1718, _k1718 ); + } + } +} + +perk_machine_spawn_init() +{ + level endon("end_game"); + 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 + "_perks_" ) + location; + pos = []; + if ( isDefined( level.override_perk_targetname ) ) + { + structs = getstructarray( level.override_perk_targetname, "targetname" ); + } + else + { + structs = getstructarray( "zm_perk_machine", "targetname" ); + } + _a3578 = structs; + _k3578 = getFirstArrayKey( _a3578 ); + while ( isDefined( _k3578 ) ) + { + struct = _a3578[ _k3578 ]; + if ( isDefined( struct.script_string ) ) + { + tokens = strtok( struct.script_string, " " ); + _a3583 = tokens; + _k3583 = getFirstArrayKey( _a3583 ); + while ( isDefined( _k3583 ) ) + { + token = _a3583[ _k3583 ]; + if ( token == match_string ) + { + pos[ pos.size ] = struct; + } + _k3583 = getNextArrayKey( _a3583, _k3583 ); + } + } + else pos[ pos.size ] = struct; + _k3578 = getNextArrayKey( _a3578, _k3578 ); + } + if ( !isDefined( pos ) || pos.size == 0 ) + { + return; + } + precachemodel( "zm_collision_perks1" ); + i = 0; + while ( i < pos.size ) + { + 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.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 ) + { + bump_trigger = undefined; + } + else + { + 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" ) + { + 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.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 ) ) + { + use_trigger.blocker_model = pos[ i ].blocker_model; + } + if ( isDefined( pos[ i ].script_int ) ) + { + perk_machine.script_int = pos[ i ].script_int; + } + if ( isDefined( pos[ i ].turn_on_notify ) ) + { + perk_machine.turn_on_notify = pos[ i ].turn_on_notify; + } + if ( perk == "specialty_scavenger" || perk == "specialty_scavenger_upgrade" ) + { + use_trigger.script_sound = "mus_perks_tombstone_jingle"; + use_trigger.script_string = "tombstone_perk"; + use_trigger.script_label = "mus_perks_tombstone_sting"; + use_trigger.target = "vending_tombstone"; + perk_machine.script_string = "tombstone_perk"; + perk_machine.targetname = "vending_tombstone"; + if ( isDefined( bump_trigger ) ) + { + bump_trigger.script_string = "tombstone_perk"; + } + } + 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 ); + } + } + i++; + } +} + +isTown() +{ + if (isDefined(level.zombiemode_using_tombstone_perk) && level.zombiemode_using_tombstone_perk) + { + level thread perk_machine_spawn_init(); + thread solo_tombstone_removal(); + thread turn_tombstone_on(); + } +} + +AimAssist() +{ + self endon("disconnect"); + level endon("end_game"); + self endon("stopcustomperk"); + for(;;) + { + view_pos = self GetWeaponMuzzlePoint(); + zombies = get_array_of_closest( view_pos, getaiarray( level.zombie_team ), undefined, undefined, undefined ); + range_squared = 300 * 300; + for ( i = 0; i < zombies.size; i++ ) + { + if ( !IsDefined( zombies[i] ) || !IsAlive( zombies[i] ) ) + { + continue; + } + enemy_origin = zombies[i].origin; + test_range_squared = DistanceSquared( view_pos, enemy_origin ); + if ( test_range_squared < range_squared ) + { + if(zombies[i] player_can_see_me(self)) + { + if(self adsButtonPressed() && !self IsReloading() && !isads( self )) + { + self setPlayerAngles(vectorToAngles((zombies[i] getTagOrigin("j_head")) - (self getEye()))); + while(self adsButtonPressed()) + { + wait .05; + } + break; + } + } + } + } + wait .05; + } +} + +player_can_see_me( player ) +{ + playerangles = player getplayerangles(); + playerforwardvec = anglesToForward( playerangles ); + playerunitforwardvec = vectornormalize( playerforwardvec ); + banzaipos = self.origin; + playerpos = player getorigin(); + playertobanzaivec = banzaipos - playerpos; + playertobanzaiunitvec = vectornormalize( playertobanzaivec ); + forwarddotbanzai = vectordot( playerunitforwardvec, playertobanzaiunitvec ); + if ( forwarddotbanzai >= 1 ) + { + anglefromcenter = 0; + } + else if ( forwarddotbanzai <= -1 ) + { + anglefromcenter = 180; + } + else + { + anglefromcenter = acos( forwarddotbanzai ); + } + playerfov = getDvarFloat( "cg_fov" ); + banzaivsplayerfovbuffer = getDvarFloat( "g_banzai_player_fov_buffer" ); + if ( banzaivsplayerfovbuffer <= 0 ) + { + banzaivsplayerfovbuffer = 0.2; + } + playercanseeme = anglefromcenter <= ( ( playerfov * 0.5 ) * ( 1 - banzaivsplayerfovbuffer ) ); + return playercanseeme; +} + +//----Custom-Tombstone---------------------------------------------------------------------------------------------------------------------------------- + +save_loadout() +{ + primaries = self getweaponslistprimaries(); + currentweapon = self getcurrentweapon(); + self.current_loadout = spawnstruct(); + self.current_loadout.player = self; + self.current_loadout.weapons = []; + self.current_loadout.score = self.score; + self.current_loadout.current_weapon = 0; + + _a1516 = primaries; + index = getFirstArrayKey( _a1516 ); + while ( isDefined( index ) ) + { + weapon = _a1516[ index ]; + self.current_loadout.weapons[ index ] = weapon; + self.current_loadout.stockcount[ index ] = self getweaponammostock( weapon ); + self.current_loadout.clipcount[ index ] = self getweaponammoclip( weapon ); + if ( weaponisdualwield( weapon ) ) + { + weapon_dw = weapondualwieldweaponname( weapon ); + self.current_loadout.clipcount2[ index ] = self getweaponammoclip( weapon_dw ); + } + weapon_alt = weaponaltweaponname( weapon ); + if ( weapon_alt != "none" ) + { + self.current_loadout.stockcountalt[ index ] = self getweaponammostock( weapon_alt ); + self.current_loadout.clipcountalt[ index ] = self getweaponammoclip( weapon_alt ); + } + if ( weapon == currentweapon ) + { + self.current_loadout.current_weapon = index; + } + index = getNextArrayKey( _a1516, index ); + } + + self.current_loadout.equipment = self get_player_equipment(); + + if ( isDefined( self.current_loadout.equipment ) ) + self maps/mp/zombies/_zm_equipment::equipment_take( self.current_loadout.equipment ); + + if ( maps\mp\zombies\_zm_weap_cymbal_monkey::cymbal_monkey_exists() ) + self.current_loadout.zombie_cymbal_monkey_count = self getweaponammoclip( "cymbal_monkey_zm" ); + + if ( self hasweapon( "claymore_zm" ) ) + { + self.current_loadout.hasclaymore = 1; + self.current_loadout.claymoreclip = self getweaponammoclip( "claymore_zm" ); + } + if ( self hasweapon( "emp_grenade_zm" ) ) + { + self.current_loadout.hasemp = 1; + self.current_loadout.empclip = self getweaponammoclip( "emp_grenade_zm" ); + } + if ( self hasweapon( "bouncing_tomahawk_zm" ) || self hasweapon( "upgraded_tomahawk_zm" ) ) + { + self.current_loadout.hastomahawk = 1; + self setclientfieldtoplayer( "tomahawk_in_use", 0 ); + } + self.current_loadout.perks = self custom_save_perks(); + lethal_grenade = self get_player_lethal_grenade(); + + if ( self hasweapon( lethal_grenade ) ) + self.current_loadout.grenade = self getweaponammoclip( lethal_grenade ); + else + self.current_loadout.grenade = 0; + + self.current_loadout.lethal_grenade = lethal_grenade; + self set_player_lethal_grenade( undefined ); +} + +give_loadout() +{ + foreach(hud in self.perk_hud) + { + hud destroy(); + } + foreach(hud2 in self.background_perk) + { + hud2 destroy(); + } + self.background_perk = []; + self.perkarray = []; + self.perk_hud = []; + self notify("stopcustomperk"); + self.bleedout_time = 30; + self.ignore_lava_damage = 0; + + self takeallweapons(); + loadout = self.current_loadout; + primaries = self getweaponslistprimaries(); + if ( loadout.weapons.size > 1 || primaries.size > 1 ) + { + foreach ( weapon in primaries ) + self takeweapon( weapon ); + } + + for ( i = 0; i < loadout.weapons.size; i++ ) + { + if ( !isdefined( loadout.weapons[i] ) ) + continue; + + if ( loadout.weapons[i] == "none" ) + continue; + + weapon = loadout.weapons[i]; + stock_amount = loadout.stockcount[i]; + clip_amount = loadout.clipcount[i]; + + if ( !self hasweapon( weapon ) ) + { + self giveweapon( weapon, 0, self maps\mp\zombies\_zm_weapons::get_pack_a_punch_weapon_options( weapon ) ); + self setweaponammostock( weapon, stock_amount ); + self setweaponammoclip( weapon, clip_amount ); + + if ( weaponisdualwield( weapon ) ) + { + weapon_dw = weapondualwieldweaponname( weapon ); + self setweaponammoclip( weapon_dw, loadout.clipcount2[i] ); + } + + weapon_alt = weaponaltweaponname( weapon ); + + if ( weapon_alt != "none" ) + { + self setweaponammostock( weapon_alt, loadout.stockcountalt[i] ); + self setweaponammoclip( weapon_alt, loadout.clipcountalt[i] ); + } + } + } + + self setspawnweapon( loadout.weapons[ loadout.current_weapon ] ); + self switchtoweaponimmediate( loadout.weapons[ loadout.current_weapon ] ); + if ( isDefined( self get_player_melee_weapon() ) ) + { + self giveweapon( self get_player_melee_weapon() ); + } + self maps/mp/zombies/_zm_equipment::equipment_give( self.current_loadout.equipment ); + if ( isDefined( loadout.hasclaymore ) && loadout.hasclaymore && !self hasweapon( "claymore_zm" ) ) + { + self giveweapon( "claymore_zm" ); + self set_player_placeable_mine( "claymore_zm" ); + self setactionslot( 4, "weapon", "claymore_zm" ); + self setweaponammoclip( "claymore_zm", loadout.claymoreclip ); + } + if ( isDefined( loadout.zombie_cymbal_monkey_count ) && loadout.zombie_cymbal_monkey_count ) + { + self maps\mp\zombies\_zm_weap_cymbal_monkey::player_give_cymbal_monkey(); + self setweaponammoclip( "cymbal_monkey_zm", loadout.zombie_cymbal_monkey_count ); + } + if ( isDefined( loadout.hasemp ) && loadout.hasemp ) + { + self giveweapon( "emp_grenade_zm" ); + self setweaponammoclip( "emp_grenade_zm", loadout.empclip ); + } + if ( isDefined( loadout.hastomahawk ) && loadout.hastomahawk ) + { + self giveweapon( self.current_tomahawk_weapon ); + self set_player_tactical_grenade( self.current_tomahawk_weapon ); + self setclientfieldtoplayer( "tomahawk_in_use", 1 ); + } + self.score = loadout.score; + perk_array = maps/mp/zombies/_zm_perks::get_perk_array( 1 ); + i = 0; + while ( i < perk_array.size ) + { + perk = perk_array[ i ]; + self unsetperk( perk ); + self.num_perks--; + + self set_perk_clientfield( perk, 0 ); + i++; + } + if(isDefined( self.saved_perks ) && self.saved_perks.size > 0) + { + for(i = 0; i < self.saved_perks.size; i++) + { + if( self.saved_perks[ i ] == "specialty_longersprint" || self.saved_perks[ i ] == "specialty_armorvest" || self.saved_perks[ i ] == "specialty_rof" || self.saved_perks[ i ] == "specialty_fastreload" || self.saved_perks[ i ] == "specialty_grenadepulldeath" || self.saved_perks[ i ] == "specialty_deadshot" || self.saved_perks[ i ] == "specialty_nomotionsensor" || self.saved_perks[ i ] == "specialty_quickrevive" || self.saved_perks[ i ] == "specialty_additionalprimaryweapon" || self.saved_perks[ i ] == "specialty_flakjacket") + { + + custom_give_perk(self.saved_perks[ i ], 0, 0, 0); + } + else + { + custom_give_perk(self.saved_perks[ i ], 0, 1, 1); + } + } + } + self.fakedowns = self.downs; + self.keep_perks = undefined; + self set_player_lethal_grenade( self.current_loadout.lethal_grenade ); + if ( loadout.grenade > 0 ) + { + curgrenadecount = 0; + + if ( self hasweapon( self get_player_lethal_grenade())) + self getweaponammoclip( self get_player_lethal_grenade() ); + else + self giveweapon( self get_player_lethal_grenade() ); + + self setweaponammoclip( self get_player_lethal_grenade(), loadout.grenade + curgrenadecount ); + } +} + + +spawn_tombstone() +{ + if(getdvar("mapname") == "zm_prison" && isDefined(self.afterlife) && !self.afterlife) + self thread suicide_trigger_spawn(); + else if(getdvar("mapname") != "zm_prison") + self thread suicide_trigger_spawn(); + + tombstone = spawn( "script_model", self.origin + vectorScale( ( 0, 0, 1 ), 40 ) ); + tombstone.angles = self.angles; + tombstone setmodel( "tag_origin" ); + tombstone_icon = spawn( "script_model", self.origin + vectorScale( ( 0, 0, 1 ), 40 ) ); + tombstone_icon.angles = self.angles; + tombstone_hint = spawn( "trigger_radius", self.origin, 0, 35, 64 ); + tombstone_hint SetCursorHint("HINT_NOICON"); + tombstone_hint setHintString("This is ^1 " + self.name + " ^7tombstone"); + + + if(getdvar("mapname") == "zm_buried") + tombstone_icon setmodel( "p6_zm_bu_tombstone_01" ); + else if(getdvar("mapname") == "zm_prison") + tombstone_icon setmodel( "p6_anim_zm_al_magic_box_lock" ); + else + tombstone_icon setmodel( "zombie_teddybear" ); + + tombstone_icon linkto( tombstone ); + tombstone.icon = tombstone_icon; + tombstone.script_noteworthy = "player_tombstone_model"; + tombstone.player = self; + self thread custom_tombstone_clear(); + tombstone thread custom_tombstone_wobble(); + tombstone thread custom_tombstone_revived( self ); + result = self waittill_any_return( "player_revived", "spawned_player", "disconnect" ); + if(isdefined(self.keep_perks) && self.keep_perks) + { + if ( result == "player_revived" || result == "disconnect" ) + { + tombstone notify( "tombstone_timedout" ); + tombstone_icon unlink(); + tombstone_icon delete(); + tombstone delete(); + tombstone_hint delete(); + return; + } + } + if(getdvar("mapname") != "zm_prison") + { + if ( result == "player_revived" || result == "disconnect" ) + { + tombstone notify( "tombstone_timedout" ); + tombstone_icon unlink(); + tombstone_icon delete(); + tombstone delete(); + tombstone_hint delete(); + return; + } + } + tombstone thread custom_tombstone_timeout(tombstone_hint); + tombstone thread grab_custom_tombstone(tombstone_hint); +} + +grab_custom_tombstone(hint) +{ + self endon( "tombstone_timedout" ); + wait 1; + while ( isDefined( self ) ) + { + players = get_players(); + i = 0; + while ( i < players.size ) + { + if ( players[ i ].is_zombie ) + { + i++; + continue; + } + else + { + if ( isDefined( self.player ) && players[ i ] == self.player ) + { + istombstonepowered = 1; + if ( istombstonepowered && !players[ i ] maps/mp/zombies/_zm_laststand::player_is_in_laststand() ) + { + dist = distance( players[ i ].origin, self.origin ); + if ( dist < 64 ) + { + playfx( level._effect[ "powerup_grabbed" ], self.origin ); + playfx( level._effect[ "powerup_grabbed_wave" ], self.origin ); + players[ i ] give_loadout(); + wait 0.1; + playsoundatposition( "zmb_tombstone_grab", self.origin ); + self stoploopsound(); + self.icon unlink(); + self.icon delete(); + self delete(); + hint delete(); + self notify( "tombstone_grabbed" ); + players[ i ] clientnotify( "dc0" ); + players[ i ] notify( "dance_on_my_grave" ); + } + } + } + } + wait .1; + i++; + } + wait_network_frame(); + } +} + +custom_tombstone_clear() +{ + result = self waittill_any_return( "tombstone_timedout", "tombstone_grabbed" ); + self.current_loadout = spawnstruct(); +} + +custom_tombstone_wobble() +{ + self endon( "tombstone_grabbed" ); + self endon( "tombstone_timedout" ); + + if ( isdefined( self ) ) + { + wait 1; + playfxontag( level._effect["powerup_on"], self, "tag_origin" ); + } + + while ( isdefined( self ) ) + { + self rotateyaw( 360, 3 ); + wait 2.9; + } +} + +custom_tombstone_timeout(hint) +{ + self endon( "tombstone_grabbed" ); + self thread playtombstonetimeraudio(); + wait 48.5; + + for ( i = 0; i < 40; i++ ) + { + if ( i % 2 ) + self.icon ghost(); + else + self.icon show(); + + if ( i < 15 ) + { + wait 0.5; + continue; + } + + if ( i < 25 ) + { + wait 0.25; + continue; + } + + wait 0.1; + } + + self notify( "tombstone_timedout" ); + self.icon unlink(); + self.icon delete(); + self delete(); + hint delete(); +} + +custom_tombstone_revived( player ) +{ + self endon( "tombstone_timedout" ); + player endon( "disconnect" ); + shown = 1; + + while ( isdefined( self ) && isdefined( player ) ) + { + if ( isdefined( player.revivetrigger ) && isdefined( player.revivetrigger.beingrevived ) && player.revivetrigger.beingrevived ) + { + if ( shown ) + { + shown = 0; + self.icon hide(); + } + } + else if ( !shown ) + { + shown = 1; + self.icon show(); + } + + wait 0.05; + } +} + +//--^-Custom-Tombstone-^-------------------------------------------------------------------------------------------------------------------------------- + +divetonuke_explode_network_optimized( origin, radius, max_damage, min_damage, damage_mod ) +{ + self endon( "disconnect" ); + a_zombies = get_array_of_closest( origin, get_round_enemy_array(), undefined, undefined, radius ); + network_stall_counter = 0; + + if ( isdefined( a_zombies ) ) + { + for ( i = 0; i < a_zombies.size; i++ ) + { + e_zombie = a_zombies[i]; + + if ( !isdefined( e_zombie ) || !isalive( e_zombie ) ) + continue; + + if ( isdefined( level.sloth ) && e_zombie == level.sloth ) + continue; + + if ( isdefined( e_zombie.is_avogadro ) && e_zombie.is_avogadro ) + continue; + + dist = distance( e_zombie.origin, origin ); + damage = min_damage + ( max_damage - min_damage ) * ( 1.0 - dist / radius ); + e_zombie dodamage( damage, e_zombie.origin, self, self, 0, damage_mod ); + network_stall_counter--; + + if ( network_stall_counter <= 0 ) + { + wait_network_frame(); + network_stall_counter = randomintrange( 1, 3 ); + } + } + } +} diff --git a/t6/uncompiled mods/customperks - Copie.gsc b/t6/uncompiled mods/customperks - Copie.gsc new file mode 100644 index 0000000..f0c65c8 --- /dev/null +++ b/t6/uncompiled mods/customperks - Copie.gsc @@ -0,0 +1,1070 @@ +//PLUTO v1 - TOWN Survival with Dogs + +#include maps/mp/_utility; +#include common_scripts/utility; +#include maps/mp/gametypes_zm/_hud_util; +#include maps/mp/zombies/_zm_weapons; +#include maps/mp/zombies/_zm_stats; +#include maps/mp/gametypes_zm/_spawnlogic; +#include maps/mp/animscripts/traverse/shared; +#include maps/mp/animscripts/utility; +#include maps/mp/zombies/_load; +#include maps/mp/_createfx; +#include maps/mp/_music; +#include maps/mp/_busing; +#include maps/mp/_script_gen; +#include maps/mp/gametypes_zm/_globallogic_audio; +#include maps/mp/gametypes_zm/_tweakables; +#include maps/mp/_challenges; +#include maps/mp/gametypes_zm/_weapons; +#include maps/mp/_demo; +#include maps/mp/gametypes_zm/_hud_message; +#include maps/mp/gametypes_zm/_spawning; +#include maps/mp/gametypes_zm/_globallogic_utils; +#include maps/mp/gametypes_zm/_spectating; +#include maps/mp/gametypes_zm/_globallogic_spawn; +#include maps/mp/gametypes_zm/_globallogic_ui; +#include maps/mp/gametypes_zm/_hostmigration; +#include maps/mp/gametypes_zm/_globallogic_score; +#include maps/mp/gametypes_zm/_globallogic; +#include maps/mp/zombies/_zm; +#include maps/mp/zombies/_zm_ai_faller; +#include maps/mp/zombies/_zm_spawner; +#include maps/mp/zombies/_zm_pers_upgrades_functions; +#include maps/mp/zombies/_zm_pers_upgrades; +#include maps/mp/zombies/_zm_score; +#include maps/mp/animscripts/zm_run; +#include maps/mp/animscripts/zm_death; +#include maps/mp/zombies/_zm_blockers; +#include maps/mp/animscripts/zm_shared; +#include maps/mp/animscripts/zm_utility; +#include maps/mp/zombies/_zm_ai_basic; +#include maps/mp/zombies/_zm_laststand; +#include maps/mp/zombies/_zm_net; +#include maps/mp/zombies/_zm_audio; +#include maps/mp/gametypes_zm/_zm_gametype; +#include maps/mp/_visionset_mgr; +#include maps/mp/zombies/_zm_equipment; +#include maps/mp/zombies/_zm_power; +#include maps/mp/zombies/_zm_server_throttle; +#include maps/mp/gametypes/_hud_util; +#include maps/mp/zombies/_zm_unitrigger; +#include maps/mp/zombies/_zm_zonemgr; +#include maps/mp/zombies/_zm_perks; +#include maps/mp/zombies/_zm_melee_weapon; +#include maps/mp/zombies/_zm_audio_announcer; +#include maps/mp/zombies/_zm_magicbox; +#include maps/mp/zombies/_zm_utility; +#include maps/mp/zombies/_zm_ai_dogs; +#include maps/mp/gametypes_zm/_hud_message; +#include maps/mp/zombies/_zm_game_module; +#include maps/mp/zombies/_zm_buildables; +#include codescripts/character; +#include maps/mp/zombies/_zm_weap_riotshield; +init() +{ + // if( (getdvar( "mapname" ) == "zm_transit" || getdvar( "mapname" ) == "zm_highrise") && getdvar ( "g_gametype") == "zstandard" ) + // { + precacheshader("menu_mp_lobby_icon_film"); + precacheshader( "menu_mp_lobby_icon_customgamemode" ); + precacheshader( "waypoint_revive" ); + precacheshader( "killiconheadshot" ); + precacheshader( "menu_lobby_icon_twitter" ); + precacheshader( "hud_grenadeicon" ); + precacheshader( "menu_mp_weapons_1911" ); + precacheshader( "menu_mp_lobby_icon_screenshot" ); + precacheshader( "damage_feedback" ); + precacheshader( "zombies_rank_1" ); + precacheshader( "zombies_rank_3" ); + precacheshader( "zombies_rank_2" ); + precacheshader( "zombies_rank_4" ); + precacheshader( "menu_mp_weapons_xm8" ); + precacheshader( "faction_cdc" ); + precacheshader( "menu_mp_weapons_hamr" ); + precacheshader( "zombies_rank_5" ); + precacheshader( "hud_icon_sticky_grenade" ); + precacheshader( "specialty_instakill_zombies" ); + precacheshader( "menu_mp_weapons_1911" ); + precacheshader( "hud_icon_colt" ); + precachemodel("p6_zm_buildable_sq_meteor"); + precachemodel( "collision_player_wall_512x512x10" ); + precachemodel( "collision_physics_512x512x10" ); + precachemodel( "t5_foliage_tree_burnt03" ); + precachemodel( "p_rus_door_roller" ); + precachemodel( "ch_tombstone1" ); + precachemodel( "collision_geo_256x256x10_standard" ); + precachemodel( "zombie_vending_tombstone_on" ); + precachemodel( "zombie_vending_revive_on" ); + precachemodel( "zombie_vending_sleight_on" ); + precachemodel( "zombie_vending_doubletap2_on" ); + precachemodel( "zombie_pickup_perk_bottle" ); + precachemodel( "zm_collision_perks1" ); + precachemodel( "p6_zm_screecher_hole" ); + precachemodel( "p_cub_door01_wood_fullsize" ); + precachemodel( "veh_t6_civ_microbus_dead" ); + precachemodel( "p_rus_door_white_window_plain_left" ); + if (level.script != "zm_prison") + { + level._effect["fx_zombie_cola_revive_on"] = loadfx( "misc/fx_zombie_cola_revive_on" ); + level._effect["fx_zombie_cola_dtap_on"] = loadfx( "misc/fx_zombie_cola_dtap_on" ); + } + + level._effect["fx_zombie_cola_on"] = loadfx( "misc/fx_zombie_cola_on" ); + if (!(level.script == "zm_tomb" || level.script == "zm_prison")) + { + level._effect["fx_zmb_wall_buy_taseknuck"] = loadfx( "maps/zombie/fx_zmb_wall_buy_taseknuck" ); + level._effect["fx_zmb_wall_buy_bowie"] = loadfx( "maps/zombie/fx_zmb_wall_buy_bowie" ); + } + // level._effect["fx_default_explosion"] = loadfx( "explosions/fx_default_explosion" ); + + + if( level.script == "zm_buried" || level.script == "zm_tomb" ) + { + level._effect["fx_default_explosion"] = level._effect[ "divetonuke_groundhit"]; + } + else + { + level._effect["fx_default_explosion"] = loadfx( "explosions/fx_default_explosion" ); + } + + + level.town = 1; + level.diner = 0; + + level thread onPlayerConnect(); + + level thread perk_machine_removal( "specialty_scavenger" ); + init_custom_map(); + + if(level.script != "zm_buried" && level.script != "zm_highrise" && level.script != "zm_tomb" && level.script != "zm_prison") + level.get_player_weapon_limit = ::custom_get_player_weapon_limit; + level.zombie_last_stand = ::LastStand; + level.custom_vending_precaching = ::default_vending_precaching; + + register_player_damage_callback( ::damage_callback ); + + + + + level.player_out_of_playable_area_monitor = 0; + level.perk_purchase_limit = 50; + if( getdvar( "mapname" ) == "zm_transit" && getdvar ( "g_gametype" ) == "zstandard" ) + { + foreach( weapon in level.zombie_weapons) + { + weapon.is_in_box = 1; + } + } +// } +} + + + +onPlayerConnect() +{ + while( 1 ) + { + level waittill( "connected", player ); + player thread onPlayerSpawned(); + } +} + +onPlayerSpawned() +{ + self endon( "disconnect" ); + level endon( "game_ended" ); + self waittill( "spawned_player" ); + + self.perkarray = []; + self.dying_wish_on_cooldown = 0; + self.perk_reminder = 0; + self.perk_count = 0; + self.num_perks = 0; + self thread removeperkshader(); + self thread perkboughtcheck(); + self thread damagehitmarker(); + for(;;) + { + self waittill( "spawned_player" ); + if(self.score < 1500) + { + self.score = 1500; + } + } +} + + + +damagehitmarker() +{ + self thread startwaiting(); + self.hitmarker = newdamageindicatorhudelem( self ); + self.hitmarker.horzalign = "center"; + self.hitmarker.vertalign = "middle"; + self.hitmarker.x = -12; + self.hitmarker.y = -12; + self.hitmarker.alpha = 0; + self.hitmarker setshader( "damage_feedback", 24, 48 ); + +} + +startwaiting() +{ + while( 1 ) + { + foreach( zombie in getaiarray( level.zombie_team ) ) + { + if( !(IsDefined( zombie.waitingfordamage )) ) + { + zombie thread hitmark(); + } + } + wait 0.25; + } +} + +hitmark() +{ + self endon( "killed" ); + self.waitingfordamage = 1; + while( 1 ) + { + self waittill( "damage", amount, attacker, dir, point, mod ); + attacker.hitmarker.alpha = 0; + if( isplayer( attacker ) ) + { + if( isalive( self ) ) + { + attacker.hitmarker.color = ( 1, 1, 1 ); + attacker.hitmarker.alpha = 1; + attacker.hitmarker fadeovertime( 1 ); + attacker.hitmarker.alpha = 0; + } + else + { + attacker.hitmarker.color = ( 1, 0, 0 ); + attacker.hitmarker.alpha = 1; + attacker.hitmarker fadeovertime( 1 ); + attacker.hitmarker.alpha = 0; + self notify( "killed" ); + } + } + } +} + + + + +init_custom_map() +{ + if( getdvar( "mapname" ) == "zm_transit" && getdvar ( "g_gametype" ) == "zstandard" ) + { + perk_system( "script_model", ( 1856, -810.722, -55.875), "zombie_vending_tombstone_on", ( 0, 180, 0 ), "custom", "mus_perks_deadshot_sting", "Deadshot", 2000, "tombstone_light", "deadshot" ); + perk_system( "script_model", ( 2460, -780, -55.875 ), "zombie_vending_tombstone_on", ( 0, 225, 0 ), "custom", "mus_perks_doubletap_sting", "Burn Heart", 2500, "jugger_light", "Burn_Heart" ); + perk_system( "script_model", ( 901.86, -1575.574, -47.875 ), "zombie_vending_tombstone_on", ( 0, 180, 0 ), "custom", "mus_perks_deadshot_sting", "Widow's Wine", 4000, "tombstone_light", "WIDOWS_WINE" ); + perk_system( "script_model", ( 450, -300.574, -61.875 ), "zombie_vending_tombstone_on", ( 0, 45, 0 ), "custom", "mus_perks_packa_sting", "Electric Cherry", 2000, "tombstone_light", "ELECTRIC_CHERRY" ); // 613,-250,z 0,0,0 + perk_system( "script_model", ( 1069, -1133, 120.125 ), "zombie_vending_tombstone_on", ( 0, 180, 0 ), "custom", "mus_perks_doubletap_sting", "Ethereal Razor", 3500, "tombstone_light", "Ethereal_Razor" ); + perk_system( "script_model", ( 1823.86, 670.574, -55.875 ), "zombie_vending_tombstone_on", ( 0, 45, 0 ), "custom", "mus_perks_doubletap_sting", "Mule Kick", 4000, "tombstone_light", "MULE" ); + perk_system( "script_model", ( 840, 603.809, -40.875 ), "zombie_vending_tombstone_on", ( 0, 0, 0 ), "custom", "mus_perks_packa_sting", "PhD Flopper", 2500, "tombstone_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( 2358, -87, -55.875 ), "zombie_vending_tombstone_on", ( 0, -90, 0 ), "custom", "mus_perks_doubletap_sting", "Downer's Delight", 2000, "tombstone_light", "Downers_Delight" ); + perk_system( "script_model", ( 2015, 858, -56.875 ), "zombie_vending_tombstone_on", ( 0, -90, 0 ), "custom", "mus_perks_doubletap_sting", "Dying Wish", 6000, "tombstone_light", "Dying_Wish" ); + perk_system( "script_model", ( 559, -1364, 120.125 ), "zombie_vending_tombstone_on", ( 0, 180, 0 ), "custom", "mus_perks_doubletap_sting", "Ammo Regen", 3000, "tombstone_light", "Ammo_Regen" ); + } + if( level.script == "zm_highrise") + { + perk_system( "script_model", ( 1884.42, 491.946, 1298.72), "zombie_vending_jugg_on", ( 0, 418.728, 0 ), "custom", "mus_perks_deadshot_sting", "Deadshot", 2000, "tombstone_light", "deadshot" ); +// perk_system( "script_model", ( 2764.64, 1868.03, 1391.01 ), "zombie_vending_jugg_on", ( 0, 384.236, 0 ), "custom", "mus_perks_doubletap_sting", "Burn Heart", 2500, "jugger_light", "Burn_Heart" ); + perk_system( "script_model", ( 1978.25, 597.657, 2704.13 ), "zombie_vending_jugg_on", ( 0, 329.291, 0 ), "custom", "mus_perks_deadshot_sting", "Widow's Wine", 4000, "tombstone_light", "WIDOWS_WINE" ); + perk_system( "script_model", ( 1415.64, 2108.36, 3220.26 ), "zombie_vending_jugg_on", ( 0, 406.661, 0 ), "custom", "mus_perks_packa_sting", "Electric Cherry", 2000, "tombstone_light", "ELECTRIC_CHERRY" ); // 613,-250,z 0,0,0 + perk_system( "script_model", ( 1901.97, 1431.36, 3216.13 ), "zombie_vending_jugg_on", ( 0, 404.762, 0 ), "custom", "mus_perks_doubletap_sting", "Ethereal Razor", 3500, "tombstone_light", "Ethereal_Razor" ); +// perk_system( "script_model", ( 1891.64, 1119.64, 3048.36 ), "zombie_vending_jugg_on", ( 0, 45, 0 ), "custom", "mus_perks_doubletap_sting", "Mule Kick", 4000, "tombstone_light", "MULE" ); + perk_system( "script_model", ( 1429.29, -453.397, 2880.13 ), "zombie_vending_jugg_on", ( 0, 149.1426, 0 ), "custom", "mus_perks_packa_sting", "PhD Flopper", 2500, "tombstone_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( 1109.64, 2701.36, 3043.82 ), "zombie_vending_jugg_on", ( 0, 394.926, 0 ), "custom", "mus_perks_doubletap_sting", "Downer's Delight", 2000, "tombstone_light", "Downers_Delight" ); + perk_system( "script_model", ( 1706.28, 1055.64, 3395.1 ), "zombie_vending_jugg_on", ( 0, 180, 0 ), "custom", "mus_perks_doubletap_sting", "Dying Wish", 6000, "tombstone_light", "Dying_Wish" ); + perk_system( "script_model", ( 2269.17, 182.377, 2880.13 ), "zombie_vending_jugg_on", ( 0, 418.596, 0 ), "custom", "mus_perks_doubletap_sting", "Ammo Regen", 3000, "tombstone_light", "Ammo_Regen" ); + } + if( level.script == "zm_buried") + { + perk_system( "script_model", ( 1618.14, 1513.46, 200.62), "zombie_vending_jugg_on", ( 0, 250.147, 0 ), "custom", "mus_perks_deadshot_sting", "Deadshot", 2000, "sleight_light", "deadshot" ); +// perk_system( "script_model", ( -1176.36, 508.26, 144.125 ), "zombie_vending_jugg_on", ( 0, 448.269, 0 ), "custom", "mus_perks_doubletap_sting", "Burn Heart", 2500, "sleight_light", "Burn_Heart" ); + perk_system( "script_model", ( -1176.36, 510.625, 144.125 ), "zombie_vending_jugg_on", ( 0, 449.412, 0 ), "custom", "mus_perks_deadshot_sting", "Widow's Wine", 4000, "sleight_light", "WIDOWS_WINE" ); + perk_system( "script_model", ( -448.859, 131.435, 143.491 ), "zombie_vending_jugg_on", ( 0, 180.3, 0 ), "custom", "mus_perks_packa_sting", "Electric Cherry", 2000, "sleight_light", "ELECTRIC_CHERRY" ); // 613,-250,z 0,0,0 + perk_system( "script_model", ( 890.359, -840.206, -22.8006 ), "zombie_vending_jugg_on", ( 0, 270.367, 0 ), "custom", "mus_perks_doubletap_sting", "Ethereal Razor", 3500, "sleight_light", "Ethereal_Razor" ); +// perk_system( "script_model", ( 1891.64, 1119.64, 3048.36 ), "zombie_vending_jugg_on", ( 0, 45, 0 ), "custom", "mus_perks_doubletap_sting", "Mule Kick", 4000, "sleight_light", "MULE" ); + perk_system( "script_model", ( 572.507, -712.359, 149.95 ), "zombie_vending_jugg_on", ( 0, 178.4505, 0 ), "custom", "mus_perks_packa_sting", "PhD Flopper", 2500, "sleight_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( 488.324, 727.641, 176.125 ), "zombie_vending_jugg_on", ( 0, 178.9998, 0 ), "custom", "mus_perks_doubletap_sting", "Downer's Delight", 2000, "sleight_light", "Downers_Delight" ); + perk_system( "script_model", ( -1298.32, -837.178, -23.875 ), "zombie_vending_jugg_on", ( 0, 91.37286, 0 ), "custom", "mus_perks_doubletap_sting", "Dying Wish", 6000, "sleight_light", "Dying_Wish" ); + perk_system( "script_model", ( -122.161, -1469.21, 168.125 ), "zombie_vending_jugg_on", ( 0, 448.841, 0 ), "custom", "mus_perks_doubletap_sting", "Ammo Regen", 3000, "sleight_light", "Ammo_Regen" ); + } + if( level.script == "zm_nuked") + { + perk_system( "script_model", ( 28.8155, -356.18, -65.8346 ), "zombie_vending_jugg_on", ( 0, 129.8755, 0 ), "custom", "mus_perks_deadshot_sting", "Deadshot", 2000, "sleight_light", "deadshot" ); +// perk_system( "script_model", ( ), "zombie_vending_jugg_on", ( ), "custom", "mus_perks_doubletap_sting", "Burn Heart", 2500, "sleight_light", "Burn_Heart" ); + perk_system( "script_model", ( -954.194, 714.594, 84.0385 ), "zombie_vending_jugg_on", ( 0, 429.46, 0 ), "custom", "mus_perks_deadshot_sting", "Widow's Wine", 4000, "sleight_light", "WIDOWS_WINE" ); + perk_system( "script_model", ( 683.524, 618.635, -56.875 ), "zombie_vending_jugg_on", ( 0, 102.5635, 0 ), "custom", "mus_perks_packa_sting", "Electric Cherry", 2000, "sleight_light", "ELECTRIC_CHERRY" ); // 613,-250,z 0,0,0 + perk_system( "script_model", ( 1420.35, -21.4313, -63.8849 ), "zombie_vending_jugg_on", ( 0, 194.085, 0 ), "custom", "mus_perks_doubletap_sting", "Ethereal Razor", 3500, "sleight_light", "Ethereal_Razor" ); + perk_system( "script_model", ( 618.292, -188.322, -56.3686 ), "zombie_vending_jugg_on", ( 0, 105.5011, 0 ), "custom", "mus_perks_doubletap_sting", "Mule Kick", 4000, "sleight_light", "MULE" ); + perk_system( "script_model", ( 1152.5, 160.6, 79.125 ), "zombie_vending_jugg_on", ( 0, 347.541, 0 ), "custom", "mus_perks_packa_sting", "PhD Flopper", 2500, "sleight_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( 156.738, 513.899, -62.3141 ), "zombie_vending_jugg_on", ( 0, 101.8164, 0 ), "custom", "mus_perks_doubletap_sting", "Downer's Delight", 2000, "sleight_light", "Downers_Delight" ); + perk_system( "script_model", ( -646.863, 271.522, -55.875 ), "zombie_vending_jugg_on", ( 0, 160.8405, 0 ), "custom", "mus_perks_doubletap_sting", "Dying Wish", 6000, "sleight_light", "Dying_Wish" ); + perk_system( "script_model", ( -1582.46, 112.604, -63.2092 ), "zombie_vending_jugg_on", ( 0, 250.829, 0 ), "custom", "mus_perks_doubletap_sting", "Ammo Regen", 3000, "sleight_light", "Ammo_Regen" ); + } + if( level.script == "zm_tomb") + { + perk_system( "script_model", ( 184.995, -2422.49, 50.125), "zombie_vending_jugg_on", ( 0, 369.091, 0 ), "custom", "mus_perks_deadshot_sting", "Deadshot", 2000, "sleight_light", "deadshot" ); + perk_system( "script_model", ( 160.359, 3781.17, -351.875 ), "zombie_vending_jugg_on", ( 0, 266.122, 0 ), "custom", "mus_perks_deadshot_sting", "Widow's Wine", 4000, "sleight_light", "WIDOWS_WINE" ); + perk_system( "script_model", ( 375.771, 2119.22, -122.951 ), "zombie_vending_jugg_on", ( 0, 179.5935, 0 ), "custom", "mus_perks_doubletap_sting", "Ethereal Razor", 3500, "sleight_light", "Ethereal_Razor" ); + perk_system( "script_model", ( -335.604, -187.006, 325.273 ), "zombie_vending_jugg_on", ( 0, 132.9565, 0 ), "custom", "mus_perks_packa_sting", "PhD Flopper", 2500, "sleight_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( 924.47, 360.72, 131.005 ), "zombie_vending_jugg_on", ( 0, 373.266, 0 ), "custom", "mus_perks_doubletap_sting", "Downer's Delight", 2000, "sleight_light", "Downers_Delight" ); + perk_system( "script_model", ( 1345.09, -3822.62, 302.125 ), "zombie_vending_jugg_on", ( 0, 270.593, 0 ), "custom", "mus_perks_doubletap_sting", "Dying Wish", 6000, "sleight_light", "Dying_Wish" ); + perk_system( "script_model", ( 2972.36, 5218.91, -378.566 ), "zombie_vending_jugg_on", ( 0, 270.379, 0 ), "custom", "mus_perks_doubletap_sting", "Ammo Regen", 3000, "sleight_light", "Ammo_Regen" ); + } + if( level.script == "zm_prison") + { + perk_system( "script_model", ( -1344.65, 5598.31, -71.875 ), "p6_zm_al_vending_jugg_on", ( 0, 98.34412, 0 ), "custom", "mus_perks_deadshot_sting", "Deadshot", 2000, "sleight_light", "deadshot" ); + perk_system( "script_model", ( 3763.64, 9669.99, 1704.13 ), "p6_zm_al_vending_jugg_on", ( 0, 90, 0 ), "custom", "mus_perks_deadshot_sting", "Widow's Wine", 4000, "sleight_light", "WIDOWS_WINE" ); + perk_system( "script_model", ( 2160.71, 9247.64, 1558.13 ), "p6_zm_al_vending_jugg_on", ( 0, 179.1815, 0 ), "custom", "mus_perks_doubletap_sting", "Ethereal Razor", 3500, "sleight_light", "Ethereal_Razor" ); + perk_system( "script_model", ( 597.633, 8546.86, 832.125 ), "p6_zm_al_vending_jugg_on", ( 0, 221.984, 0 ), "custom", "mus_perks_doubletap_sting", "Mule Kick", 4000, "sleight_light", "MULE" ); + perk_system( "script_model", ( 456.359, 8679.51, 1128.13 ), "p6_zm_al_vending_jugg_on", ( 0, 269.533, 0 ), "custom", "mus_perks_packa_sting", "PhD Flopper", 2500, "sleight_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( -685.943, 9199.64, 1336.13 ), "p6_zm_al_vending_jugg_on", ( 0, 178.5443, 0 ), "custom", "mus_perks_doubletap_sting", "Downer's Delight", 2000, "sleight_light", "Downers_Delight" ); + perk_system( "script_model", ( 1728.56, 10688.4, 1336.13 ), "p6_zm_al_vending_jugg_on", ( 0, 357.896, 0 ), "custom", "mus_perks_doubletap_sting", "Dying Wish", 6000, "sleight_light", "Dying_Wish" ); + perk_system( "script_model", ( 1367.28, 10096.4, 1128.13 ), "p6_zm_al_vending_jugg_on", ( 0, 358.687, 0 ), "custom", "mus_perks_doubletap_sting", "Ammo Regen", 3000, "sleight_light", "Ammo_Regen" ); + } +} + +play_fx( fx ) +{ + playfxontag( level._effect[ fx ], self, "tag_origin" ); +} + +defaulth_vending_precaching() +{ + level._effect[ "sleight_light" ] = loadfx( "misc/fx_zombie_cola_on" ); + level._effect[ "tombstone_light" ] = loadfx( "misc/fx_zombie_cola_on" ); + level._effect[ "revive_light" ] = loadfx( "misc/fx_zombie_cola_revive_on" ); + level._effect[ "marathon_light" ] = loadfx( "maps/zombie/fx_zmb_cola_staminup_on" ); + level._effect[ "jugger_light" ] = loadfx( "misc/fx_zombie_cola_jugg_on" ); + level._effect[ "doubletap_light" ] = loadfx( "misc/fx_zombie_cola_dtap_on" ); + level._effect[ "deadshot_light" ] = loadfx( "misc/fx_zombie_cola_dtap_on" ); + level._effect[ "additionalprimaryweapon_light" ] = loadfx( "misc/fx_zombie_cola_arsenal_on" ); + level._effect[ "packapunch_fx" ] = loadfx( "maps/zombie/fx_zombie_packapunch" ); + level._effect[ "wall_taseknuck" ] = loadfx( "maps/zombie/fx_zmb_wall_buy_taseknuck" ); +} + + +playchalkfx(effect, origin, angles) +{ + fx = SpawnFX(level._effect[ effect ], origin,AnglesToForward(angles),AnglesToUp(angles)); + TriggerFX(fx); + level waittill("connected", player); + fx Delete(); +} + + + +perk_system( script, pos, model, angles, type, sound, name, cost, fx, perk) +{ + col = spawn( script, pos); + col setmodel( model ); + col.angles = angles; + x = spawn( script, pos ); + x setmodel( "zm_collision_perks1" ); + x.angles = angles; + col thread buy_system( perk, sound, name, cost, type ); + col thread play_fx( fx ); +} + +buy_system( perk, sound, name, cost, type ) +{ + self endon( "game_ended" ); + while( 1 ) + { + foreach( player in level.players ) + { + if(!player.machine_is_in_use) + { + if( distance( self.origin, player.origin ) <= 70 ) + { + player thread SpawnHint( self.origin, 30, 30, "HINT_ACTIVATE", "Hold ^3&&1^7 for " + name + " [Cost: " + cost + "]" ); + if(player usebuttonpressed() && !player hasperk(perk) && !player hascustomperk(perk) && player.score >= cost && !player maps/mp/zombies/_zm_laststand::player_is_in_laststand()) + { + player.machine_is_in_use = 1; + player playsound( "zmb_cha_ching" ); + player.score -= cost; + player playsound( sound ); + player thread drawshader_and_shadermove( perk, 1, 1, type ); + wait 4; + player.machine_is_in_use = 0; + } + else + { + if( player usebuttonpressed() && player.score < cost ) + { + player maps/mp/zombies/_zm_audio::create_and_play_dialog( "general", "perk_deny", undefined, 0 ); + } + } + } + } + } + wait 0.1; + } +} + +hascustomperk(perk) +{ + for(i = 0; i < self.perkarray.size; i++) + { + if(self.perkarray[i].name == perk) + { + return 1; + } + } + return 0; +} + +removeperkshader() +{ + for(;;) + { + self waittill_any_return( "fake_death", "player_downed", "player_revived", "spawned_player", "disconnect", "death" ); + self.num_perks = 0; + self.perk_reminder = 0; + self.perk_count = 0; + self.dying_wish_on_cooldown = 0; + self removeallcustomshader(); + self.perkarray = []; + self notify( "stopcustomperk" ); + self.bleedout_time = 30; + self.ignore_lava_damage = 0; + self setclientfieldtoplayer( "deadshot_perk", 0 ); + } +} + +removeallcustomshader() +{ + for(i = 0; i < self.perkarray.size; i++) + { + self.perkarray[i] destroy(); + } +} + +drawshader( shader, x, y, width, height, color, alpha, sort ) +{ + hud = newclienthudelem( self ); + hud.elemtype = "icon"; + hud.color = color; + hud.alpha = alpha; + hud.sort = sort; + hud.children = []; + hud.hidewheninmenu = 1; + hud setparent( level.uiparent ); + hud setshader( shader, width, height ); + hud.x = x; + hud.y = y; + return hud; +} + +perkboughtcheck() +{ + self endon("death"); + self endon("disconnect"); + for(;;) + { + self.perk_reminder = self.num_perks; + self waittill("perk_acquired"); + n = 1; + if(!(self.num_perks > self.perk_reminder)) + { + n = (self.num_perks - self.perk_reminder); + self.num_perks = (self.perk_reminder + n); + } + self.perk_reminder = self.num_perks; + self.perk_count += n; + self drawshader_and_shadermove("none", 0, 0, "normal"); //modified to remove perk alignement since 2 perk lines Added "normal" for type check + } +} + +drawshader_and_shadermove(perk, custom, print, type) +{ + if(custom) + { + self allowProne(false); + self allowSprint(false); + self disableoffhandweapons(); + self disableweaponcycling(); + weapona = self getcurrentweapon(); + weaponb = "zombie_perk_bottle_jugg"; + self giveweapon( weaponb ); + self switchtoweapon( weaponb ); + self waittill( "weapon_change_complete" ); + self enableoffhandweapons(); + self enableweaponcycling(); + self takeweapon( weaponb ); + self switchtoweapon( weapona ); + self maps/mp/zombies/_zm_audio::playerexert( "burp" ); + self setblur( 4, 0.1 ); + wait 0.1; + self setblur( 0, 0.1 ); + self allowProne(true); + self allowSprint(true); + } + + yPerk = 325; + if (level.script == "zm_buried") + { + yPerk = 300; + } + + x = -408; + for(i = 0; i < self.perkarray.size; i++) + { + if (type == "custom") + { + x += 15; + } + } + /*if (perk == "custom") + { + for(i = 0; i < self.perkarray.size; i++) + { + self.perkarray[i].x = self.perkarray[i].x + 30; + } + }*/ + if(perk == "Downers_Delight") + { + self.perk1back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk1front = self drawshader( "waypoint_revive", x, yPerk, 23, 23, ( 0, 1, 1 ), 100, 0 ); + self.perk1front.name = perk; + self.perkarray[self.perkarray.size] = self.perk1front; + self.perk1back.name = perk; + self.perkarray[self.perkarray.size] = self.perk1back; + self.num_perks++; + self thread DDown(); + if(print) + { + self iprintln("^9Downer's Delight"); + wait 0.2; + self iprintln("This Perk will increase players bleedout time by 10 seconds and current weapons is used in laststand."); + } + } + if(perk == "MULE") + { + self.perk2back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk2front = self drawshader( "menu_mp_weapons_1911", x, yPerk, 22, 22, ( 0, 1, 0 ), 100, 0 ); + self.perk2front.name = perk; + self.perkarray[self.perkarray.size] = self.perk2front; + self.perk2back.name = perk; + self.perkarray[self.perkarray.size] = self.perk2back; + self.num_perks++; + if(print) + { + self iprintln("^9Mule Kick"); + wait 0.2; + self iprintln("This Perk enables additional primary weapon slot for player. "); + } + } + if(perk == "PHD_FLOPPER") + { + self.perk3back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk3front = self drawshader( "hud_icon_sticky_grenade", x, yPerk, 23, 23, (1, 0, 1 ), 100, 0 ); + self.perk3front.name = perk; + self.perkarray[self.perkarray.size] = self.perk3front; + self.perk3back.name = perk; + self.perkarray[self.perkarray.size] = self.perk3back; + self.num_perks++; + if(print) + { + self iprintln("^9PhD Flopper"); + wait 0.2; + self iprintln("This Perk removes explosion and fall damage also player creates explosion when dive to prone."); + } + } + if(perk == "Victorious_Tortoise") + { + self.perk4back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 200, 0 ), 100, 0 ); + self.perk4front = self drawshader( "zombies_rank_2", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk4front.name = perk; + self.perkarray[self.perkarray.size] = self.perk4front; + self.perk4back.name = perk; + self.perkarray[self.perkarray.size] = self.perk4back; + self.num_perks++; + self thread start_vt(); + if(print) + { + self iprintln("^9Victorious Tortoise"); + wait 0.2; + self iprintln("This Perk allows shield block damage from all directions when in use."); + } + } + if(perk == "ELECTRIC_CHERRY") + { + self.perk5back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 200 ), 100, 0 ); + self.perk5front = self drawshader( "zombies_rank_5", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk5front.name = perk; + self.perkarray[self.perkarray.size] = self.perk5front; + self.perk5back.name = perk; + self.perkarray[self.perkarray.size] = self.perk5back; + self.num_perks++; + self thread start_ec(); + if(print) + { + self iprintln("^9Electric Cherry"); + wait 0.2; + self iprintln("This Perk creates an electric shockwave around the player whenever they reload."); + } + } + if(perk == "WIDOWS_WINE") + { + self.perk6back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk6front = self drawshader( "zombies_rank_3", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk6front.name = perk; + self.perkarray[self.perkarray.size] = self.perk6front; + self.perk6back.name = perk; + self.perkarray[self.perkarray.size] = self.perk6back; + self.num_perks++; + self takeweapon( self get_player_lethal_grenade() ); + self set_player_lethal_grenade( "sticky_grenade_zm" ); + self giveweapon("sticky_grenade_zm"); + self thread ww_nades(); + if(print) + { + self iprintln("^9Widow's Wine"); + wait 0.2; + self iprintln("This Perk damages zombies around the player when player is hit and grenades are upgraded."); + } + } + if(perk == "Ethereal_Razor") + { + self.perk7back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 200, 0, 0 ), 100, 0 ); + self.perk7front = self drawshader( "zombies_rank_4", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk7front.name = perk; + self.perkarray[self.perkarray.size] = self.perk7front; + self.perk7back.name = perk; + self.perkarray[self.perkarray.size] = self.perk7back; + self.num_perks++; + if(print) + { + self iprintln("^9Ethereal Razor"); + wait 0.2; + self iprintln("This Perk deals extra damage when player using melee attacks and restores a small amount of health."); + } + } + if(perk == "Ammo_Regen") + { + self.perk8back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk8front = self drawshader( "menu_mp_lobby_icon_customgamemode", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk8front.name = perk; + self.perkarray[self.perkarray.size] = self.perk8front; + self.perk8back.name = perk; + self.perkarray[self.perkarray.size] = self.perk8back; + self.num_perks++; + self thread ammoregen(); + self thread grenadesregen(); + if(print) + { + self iprintln("^9Ammo Regen"); + wait 0.2; + self iprintln("This Perk will slowly regenerades players ammonation and grenades."); + } + } + if(perk == "Burn_Heart") + { + self.perk9back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 200, 0, 0 ), 100, 0 ); + self.perk9front = self drawshader( "faction_cdc", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk9front.name = perk; + self.perkarray[self.perkarray.size] = self.perk9front; + self.perk9back.name = perk; + self.perkarray[self.perkarray.size] = self.perk9back; + self.num_perks++; + self.ignore_lava_damage = 1; + if(print) + { + self iprintln("^9Burn Heart"); + wait 0.2; + self iprintln("This Perk removes lava damage."); + } + } + if(perk == "Dying_Wish") + { + self.perk10back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 200, 0, 0 ), 100, 0 ); + self.perk10front = self drawshader( "zombies_rank_5", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk10front.name = perk; + self.perkarray[self.perkarray.size] = self.perk10front; + self.perk10back.name = perk; + self.perkarray[self.perkarray.size] = self.perk10back; + self.num_perks++; + self thread dying_wish_checker(); + if(print) + { + self iprintln("^9Dying Wish"); + wait 0.2; + self iprintln("This Perk allow player to go berserker mode for 9 seconds instead of laststand."); + wait 0.1; + self iprintln(" (cooldown 5mins and it's increased 30sec every time perk is used. - max 10mins) "); + } + } + if(perk == "deadshot") + { + self.perk11back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk11front = self drawshader( "killiconheadshot", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk11front.name = perk; + self.perkarray[self.perkarray.size] = self.perk11front; + self.perk11back.name = perk; + self.perkarray[self.perkarray.size] = self.perk11back; + self.num_perks++; + self setclientfieldtoplayer( "deadshot_perk", 1 ); + if(print) + { + self iprintln("^9Deadshot"); + wait 0.2; + self iprintln("This Perk aims automatically enemys head instead of body."); + } + } +} + +custom_get_player_weapon_limit( player ) +{ + weapon_limit = 2; + if ( player hascustomperk("MULE") ) + { + weapon_limit = 3; + } + else + { + weapons = self getWeaponsListPrimaries(); + if(weapons.size > 2) + { + self takeWeapon(weapons[2]); + } + } + return weapon_limit; +} + +ammoregen() +{ + self endon( "disconnect" ); + level endon( "end_game" ); + self endon( "stopcustomperk" ); + for(;;) + { + if(!self GetCurrentWeapon() == "" && !is_grenade_launcher( self GetCurrentWeapon()) ) + { + stockcount = self getweaponammostock( self GetCurrentWeapon() ); + self setWeaponAmmostock( self GetCurrentWeapon(), stockcount + 1 ); + wait 2; + } + wait 0.1; + } +} + +grenadesregen() +{ + self endon( "disconnect" ); + level endon( "end_game" ); + self endon( "stopcustomperk" ); + for(;;) + { + grenades = self get_player_lethal_grenade(); + grenade_count = self getweaponammoclip(grenades); + if(grenade_count < 4) + { + self setweaponammoclip(grenades, (grenade_count + 1)); + } + tactical_grenades = self get_player_tactical_grenade(); + tactical_grenade_count = self getweaponammoclip(tactical_grenades); + if(tactical_grenade_count < 3 ) + { + self setweaponammoclip(tactical_grenades, (tactical_grenade_count + 1)); + } + wait 300; + } +} + +start_ec() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("stopcustomperk"); + for(;;) + { + self waittill( "reload_start" ); + playfxontag( level._effect[ "poltergeist"], self, "J_SpineUpper" ); + self EnableInvulnerability(); + RadiusDamage(self.origin, 120, 200, 100, self); + self DisableInvulnerability(); + self playsound( "zmb_turbine_explo" ); + wait 1; + } +} + +start_vt() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("stopcustomperk"); + for(;;) + { + if(self getcurrentweapon() == "riotshield_zm" ) + { + self enableInvulnerability(); + self.shielddamagetaken += 100; + wait 0.9; + } + else + { + self disableInvulnerability(); + } + wait 0.1; + } +} + +start_er() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("stopcustomperk"); + for(;;) + { + if (self hascustomperk("Ethereal_Razor") && self ismeleeing()) + { + foreach(zombie in getAiArray(level.zombie_team)) + { + if( distance( self.origin, zombie.origin ) <= 100 ) + { + + } + } + self.health += 20; + if(self.health > self.maxhealth) + { + self.health = self.maxhealth; + } + while(self ismeleeing()) + { + wait 0.1; + } + } + wait 0.05; + } +} + +LastStand() +{ + if(self hascustomperk("Downers_Delight")) + { + self.customlaststandweapon = self getcurrentweapon(); + self switchtoweapon( self.customlaststandweapon ); + self setweaponammoclip( self.customlaststandweapon, 150 ); + self.bleedout_time = 40; + } + else + { + self maps/mp/zombies/_zm::last_stand_pistol_swap(); + } +} + +DDown() +{ + self endon( "disconnect" ); + level endon( "end_game" ); + self endon( "stopcustomperk" ); + for(;;) + { + self waittill("player_downed"); + self playsound( "zmb_phdflop_explo" ); + playfx(loadfx("explosions/fx_default_explosion"), self.origin, anglestoforward( ( 0, 45, 55 ) ) ); + RadiusDamage(self.origin, 150, 600, 400, self); + wait 0.1; + } +} + +doGivePerk(perk) +{ + self endon("disconnect"); + self endon("death"); + level endon("game_ended"); + self endon("perk_abort_drinking"); + if (!(self hasperk(perk) || (self maps/mp/zombies/_zm_perks::has_perk_paused(perk)))) + { + gun = self maps/mp/zombies/_zm_perks::perk_give_bottle_begin(perk); + evt = self waittill_any_return("fake_death", "death", "player_downed", "weapon_change_complete"); + if (evt == "weapon_change_complete") + self thread maps/mp/zombies/_zm_perks::wait_give_perk(perk, 1); + self maps/mp/zombies/_zm_perks::perk_give_bottle_end(gun, perk); + if (self maps/mp/zombies/_zm_laststand::player_is_in_laststand() || isDefined(self.intermission) && self.intermission) + return; + self notify("burp"); + } +} + + +SpawnHint( origin, width, height, cursorhint, string ) +{ + hint = spawn( "trigger_radius", origin, 1, width, height ); + hint setcursorhint( cursorhint, hint ); + hint sethintstring( string ); + hint setvisibletoall(); + wait 0.2; + hint delete(); +} + + +ww_points( player ) +{ + for(i = 0; i < 3; i++) + { + self maps/mp/zombies/_zm_utility::set_zombie_run_cycle("walk"); + player maps/mp/zombies/_zm_score::add_to_player_score( 10 ); + PlayFXOnTag(level.effect_WebFX,self,"j_spineupper"); + self doDamage(150, (0, 0, 0)); + wait 1; + } +} + +ww_nade_explosion() +{ + wait 2; + // if( self maps/mp/zm_transit_lava::object_touching_lava()) +// { + // self delete(); + // return 0; + // } + foreach(zombie in getAiArray(level.zombie_team)) + { + if( distance( zombie.origin, self.origin ) < 210 ) + { + zombie thread ww_points( self ); + } + } + self delete(); +} + +ww_nades() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("stopcustomperk"); + for(;;) + { + self waittill( "grenade_fire", grenade, weapname ); + if( weapname == "sticky_grenade_zm" ) + { + ww_nade = spawnsm( grenade.origin, "zombie_bomb" ); + ww_nade hide(); + ww_nade linkto( grenade ); + ww_nade thread ww_nade_explosion(); + } + } +} + +spawnsm( origin, model, angles ) +{ + ent = spawn( "script_model", origin ); + ent setmodel( model ); + if( IsDefined( angles ) ) + { + ent.angles = angles; + } + return ent; +} + + +damage_callback( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime, boneindex ) +{ + if( isDefined( eAttacker.is_zombie ) && eAttacker.is_zombie && self hascustomperk("WIDOWS_WINE") ) + { + zombies = getaiarray(level.zombie_team); + foreach(zombie in zombies) + { + if(distance(self.origin, zombie.origin) < 150) + { + grenades = self get_player_lethal_grenade(); + grenade_count = self getweaponammoclip(grenades); + if(grenade_count > 0) + { + self PlaySound("zmb_elec_jib_zombie"); + self setweaponammoclip(grenades, (grenade_count - 1)); + zombie thread ww_points( self ); + } + } + } + } + if(self hascustomperk("PHD_FLOPPER")) + { + if( smeansofdeath == "MOD_FALLING" ) + { + if(isDefined( self.divetoprone ) && self.divetoprone == 1 ) + { + radiusdamage( self.origin, 300, 5000, 1000, self, "MOD_GRENADE_SPLASH" ); + playfx(loadfx("explosions/fx_default_explosion"), self.origin, anglestoforward( ( 0, 45, 55 ) ) ); + self playsound( "zmb_phdflop_explo" ); + } + return 0; + } + if( smeansofdeath == "MOD_PROJECTILE" || smeansofdeath == "MOD_PROJECTILE_SPLASH" || smeansofdeath == "MOD_GRENADE" || smeansofdeath == "MOD_GRENADE_SPLASH" && eattacker == self) + { + return 0; + } + } + if(idamage > self.health && !self.dying_wish_on_cooldown && self hascustomperk("Dying_Wish") ) + { + self notify("dying_wish_charge"); + self thread dying_wish_effect(); + return 0; + } + else + { + return idamage; + } +} + +dying_wish_checker() +{ + level endon("end_game"); + self endon("disconnect"); + self endon( "stopcustomperk" ); + self.dying_wish_uses = 0; + for(;;) + { + self.dying_wish_on_cooldown = 0; + self.perk10back.alpha = 1; + self.perk10front.alpha = 1; + self waittill("dying_wish_charge"); + self.perk10back.alpha = 0.3; + self.perk10front.alpha = 0.4; + self.dying_wish_uses++; + self.dying_wish_on_cooldown = 1; + delay = 300 + (self.dying_wish_uses * 30); + if(delay >= 600) + delay = 600; + wait delay; + } +} + +dying_wish_effect() +{ + self enableInvulnerability(); + self.ignoreme = 1; + self useServerVisionSet(true); + self setvisionsetforplayer( "zombie_death", 0 ); + self freezeControls(1); + wait 1; + self freezeControls(0); + wait 8; + self.health = 1; + self disableInvulnerability(); + self.ignoreme = 0; + self useServerVisionSet(false); + self setvisionsetforplayer("remote_mortar_enhanced", 0); +} + + +player_burning_audio() +{ + fire_ent = spawn( "script_model", self.origin ); + wait_network_frame(); + fire_ent linkto( self ); + fire_ent playloopsound( "evt_plr_fire_loop" ); + self waittill_any( "stop_flame_damage", "stop_flame_sounds", "death", "disconnect" ); + fire_ent delete(); +} diff --git a/t6/uncompiled mods/customperks.gsc b/t6/uncompiled mods/customperks.gsc new file mode 100644 index 0000000..ed36707 --- /dev/null +++ b/t6/uncompiled mods/customperks.gsc @@ -0,0 +1,1067 @@ +//PLUTO v1 - TOWN Survival with Dogs + +#include maps/mp/_utility; +#include common_scripts/utility; +#include maps/mp/gametypes_zm/_hud_util; +#include maps/mp/zombies/_zm_weapons; +#include maps/mp/zombies/_zm_stats; +#include maps/mp/gametypes_zm/_spawnlogic; +#include maps/mp/animscripts/traverse/shared; +#include maps/mp/animscripts/utility; +#include maps/mp/zombies/_load; +#include maps/mp/_createfx; +#include maps/mp/_music; +#include maps/mp/_busing; +#include maps/mp/_script_gen; +#include maps/mp/gametypes_zm/_globallogic_audio; +#include maps/mp/gametypes_zm/_tweakables; +#include maps/mp/_challenges; +#include maps/mp/gametypes_zm/_weapons; +#include maps/mp/_demo; +#include maps/mp/gametypes_zm/_hud_message; +#include maps/mp/gametypes_zm/_spawning; +#include maps/mp/gametypes_zm/_globallogic_utils; +#include maps/mp/gametypes_zm/_spectating; +#include maps/mp/gametypes_zm/_globallogic_spawn; +#include maps/mp/gametypes_zm/_globallogic_ui; +#include maps/mp/gametypes_zm/_hostmigration; +#include maps/mp/gametypes_zm/_globallogic_score; +#include maps/mp/gametypes_zm/_globallogic; +#include maps/mp/zombies/_zm; +#include maps/mp/zombies/_zm_ai_faller; +#include maps/mp/zombies/_zm_spawner; +#include maps/mp/zombies/_zm_pers_upgrades_functions; +#include maps/mp/zombies/_zm_pers_upgrades; +#include maps/mp/zombies/_zm_score; +#include maps/mp/animscripts/zm_run; +#include maps/mp/animscripts/zm_death; +#include maps/mp/zombies/_zm_blockers; +#include maps/mp/animscripts/zm_shared; +#include maps/mp/animscripts/zm_utility; +#include maps/mp/zombies/_zm_ai_basic; +#include maps/mp/zombies/_zm_laststand; +#include maps/mp/zombies/_zm_net; +#include maps/mp/zombies/_zm_audio; +#include maps/mp/gametypes_zm/_zm_gametype; +#include maps/mp/_visionset_mgr; +#include maps/mp/zombies/_zm_equipment; +#include maps/mp/zombies/_zm_power; +#include maps/mp/zombies/_zm_server_throttle; +#include maps/mp/gametypes/_hud_util; +#include maps/mp/zombies/_zm_unitrigger; +#include maps/mp/zombies/_zm_zonemgr; +#include maps/mp/zombies/_zm_perks; +#include maps/mp/zombies/_zm_melee_weapon; +#include maps/mp/zombies/_zm_audio_announcer; +#include maps/mp/zombies/_zm_magicbox; +#include maps/mp/zombies/_zm_utility; +#include maps/mp/zombies/_zm_ai_dogs; +#include maps/mp/gametypes_zm/_hud_message; +#include maps/mp/zombies/_zm_game_module; +#include maps/mp/zombies/_zm_buildables; +#include codescripts/character; +#include maps/mp/zombies/_zm_weap_riotshield; +init() +{ + // if( (getdvar( "mapname" ) == "zm_transit" || getdvar( "mapname" ) == "zm_highrise") && getdvar ( "g_gametype") == "zstandard" ) + // { + precacheshader("menu_mp_lobby_icon_film"); + precacheshader( "menu_mp_lobby_icon_customgamemode" ); + precacheshader( "waypoint_revive" ); + precacheshader( "killiconheadshot" ); + precacheshader( "menu_lobby_icon_twitter" ); + precacheshader( "hud_grenadeicon" ); + precacheshader( "menu_mp_weapons_1911" ); + precacheshader( "menu_mp_lobby_icon_screenshot" ); + precacheshader( "damage_feedback" ); + precacheshader( "zombies_rank_1" ); + precacheshader( "zombies_rank_3" ); + precacheshader( "zombies_rank_2" ); + precacheshader( "zombies_rank_4" ); + precacheshader( "menu_mp_weapons_xm8" ); + precacheshader( "faction_cdc" ); + precacheshader( "menu_mp_weapons_hamr" ); + precacheshader( "zombies_rank_5" ); + precacheshader( "hud_icon_sticky_grenade" ); + precacheshader( "specialty_instakill_zombies" ); + precacheshader( "menu_mp_weapons_1911" ); + precacheshader( "hud_icon_colt" ); + precachemodel("p6_zm_buildable_sq_meteor"); + precachemodel( "collision_player_wall_512x512x10" ); + precachemodel( "collision_physics_512x512x10" ); + precachemodel( "t5_foliage_tree_burnt03" ); + precachemodel( "p_rus_door_roller" ); + precachemodel( "ch_tombstone1" ); + precachemodel( "collision_geo_256x256x10_standard" ); + precachemodel( "zombie_vending_tombstone_on" ); + precachemodel( "zombie_vending_revive_on" ); + precachemodel( "zombie_vending_sleight_on" ); + precachemodel( "zombie_vending_doubletap2_on" ); + precachemodel( "zombie_pickup_perk_bottle" ); + precachemodel( "zm_collision_perks1" ); + precachemodel( "p6_zm_screecher_hole" ); + precachemodel( "p_cub_door01_wood_fullsize" ); + precachemodel( "veh_t6_civ_microbus_dead" ); + precachemodel( "p_rus_door_white_window_plain_left" ); + if (level.script != "zm_prison") + { + level._effect["fx_zombie_cola_revive_on"] = loadfx( "misc/fx_zombie_cola_revive_on" ); + level._effect["fx_zombie_cola_dtap_on"] = loadfx( "misc/fx_zombie_cola_dtap_on" ); + } + + level._effect["fx_zombie_cola_on"] = loadfx( "misc/fx_zombie_cola_on" ); + if (!(level.script == "zm_tomb" || level.script == "zm_prison")) + { + level._effect["fx_zmb_wall_buy_taseknuck"] = loadfx( "maps/zombie/fx_zmb_wall_buy_taseknuck" ); + level._effect["fx_zmb_wall_buy_bowie"] = loadfx( "maps/zombie/fx_zmb_wall_buy_bowie" ); + } + // level._effect["fx_default_explosion"] = loadfx( "explosions/fx_default_explosion" ); + + + if( level.script == "zm_buried" || level.script == "zm_tomb" ) + { + level._effect["fx_default_explosion"] = level._effect[ "divetonuke_groundhit"]; + } + else + { + level._effect["fx_default_explosion"] = loadfx( "explosions/fx_default_explosion" ); + } + + + level.town = 1; + level.diner = 0; + + level thread onPlayerConnect(); + + level thread perk_machine_removal( "specialty_scavenger" ); + init_custom_map(); + + if(level.script != "zm_buried" && level.script != "zm_highrise" && level.script != "zm_tomb" && level.script != "zm_prison") + level.get_player_weapon_limit = ::custom_get_player_weapon_limit; + level.zombie_last_stand = ::LastStand; + level.custom_vending_precaching = ::default_vending_precaching; + + register_player_damage_callback( ::damage_callback ); + + + + + level.player_out_of_playable_area_monitor = 0; + level.perk_purchase_limit = 50; + if( getdvar( "mapname" ) == "zm_transit" && getdvar ( "g_gametype" ) == "zstandard" ) + { + foreach( weapon in level.zombie_weapons) + { + weapon.is_in_box = 1; + } + } +// } +} + + + +onPlayerConnect() +{ + while( 1 ) + { + level waittill( "connected", player ); + player thread onPlayerSpawned(); + } +} + +onPlayerSpawned() +{ + self endon( "disconnect" ); + level endon( "game_ended" ); + self waittill( "spawned_player" ); + + self.perkarray = []; + self.dying_wish_on_cooldown = 0; + self.perk_reminder = 0; + self.perk_count = 0; + self.num_perks = 0; + self thread removeperkshader(); + self thread perkboughtcheck(); + self thread damagehitmarker(); + for(;;) + { + self waittill( "spawned_player" ); + if(self.score < 1500) + { + self.score = 1500; + } + } +} + + + +damagehitmarker() +{ + self thread startwaiting(); + self.hitmarker = newdamageindicatorhudelem( self ); + self.hitmarker.horzalign = "center"; + self.hitmarker.vertalign = "middle"; + self.hitmarker.x = -12; + self.hitmarker.y = -12; + self.hitmarker.alpha = 0; + self.hitmarker setshader( "damage_feedback", 24, 48 ); +} + +startwaiting() +{ + while( 1 ) + { + foreach( zombie in getaiarray( level.zombie_team ) ) + { + if( !(IsDefined( zombie.waitingfordamage )) ) + { + zombie thread hitmark(); + } + } + wait 0.25; + } +} + +hitmark() +{ + self endon( "killed" ); + self.waitingfordamage = 1; + while( 1 ) + { + self waittill( "damage", amount, attacker, dir, point, mod ); + attacker.hitmarker.alpha = 0; + if( isplayer( attacker ) ) + { + if( isalive( self ) ) + { + attacker.hitmarker.color = ( 1, 1, 1 ); + attacker.hitmarker.alpha = 1; + attacker.hitmarker fadeovertime( 1 ); + attacker.hitmarker.alpha = 0; + } + else + { + attacker.hitmarker.color = ( 1, 0, 0 ); + attacker.hitmarker.alpha = 1; + attacker.hitmarker fadeovertime( 1 ); + attacker.hitmarker.alpha = 0; + self notify( "killed" ); + } + } + } +} + + +init_custom_map() +{ + if( getdvar( "mapname" ) == "zm_transit" && getdvar ( "g_gametype" ) == "zstandard" ) + { + perk_system( "script_model", ( 1856, -810.722, -55.875), "zombie_vending_tombstone_on", ( 0, 180, 0 ), "custom", "mus_perks_deadshot_sting", "Deadshot", 2000, "tombstone_light", "deadshot" ); + perk_system( "script_model", ( 2460, -780, -55.875 ), "zombie_vending_tombstone_on", ( 0, 225, 0 ), "custom", "mus_perks_doubletap_sting", "Burn Heart", 2500, "jugger_light", "Burn_Heart" ); + perk_system( "script_model", ( 901.86, -1575.574, -47.875 ), "zombie_vending_tombstone_on", ( 0, 180, 0 ), "custom", "mus_perks_deadshot_sting", "Widow's Wine", 4000, "tombstone_light", "WIDOWS_WINE" ); + perk_system( "script_model", ( 450, -300.574, -61.875 ), "zombie_vending_tombstone_on", ( 0, 45, 0 ), "custom", "mus_perks_packa_sting", "Electric Cherry", 2000, "tombstone_light", "ELECTRIC_CHERRY" ); // 613,-250,z 0,0,0 + perk_system( "script_model", ( 1069, -1133, 120.125 ), "zombie_vending_tombstone_on", ( 0, 180, 0 ), "custom", "mus_perks_doubletap_sting", "Ethereal Razor", 3500, "tombstone_light", "Ethereal_Razor" ); + perk_system( "script_model", ( 1823.86, 670.574, -55.875 ), "zombie_vending_tombstone_on", ( 0, 45, 0 ), "custom", "mus_perks_doubletap_sting", "Mule Kick", 4000, "tombstone_light", "MULE" ); + perk_system( "script_model", ( 840, 603.809, -40.875 ), "zombie_vending_tombstone_on", ( 0, 0, 0 ), "custom", "mus_perks_packa_sting", "PhD Flopper", 2500, "tombstone_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( 2358, -87, -55.875 ), "zombie_vending_tombstone_on", ( 0, -90, 0 ), "custom", "mus_perks_doubletap_sting", "Downer's Delight", 2000, "tombstone_light", "Downers_Delight" ); + perk_system( "script_model", ( 2015, 858, -56.875 ), "zombie_vending_tombstone_on", ( 0, -90, 0 ), "custom", "mus_perks_doubletap_sting", "Dying Wish", 6000, "tombstone_light", "Dying_Wish" ); + perk_system( "script_model", ( 559, -1364, 120.125 ), "zombie_vending_tombstone_on", ( 0, 180, 0 ), "custom", "mus_perks_doubletap_sting", "Ammo Regen", 3000, "tombstone_light", "Ammo_Regen" ); + } + if( level.script == "zm_highrise") + { + perk_system( "script_model", ( 1884.42, 491.946, 1298.72), "zombie_vending_jugg_on", ( 0, 418.728, 0 ), "custom", "mus_perks_deadshot_sting", "Deadshot", 2000, "tombstone_light", "deadshot" ); +// perk_system( "script_model", ( 2764.64, 1868.03, 1391.01 ), "zombie_vending_jugg_on", ( 0, 384.236, 0 ), "custom", "mus_perks_doubletap_sting", "Burn Heart", 2500, "jugger_light", "Burn_Heart" ); + perk_system( "script_model", ( 1978.25, 597.657, 2704.13 ), "zombie_vending_jugg_on", ( 0, 329.291, 0 ), "custom", "mus_perks_deadshot_sting", "Widow's Wine", 4000, "tombstone_light", "WIDOWS_WINE" ); + perk_system( "script_model", ( 1415.64, 2108.36, 3220.26 ), "zombie_vending_jugg_on", ( 0, 406.661, 0 ), "custom", "mus_perks_packa_sting", "Electric Cherry", 2000, "tombstone_light", "ELECTRIC_CHERRY" ); // 613,-250,z 0,0,0 + perk_system( "script_model", ( 1901.97, 1431.36, 3216.13 ), "zombie_vending_jugg_on", ( 0, 404.762, 0 ), "custom", "mus_perks_doubletap_sting", "Ethereal Razor", 3500, "tombstone_light", "Ethereal_Razor" ); +// perk_system( "script_model", ( 1891.64, 1119.64, 3048.36 ), "zombie_vending_jugg_on", ( 0, 45, 0 ), "custom", "mus_perks_doubletap_sting", "Mule Kick", 4000, "tombstone_light", "MULE" ); + perk_system( "script_model", ( 1429.29, -453.397, 2880.13 ), "zombie_vending_jugg_on", ( 0, 149.1426, 0 ), "custom", "mus_perks_packa_sting", "PhD Flopper", 2500, "tombstone_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( 1109.64, 2701.36, 3043.82 ), "zombie_vending_jugg_on", ( 0, 394.926, 0 ), "custom", "mus_perks_doubletap_sting", "Downer's Delight", 2000, "tombstone_light", "Downers_Delight" ); + perk_system( "script_model", ( 1706.28, 1055.64, 3395.1 ), "zombie_vending_jugg_on", ( 0, 180, 0 ), "custom", "mus_perks_doubletap_sting", "Dying Wish", 6000, "tombstone_light", "Dying_Wish" ); + perk_system( "script_model", ( 2269.17, 182.377, 2880.13 ), "zombie_vending_jugg_on", ( 0, 418.596, 0 ), "custom", "mus_perks_doubletap_sting", "Ammo Regen", 3000, "tombstone_light", "Ammo_Regen" ); + } + if( level.script == "zm_buried") + { + perk_system( "script_model", ( 1618.14, 1513.46, 200.62), "zombie_vending_jugg_on", ( 0, 250.147, 0 ), "custom", "mus_perks_deadshot_sting", "Deadshot", 2000, "sleight_light", "deadshot" ); +// perk_system( "script_model", ( -1176.36, 508.26, 144.125 ), "zombie_vending_jugg_on", ( 0, 448.269, 0 ), "custom", "mus_perks_doubletap_sting", "Burn Heart", 2500, "sleight_light", "Burn_Heart" ); + perk_system( "script_model", ( -1176.36, 510.625, 144.125 ), "zombie_vending_jugg_on", ( 0, 449.412, 0 ), "custom", "mus_perks_deadshot_sting", "Widow's Wine", 4000, "sleight_light", "WIDOWS_WINE" ); + perk_system( "script_model", ( -448.859, 131.435, 143.491 ), "zombie_vending_jugg_on", ( 0, 180.3, 0 ), "custom", "mus_perks_packa_sting", "Electric Cherry", 2000, "sleight_light", "ELECTRIC_CHERRY" ); // 613,-250,z 0,0,0 + perk_system( "script_model", ( 890.359, -840.206, -22.8006 ), "zombie_vending_jugg_on", ( 0, 270.367, 0 ), "custom", "mus_perks_doubletap_sting", "Ethereal Razor", 3500, "sleight_light", "Ethereal_Razor" ); +// perk_system( "script_model", ( 1891.64, 1119.64, 3048.36 ), "zombie_vending_jugg_on", ( 0, 45, 0 ), "custom", "mus_perks_doubletap_sting", "Mule Kick", 4000, "sleight_light", "MULE" ); + perk_system( "script_model", ( 572.507, -712.359, 149.95 ), "zombie_vending_jugg_on", ( 0, 178.4505, 0 ), "custom", "mus_perks_packa_sting", "PhD Flopper", 2500, "sleight_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( 488.324, 727.641, 176.125 ), "zombie_vending_jugg_on", ( 0, 178.9998, 0 ), "custom", "mus_perks_doubletap_sting", "Downer's Delight", 2000, "sleight_light", "Downers_Delight" ); + perk_system( "script_model", ( -1298.32, -837.178, -23.875 ), "zombie_vending_jugg_on", ( 0, 91.37286, 0 ), "custom", "mus_perks_doubletap_sting", "Dying Wish", 6000, "sleight_light", "Dying_Wish" ); + perk_system( "script_model", ( -122.161, -1469.21, 168.125 ), "zombie_vending_jugg_on", ( 0, 448.841, 0 ), "custom", "mus_perks_doubletap_sting", "Ammo Regen", 3000, "sleight_light", "Ammo_Regen" ); + } + if( level.script == "zm_nuked") + { + perk_system( "script_model", ( 28.8155, -356.18, -65.8346 ), "zombie_vending_jugg_on", ( 0, 129.8755, 0 ), "custom", "mus_perks_deadshot_sting", "Deadshot", 2000, "sleight_light", "deadshot" ); +// perk_system( "script_model", ( ), "zombie_vending_jugg_on", ( ), "custom", "mus_perks_doubletap_sting", "Burn Heart", 2500, "sleight_light", "Burn_Heart" ); + perk_system( "script_model", ( -954.194, 714.594, 84.0385 ), "zombie_vending_jugg_on", ( 0, 429.46, 0 ), "custom", "mus_perks_deadshot_sting", "Widow's Wine", 4000, "sleight_light", "WIDOWS_WINE" ); + perk_system( "script_model", ( 683.524, 618.635, -56.875 ), "zombie_vending_jugg_on", ( 0, 102.5635, 0 ), "custom", "mus_perks_packa_sting", "Electric Cherry", 2000, "sleight_light", "ELECTRIC_CHERRY" ); // 613,-250,z 0,0,0 + perk_system( "script_model", ( 1420.35, -21.4313, -63.8849 ), "zombie_vending_jugg_on", ( 0, 194.085, 0 ), "custom", "mus_perks_doubletap_sting", "Ethereal Razor", 3500, "sleight_light", "Ethereal_Razor" ); + perk_system( "script_model", ( 618.292, -188.322, -56.3686 ), "zombie_vending_jugg_on", ( 0, 105.5011, 0 ), "custom", "mus_perks_doubletap_sting", "Mule Kick", 4000, "sleight_light", "MULE" ); + perk_system( "script_model", ( 1152.5, 160.6, 79.125 ), "zombie_vending_jugg_on", ( 0, 347.541, 0 ), "custom", "mus_perks_packa_sting", "PhD Flopper", 2500, "sleight_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( 156.738, 513.899, -62.3141 ), "zombie_vending_jugg_on", ( 0, 101.8164, 0 ), "custom", "mus_perks_doubletap_sting", "Downer's Delight", 2000, "sleight_light", "Downers_Delight" ); + perk_system( "script_model", ( -646.863, 271.522, -55.875 ), "zombie_vending_jugg_on", ( 0, 160.8405, 0 ), "custom", "mus_perks_doubletap_sting", "Dying Wish", 6000, "sleight_light", "Dying_Wish" ); + perk_system( "script_model", ( -1582.46, 112.604, -63.2092 ), "zombie_vending_jugg_on", ( 0, 250.829, 0 ), "custom", "mus_perks_doubletap_sting", "Ammo Regen", 3000, "sleight_light", "Ammo_Regen" ); + } + if( level.script == "zm_tomb") + { + perk_system( "script_model", ( 184.995, -2422.49, 50.125), "zombie_vending_jugg_on", ( 0, 369.091, 0 ), "custom", "mus_perks_deadshot_sting", "Deadshot", 2000, "sleight_light", "deadshot" ); + perk_system( "script_model", ( 160.359, 3781.17, -351.875 ), "zombie_vending_jugg_on", ( 0, 266.122, 0 ), "custom", "mus_perks_deadshot_sting", "Widow's Wine", 4000, "sleight_light", "WIDOWS_WINE" ); + perk_system( "script_model", ( 375.771, 2119.22, -122.951 ), "zombie_vending_jugg_on", ( 0, 179.5935, 0 ), "custom", "mus_perks_doubletap_sting", "Ethereal Razor", 3500, "sleight_light", "Ethereal_Razor" ); + perk_system( "script_model", ( -335.604, -187.006, 325.273 ), "zombie_vending_jugg_on", ( 0, 132.9565, 0 ), "custom", "mus_perks_packa_sting", "PhD Flopper", 2500, "sleight_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( 924.47, 360.72, 131.005 ), "zombie_vending_jugg_on", ( 0, 373.266, 0 ), "custom", "mus_perks_doubletap_sting", "Downer's Delight", 2000, "sleight_light", "Downers_Delight" ); + perk_system( "script_model", ( 1345.09, -3822.62, 302.125 ), "zombie_vending_jugg_on", ( 0, 270.593, 0 ), "custom", "mus_perks_doubletap_sting", "Dying Wish", 6000, "sleight_light", "Dying_Wish" ); + perk_system( "script_model", ( 2972.36, 5218.91, -378.566 ), "zombie_vending_jugg_on", ( 0, 270.379, 0 ), "custom", "mus_perks_doubletap_sting", "Ammo Regen", 3000, "sleight_light", "Ammo_Regen" ); + } + if( level.script == "zm_prison") + { + perk_system( "script_model", ( -1344.65, 5598.31, -71.875 ), "p6_zm_al_vending_jugg_on", ( 0, 98.34412, 0 ), "custom", "mus_perks_deadshot_sting", "Deadshot", 2000, "sleight_light", "deadshot" ); + perk_system( "script_model", ( 3763.64, 9669.99, 1704.13 ), "p6_zm_al_vending_jugg_on", ( 0, 90, 0 ), "custom", "mus_perks_deadshot_sting", "Widow's Wine", 4000, "sleight_light", "WIDOWS_WINE" ); + perk_system( "script_model", ( 2160.71, 9247.64, 1558.13 ), "p6_zm_al_vending_jugg_on", ( 0, 179.1815, 0 ), "custom", "mus_perks_doubletap_sting", "Ethereal Razor", 3500, "sleight_light", "Ethereal_Razor" ); + perk_system( "script_model", ( 597.633, 8546.86, 832.125 ), "p6_zm_al_vending_jugg_on", ( 0, 221.984, 0 ), "custom", "mus_perks_doubletap_sting", "Mule Kick", 4000, "sleight_light", "MULE" ); + perk_system( "script_model", ( 456.359, 8679.51, 1128.13 ), "p6_zm_al_vending_jugg_on", ( 0, 269.533, 0 ), "custom", "mus_perks_packa_sting", "PhD Flopper", 2500, "sleight_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( -685.943, 9199.64, 1336.13 ), "p6_zm_al_vending_jugg_on", ( 0, 178.5443, 0 ), "custom", "mus_perks_doubletap_sting", "Downer's Delight", 2000, "sleight_light", "Downers_Delight" ); + perk_system( "script_model", ( 1728.56, 10688.4, 1336.13 ), "p6_zm_al_vending_jugg_on", ( 0, 357.896, 0 ), "custom", "mus_perks_doubletap_sting", "Dying Wish", 6000, "sleight_light", "Dying_Wish" ); + perk_system( "script_model", ( 1367.28, 10096.4, 1128.13 ), "p6_zm_al_vending_jugg_on", ( 0, 358.687, 0 ), "custom", "mus_perks_doubletap_sting", "Ammo Regen", 3000, "sleight_light", "Ammo_Regen" ); + } +} + +play_fx( fx ) +{ + playfxontag( level._effect[ fx ], self, "tag_origin" ); +} + +defaulth_vending_precaching() +{ + level._effect[ "sleight_light" ] = loadfx( "misc/fx_zombie_cola_on" ); + level._effect[ "tombstone_light" ] = loadfx( "misc/fx_zombie_cola_on" ); + level._effect[ "revive_light" ] = loadfx( "misc/fx_zombie_cola_revive_on" ); + level._effect[ "marathon_light" ] = loadfx( "maps/zombie/fx_zmb_cola_staminup_on" ); + level._effect[ "jugger_light" ] = loadfx( "misc/fx_zombie_cola_jugg_on" ); + level._effect[ "doubletap_light" ] = loadfx( "misc/fx_zombie_cola_dtap_on" ); + level._effect[ "deadshot_light" ] = loadfx( "misc/fx_zombie_cola_dtap_on" ); + level._effect[ "additionalprimaryweapon_light" ] = loadfx( "misc/fx_zombie_cola_arsenal_on" ); + level._effect[ "packapunch_fx" ] = loadfx( "maps/zombie/fx_zombie_packapunch" ); + level._effect[ "wall_taseknuck" ] = loadfx( "maps/zombie/fx_zmb_wall_buy_taseknuck" ); +} + + +playchalkfx(effect, origin, angles) +{ + fx = SpawnFX(level._effect[ effect ], origin,AnglesToForward(angles),AnglesToUp(angles)); + TriggerFX(fx); + level waittill("connected", player); + fx Delete(); +} + + + +perk_system( script, pos, model, angles, type, sound, name, cost, fx, perk) +{ + col = spawn( script, pos); + col setmodel( model ); + col.angles = angles; + x = spawn( script, pos ); + x setmodel( "zm_collision_perks1" ); + x.angles = angles; + col thread buy_system( perk, sound, name, cost, type ); + col thread play_fx( fx ); +} + +buy_system( perk, sound, name, cost, type ) +{ + self endon( "game_ended" ); + while( 1 ) + { + foreach( player in level.players ) + { + if(!player.machine_is_in_use) + { + if( distance( self.origin, player.origin ) <= 70 ) + { + player thread SpawnHint( self.origin, 30, 30, "HINT_ACTIVATE", "Hold ^3&&1^7 for " + name + " [Cost: " + cost + "]" ); + if(player usebuttonpressed() && !player hasperk(perk) && !player hascustomperk(perk) && player.score >= cost && !player maps/mp/zombies/_zm_laststand::player_is_in_laststand()) + { + player.machine_is_in_use = 1; + player playsound( "zmb_cha_ching" ); + player.score -= cost; + player playsound( sound ); + player thread drawshader_and_shadermove( perk, 1, 1, type ); + wait 4; + player.machine_is_in_use = 0; + } + else + { + if( player usebuttonpressed() && player.score < cost ) + { + player maps/mp/zombies/_zm_audio::create_and_play_dialog( "general", "perk_deny", undefined, 0 ); + } + } + } + } + } + wait 0.1; + } +} + +hascustomperk(perk) +{ + for(i = 0; i < self.perkarray.size; i++) + { + if(self.perkarray[i].name == perk) + { + return 1; + } + } + return 0; +} + +removeperkshader() +{ + for(;;) + { + self waittill_any_return( "fake_death", "player_downed", "player_revived", "spawned_player", "disconnect", "death" ); + self.num_perks = 0; + self.perk_reminder = 0; + self.perk_count = 0; + self.dying_wish_on_cooldown = 0; + self removeallcustomshader(); + self.perkarray = []; + self notify( "stopcustomperk" ); + self.bleedout_time = 30; + self.ignore_lava_damage = 0; + self setclientfieldtoplayer( "deadshot_perk", 0 ); + } +} + +removeallcustomshader() +{ + for(i = 0; i < self.perkarray.size; i++) + { + self.perkarray[i] destroy(); + } +} + +drawshader( shader, x, y, width, height, color, alpha, sort ) +{ + hud = newclienthudelem( self ); + hud.elemtype = "icon"; + hud.color = color; + hud.alpha = alpha; + hud.sort = sort; + hud.children = []; + hud.hidewheninmenu = 1; + hud setparent( level.uiparent ); + hud setshader( shader, width, height ); + hud.x = x; + hud.y = y; + return hud; +} + +perkboughtcheck() +{ + self endon("death"); + self endon("disconnect"); + for(;;) + { + self.perk_reminder = self.num_perks; + self waittill("perk_acquired"); + n = 1; + if(!(self.num_perks > self.perk_reminder)) + { + n = (self.num_perks - self.perk_reminder); + self.num_perks = (self.perk_reminder + n); + } + self.perk_reminder = self.num_perks; + self.perk_count += n; + self drawshader_and_shadermove("none", 0, 0, "normal"); //modified to remove perk alignement since 2 perk lines Added "normal" for type check + } +} + +drawshader_and_shadermove(perk, custom, print, type) +{ + if(custom) + { + self allowProne(false); + self allowSprint(false); + self disableoffhandweapons(); + self disableweaponcycling(); + weapona = self getcurrentweapon(); + weaponb = "zombie_perk_bottle_jugg"; + self giveweapon( weaponb ); + self switchtoweapon( weaponb ); + self waittill( "weapon_change_complete" ); + self enableoffhandweapons(); + self enableweaponcycling(); + self takeweapon( weaponb ); + self switchtoweapon( weapona ); + self maps/mp/zombies/_zm_audio::playerexert( "burp" ); + self setblur( 4, 0.1 ); + wait 0.1; + self setblur( 0, 0.1 ); + self allowProne(true); + self allowSprint(true); + } + + yPerk = 325; + if (level.script == "zm_buried") + { + yPerk = 300; + } + + x = -408; + for(i = 0; i < self.perkarray.size; i++) + { + if (type == "custom") + { + x += 15; + } + } + /*if (perk == "custom") + { + for(i = 0; i < self.perkarray.size; i++) + { + self.perkarray[i].x = self.perkarray[i].x + 30; + } + }*/ + if(perk == "Downers_Delight") + { + self.perk1back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk1front = self drawshader( "waypoint_revive", x, yPerk, 23, 23, ( 0, 1, 1 ), 100, 0 ); + self.perk1front.name = perk; + self.perkarray[self.perkarray.size] = self.perk1front; + self.perk1back.name = perk; + self.perkarray[self.perkarray.size] = self.perk1back; + self.num_perks++; + self thread DDown(); + if(print) + { + self iprintln("^9Downer's Delight"); + wait 0.2; + self iprintln("This Perk will increase players bleedout time by 10 seconds and current weapons is used in laststand."); + } + } + if(perk == "MULE") + { + self.perk2back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk2front = self drawshader( "menu_mp_weapons_1911", x, yPerk, 22, 22, ( 0, 1, 0 ), 100, 0 ); + self.perk2front.name = perk; + self.perkarray[self.perkarray.size] = self.perk2front; + self.perk2back.name = perk; + self.perkarray[self.perkarray.size] = self.perk2back; + self.num_perks++; + if(print) + { + self iprintln("^9Mule Kick"); + wait 0.2; + self iprintln("This Perk enables additional primary weapon slot for player. "); + } + } + if(perk == "PHD_FLOPPER") + { + self.perk3back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk3front = self drawshader( "hud_icon_sticky_grenade", x, yPerk, 23, 23, (1, 0, 1 ), 100, 0 ); + self.perk3front.name = perk; + self.perkarray[self.perkarray.size] = self.perk3front; + self.perk3back.name = perk; + self.perkarray[self.perkarray.size] = self.perk3back; + self.num_perks++; + if(print) + { + self iprintln("^9PhD Flopper"); + wait 0.2; + self iprintln("This Perk removes explosion and fall damage also player creates explosion when dive to prone."); + } + } + if(perk == "Victorious_Tortoise") + { + self.perk4back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 200, 0 ), 100, 0 ); + self.perk4front = self drawshader( "zombies_rank_2", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk4front.name = perk; + self.perkarray[self.perkarray.size] = self.perk4front; + self.perk4back.name = perk; + self.perkarray[self.perkarray.size] = self.perk4back; + self.num_perks++; + self thread start_vt(); + if(print) + { + self iprintln("^9Victorious Tortoise"); + wait 0.2; + self iprintln("This Perk allows shield block damage from all directions when in use."); + } + } + if(perk == "ELECTRIC_CHERRY") + { + self.perk5back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 200 ), 100, 0 ); + self.perk5front = self drawshader( "zombies_rank_5", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk5front.name = perk; + self.perkarray[self.perkarray.size] = self.perk5front; + self.perk5back.name = perk; + self.perkarray[self.perkarray.size] = self.perk5back; + self.num_perks++; + self thread start_ec(); + if(print) + { + self iprintln("^9Electric Cherry"); + wait 0.2; + self iprintln("This Perk creates an electric shockwave around the player whenever they reload."); + } + } + if(perk == "WIDOWS_WINE") + { + self.perk6back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk6front = self drawshader( "zombies_rank_3", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk6front.name = perk; + self.perkarray[self.perkarray.size] = self.perk6front; + self.perk6back.name = perk; + self.perkarray[self.perkarray.size] = self.perk6back; + self.num_perks++; + self takeweapon( self get_player_lethal_grenade() ); + self set_player_lethal_grenade( "sticky_grenade_zm" ); + self giveweapon("sticky_grenade_zm"); + self thread ww_nades(); + if(print) + { + self iprintln("^9Widow's Wine"); + wait 0.2; + self iprintln("This Perk damages zombies around the player when player is hit and grenades are upgraded."); + } + } + if(perk == "Ethereal_Razor") + { + self.perk7back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 200, 0, 0 ), 100, 0 ); + self.perk7front = self drawshader( "zombies_rank_4", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk7front.name = perk; + self.perkarray[self.perkarray.size] = self.perk7front; + self.perk7back.name = perk; + self.perkarray[self.perkarray.size] = self.perk7back; + self.num_perks++; + if(print) + { + self iprintln("^9Ethereal Razor"); + wait 0.2; + self iprintln("This Perk deals extra damage when player using melee attacks and restores a small amount of health."); + } + } + if(perk == "Ammo_Regen") + { + self.perk8back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk8front = self drawshader( "menu_mp_lobby_icon_customgamemode", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk8front.name = perk; + self.perkarray[self.perkarray.size] = self.perk8front; + self.perk8back.name = perk; + self.perkarray[self.perkarray.size] = self.perk8back; + self.num_perks++; + self thread ammoregen(); + self thread grenadesregen(); + if(print) + { + self iprintln("^9Ammo Regen"); + wait 0.2; + self iprintln("This Perk will slowly regenerades players ammonation and grenades."); + } + } + if(perk == "Burn_Heart") + { + self.perk9back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 200, 0, 0 ), 100, 0 ); + self.perk9front = self drawshader( "faction_cdc", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk9front.name = perk; + self.perkarray[self.perkarray.size] = self.perk9front; + self.perk9back.name = perk; + self.perkarray[self.perkarray.size] = self.perk9back; + self.num_perks++; + self.ignore_lava_damage = 1; + if(print) + { + self iprintln("^9Burn Heart"); + wait 0.2; + self iprintln("This Perk removes lava damage."); + } + } + if(perk == "Dying_Wish") + { + self.perk10back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 200, 0, 0 ), 100, 0 ); + self.perk10front = self drawshader( "zombies_rank_5", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk10front.name = perk; + self.perkarray[self.perkarray.size] = self.perk10front; + self.perk10back.name = perk; + self.perkarray[self.perkarray.size] = self.perk10back; + self.num_perks++; + self thread dying_wish_checker(); + if(print) + { + self iprintln("^9Dying Wish"); + wait 0.2; + self iprintln("This Perk allow player to go berserker mode for 9 seconds instead of laststand."); + wait 0.1; + self iprintln(" (cooldown 5mins and it's increased 30sec every time perk is used. - max 10mins) "); + } + } + if(perk == "deadshot") + { + self.perk11back = self drawshader( "specialty_marathon_zombies", x, yPerk, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk11front = self drawshader( "killiconheadshot", x, yPerk, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk11front.name = perk; + self.perkarray[self.perkarray.size] = self.perk11front; + self.perk11back.name = perk; + self.perkarray[self.perkarray.size] = self.perk11back; + self.num_perks++; + self setclientfieldtoplayer( "deadshot_perk", 1 ); + if(print) + { + self iprintln("^9Deadshot"); + wait 0.2; + self iprintln("This Perk aims automatically enemys head instead of body."); + } + } +} + +custom_get_player_weapon_limit( player ) +{ + weapon_limit = 2; + if ( player hascustomperk("MULE") ) + { + weapon_limit = 3; + } + else + { + weapons = self getWeaponsListPrimaries(); + if(weapons.size > 2) + { + self takeWeapon(weapons[2]); + } + } + return weapon_limit; +} + +ammoregen() +{ + self endon( "disconnect" ); + level endon( "end_game" ); + self endon( "stopcustomperk" ); + for(;;) + { + if(!self GetCurrentWeapon() == "" && !is_grenade_launcher( self GetCurrentWeapon()) ) + { + stockcount = self getweaponammostock( self GetCurrentWeapon() ); + self setWeaponAmmostock( self GetCurrentWeapon(), stockcount + 1 ); + wait 2; + } + wait 0.1; + } +} + +grenadesregen() +{ + self endon( "disconnect" ); + level endon( "end_game" ); + self endon( "stopcustomperk" ); + for(;;) + { + grenades = self get_player_lethal_grenade(); + grenade_count = self getweaponammoclip(grenades); + if(grenade_count < 4) + { + self setweaponammoclip(grenades, (grenade_count + 1)); + } + tactical_grenades = self get_player_tactical_grenade(); + tactical_grenade_count = self getweaponammoclip(tactical_grenades); + if(tactical_grenade_count < 3 ) + { + self setweaponammoclip(tactical_grenades, (tactical_grenade_count + 1)); + } + wait 300; + } +} + +start_ec() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("stopcustomperk"); + for(;;) + { + self waittill( "reload_start" ); + playfxontag( level._effect[ "poltergeist"], self, "J_SpineUpper" ); + self EnableInvulnerability(); + RadiusDamage(self.origin, 120, 200, 100, self); + self DisableInvulnerability(); + self playsound( "zmb_turbine_explo" ); + wait 1; + } +} + +start_vt() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("stopcustomperk"); + for(;;) + { + if(self getcurrentweapon() == "riotshield_zm" ) + { + self enableInvulnerability(); + self.shielddamagetaken += 100; + wait 0.9; + } + else + { + self disableInvulnerability(); + } + wait 0.1; + } +} + +start_er() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("stopcustomperk"); + for(;;) + { + if (self hascustomperk("Ethereal_Razor") && self ismeleeing()) + { + foreach(zombie in getAiArray(level.zombie_team)) + { + if( distance( self.origin, zombie.origin ) <= 100 ) + { + + } + } + self.health += 20; + if(self.health > self.maxhealth) + { + self.health = self.maxhealth; + } + while(self ismeleeing()) + { + wait 0.1; + } + } + wait 0.05; + } +} + +LastStand() +{ + if(self hascustomperk("Downers_Delight")) + { + self.customlaststandweapon = self getcurrentweapon(); + self switchtoweapon( self.customlaststandweapon ); + self setweaponammoclip( self.customlaststandweapon, 150 ); + self.bleedout_time = 40; + } + else + { + self maps/mp/zombies/_zm::last_stand_pistol_swap(); + } +} + +DDown() +{ + self endon( "disconnect" ); + level endon( "end_game" ); + self endon( "stopcustomperk" ); + for(;;) + { + self waittill("player_downed"); + self playsound( "zmb_phdflop_explo" ); + playfx(loadfx("explosions/fx_default_explosion"), self.origin, anglestoforward( ( 0, 45, 55 ) ) ); + RadiusDamage(self.origin, 150, 600, 400, self); + wait 0.1; + } +} + +doGivePerk(perk) +{ + self endon("disconnect"); + self endon("death"); + level endon("game_ended"); + self endon("perk_abort_drinking"); + if (!(self hasperk(perk) || (self maps/mp/zombies/_zm_perks::has_perk_paused(perk)))) + { + gun = self maps/mp/zombies/_zm_perks::perk_give_bottle_begin(perk); + evt = self waittill_any_return("fake_death", "death", "player_downed", "weapon_change_complete"); + if (evt == "weapon_change_complete") + self thread maps/mp/zombies/_zm_perks::wait_give_perk(perk, 1); + self maps/mp/zombies/_zm_perks::perk_give_bottle_end(gun, perk); + if (self maps/mp/zombies/_zm_laststand::player_is_in_laststand() || isDefined(self.intermission) && self.intermission) + return; + self notify("burp"); + } +} + + +SpawnHint( origin, width, height, cursorhint, string ) +{ + hint = spawn( "trigger_radius", origin, 1, width, height ); + hint setcursorhint( cursorhint, hint ); + hint sethintstring( string ); + hint setvisibletoall(); + wait 0.2; + hint delete(); +} + + +ww_points( player ) +{ + for(i = 0; i < 3; i++) + { + self maps/mp/zombies/_zm_utility::set_zombie_run_cycle("walk"); + player maps/mp/zombies/_zm_score::add_to_player_score( 10 ); + PlayFXOnTag(level.effect_WebFX,self,"j_spineupper"); + self doDamage(150, (0, 0, 0)); + wait 1; + } +} + +ww_nade_explosion() +{ + wait 2; + // if( self maps/mp/zm_transit_lava::object_touching_lava()) +// { + // self delete(); + // return 0; + // } + foreach(zombie in getAiArray(level.zombie_team)) + { + if( distance( zombie.origin, self.origin ) < 210 ) + { + zombie thread ww_points( self ); + } + } + self delete(); +} + +ww_nades() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("stopcustomperk"); + for(;;) + { + self waittill( "grenade_fire", grenade, weapname ); + if( weapname == "sticky_grenade_zm" ) + { + ww_nade = spawnsm( grenade.origin, "zombie_bomb" ); + ww_nade hide(); + ww_nade linkto( grenade ); + ww_nade thread ww_nade_explosion(); + } + } +} + +spawnsm( origin, model, angles ) +{ + ent = spawn( "script_model", origin ); + ent setmodel( model ); + if( IsDefined( angles ) ) + { + ent.angles = angles; + } + return ent; +} + + +damage_callback( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime, boneindex ) +{ + if( isDefined( eAttacker.is_zombie ) && eAttacker.is_zombie && self hascustomperk("WIDOWS_WINE") ) + { + zombies = getaiarray(level.zombie_team); + foreach(zombie in zombies) + { + if(distance(self.origin, zombie.origin) < 150) + { + grenades = self get_player_lethal_grenade(); + grenade_count = self getweaponammoclip(grenades); + if(grenade_count > 0) + { + self PlaySound("zmb_elec_jib_zombie"); + self setweaponammoclip(grenades, (grenade_count - 1)); + zombie thread ww_points( self ); + } + } + } + } + if(self hascustomperk("PHD_FLOPPER")) + { + if( smeansofdeath == "MOD_FALLING" ) + { + if(isDefined( self.divetoprone ) && self.divetoprone == 1 ) + { + radiusdamage( self.origin, 300, 5000, 1000, self, "MOD_GRENADE_SPLASH" ); + playfx(loadfx("explosions/fx_default_explosion"), self.origin, anglestoforward( ( 0, 45, 55 ) ) ); + self playsound( "zmb_phdflop_explo" ); + } + return 0; + } + if( smeansofdeath == "MOD_PROJECTILE" || smeansofdeath == "MOD_PROJECTILE_SPLASH" || smeansofdeath == "MOD_GRENADE" || smeansofdeath == "MOD_GRENADE_SPLASH" && eattacker == self) + { + return 0; + } + } + if(idamage > self.health && !self.dying_wish_on_cooldown && self hascustomperk("Dying_Wish") ) + { + self notify("dying_wish_charge"); + self thread dying_wish_effect(); + return 0; + } + else + { + return idamage; + } +} + +dying_wish_checker() +{ + level endon("end_game"); + self endon("disconnect"); + self endon( "stopcustomperk" ); + self.dying_wish_uses = 0; + for(;;) + { + self.dying_wish_on_cooldown = 0; + self.perk10back.alpha = 1; + self.perk10front.alpha = 1; + self waittill("dying_wish_charge"); + self.perk10back.alpha = 0.3; + self.perk10front.alpha = 0.4; + self.dying_wish_uses++; + self.dying_wish_on_cooldown = 1; + delay = 300 + (self.dying_wish_uses * 30); + if(delay >= 600) + delay = 600; + wait delay; + } +} + +dying_wish_effect() +{ + self enableInvulnerability(); + self.ignoreme = 1; + self useServerVisionSet(true); + self setvisionsetforplayer( "zombie_death", 0 ); + self freezeControls(1); + wait 1; + self freezeControls(0); + wait 8; + self.health = 1; + self disableInvulnerability(); + self.ignoreme = 0; + self useServerVisionSet(false); + self setvisionsetforplayer("remote_mortar_enhanced", 0); +} + + +player_burning_audio() +{ + fire_ent = spawn( "script_model", self.origin ); + wait_network_frame(); + fire_ent linkto( self ); + fire_ent playloopsound( "evt_plr_fire_loop" ); + self waittill_any( "stop_flame_damage", "stop_flame_sounds", "death", "disconnect" ); + fire_ent delete(); +} diff --git a/t6/uncompiled mods/dropweapon.gsc b/t6/uncompiled mods/dropweapon.gsc new file mode 100644 index 0000000..c391a55 --- /dev/null +++ b/t6/uncompiled mods/dropweapon.gsc @@ -0,0 +1,131 @@ +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\gametypes_zm\_weapon_utils; +#include maps\mp\gametypes_zm\_weaponobjects; +#include maps\mp\_sticky_grenade; +#include maps\mp\_bb; +#include maps\mp\gametypes_zm\_weapons; +#include maps\mp\_challenges; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\gametypes_zm\_globallogic_utils; +#include maps\mp\gametypes_zm\_shellshock; +#include maps\mp\gametypes_zm\_gameobjects; + +main() +{ + setDvar("drop", "0"); + replaceFunc(maps\mp\gametypes_zm\_weapons::dropweapontoground, ::dropweapon); +} + +init() +{ + level thread dropPlayerWeapon(); +} + +dropPlayerWeapon() +{ + level endon("game_ended"); + for(;;) + { + if (getDvar("drop") != "0") + { + drop = strTok(getDvar("drop"), ";"); + setDvar("drop", "0"); + getPlayerByGuid(drop[0]) dropweapon(getPlayerByGuid(drop[0]) GetCurrentWeapon()); + iPrintLn("^5" + getPlayerByGuid(drop[0]).name + "^7 dropped a ^5weapon^7 on the ground!"); + } + wait 0.1; + } +} +getPlayerByGuid(guid) { + for (i = 0; i < level.players.size; i++) { + if (isAlive(level.players[i]) && int(level.players[i] getGuid()) == int(guid)) { + return level.players[i]; + } + } + return false; +} + + +dropweapon(weapon) +{ + if ( !isdefined( weapon ) ) + { +/# + if ( getdvar( _hash_8F7FC88 ) == "1" ) + println( "didn't drop weapon: not defined" ); +#/ + return; + } + + if ( weapon == "none" ) + { +/# + if ( getdvar( _hash_8F7FC88 ) == "1" ) + println( "didn't drop weapon: weapon == none" ); +#/ + return; + } + + if ( !self hasweapon( weapon ) ) + { +/# + if ( getdvar( _hash_8F7FC88 ) == "1" ) + println( "didn't drop weapon: don't have it anymore (" + weapon + ")" ); +#/ + return; + } + + if ( !self anyammoforweaponmodes( weapon ) ) + { +/# + if ( getdvar( _hash_8F7FC88 ) == "1" ) + println( "didn't drop weapon: no ammo for weapon modes" ); +#/ + switch ( weapon ) + { + case "mp40_blinged_mp": + case "minigun_mp": + case "m32_mp": + case "m220_tow_mp": + case "m202_flash_mp": + self takeweapon( weapon ); + break; + default: + break; + } + + return; + } + + + clipammo = self getweaponammoclip( weapon ); + stockammo = self getweaponammostock( weapon ); + clip_and_stock_ammo = clipammo + stockammo; + + if ( !clip_and_stock_ammo ) + { +/# + if ( getdvar( _hash_8F7FC88 ) == "1" ) + println( "didn't drop weapon: no ammo" ); +#/ + return; + } + + stockmax = weaponmaxammo( weapon ); + + if ( stockammo > stockmax ) + stockammo = stockmax; + + item = self dropitem( weapon ); +/# + if ( getdvar( _hash_8F7FC88 ) == "1" ) + println( "dropped weapon: " + weapon ); +#/ + droplimitedweapon( weapon, self, item ); + item itemweaponsetammo( clipammo, stockammo ); + item.owner = self; + item thread watchpickup(); + item thread deletepickupafterawhile(); + +} \ No newline at end of file diff --git a/t6/uncompiled mods/emp_no_perk_disable.gsc b/t6/uncompiled mods/emp_no_perk_disable.gsc new file mode 100644 index 0000000..9f18023 --- /dev/null +++ b/t6/uncompiled mods/emp_no_perk_disable.gsc @@ -0,0 +1,71 @@ +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\_demo; +#include maps\mp\zombies\_zm_ai_basic; +//always add includes of the replaced functions +main() +{ + if (level.script == "zm_transit") //only for transit + { + replaceFunc( maps\mp\zombies\_zm_power::change_power_in_radius, ::emp_no_perk_disable); //replace base function by custom function + } +} + +emp_no_perk_disable( delta, origin, radius ) +{ + changed_list = []; + +if (level.script == "zm_transit") +{ + for ( i = 0; i < level.powered_items.size; i++ ) + { + powered = level.powered_items[i]; // this is in base code and is equivalent to a foreach item in level.powered_items + + if (isdefined(powered.target) && powered.target) // check if target exist + { + if (isdefined(powered.target.script_noteworthy) && powered.target.script_noteworthy) // check if target name exist + { + powered_name = strTok(powered.target.script_noteworthy, "_"); //separate the target name using "_" (since we want only to avoid disabled perks and their name is "specialty_XXX" + if ( powered.power_sources != 2 && powered_name[0] != "specialty") // in powered_named array, check if the first text element is different than "specialty" + { + if ( powered [[ powered.range_func ]]( delta, origin, radius ) ) + { + powered maps\mp\zombies\_zm_power::change_power( delta, origin, radius ); //if the replaced functions call other functions you must link the called function path + changed_list[changed_list.size] = powered; + } + } + } + /* else + { + iprintLn("^1Error^7, please contact ^1admin^7"); + }*/ + } + /* else + { + iprintLn("^1Error^7, please contact ^1admin^7"); + }*/ + } + return changed_list; +} +else +{ + for ( i = 0; i < level.powered_items.size; i++ ) + { + powered = level.powered_items[i]; + + if ( powered.power_sources != 2 ) + { + if ( powered [[ powered.range_func ]]( delta, origin, radius ) ) + { + powered maps\mp\zombies\_zm_power::change_power( delta, origin, radius ); + changed_list[changed_list.size] = powered; + } + } + } + + return changed_list; +} + +} \ No newline at end of file diff --git a/t6/uncompiled mods/fastwavespawn.gsc b/t6/uncompiled mods/fastwavespawn.gsc new file mode 100644 index 0000000..acb906e --- /dev/null +++ b/t6/uncompiled mods/fastwavespawn.gsc @@ -0,0 +1,104 @@ +#include maps\mp\gametypes_zm\_globallogic_player; +#include maps\mp\gametypes_zm\_spawning; +#include maps\mp\gametypes_zm\_globallogic_audio; +#include maps\mp\gametypes_zm\_globallogic_utils; +#include maps\mp\gametypes_zm\_globallogic; +#include maps\mp\gametypes_zm\_hud_message; +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\gametypes_zm\_globallogic_ui; +#include maps\mp\gametypes_zm\_globallogic_defaults; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\gametypes_zm\_globallogic_score; +#include maps\mp\gametypes_zm\_hostmigration; +#include maps\mp\gametypes_zm\_globallogic_spawn; +#include maps\mp\gametypes_zm\_spectating; +#include maps\mp\_demo; +#include maps\mp\gametypes_zm\_weapons; +#include maps\mp\gametypes_zm\_spawnlogic; +#include maps\mp\_challenges; +#include maps\mp\gametypes_zm\_tweakables; + +#include common_scripts\utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_ffotd; +#include maps\mp\zombies\_zm; +#include maps\mp\_visionset_mgr; +#include maps\mp\zombies\_zm_devgui; +#include maps\mp\zombies\_zm_zonemgr; +#include maps\mp\zombies\_zm_unitrigger; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_blockers; +#include maps\mp\zombies\_zm_bot; +#include maps\mp\zombies\_zm_clone; +#include maps\mp\zombies\_zm_buildables; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\zombies\_zm_magicbox; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm_playerhealth; +#include maps\mp\zombies\_zm_power; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_spawner; +#include maps\mp\zombies\_zm_gump; +#include maps\mp\zombies\_zm_timer; +#include maps\mp\zombies\_zm_traps; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_tombstone; +#include maps\mp\zombies\_zm_pers_upgrades; +#include maps\mp\gametypes_zm\_zm_gametype; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\zombies\_zm_melee_weapon; +#include maps\mp\zombies\_zm_ai_dogs; +#include maps\mp\zombies\_zm_pers_upgrades_system; +#include maps\mp\zombies\_zm_ai_basic; +#include maps\mp\zombies\_zm_game_module; + +init() +{ + //level.zombie_vars["zombie_between_round_time"] = 1; + //level.zombie_vars["zombie_intermission_time"] = 1; + // level.zombie_vars["zombie_move_speed_multiplier"] = 3600; + level thread SpawnRate(); + if (level.script == "zm_transit") + { + level.zombie_vars["riotshield_hit_points"] = 30000; + } + +} + +SpawnRate() +{ + level endon("game_ended"); + level.zombie_vars["zombie_spawn_delay"] = 1.5; + + lock = 0; + for (;;) + { + if (lock == 0 && level.round_number >= 5) + { + level.zombie_vars["zombie_spawn_delay"] = 1; + lock = 1; + iPrintLn("^3The zombies are ^1pissed ^7! Spawn rate ^3increased^7"); + wait 5; + iPrintLn("^3The zombies are ^1pissed ^7! Spawn rate ^3increased^7"); + } + if (lock == 1 && level.round_number >= 10) + { + level.zombie_vars["zombie_spawn_delay"] = 0.5; + lock = 2; + iPrintLn("^3The zombies are ^1angry ^7! Spawn rate ^3increased^7"); + wait 5; + iPrintLn("^3The zombies are ^1angry ^7! Spawn rate ^3increased^7"); + } + if (lock == 2 && level.round_number >= 15) + { + level.zombie_vars["zombie_spawn_delay"] = 0; + iPrintLn("^3The zombies are ^1REALLY angry ^7! Spawn rate ^1maxed out^7"); + wait 5; + iPrintLn("^3The zombies are ^1REALLY angry ^7! Spawn rate ^1maxed out^7"); + lock = 3; + } + wait 1; + } +} \ No newline at end of file diff --git a/t6/uncompiled mods/give.gsc b/t6/uncompiled mods/give.gsc new file mode 100644 index 0000000..86edb25 --- /dev/null +++ b/t6/uncompiled mods/give.gsc @@ -0,0 +1,76 @@ + +#include maps\mp\_visionset_mgr; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\_demo; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_power; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\_utility; +#include common_scripts\utility; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\zombies\_zm_chugabud; +#include maps\mp\zombies\_zm_afterlife; +#include maps\mp\zombies\_zm_tombstone; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm_perk_vulture; +#include maps\mp\zombies\_zm_weap_time_bomb; +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\gametypes_zm\_gameobjects; +#include maps\mp\zombies\_zm_buildables; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm_clone; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_weap_cymbal_monkey; +#include maps\mp\zombies\_zm; + +init() +{ + setDvar("give", ""); + level thread giveCommand(); +} + +giveCommand() +{ + level endon("game_ended"); + + for (;;) + { + if (getDvar("give") != "") + { + content = strTok(getDvar("give"), ";"); + setDvar("give", ""); + if (int(content[0]) == -1) + { + for (i = 0; i < level.players.size; i++) + { + weapon_list = level.players[i] GetWeaponsListPrimaries(); + level.players[i] TakeWeapon(weapon_list[int(content[2])]); + level.players[i] GiveWeapon(content[1], int(content[2])); + level.players[i] SwitchToWeapon(content[1]); + level.players[i] IPrintLn("You have been given ^3" + content[1] + "^7"); + } + } + else + { + weapon_list = level.players[int(content[0])] GetWeaponsListPrimaries(); + level.players[int(content[0])] TakeWeapon(weapon_list[int(content[2])]); + level.players[int(content[0])] GiveWeapon(content[1], int(content[2])); + level.players[int(content[0])] SwitchToWeapon(content[1]); + level.players[int(content[0])] IPrintLn("You have been given ^3" + content[1] + "^7"); + } + } + wait 0.5; + } +} + +getPlayerByGuid(guid) { + for (i = 0; i < level.players.size; i++) { + if (isAlive(level.players[i]) && int(level.players[i] getGuid()) == int(guid)) { + return level.players[i]; + } + } + return false; +} \ No newline at end of file diff --git a/t6/uncompiled mods/godnoclip.gsc b/t6/uncompiled mods/godnoclip.gsc new file mode 100644 index 0000000..202b491 --- /dev/null +++ b/t6/uncompiled mods/godnoclip.gsc @@ -0,0 +1,37 @@ +init() { + setDvar("godmodeon", ""); + setDvar("godmodeoff", ""); + level thread godNoclip(); +} + +getPlayerByGuid(guid) { + for (i = 0; i < level.players.size; i++) { + if (isAlive(level.players[i]) && int(level.players[i] getGuid()) == int(guid)) { + return level.players[i]; + } + } + return false; +} + +godNoclip() { + for (;;) { + if (getDvar("godmodeon") != "") { + godmodeon = getDvar("godmodeon"); + setDvar("godmodeon", ""); + getPlayerByGuid(godmodeon) EnableInvulnerability(); + getPlayerByGuid(godmodeon) noclip(); + getPlayerByGuid(godmodeon).ignoreme = true; + getPlayerByGuid(godmodeon) iPrintLn("^1Admin Access Override: ^3God + Noclip^2 ON"); + } + if (getDvar("godmodeoff") != "") { + godmodeoff = getDvar("godmodeoff"); + setDvar("godmodeoff", ""); + getPlayerByGuid(godmodeoff) DisableInvulnerability(); + getPlayerByGuid(godmodeoff) noclip(); + getPlayerByGuid(godmodeon).ignoreme = false; + getPlayerByGuid(godmodeoff) iPrintLn("^1Admin Access Override: ^3God + Noclip^1 OFF"); + + } + wait 0.5; + } +} \ No newline at end of file diff --git a/t6/uncompiled mods/guild.gsc b/t6/uncompiled mods/guild.gsc new file mode 100644 index 0000000..50fddfa --- /dev/null +++ b/t6/uncompiled mods/guild.gsc @@ -0,0 +1,176 @@ +init() +{ + setdvar("guild", "0"); + + level thread on_player_connect(); +} + +on_player_connect() +{ + for (;;) + { + level waittill("connected", player); + player thread preload_guild_menu(); + } +} + +fade_in(icon, range) +{ + for (i = 0; i < range; i++) + { + icon.alpha = (i * 0.1); + wait 0.1; + } +} + +fade_out(icon, range) +{ + for (i = range; i >= 0; i--) + { + icon.alpha = (i * 0.1); + wait 0.1; + } +} + +drawshader( shader, x, y, width, height, color, alpha) +{ + level endon("end_game"); + self endon("disconnect"); + hud = newclienthudelem( self ); + hud.elemtype = "icon"; + hud.color = color; + hud.alpha = alpha; + hud.sort = 0; + hud.children = []; + hud.hidewheninmenu = 1; + hud setparent(self.guild_menu ); + hud setshader( shader, width, height ); + hud.x = x; + hud.y = y; + hud.foreground = 0; + return hud; +} + +preload_guild_menu() +{ + setdvar("guild", "0"); + self.guild_menu = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1.5 ); + self.guild_menu maps\mp\gametypes_zm\_hud_util::setPoint( "BOTTOM", "LEFT", 570, 120 ); + self.guild_menu SetText("^6GUILD MENU\n\n-> ^3Stats\n^2Dailies^7\n^5Raid\n^1Close^7"); + self.guild_menu.alpha = 0; + self.guild_menu.sort = 1; + self.hidewheninmenu = 1; + shader = "zombies_rank_2"; + self.notifyiconb = self drawshader(shader, 570, 60, 200, 300, (0, 0, 0)); + self.notifyiconb.alpha = 0; + + selector = 0; + guild_money = 0; + guild_hp = 0; + guild_speed = 0; + guild_mult = 0; + + for (;;) + { + for (;;) + { + if (getdvar("guild") != "0") + { + str = StrTok(getdvar("guild"), ";"); + setdvar("guild", "0"); + if (int(self getGuid()) == int(str[0])) + break; + continue; + } + wait 0.1; + } + + level thread fade_in(self.guild_menu, 8); + level thread fade_in(self.notifyiconb, 9); + + main_menu = 1; + for (;;) + { + if (self UseButtonPressed()) + { + if (selector == 3) + { + if (main_menu == 1) + { + main_menu = 0; + self.guild_menu SetText("^6GUILD MENU\n\n^3Stats^7\n^2Dailies^7\n^5Raid\n^7Close^7"); + wait 0.1; + self.guild_menu SetText("^6GUILD MENU\n\n^3Stats^7\n^2Dailies^7\n^5Raid\n^1Close^7"); + wait 0.1; + } + break; + } + else if ( selector == 0) + { + if (main_menu == 1) + { + main_menu = 0; + self.guild_menu SetText("^6GUILD MENU\n\n^6-> ^7Stats^7\n^2Dailies^7\n^5Raid\n^1Close^7"); + wait 0.1; + self.guild_menu SetText("^6GUILD MENU\n\n^6-> ^3Stats^7\n^2Dailies^7\n^5Raid\n^1Close^7"); + wait 0.1; + } + + self.guild_menu SetText("^3" + str[1] + "\n^2Money^7 : " + str[3] + "\n^6G-Coins^7 : " + str[4] + "\n^1+HP^7 : " + str[5] + "\n^2+Speed^7 : " + str[7] + "\n^5+Multiplier^7 : " + "0"); + } + else if (selector == 1) + { + if (main_menu == 1) + { + main_menu = 0; + self.guild_menu SetText("^6GUILD MENU\n\n^3Stats^7\n^6-> ^7Dailies^7\n^5Raid\n^1Close^7"); + wait 0.1; + self.guild_menu SetText("^6GUILD MENU\n\n^3Stats^7\n^6-> ^2Dailies^7\n^5Raid\n^1Close^7"); + wait 0.1; + } + self.guild_menu SetText("^6\n\nDailies : " + str[3] + " ^2$^7\n" + str[4] + " ^6G-Coins^7"); + } + else if (selector == 2) + { + if (main_menu == 1) + { + main_menu = 0; + self.guild_menu SetText("^6GUILD MENU\n\n^3Stats^7\n^2Dailies^7\n^6-> ^7Raid\n^1Close^7"); + wait 0.1; + self.guild_menu SetText("^6GUILD MENU\n\n^3Stats^7\n^2Dailies^7\n^6-> ^5Raid\n^1Close^7"); + wait 0.1; + } + self.guild_menu SetText("^6\nIn progress"); + } + //0 name 1 level 2 money 3 coins 4 revive hp 5 speed 6 skills_count +1 ALL + } + if (self MeleeButtonPressed()) + { + main_menu = 1; + selector++; + if (selector == 4) + selector = 0; + if (selector == 0) + { + self.guild_menu SetText("^6GUILD MENU\n\n^6-> ^3Stats\n^2Dailies^7\n^5Raid\n^1Close^7"); + } + else if (selector == 1) + { + self.guild_menu SetText("^6GUILD MENU\n\n^3Stats\n^6-> ^2Dailies^7\n^5Raid\n^1Close^7"); + } + else if (selector == 2) + { + self.guild_menu SetText("^6GUILD MENU\n\n^3Stats\n^2Dailies^7\n^6-> ^5Raid\n^1Close^7"); + } + else if (selector == 3) + { + self.guild_menu SetText("^6GUILD MENU\n\n^3Stats\n^2Dailies^7\n^5Raid\n^6-> ^1Close^7"); + } + } + wait 0.15; + } + level thread fade_out(self.guild_menu, 8); + level thread fade_out(self.notifyiconb, 9); + wait 0.1; + } +} \ No newline at end of file diff --git a/t6/uncompiled mods/hitmarker.gsc b/t6/uncompiled mods/hitmarker.gsc new file mode 100644 index 0000000..dce6fd8 --- /dev/null +++ b/t6/uncompiled mods/hitmarker.gsc @@ -0,0 +1,80 @@ +#include maps\mp\_utility; +#include common_scripts\utility; +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\gametypes_zm\_hud_message; + +init() +{ + precacheshader("damage_feedback"); + + level thread onplayerconnect(); + + maps/mp/zombies/_zm_spawner::register_zombie_damage_callback(::do_hitmarker); + maps/mp/zombies/_zm_spawner::register_zombie_death_event_callback(::do_hitmarker_death); + + level.red_hitmarkers_on_death = getDvarIntDefault("redHitmarkers", 0); +} + +onplayerconnect() +{ + for(;;) + { + level waittill("connected", player); + + if (!isdefined(player.hud_damagefeedback)) + player thread init_player_hitmarkers(); + } +} + +init_player_hitmarkers() +{ + self.hud_damagefeedback = newdamageindicatorhudelem(self); + self.hud_damagefeedback.horzalign = "center"; + self.hud_damagefeedback.vertalign = "middle"; + self.hud_damagefeedback.x = -12; + self.hud_damagefeedback.y = -12; + self.hud_damagefeedback.alpha = 0; + self.hud_damagefeedback.archived = 1; + self.hud_damagefeedback.color = (1, 1, 1); + + self.hud_damagefeedback setshader("damage_feedback", 24, 48); + self.hitsoundtracker = 1; +} + +// a improved updatedamagefeedback +do_hitmarker_internal(mod, death) +{ + if (!isplayer(self)) + return; + + if (!isdefined(death)) + death = false; + + if (isdefined(mod) && mod != "MOD_CRUSH" && mod != "MOD_GRENADE_SPLASH" && mod != "MOD_HIT_BY_OBJECT") + { + self.hud_damagefeedback.color = (1, 1, 1); + + if (death && level.red_hitmarkers_on_death) + self.hud_damagefeedback.color = (1, 0, 0); + + self.hud_damagefeedback setshader("damage_feedback", 24, 48); + self.hud_damagefeedback.alpha = 1; + self.hud_damagefeedback fadeovertime(1); + self.hud_damagefeedback.alpha = 0; + } +} + +do_hitmarker(mod, hit_location, hit_origin, player, amount) +{ + if (isdefined(player) && isplayer(player) && player != self) + player thread do_hitmarker_internal(mod, player); + + return false; +} + +do_hitmarker_death() +{ + // self is the zombie victim in this case + if (isdefined(self.attacker) && isplayer(self.attacker) && self.attacker != self) + self.attacker thread do_hitmarker_internal(self.damagemod, self.attacker, true); +} \ No newline at end of file diff --git a/t6/uncompiled mods/hpspeed.gsc b/t6/uncompiled mods/hpspeed.gsc new file mode 100644 index 0000000..8ca1d45 --- /dev/null +++ b/t6/uncompiled mods/hpspeed.gsc @@ -0,0 +1,147 @@ +/*#include maps\mp\_utility; +#include maps\mp\gametypes_zm\_hud_util; + +#include common_scripts/utility; +#include maps/mp/_demo; +#include maps/mp/_utility; +#include maps/mp/_visionset_mgr; +#include maps/mp/gametypes_zm/_hud_util; +#include maps/mp/gametypes_zm/_weapons; +#include maps/mp/gametypes_zm/_zm_gametype; +#include maps/mp/zombies/_zm; +#include maps/mp/zombies/_zm_ai_basic; +#include maps/mp/zombies/_zm_ai_dogs; +#include maps/mp/zombies/_zm_audio; +#include maps/mp/zombies/_zm_audio_announcer; +#include maps/mp/zombies/_zm_blockers; +#include maps/mp/zombies/_zm_bot; +#include maps/mp/zombies/_zm_buildables; +#include maps/mp/zombies/_zm_clone; +#include maps/mp/zombies/_zm_devgui; +#include maps/mp/zombies/_zm_equipment; +#include maps/mp/zombies/_zm_ffotd; +#include maps/mp/zombies/_zm_game_module; +#include maps/mp/zombies/_zm_gump; +#include maps/mp/zombies/_zm_laststand; +#include maps/mp/zombies/_zm_magicbox; +#include maps/mp/zombies/_zm_melee_weapon; +#include maps/mp/zombies/_zm_perks; +#include maps/mp/zombies/_zm_pers_upgrades; +#include maps/mp/zombies/_zm_pers_upgrades_system; +#include maps/mp/zombies/_zm_pers_upgrades_functions; +#include maps/mp/zombies/_zm_playerhealth; +#include maps/mp/zombies/_zm_powerups; +#include maps/mp/zombies/_zm_power; +#include maps/mp/zombies/_zm_score; +#include maps/mp/zombies/_zm_sidequests; +#include maps/mp/zombies/_zm_spawner; +#include maps/mp/zombies/_zm_stats; +#include maps/mp/zombies/_zm_timer; +#include maps/mp/zombies/_zm_tombstone; +#include maps/mp/zombies/_zm_traps; +#include maps/mp/zombies/_zm_unitrigger; +#include maps/mp/zombies/_zm_utility; +#include maps/mp/zombies/_zm_weapons; +#include maps/mp/zombies/_zm_zonemgr;*/ +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_magicbox; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\zombies\_zm_power; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\_demo; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_chugabud; +#include maps\mp\_visionset_mgr; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm; + +main() +{ + replaceFunc(maps/mp/zombies/_zm_perks::perk_set_max_health_if_jugg, ::customJugg); +} +init() +{ + setdvar("hp", ""); + level thread onPlayerConnect(); +} + +onPlayerConnect() +{ + while( 1 ) + { + level waittill( "connected", player ); + player thread onPlayerSpawned(); + } +} + +onPlayerSpawned() +{ + if (getdvar("hp" != "") + { + self iPrintln("custom hp activated) + } + setdvar("hp", ""); + level endon("game_ended"); + self endon("disconnect"); + self waittill( "spawned_player" ); + + self.extrahealth = 50; + self.maxhealth += self.extrahealth; + self.health = self.maxhealth; + + // self SetMoveSpeedScale(1.9); +} + +customJugg( perk, set_premaxhealth, clamp_health_to_max_health ) +{ + max_total_health = undefined; + + if ( perk == "specialty_armorvest" ) + { + if ( set_premaxhealth ) + self.premaxhealth = self.maxhealth; + + max_total_health = level.zombie_vars["zombie_perk_juggernaut_health"]; + } + else if ( perk == "specialty_armorvest_upgrade" ) + { + if ( set_premaxhealth ) + self.premaxhealth = self.maxhealth; + + max_total_health = level.zombie_vars["zombie_perk_juggernaut_health_upgrade"]; + } + else if ( perk == "jugg_upgrade" ) + { + if ( set_premaxhealth ) + self.premaxhealth = self.maxhealth; + + if ( self hasperk( "specialty_armorvest" ) ) + max_total_health = level.zombie_vars["zombie_perk_juggernaut_health"]; + else + max_total_health = 100; + } + else if ( perk == "health_reboot" ) + max_total_health = 100; + + if ( isdefined( max_total_health ) ) + { + if ( self maps\mp\zombies\_zm_pers_upgrades_functions::pers_jugg_active() ) + max_total_health += level.pers_jugg_upgrade_health_bonus; + + if (self.extrahealth) + self setmaxhealth( max_total_health + self.extrahealth); + else + self setmaxhealth( max_total_health + self.extrahealth); + + if ( isdefined( clamp_health_to_max_health ) && clamp_health_to_max_health == 1 ) + { + if ( self.health > self.maxhealth ) + self.health = self.maxhealth; + } + } +} \ No newline at end of file diff --git a/t6/uncompiled mods/infinite_money-compiled.gsc b/t6/uncompiled mods/infinite_money-compiled.gsc new file mode 100644 index 0000000000000000000000000000000000000000..82a03126c6d150406940f2b7df1f738d601a0163 GIT binary patch literal 2512 zcmaKu&x;&I6vu0J;&u$?D7vtR1j7;nam2_f5k!cr9u!3vF9wS0s+#G_RCV`uRn2Aw z6upRGP7+WM?}CtvUi=S&AjE_I10Kvl#Diz?`+9!$W^0_`Lv`1CujnFCJ&?8SoXz!3;cDKsv9ojBVjhKMPDbG^GieyQxfunrzycF4*htXO+v>fi^sPGP zPRk;WL>|+giDA%ztgrTv#gZak{#>Y!JXl z#&=v;DMBM=t5mLX){&9xu0qYNmNs*|Zj49HhqqIm!z!$kC`#j&r2#{wMJT#PD<4EB zwyV(CO00)k&nskM^hBS?>B)TfS{#?A9IdBX@AYI@QEezQ z(WtFB?o?MNKFZL3lA0rua(rUSjuwR7vOg)AXq)uYiII_cb$b!+q>eB=7v9LEa9$l& zOx>n)snuvq6+9wp)&I@Zs^&J93MWx*MS456TG)@G5Xa-BQ!~`^i379~jMn-nYTp^W zBOWzI54qIV=C+cZ;g=Q3WFe3SoD~Dfkx4FaXp|$Q@03Jo8>KkaUEpl=mD8sLmDOTH znY7LzD9Pp0lCV|C-wkK-GR;Zzwvb^+_ZQ<-fuYKH1a!q)RrWPxCGN|AY?B zz1^SdlfUF^cYKmxh5SuWfKS2KfONk{`v5!y|AO5!jJ*sL_zc_w_rdQVdyKJ5-~b$f zFTs!CSMU#@d7s9|$rbP#_y7bzvHBcs*Qe!LyM1>SYoT$LHni4nVfz!1=wIf5VnhD_ zfqq&8`9^WwdlH>{_%=F!@oaXPJ=MRKUC$1(t2=D_VgH?-t>++Shmh~@Y`u7ax$GRk zXWx_K9A?UtPfsc@T7MM?}yo4JonDr!1MffHtY4C#oINs cFQC1Sb|38l+LzEewC~Pa_CDGI?>Eu@2e1wl`Tzg` literal 0 HcmV?d00001 diff --git a/t6/uncompiled mods/infinite_money.gsc b/t6/uncompiled mods/infinite_money.gsc new file mode 100644 index 0000000..f8a0a0d --- /dev/null +++ b/t6/uncompiled mods/infinite_money.gsc @@ -0,0 +1,127 @@ +#include maps\mp\zombies\_zm; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\_visionset_mgr; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\_demo; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\zombies\_zm_power; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_stats; +#include common_scripts\utility; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\zombies\_zm_chugabud; +#include maps\mp\zombies\_zm_afterlife; +#include maps\mp\zombies\_zm_tombstone; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm_perk_vulture; +#include maps\mp\zombies\_zm_weap_time_bomb; + +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\_demo; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\gametypes_zm\_gameobjects; +#include maps\mp\zombies\_zm_buildables; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm_chugabud; +#include maps\mp\zombies\_zm_perks; + + +#include maps\mp\_utility; +#include common_scripts\utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\zombies\_zm_chugabud; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm_clone; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_weap_cymbal_monkey; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm; +#include maps\mp\_visionset_mgr; + +//motd +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_craftables; +#include maps\mp\zm_alcatraz_utility; +#include maps\mp\zm_alcatraz_gamemodes; +#include maps\mp\zm_prison_fx; +#include maps\mp\zm_prison_ffotd; +#include maps\mp\zombies\_zm; +#include maps\mp\animscripts\zm_death; +#include maps\mp\zm_alcatraz_amb; +#include maps\mp\zombies\_load; +#include maps\mp\zm_prison_achievement; +#include maps\mp\gametypes_zm\_spawning; +#include maps\mp\zombies\_zm_perk_electric_cherry; +#include maps\mp\zombies\_zm_perk_divetonuke; +#include maps\mp\zm_alcatraz_distance_tracking; +#include maps\mp\zm_alcatraz_traps; +#include maps\mp\zm_alcatraz_travel; +#include maps\mp\zombies\_zm_magicbox_prison; +#include maps\mp\zombies\_zm_ai_basic; +#include maps\mp\zombies\_zm_weap_claymore; +#include maps\mp\zombies\_zm_weap_riotshield_prison; +#include maps\mp\zombies\_zm_weap_blundersplat; +#include maps\mp\zombies\_zm_weap_tomahawk; +#include maps\mp\zombies\_zm_zonemgr; +#include maps\mp\zm_alcatraz_weap_quest; +#include maps\mp\zm_alcatraz_grief_cellblock; +#include maps\mp\_visionset_mgr; +#include maps\mp\zm_prison; +#include character\c_zom_arlington; +#include character\c_zom_deluca; +#include character\c_zom_handsome; +#include character\c_zom_oleary; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_blockers; + +//points +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zombies\_zm_pers_upgrades_functions; + + +//timebomb +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\_visionset_mgr; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_blockers; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\zombies\_zm_weapon_locker; +#include maps\mp\zombies\_zm_magicbox; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm; +#include maps\mp\zombies\_zm_spawner; +#include maps\mp\animscripts\zm_death; +#include maps\mp\zombies\_zm_ai_basic; +#include maps\mp\zombies\_zm_weap_time_bomb; + +init() { + level._game_module_point_adjustment = ::doublepoints; +} + +doublepoints(player, zombie_team, player_points){ + player maps/mp/zombies/_zm_score::add_to_player_score( player_points * 1000); + player.pers[ "score" ] = player.score; +} \ No newline at end of file diff --git a/t6/uncompiled mods/isSaved.gsc b/t6/uncompiled mods/isSaved.gsc new file mode 100644 index 0000000..91c9fe6 --- /dev/null +++ b/t6/uncompiled mods/isSaved.gsc @@ -0,0 +1,4 @@ +init() +{ + setDvar("isSaved", "0"); +} \ No newline at end of file diff --git a/t6/uncompiled mods/killzm.gsc b/t6/uncompiled mods/killzm.gsc new file mode 100644 index 0000000..2f45538 --- /dev/null +++ b/t6/uncompiled mods/killzm.gsc @@ -0,0 +1,123 @@ +#include maps\mp\_utility; +#include common_scripts\utility; +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\gametypes_zm\_hud; +#include maps\mp\zombies\_zm; + +init() { + setDvar("killzm", "0"); + setDvar("killzmadmin", "0"); + setDvar("customround", "0"); + setDvar("load", "0"); + setDvar("votecount", "0"); + setDvar("vote", "0"); + level thread killZm(); + level thread setZmCount(); +// level thread setRound(); + +} + + +/*setRound() +{ + for(;;) + { + if (getDvar("customround") != "0") + { + customround = int(getDvar("customround")); + level.round_number = customround; + if(customround == level.round_number) + setDvar("customround", "0"); + } + wait 3; + } +}*/ + +setZmCount() +{ + saveRound = 1; + for (;;) + { + if (level.round_number > 29 && level.round_number != saveRound && level.script != "zm_highrise") + { + saveRound = level.round_number; + setDvar("currentround", saveRound); + wait 16; + intval = int((0.0896 * (saveRound * saveRound)) + (0.0115 * saveRound) + 23.518); + level.zombie_total = intval; + iPrintLn("Entering ^1High Rounds^7: Zombie amount set to 1 player."); + } + if (level.zombie_total < 0) + level.zombie_total = 0; + if (getDvar("load") == "1") + { + setDvar("load", "0"); + flag_wait( "initial_blackscreen_passed" ); + level.round_number = int(getDvar("customround")) - 1; + saveRound = level.round_number; + wait 8; + setDvar("killzmadmin", "1"); + wait 1; + level.zombie_total = 1; + } + round = getDvar("votecount"); + if (int(round) > 0) + { + level thread Announcement(round); + setDvar("votecount", "0"); + + } + wait 1; + } +} + +Announcement(round) +{ + level endon("game_ended"); + for (i = 0; i < 3; i++) + { + iPrintlnbold("^2Vote ^3Request^7 : Load ^5Round " + round + "^7 Game ? ^3Type ^2.yes^7"); + wait 3; + } +} +killZm() +{ + for(;;) + { + if (getDvar("killzmadmin") == "1") + { + zombies = getaiarray( level.zombie_team ); + if (zombies && zombies.size > 0) + { + for ( i = 0; i < zombies.size; i++ ) + { + zombies[i] dodamage( zombies[i].health + 666, zombies[i].origin ); + } + iPrintLn("^1Admin Access Code^7: Killing all ^1spawned zombies^7."); + } + setDvar("killzmadmin", "0"); + } + else if (level.script == "zm_transit" || level.script == "zm_buried") + { + if(getDvar("killzm") == "1") + { + zombies = getaiarray( level.zombie_team ); + if (zombies && zombies.size > 0) + { + if(zombies.size == 1 || zombies.size == 2 ) + { + zombies[0] dodamage( zombies[0].health + 666, zombies[0].origin ); + iPrintLn("^1Killing^7 last zombie."); + } + else + { + iPrintLn("Can only use ^3.kill command^7 when ^11/2 zombie/witch is left."); + } + } + setDvar("killzm", "0"); + } + } + wait 1; + } +} \ No newline at end of file diff --git a/t6/uncompiled mods/killzmtourneymotd.gsc b/t6/uncompiled mods/killzmtourneymotd.gsc new file mode 100644 index 0000000..89685a6 --- /dev/null +++ b/t6/uncompiled mods/killzmtourneymotd.gsc @@ -0,0 +1,266 @@ +#include maps\mp\zombies\_zm; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\_visionset_mgr; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\_demo; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\zombies\_zm_power; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_stats; +#include common_scripts\utility; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\zombies\_zm_chugabud; +#include maps\mp\zombies\_zm_afterlife; +#include maps\mp\zombies\_zm_tombstone; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm_perk_vulture; +#include maps\mp\zombies\_zm_weap_time_bomb; + +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\_demo; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\gametypes_zm\_gameobjects; +#include maps\mp\zombies\_zm_buildables; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm_chugabud; +#include maps\mp\zombies\_zm_perks; + + +#include maps\mp\_utility; +#include common_scripts\utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\zombies\_zm_chugabud; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm_clone; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_weap_cymbal_monkey; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm; +#include maps\mp\_visionset_mgr; + +//motd +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_craftables; +#include maps\mp\zm_alcatraz_utility; +#include maps\mp\zm_alcatraz_gamemodes; +#include maps\mp\zm_prison_fx; +#include maps\mp\zm_prison_ffotd; +#include maps\mp\zombies\_zm; +#include maps\mp\animscripts\zm_death; +#include maps\mp\zm_alcatraz_amb; +#include maps\mp\zombies\_load; +#include maps\mp\zm_prison_achievement; +#include maps\mp\gametypes_zm\_spawning; +#include maps\mp\zombies\_zm_perk_electric_cherry; +#include maps\mp\zombies\_zm_perk_divetonuke; +#include maps\mp\zm_alcatraz_distance_tracking; +#include maps\mp\zm_alcatraz_traps; +#include maps\mp\zm_alcatraz_travel; +#include maps\mp\zombies\_zm_magicbox_prison; +#include maps\mp\zombies\_zm_ai_basic; +#include maps\mp\zombies\_zm_weap_claymore; +#include maps\mp\zombies\_zm_weap_riotshield_prison; +#include maps\mp\zombies\_zm_weap_blundersplat; +#include maps\mp\zombies\_zm_weap_tomahawk; +#include maps\mp\zombies\_zm_zonemgr; +#include maps\mp\zm_alcatraz_weap_quest; +#include maps\mp\zm_alcatraz_grief_cellblock; +#include maps\mp\_visionset_mgr; +#include maps\mp\zm_prison; +#include character\c_zom_arlington; +#include character\c_zom_deluca; +#include character\c_zom_handsome; +#include character\c_zom_oleary; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_blockers; + +//points +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zombies\_zm_pers_upgrades_functions; + + +//timebomb +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\_visionset_mgr; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_blockers; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\zombies\_zm_weapon_locker; +#include maps\mp\zombies\_zm_magicbox; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm; +#include maps\mp\zombies\_zm_spawner; +#include maps\mp\animscripts\zm_death; +#include maps\mp\zombies\_zm_ai_basic; +#include maps\mp\zombies\_zm_weap_time_bomb; + + +init() { + setDvar("killzm", "0"); + setDvar("killzmadmin", "0"); + setDvar("customround", "0"); + level thread killZm(); + if(level.script != "zm_highrise") + level thread setZmCount(); +// level thread setRound(); + +} + + +/*setRound() +{ + for(;;) + { + if (getDvar("customround") != "0") + { + customround = int(getDvar("customround")); + level.round_number = customround; + if(customround == level.round_number) + setDvar("customround", "0"); + } + wait 3; + } +}*/ + +setZmCount() +{ + saveRound = 0; + + for (;;) + { + if (level.round_number == 1 && level.round_number != saveRound) + { + saveRound = level.round_number; + wait 40; + level.zombie_total = 4; + } + if (level.round_number == 2 && level.round_number != saveRound) + { + saveRound = level.round_number; + wait 16; + level.zombie_total = 6; + } + if (level.round_number == 3 && level.round_number != saveRound) + { + saveRound = level.round_number; + wait 16; + level.zombie_total = 12; + } + if (level.round_number == 4 && level.round_number != saveRound) + { + saveRound = level.round_number; + wait 16; + level.zombie_total = 18; + } + if (level.round_number == 5 && level.round_number != saveRound) + { + saveRound = level.round_number; + wait 16; + level.zombie_total = 23; + } + if (level.round_number == 6 && level.round_number != saveRound) + { + saveRound = level.round_number; + wait 16; + level.zombie_total = 28; + } + if (level.round_number == 7 && level.round_number != saveRound) + { + saveRound = level.round_number; + wait 16; + level.zombie_total = 29; + } + if (level.round_number == 8 && level.round_number != saveRound) + { + saveRound = level.round_number; + wait 16; + level.zombie_total = 30; + } + if (level.round_number == 9 && level.round_number != saveRound) + { + saveRound = level.round_number; + wait 16; + level.zombie_total = 31; + } + if (level.round_number == 10 && level.round_number != saveRound) + { + saveRound = level.round_number; + wait 16; + level.zombie_total = 34; + } + if (level.round_number > 10 && level.round_number != saveRound) + { + saveRound = level.round_number; + wait 16; + intval = int((0.0896 * (saveRound * saveRound)) + (0.0115 * saveRound) + 23.518); + level.zombie_total = intval; + } + if (level.zombie_total < 0) + level.zombie_total = 0; + wait 1; + } +} + +killZm() +{ + for(;;) + { + if (getDvar("killzmadmin") == "1") + { + zombies = getaiarray( level.zombie_team ); + if (zombies && zombies.size > 0) + { + for ( i = 0; i < zombies.size; i++ ) + { + zombies[i] dodamage( zombies[i].health + 666, zombies[i].origin ); + } + iPrintLn("^1Admin Access Code^7: Killing all ^1spawned zombies^7."); + } + setDvar("killzmadmin", "0"); + } + else if (level.script == "zm_transit" || level.script == "zm_buried") + { + if(getDvar("killzm") == "1") + { + zombies = getaiarray( level.zombie_team ); + if (zombies && zombies.size > 0) + { + if(zombies.size == 1 || zombies.size == 2 ) + { + zombies[0] dodamage( zombies[0].health + 666, zombies[0].origin ); + iPrintLn("^1Killing^7 last zombie."); + } + else + { + iPrintLn("Can only use ^3.kill command^7 when ^11/2 zombie/witch is left."); + } + } + setDvar("killzm", "0"); + } + } + wait 1; + } +} \ No newline at end of file diff --git a/t6/uncompiled mods/killzmtourneyorigin.gsc b/t6/uncompiled mods/killzmtourneyorigin.gsc new file mode 100644 index 0000000..6428f1a --- /dev/null +++ b/t6/uncompiled mods/killzmtourneyorigin.gsc @@ -0,0 +1,266 @@ +#include maps\mp\zombies\_zm; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\_visionset_mgr; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\_demo; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\zombies\_zm_power; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_stats; +#include common_scripts\utility; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\zombies\_zm_chugabud; +#include maps\mp\zombies\_zm_afterlife; +#include maps\mp\zombies\_zm_tombstone; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm_perk_vulture; +#include maps\mp\zombies\_zm_weap_time_bomb; + +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\_demo; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\gametypes_zm\_gameobjects; +#include maps\mp\zombies\_zm_buildables; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm_chugabud; +#include maps\mp\zombies\_zm_perks; + + +#include maps\mp\_utility; +#include common_scripts\utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\zombies\_zm_chugabud; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm_clone; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_weap_cymbal_monkey; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm; +#include maps\mp\_visionset_mgr; + +//motd +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_craftables; +#include maps\mp\zm_alcatraz_utility; +#include maps\mp\zm_alcatraz_gamemodes; +#include maps\mp\zm_prison_fx; +#include maps\mp\zm_prison_ffotd; +#include maps\mp\zombies\_zm; +#include maps\mp\animscripts\zm_death; +#include maps\mp\zm_alcatraz_amb; +#include maps\mp\zombies\_load; +#include maps\mp\zm_prison_achievement; +#include maps\mp\gametypes_zm\_spawning; +#include maps\mp\zombies\_zm_perk_electric_cherry; +#include maps\mp\zombies\_zm_perk_divetonuke; +#include maps\mp\zm_alcatraz_distance_tracking; +#include maps\mp\zm_alcatraz_traps; +#include maps\mp\zm_alcatraz_travel; +#include maps\mp\zombies\_zm_magicbox_prison; +#include maps\mp\zombies\_zm_ai_basic; +#include maps\mp\zombies\_zm_weap_claymore; +#include maps\mp\zombies\_zm_weap_riotshield_prison; +#include maps\mp\zombies\_zm_weap_blundersplat; +#include maps\mp\zombies\_zm_weap_tomahawk; +#include maps\mp\zombies\_zm_zonemgr; +#include maps\mp\zm_alcatraz_weap_quest; +#include maps\mp\zm_alcatraz_grief_cellblock; +#include maps\mp\_visionset_mgr; +#include maps\mp\zm_prison; +#include character\c_zom_arlington; +#include character\c_zom_deluca; +#include character\c_zom_handsome; +#include character\c_zom_oleary; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_blockers; + +//points +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zombies\_zm_pers_upgrades_functions; + + +//timebomb +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\_visionset_mgr; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_blockers; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\zombies\_zm_weapon_locker; +#include maps\mp\zombies\_zm_magicbox; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm; +#include maps\mp\zombies\_zm_spawner; +#include maps\mp\animscripts\zm_death; +#include maps\mp\zombies\_zm_ai_basic; +#include maps\mp\zombies\_zm_weap_time_bomb; + + +init() { + setDvar("killzm", "0"); + setDvar("killzmadmin", "0"); + setDvar("customround", "0"); + level thread killZm(); + if(level.script != "zm_highrise") + level thread setZmCount(); +// level thread setRound(); + +} + + +/*setRound() +{ + for(;;) + { + if (getDvar("customround") != "0") + { + customround = int(getDvar("customround")); + level.round_number = customround; + if(customround == level.round_number) + setDvar("customround", "0"); + } + wait 3; + } +}*/ + +setZmCount() +{ + saveRound = 0; + + for (;;) + { +/* if (level.round_number == 1 && level.round_number != saveRound) + { + saveRound = level.round_number; + wait 20; + level.zombie_total = 4; + }*/ + if (level.round_number == 2 && level.round_number != saveRound) + { + saveRound = level.round_number; + wait 16; + level.zombie_total = 6; + } + if (level.round_number == 3 && level.round_number != saveRound) + { + saveRound = level.round_number; + wait 16; + level.zombie_total = 12; + } + if (level.round_number == 4 && level.round_number != saveRound) + { + saveRound = level.round_number; + wait 16; + level.zombie_total = 18; + } + if (level.round_number == 5 && level.round_number != saveRound) + { + saveRound = level.round_number; + wait 16; + level.zombie_total = 23; + } + if (level.round_number == 6 && level.round_number != saveRound) + { + saveRound = level.round_number; + wait 16; + level.zombie_total = 28; + } + if (level.round_number == 7 && level.round_number != saveRound) + { + saveRound = level.round_number; + wait 16; + level.zombie_total = 29; + } + if (level.round_number == 8 && level.round_number != saveRound) + { + saveRound = level.round_number; + wait 16; + level.zombie_total = 30; + } + if (level.round_number == 9 && level.round_number != saveRound) + { + saveRound = level.round_number; + wait 16; + level.zombie_total = 31; + } + if (level.round_number == 10 && level.round_number != saveRound) + { + saveRound = level.round_number; + wait 16; + level.zombie_total = 34; + } + if (level.round_number > 10 && level.round_number != saveRound) + { + saveRound = level.round_number; + wait 16; + intval = int((0.0896 * (saveRound * saveRound)) + (0.0115 * saveRound) + 23.518); + level.zombie_total = intval; + } + if (level.zombie_total < 0) + level.zombie_total = 0; + wait 1; + } +} + +killZm() +{ + for(;;) + { + if (getDvar("killzmadmin") == "1") + { + zombies = getaiarray( level.zombie_team ); + if (zombies && zombies.size > 0) + { + for ( i = 0; i < zombies.size; i++ ) + { + zombies[i] dodamage( zombies[i].health + 666, zombies[i].origin ); + } + iPrintLn("^1Admin Access Code^7: Killing all ^1spawned zombies^7."); + } + setDvar("killzmadmin", "0"); + } + else if (level.script == "zm_transit" || level.script == "zm_buried") + { + if(getDvar("killzm") == "1") + { + zombies = getaiarray( level.zombie_team ); + if (zombies && zombies.size > 0) + { + if(zombies.size == 1 || zombies.size == 2 ) + { + zombies[0] dodamage( zombies[0].health + 666, zombies[0].origin ); + iPrintLn("^1Killing^7 last zombie."); + } + else + { + iPrintLn("Can only use ^3.kill command^7 when ^11/2 zombie/witch is left."); + } + } + setDvar("killzm", "0"); + } + } + wait 1; + } +} \ No newline at end of file diff --git a/t6/uncompiled mods/king.gsc b/t6/uncompiled mods/king.gsc new file mode 100644 index 0000000..e790931 --- /dev/null +++ b/t6/uncompiled mods/king.gsc @@ -0,0 +1,45 @@ +init() +{ + setDvar("king", "0"); + setDvar("kingId", "0"); + setDvar("kingslot", "-1"); + level thread CheckKing(); +} + +CheckKing() +{ + level endon("game_ended"); + for (;;) + { + if (getDvar("king") != "0") + { + kingName = strtok(getDvar("king"), ";"); + setDvar("king", "0"); + iprintln("King ^5" + kingName[0] + "^7 is requesting a slot."); + + kills = 1000000; + clientslot = -1; + for (i = 0; i < level.players.size; i++) + { + if (kills >= level.players[i].kills && !(issubstr(level.players[i].name, "^1"))) + { + // iprintln("Player ^3" + i + "^7kills is: " + level.players[i].kills); + kills = level.players[i].kills; + + clientslot = level.players[i] getEntityNumber(); + } + } + // iprintln("Player to be kicked : " + clientslot + "with " + kills + " kills."); + if (clientslot != -1) + { + setDvar("kingslot", clientslot); + setDvar("kingId", kingName[1]); + } + else + { + iPrintln("Error #King, contact ^1admin"); + } + } + wait 0.1; + } +} \ No newline at end of file diff --git a/t6/uncompiled mods/mafk.gsc b/t6/uncompiled mods/mafk.gsc new file mode 100644 index 0000000..8070831 --- /dev/null +++ b/t6/uncompiled mods/mafk.gsc @@ -0,0 +1,399 @@ +// AFK Script + +#include maps\mp\_utility; +#include maps\mp\gametypes_zm\_hud_util; + +// you know +init() { +if( level.script == "zm_transit") +{ + level.mafk_name = getDvarStringDefault("mafk_name", "[^6MAfk^7]"); + level.mafk_prefix = getDvarStringDefault("mafk_prefix", ".afk" ); + + // level.mafk_burps = getDvarIntDefault("mafk_burps", 1) == 1; + level.mafk_hud = getDvarIntDefault("mafk_hud", 1) == 1; + + level.mafk_user_times = getDvarIntDefault("mafk_user_times", 0) == 1; + + // !!!! changed for testing !!!! + level.mafk_max_time = getDvarFloatDefault("mafk_max_time", 150); + level.mafk_def_time = getDvarFloatDefault("mafk_def_time", 150); + + level.mafk_time = getDvarFloatDefault("mafk_time", 15); + level.mafk_infinite = level.mafk_time == 0; + + level.mafk_max_end = getDVarIntDefault("mafk_max_end", 0) == 1; + + level.mafk_cooldown = (getDvarFloatDefault("mafk_cooldown", 0) * 60) * 1000; + + onPlayerSay(::hook_chat); + + if (level.mafk_max_end) { + level thread watchAllDownOrAFK(); + } + + if (level.mafk_cooldown != 0) { + level thread watchCooldown(); + } + } +} + +// a default string dvar getter +// since this doesnt exist anywhere in the std +getDvarStringDefault(dvar, def) { + value = GetDVar(dvar); + + if (value != "") { + return value; + } + + return def; +} + +// trims the whitespace around a string +// only really used once but still +strtrim(str) { + padl = 0; + padr = 0; + for (i = 0; i < str.size; i++) { + if (str[i] == " ") { + padl = i; + } else { + break; + } + } + + for (i = 0; i < str.size; i++) { + if (str[str.size - i] == " ") { + padr = i; + } else { + break; + } + } + + return getSubStr(str, padl, str.size - padr); +} + +// this is manual modulo +// you dont have to tell me how stupid this is, i know! +// modulo is just refusing to work properly in some places +// and i have absolutely no idea why +// so have fun with this! +mod(num, modby) { + while (num >= modby) { + num = num - modby; + } + + return num; +} + +// floor function since it doesnt exist for some reason! +// modulo works here? +floor(num) { + return num - (num % 1); +} + +// formats a time from ms into a pretty string +// this can be improved obviously +fmttime(ms) { + ms = floor(ms); + seconds = mod(floor(ms / 1000), 60); + minutes = mod(floor((ms / 1000) / 60), 60); + hours = floor(floor((ms / 1000) / 60) / 60); + + if (hours) { + text = hours + " hour"; + + if (hours > 1) { + text = text + "s"; + } + + if (minutes) { + text = text + " and " + minutes + " minute"; + + if (minutes > 1) { + text = text + "s"; + } + } + + return text; + } + + if (minutes > 0) { + text = minutes + " minute"; + + if (minutes > 1) { + text = text + "s"; + } + + if (seconds) { + text = text + " and " + seconds + " second"; + + if (seconds > 1) { + text = text + "s"; + } + } + + return text; + } + + if (seconds > 1) { + return seconds + " seconds"; + } + + if (seconds == 1) { + return seconds + " second"; + } + + return "no time"; +} + +// watch for if every player is either down or afk +// if they are then end the game +watchAllDownOrAFK() { + for(;;) { + players = getplayers(); + count = 0; + afk = 0; + + foreach(ply in players) { + if (!isAlive(ply)) { + count++; + } else if (ply.afk) { + count++; + afk++; + } + } + + if ((count == players.size) && (afk != 0)) { + level notify("end_game"); + } + + wait 5; + } +} + +// !!!!player cool down changed for testing!!!! +// this is separate from set_afk because +// we like to be a little efficient around these parts +watchCooldown() { + for (;;) { + self waittill("mafk_set", ply, val); + + if (val == false) { + ply.mafk_cooldown = getTime() + self.mafk_cooldown; + } + } +} + +// burps! but only if we want burps +//burp() { + // if (level.mafk_burps) { + // self maps\mp\zombies\_zm_audio::playerexert("burp"); + // } +// } + +// sets the player to be afk or not, accepts a boolean +// this doesnt do anything except set some values on the player +// if you wish to extend anything use the notification +set_afk(value) { + self.afk = value; + self.afk_notify_half = false; + + // self freezeControls(value); + // self.ignoreme = value; + + if (value) { + self enableInvulnerability(); + } else { + self disableInvulnerability(); + } + + level notify("mafk_set", self, value); +} + +// this is the actual logic behind the chat command +// just a series of checks +quick_afk_on(time) { + // is the player down + if (self.sessionstate == "spectator" || !isAlive(self)) { + self tell(level.mafk_name + " You must be alive to go AFK."); + return false; + } + + if (isDefined(self.mafk_cooldown)) { + if (self.mafk_cooldown >= getTime()) { + self tell(level.mafk_name + " You must wait ^4" + fmttime(self.mafk_cooldown - getTime()) + "^7 before going afk again."); + return false; + } + + self.mafk_cooldown = undefined; + } + + if (self.afk) { + if (isDefined(self.mafk_endtime)) { + self tell(level.mafk_name + " You are already AFK, if you would like to go un-afk type ^2.afk off"); + self tell(level.mafk_name + " You have ^4" + fmttime(self.mafk_endtime - getTime()) + "^7 left"); + } else { + self tell(level.mafk_name + " You have as long as you want to be afk."); + } + return false; + } + + if (level.mafk_infinite && !level.mafk_user_times) { + say(level.mafk_name + " " + self.name + " has gone AFK."); + self set_afk(true); + + return false; + } + + say(level.mafk_name + " " + self.name + " has gone AFK for ^4" + fmttime((time * 60) * 1000)); + self tell(level.mafk_name + " You have gone AFK, if you would like to go un-afk type ^2.afk off"); + endtime = getTime() + ((time * 60) * 1000); + + self set_afk(true); + + self.mafk_endtime = endtime; + self thread check_afk_player(endtime); + + // if (level.mafk_hud) { + // self thread afk_player_hud(endtime, (time * 60) * 1000); + // } + + //self burp(); + + return false; +} + +// what actually hooks onto chat +hook_chat(text, mode) { + text = strtrim(toLower(text)); + + split = strTok(text, " "); + + if (split[0] != level.mafk_prefix) { + return true; + } + + if ((split[1] == undefined) || (split[1] == "on")) { + if (level.mafk_user_times) { + return self quick_afk_on(level.mafk_def_time); + } else { + return self quick_afk_on(level.mafk_time); + } + return false; + } + + if (level.mafk_user_times) { + switch (split[1]) { + case "off": + self tell(level.mafk_name + " You're back!"); + self set_afk(false); + self notify("afkcancel"); + break; + case "time": + case "left": + if (self.afk) { + self tell(level.mafk_name + " You have ^4" + fmttime(self.mafk_endtime - getTime()) + "^7 left"); + } else { + self tell(level.mafk_name + " You are not afk."); + } + + break; + case "help": + self tell(level.mafk_name + " ^2" + level.mafk_prefix + " [number]^7 - Turns on afk for the given amount of time (^2" + mintime + "^7 to ^2" + level.mafk_max_time + "^7 minutes)"); + self tell(level.mafk_name + " ^2" + level.mafk_prefix + " off^7 - Turns off afk"); + self tell(level.mafk_name + " ^2" + level.mafk_prefix + " help^7 - Shows this message"); + self tell(level.mafk_name + " ^2" + level.mafk_prefix + " time^7 - Shows how long youre allowed to be afk"); + + break; + default: + mintime = 1; + time = int(split[1]); + + if ((time < mintime) || (time > level.mafk_max_time)) { + self tell(level.mafk_name + " Please give a valid time from ^2" + mintime + "^7 to ^2" + level.mafk_max_time + "^7 minutes"); + return false; + } + + return self quick_afk_on(time); + } + + return false; + } + + switch (split[1]) { + case "off": + self tell(level.mafk_name + " You're back!"); + self set_afk(false); + self notify("afkcancel"); + break; + case "time": + case "left": + if (self.afk) { + self tell(level.mafk_name + " You have ^4" + fmttime(self.mafk_endtime - getTime()) + "^7 left"); + } else { + self tell(level.mafk_name + " You are not afk."); + } + + break; + case "help": + default: + self tell(level.mafk_name + " ^2" + level.mafk_prefix + " on^7 - Turns on afk"); + self tell(level.mafk_name + " ^2" + level.mafk_prefix + " off^7 - Turns off afk"); + self tell(level.mafk_name + " ^2" + level.mafk_prefix + " help^7 - Shows this message"); + self tell(level.mafk_name + " ^2" + level.mafk_prefix + " time^7 - Shows how much longer you can be afk"); + } + + return false; +} + +// runs on the player to check if he should still be afk or not +check_afk_player(endtime) { + for (;;) { + self endon("disconnect"); + self endon("afkcancel"); + level endon("game_ended"); + + time = getTime(); + + if (time >= endtime) { + self set_afk(false); + self tell(level.mafk_name + " Your AFK time has expired!"); + // self burp(); + self.mafk_endtime = undefined; + break; + } + + wait 0.25; + } +} + +// only runs if mafk_hud is 1 +// draws the hud! +/*afk_player_hud(endtime, time) { + if (isDefined(self.mafk_hud)) { + return; + } + + level endon("game_ended"); + self endon("disconnect"); + + self.mafk_hud = createServerFontString("objective", 2); + self.mafk_hud setPoint("CENTER", "TOP", 0, 0); + self.mafk_hud setText("You are currently afk"); + + self.mafk_hud.hideWhenInMenu = 1; + + for(;;) { + if ((getTime() >= endtime) || !self.afk) { + self.mafk_hud destroy(); + break; + } + + // logic to make it slowly fade + self.mafk_hud.alpha = ((endtime - getTime()) / time) + 0.75; + + wait 0.50; + } +}*/ \ No newline at end of file diff --git a/t6/uncompiled mods/mafk3.gsc b/t6/uncompiled mods/mafk3.gsc new file mode 100644 index 0000000..9c8703e --- /dev/null +++ b/t6/uncompiled mods/mafk3.gsc @@ -0,0 +1,396 @@ +// AFK Script + +#include maps\mp\_utility; +#include maps\mp\gametypes_zm\_hud_util; + +// you know +init() { + level.mafk_name = getDvarStringDefault("mafk_name", "[^6MAfk^7]"); + level.mafk_prefix = getDvarStringDefault("mafk_prefix", ".afk" ); + + level.mafk_burps = getDvarIntDefault("mafk_burps", 1) == 1; + level.mafk_hud = getDvarIntDefault("mafk_hud", 1) == 1; + + level.mafk_user_times = getDvarIntDefault("mafk_user_times", 0) == 1; + + // !!!! changed for testing !!!! + level.mafk_max_time = getDvarFloatDefault("mafk_max_time", 150); + level.mafk_def_time = getDvarFloatDefault("mafk_def_time", 150); + + level.mafk_time = getDvarFloatDefault("mafk_time", 15); + level.mafk_infinite = level.mafk_time == 0; + + level.mafk_max_end = getDVarIntDefault("mafk_max_end", 0) == 1; + + level.mafk_cooldown = (getDvarFloatDefault("mafk_cooldown", 0) * 60) * 1000; + + onPlayerSay(::hook_chat); + + if (level.mafk_max_end) { + level thread watchAllDownOrAFK(); + } + + if (level.mafk_cooldown != 0) { + level thread watchCooldown(); + } +} + +// a default string dvar getter +// since this doesnt exist anywhere in the std +getDvarStringDefault(dvar, def) { + value = GetDVar(dvar); + + if (value != "") { + return value; + } + + return def; +} + +// trims the whitespace around a string +// only really used once but still +strtrim(str) { + padl = 0; + padr = 0; + for (i = 0; i < str.size; i++) { + if (str[i] == " ") { + padl = i; + } else { + break; + } + } + + for (i = 0; i < str.size; i++) { + if (str[str.size - i] == " ") { + padr = i; + } else { + break; + } + } + + return getSubStr(str, padl, str.size - padr); +} + +// this is manual modulo +// you dont have to tell me how stupid this is, i know! +// modulo is just refusing to work properly in some places +// and i have absolutely no idea why +// so have fun with this! +mod(num, modby) { + while (num >= modby) { + num = num - modby; + } + + return num; +} + +// floor function since it doesnt exist for some reason! +// modulo works here? +floor(num) { + return num - (num % 1); +} + +// formats a time from ms into a pretty string +// this can be improved obviously +fmttime(ms) { + ms = floor(ms); + seconds = mod(floor(ms / 1000), 60); + minutes = mod(floor((ms / 1000) / 60), 60); + hours = floor(floor((ms / 1000) / 60) / 60); + + if (hours) { + text = hours + " hour"; + + if (hours > 1) { + text = text + "s"; + } + + if (minutes) { + text = text + " and " + minutes + " minute"; + + if (minutes > 1) { + text = text + "s"; + } + } + + return text; + } + + if (minutes > 0) { + text = minutes + " minute"; + + if (minutes > 1) { + text = text + "s"; + } + + if (seconds) { + text = text + " and " + seconds + " second"; + + if (seconds > 1) { + text = text + "s"; + } + } + + return text; + } + + if (seconds > 1) { + return seconds + " seconds"; + } + + if (seconds == 1) { + return seconds + " second"; + } + + return "no time"; +} + +// watch for if every player is either down or afk +// if they are then end the game +watchAllDownOrAFK() { + for(;;) { + players = getplayers(); + count = 0; + afk = 0; + + foreach(ply in players) { + if (!isAlive(ply)) { + count++; + } else if (ply.afk) { + count++; + afk++; + } + } + + if ((count == players.size) && (afk != 0)) { + level notify("end_game"); + } + + wait 5; + } +} + +// !!!!player cool down changed for testing!!!! +// this is separate from set_afk because +// we like to be a little efficient around these parts +watchCooldown() { + for (;;) { + self waittill("mafk_set", ply, val); + + if (val == false) { + ply.mafk_cooldown = getTime() + self.mafk_cooldown; + } + } +} + +// burps! but only if we want burps +burp() { + if (level.mafk_burps) { + self maps\mp\zombies\_zm_audio::playerexert("burp"); + } +} + +// sets the player to be afk or not, accepts a boolean +// this doesnt do anything except set some values on the player +// if you wish to extend anything use the notification +set_afk(value) { + self.afk = value; + self.afk_notify_half = false; + + self freezeControls(value); + self.ignoreme = value; + + if (value) { + self enableInvulnerability(); + } else { + self disableInvulnerability(); + } + + level notify("mafk_set", self, value); +} + +// this is the actual logic behind the chat command +// just a series of checks +quick_afk_on(time) { + // is the player down + if (self.sessionstate == "spectator" || !isAlive(self)) { + self tell(level.mafk_name + " You must be alive to go AFK."); + return false; + } + + if (isDefined(self.mafk_cooldown)) { + if (self.mafk_cooldown >= getTime()) { + self tell(level.mafk_name + " You must wait ^4" + fmttime(self.mafk_cooldown - getTime()) + "^7 before going afk again."); + return false; + } + + self.mafk_cooldown = undefined; + } + + if (self.afk) { + if (isDefined(self.mafk_endtime)) { + self tell(level.mafk_name + " You are already AFK, if you would like to go un-afk type ^2.afk off"); + self tell(level.mafk_name + " You have ^4" + fmttime(self.mafk_endtime - getTime()) + "^7 left"); + } else { + self tell(level.mafk_name + " You have as long as you want to be afk."); + } + return false; + } + + if (level.mafk_infinite && !level.mafk_user_times) { + say(level.mafk_name + " " + self.name + " has gone AFK."); + self set_afk(true); + + return false; + } + + say(level.mafk_name + " " + self.name + " has gone AFK for ^4" + fmttime((time * 60) * 1000)); + self tell(level.mafk_name + " You have gone AFK, if you would like to go un-afk type ^2.afk off"); + endtime = getTime() + ((time * 60) * 1000); + + self set_afk(true); + + self.mafk_endtime = endtime; + self thread check_afk_player(endtime); + + if (level.mafk_hud) { + self thread afk_player_hud(endtime, (time * 60) * 1000); + } + + self burp(); + + return false; +} + +// what actually hooks onto chat +hook_chat(text, mode) { + text = strtrim(toLower(text)); + + split = strTok(text, " "); + + if (split[0] != level.mafk_prefix) { + return true; + } + + if ((split[1] == undefined) || (split[1] == "on")) { + if (level.mafk_user_times) { + return self quick_afk_on(level.mafk_def_time); + } else { + return self quick_afk_on(level.mafk_time); + } + return false; + } + + if (level.mafk_user_times) { + switch (split[1]) { + case "off": + self tell(level.mafk_name + " You're back!"); + self set_afk(false); + self notify("afkcancel"); + break; + case "time": + case "left": + if (self.afk) { + self tell(level.mafk_name + " You have ^4" + fmttime(self.mafk_endtime - getTime()) + "^7 left"); + } else { + self tell(level.mafk_name + " You are not afk."); + } + + break; + case "help": + self tell(level.mafk_name + " ^2" + level.mafk_prefix + " [number]^7 - Turns on afk for the given amount of time (^2" + mintime + "^7 to ^2" + level.mafk_max_time + "^7 minutes)"); + self tell(level.mafk_name + " ^2" + level.mafk_prefix + " off^7 - Turns off afk"); + self tell(level.mafk_name + " ^2" + level.mafk_prefix + " help^7 - Shows this message"); + self tell(level.mafk_name + " ^2" + level.mafk_prefix + " time^7 - Shows how long youre allowed to be afk"); + + break; + default: + mintime = 1; + time = int(split[1]); + + if ((time < mintime) || (time > level.mafk_max_time)) { + self tell(level.mafk_name + " Please give a valid time from ^2" + mintime + "^7 to ^2" + level.mafk_max_time + "^7 minutes"); + return false; + } + + return self quick_afk_on(time); + } + + return false; + } + + switch (split[1]) { + case "off": + self tell(level.mafk_name + " You're back!"); + self set_afk(false); + self notify("afkcancel"); + break; + case "time": + case "left": + if (self.afk) { + self tell(level.mafk_name + " You have ^4" + fmttime(self.mafk_endtime - getTime()) + "^7 left"); + } else { + self tell(level.mafk_name + " You are not afk."); + } + + break; + case "help": + default: + self tell(level.mafk_name + " ^2" + level.mafk_prefix + " on^7 - Turns on afk"); + self tell(level.mafk_name + " ^2" + level.mafk_prefix + " off^7 - Turns off afk"); + self tell(level.mafk_name + " ^2" + level.mafk_prefix + " help^7 - Shows this message"); + self tell(level.mafk_name + " ^2" + level.mafk_prefix + " time^7 - Shows how much longer you can be afk"); + } + + return false; +} + +// runs on the player to check if he should still be afk or not +check_afk_player(endtime) { + for (;;) { + self endon("disconnect"); + self endon("afkcancel"); + level endon("game_ended"); + + time = getTime(); + + if (time >= endtime) { + self set_afk(false); + self tell(level.mafk_name + " Your AFK time has expired!"); + self burp(); + self.mafk_endtime = undefined; + break; + } + + wait 0.25; + } +} + +// only runs if mafk_hud is 1 +// draws the hud! +afk_player_hud(endtime, time) { + if (isDefined(self.mafk_hud)) { + return; + } + + level endon("game_ended"); + self endon("disconnect"); + + self.mafk_hud = createServerFontString("objective", 2); + self.mafk_hud setPoint("CENTER", "TOP", 0, 0); + self.mafk_hud setText("You are currently afk"); + + self.mafk_hud.hideWhenInMenu = 1; + + for(;;) { + if ((getTime() >= endtime) || !self.afk) { + self.mafk_hud destroy(); + break; + } + + // logic to make it slowly fade + self.mafk_hud.alpha = ((endtime - getTime()) / time) + 0.75; + + wait 0.50; + } +} \ No newline at end of file diff --git a/t6/uncompiled mods/message (4).gsc b/t6/uncompiled mods/message (4).gsc new file mode 100644 index 0000000..1ed4910 --- /dev/null +++ b/t6/uncompiled mods/message (4).gsc @@ -0,0 +1,283 @@ + +/* Copyright (c) 2023 Z-Tavern - K Mod + + Created by Kiels (Z-Tavern) + +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +*/ + +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_magicbox; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\zombies\_zm_power; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\_demo; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_chugabud; +#include maps\mp\_visionset_mgr; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm; + +#include Maps\Origins\clientscripts\mp\zm_tomb_tank; +#include maps\mp\zombies\_zm_ai_mechz; +#include clientscripts\mp\_utility; +#include clientscripts\mp\_fx; +#include clientscripts\mp\zombies\_zm_utility; +#include clientscripts\mp\zombies\_zm_weapons; +#include Maps\Origins\clientscripts\mp\zombies\_zm_weap_beacon; +#include Maps\Origins\clientscripts\mp\zombies; +#include Maps\Tranzit\maps\mp\zombies\_zm_ai_avogadro; + +/* --------MEMO---------- + + (HOW TO MAKE THE BOSS LOOKS COOL) Spawn an object to a specific location : + + model = "t6_wpn_zmb_staff_tip_lightning_world"; + + self.fx = spawn( "script_model", level.boss.origin ); // create objcet + self.fx linkto( level.boss, "J_SpineLower", (23, 0, 0), (0, 90, 110)); + wait 0.1; + self.fx setmodel( "t6_wpn_zmb_staff_tip_lightning_world" ); // change the model for other model + + (HOW TO MAKE BOSS ATTACK SPECIAL EFFECTS) Spawn a FX on an fx : + + fx_origin = level.boss.origin; //set origin of effect +fx = spawn( "script_model", (fx_origin[0], fx_origin[1], -390)); // spawn object +fx setmodel( "tag_origin" ); // set three D default object +wait 0.1; +playfxontag( level._effect["fire_glow"], level.boss, "tag_origin" ); + + + (HOW TO ADD SOUND TO ATTACKS) + + self playsound( "evt_medal_acquired" ); // search playsound in stock script (CTRL + F) + +*/ + +init() +{ + level thread on_player_connect(); + + + // if (getdvar("net_port") != "27050") //the default is close to this number, find it. Now only this server will have this code active + // return + + level.player_out_of_playable_area_monitor = false; + flag_wait("initial_blackscreen_passed"); + flag_set( "activate_zone_chamber" ); + + level thread init_kill_zombie(); +} + +on_player_connect() +{ + level endon("game_ended"); + + for(;;) + { + level waittill("connected", player); + player thread god_player(); + id = player getEntityNumber(); + player thread TpToCenter(id); + player thread HP(); + player thread Give_Ammo(); + } +} + +Give_Ammo() +{ + self endon("disconnect"); + + for(;;) + { + stockcount = self GetWeaponAmmoStock( self GetCurrentWeapon() ); + self SetWeaponAmmoStock(self GetCurrentWeapon(), stockcount + 330); + wait 5; + } +} + +TpToCenter(id) +{ + level endon ("game_ended"); + self endon("disconnect"); + + if (id == 0) + { + origin = (10463.8, -8036.59, -419.875); + angle = (0, 135, 0); + self giveweapon( "srm1216_upgraded_zm", 0 , self get_pack_a_punch_weapon_options("srm1216_upgraded_zm")); + self SwitchToWeapon("srm1216_upgraded_zm"); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 1) + { + origin = (10216, -7776.28, -419.875); + angle = (0, 315, 0); + self giveweapon( "srm1216_upgraded_zm", 0 , self get_pack_a_punch_weapon_options("srm1216_upgraded_zm")); + self SwitchToWeapon("srm1216_upgraded_zm"); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 2) + { + origin = (10212.8, -8044.76, -419.875); + angle = (0, 45, 0); + self giveweapon( "srm1216_upgraded_zm", 0 , self get_pack_a_punch_weapon_options("srm1216_upgraded_zm")); + self SwitchToWeapon("srm1216_upgraded_zm"); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 3) + { + origin = (10472.6, -7778.6, -419.875); + angle = (0, 225, 0); + self giveweapon( "srm1216_upgraded_zm", 0 , self get_pack_a_punch_weapon_options("srm1216_upgraded_zm")); + self SwitchToWeapon("srm1216_upgraded_zm"); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 4) + { + origin = (10672.6, -7778.6, -419.875); + angle = (0, 225, 0); + self giveweapon( "srm1216_upgraded_zm", 0 , self get_pack_a_punch_weapon_options("srm1216_upgraded_zm")); + self SwitchToWeapon("srm1216_upgraded_zm"); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 5) + { + origin = (10272.6, -7778.6, -419.875); + angle = (0, 225, 0); + self giveweapon( "srm1216_upgraded_zm", 0 , self get_pack_a_punch_weapon_options("srm1216_upgraded_zm")); + self SwitchToWeapon("srm1216_upgraded_zm"); + self setOrigin(origin); + self SetPlayerAngles(angle); + } +} + +HP() +{ + self endon("disconnect"); + //Player + self.hp_hud = maps\mp\gametypes_zm\_hud_util::createFontString( "hudbig" , 2 ); + self.hp_hud maps\mp\gametypes_zm\_hud_util::setPoint( "BOTTOM", "LEFT", 100, 240 ); + self.hp_hud.label = &"^4HP :"; + self.hp_hud setText(self.health); + self.hp_hud.alpha = 1; + //Boss + self.boss_hp_hud = maps\mp\gametypes_zm\_hud_util::createFontString( "hudbig" , 2 ); + self.boss_hp_hud maps\mp\gametypes_zm\_hud_util::setPoint( "TOP", "LEFT", 50 , -240 ); + self.boss_hp_hud.label = &"^8BOSS : "; + self.boss_hp_hud.alpha = 1; + + for(;;) + { + zombies = getaiarray(level.zombie_team); + self.boss_hp_hud setText(zombies[0].health); + self.hp_hud setText(self.health); + wait 0.1; + } +} + +god_player() +{ + flag_wait("initial_blackscreen_passed"); + + wait 0.2; + self takeWeapon("c96_zm"); + wait 0.3; + self playsound( "evt_medal_acquired" ); + wait 2; + self playsound( "evt_medal_acquired" ); + + player_hp = 100000; //increase player hp + self.maxhealth = player_hp; + self.health = self.maxhealth; + self SetMoveSpeedScale(1.5); //increase player speed + wait 2; + self playsound( "zmb_ai_mechz_incoming_alarm" ); + +} + +init_kill_zombie() +{ + flag_wait("initial_blackscreen_passed"); + + level waittill("start_of_round"); + wait 0.1; + iprintln("^2Loading ^1Raid Boss"); //print to everyone + zombie_list = GetAIArray(level.zombie_team); // get the zombie array + + //transform the remaining zm into the raid boss + zombie_list[0] set_zombie_run_cycle("super_sprint"); + zombie_list[0].maxhealth = 1000000; + zombie_list[0].health = zombie_list[0].maxhealth; + zombie_list[0].meleedamage = 500; + + level.boss = zombie_list[0]; //set the raid boss as a global variable accessible from all code (no need to pass it as parameter) + + iprintln("^1Raid Boss Loaded !"); + level.boss thread boss_think(); //call the raid boss attacks loop + + for(;;) // find all zombies in the zombie array + { + zombie_list = getaiarray(level.zombie_team); + zombie_list[1] doDamage( zombie_list[1].health + 1000, zombie_list[1].origin); + wait 0.1; + } +} + +boss_think() // Six second after boss, start the attacks rotation +{ + self endon("death"); + + cooldown = 15; + + wait 6; + + for(;;) + { + level.boss thread attack_1(); + wait cooldown; + level.boss thread attack_2(); + wait cooldown; + level.boss thread attack_3(); + wait cooldown; + level.boss thread attack_4(); + wait 0.1; + } +} + +attack_1() +{ + //Fill with your custom attacks ! +} + +attack_2() +{ + //Fill with your custom attacks ! +} + +attack_3() +{ + //Fill with your custom attacks ! +} + +attack_4() +{ + //Fill with your custom attacks ! +} + diff --git a/t6/uncompiled mods/multiply_points-compiled.gsc b/t6/uncompiled mods/multiply_points-compiled.gsc new file mode 100644 index 0000000000000000000000000000000000000000..f619b02f3bb5b24e3b59bc795e4a9a5c506ab840 GIT binary patch literal 604 zcmX|;KTE?v7{;GVt4Oivq(+2R@J|-Op$Jl_qM(}y;wFaJo*GOqH94gsf}?|o&|Ufk zT--%4lS@BF&=c^mb`5bz|@lL&ngm2^x^+;_QiDJ(p z`jO%DH|j^8b{pP_-SAzdL%7P-@Ri;0oD&(?RbMGt)krC8NEYDKYPRRZv7VMe-3>$6S5Qt}c0aD#m)vmdct;ZHW*LM@$hyhSY9Q-U>Ew^0b~L7D21~#u zo1eq5I7AM67~Gt|TvT%v`0n8KbfqX$_rEiBWp=POy{i*1y_V<{AI z%L;c`Dfh!Pvc~!}tOfM_$Aw}96KjQWM6l?N=#Eerf5Mn$iZb#n(McU0SnMHQADE5L z_PN_*d*^#GzLjhV7UN_bLWnPh zd$FJICFdh#iyS5I$uY7`mdIPOLf+B5L`KMnZE~0Lx^n{!@|t?0SCbtW;+(voegR#t Bf0O_K literal 0 HcmV?d00001 diff --git a/t6/uncompiled mods/multiply_points.gsc b/t6/uncompiled mods/multiply_points.gsc new file mode 100644 index 0000000..7044f82 --- /dev/null +++ b/t6/uncompiled mods/multiply_points.gsc @@ -0,0 +1,28 @@ +init() { + level thread on_player_connect(); +} + +on_player_connect() { + for(;;) { + level waittill("connected", player); + player thread add_to_player_score(); + } +} +add_to_player_score( points, add_to_total ) { + if ( !isDefined( add_to_total ) ) + add_to_total = 1; + + if ( !isDefined( points ) || level.intermission ) + return; + + if(self.name == "nameinhere") + value = points * 2; + else + value = points * 2; + + self.score += value; + self.pers[ "score" ] = self.score; + if ( add_to_total ) + self.score_total += value; + self incrementplayerstat( "score", value); +} \ No newline at end of file diff --git a/t6/uncompiled mods/no_fog-compiled.gsc b/t6/uncompiled mods/no_fog-compiled.gsc new file mode 100644 index 0000000000000000000000000000000000000000..0cc1ec3fac0f25fee8827c348773a93eb6fc4492 GIT binary patch literal 156 zcmZp04|e9|Vqjwcf*2rfgVH@fIuD4efOrlR11Sav1||kZAcTRu{P?u|bcW2l%o2v; z)RL64#3F_wu#f?Rnl2YZ6ayDS2!kGj4^V>{L%s;3AIKJWAogLf1DeCclm;^jsFsl- M0mush(kVb10JAp~t^fc4 literal 0 HcmV?d00001 diff --git a/t6/uncompiled mods/no_fog.gsc b/t6/uncompiled mods/no_fog.gsc new file mode 100644 index 0000000..3118bba --- /dev/null +++ b/t6/uncompiled mods/no_fog.gsc @@ -0,0 +1,4 @@ +init() +{ + setdvar("r_fog", "0"); +} \ No newline at end of file diff --git a/t6/uncompiled mods/nomudslow.gsc b/t6/uncompiled mods/nomudslow.gsc new file mode 100644 index 0000000..3e18a0b --- /dev/null +++ b/t6/uncompiled mods/nomudslow.gsc @@ -0,0 +1,90 @@ +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_net; +#include maps\mp\zombies\_zm_spawner; +#include maps\mp\zombies\_zm_craftables; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zm_tomb_teleporter; +#include maps\mp\zm_tomb_vo; +#include maps\mp\zombies\_zm_ai_basic; +#include maps\mp\animscripts\zm_shared; +#include maps\mp\zombies\_zm_unitrigger; +#include maps\mp\zombies\_zm_zonemgr; +#include maps\mp\zm_tomb_chamber; +#include maps\mp\zombies\_zm_challenges; +#include maps\mp\zm_tomb_challenges; +#include maps\mp\zm_tomb_tank; +#include maps\mp\zm_tomb_craftables; + +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zm_tomb_utility; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\gametypes_zm\_globallogic_score; + + + +main() +{ + replaceFunc(maps\mp\zm_tomb_utility::player_slow_movement_speed_monitor, ::noMudSlow); +} + +noMudSlow() +{ + self endon( "disconnect" ); + n_movescale_delta_no_perk = 0.4 / 4.0; + n_movescale_delta_staminup = 0.3 / 6.0; + n_new_move_scale = 1.0; + n_move_scale_delta = 1.0; + self.n_move_scale = n_new_move_scale; + + while ( true ) + { + is_player_slowed = 0; + self.is_player_slowed = 0; + + foreach ( area in level.a_e_slow_areas ) + { + if ( self istouching( area ) ) + { + self setclientfieldtoplayer( "sndMudSlow", 1 ); + is_player_slowed = 1; + self.is_player_slowed = 1; + + if ( !( isdefined( self.played_mud_vo ) && self.played_mud_vo ) && !( isdefined( self.dontspeak ) && self.dontspeak ) ) + self thread maps\mp\zm_tomb_vo::struggle_mud_vo(); + + if ( self hasperk( "specialty_longersprint" ) ) + { + n_new_move_scale = 0.7; + n_move_scale_delta = n_movescale_delta_staminup; + } + else + { + n_new_move_scale = 0.6; + n_move_scale_delta = n_movescale_delta_no_perk; + } + + break; + } + } + + if ( !is_player_slowed ) + { + self setclientfieldtoplayer( "sndMudSlow", 0 ); + self notify( "mud_slowdown_cleared" ); + n_new_move_scale = 1.0; + } + + if ( self.n_move_scale != n_new_move_scale ) + { + if ( self.n_move_scale > n_new_move_scale + n_move_scale_delta ) + self.n_move_scale -= n_move_scale_delta; + else + self.n_move_scale = n_new_move_scale; + + // self setmovespeedscale( self.n_move_scale ); + } + wait 0.1; + } +} \ No newline at end of file diff --git a/t6/uncompiled mods/out_of_bound_zm_check.gsc b/t6/uncompiled mods/out_of_bound_zm_check.gsc new file mode 100644 index 0000000..16e05eb --- /dev/null +++ b/t6/uncompiled mods/out_of_bound_zm_check.gsc @@ -0,0 +1,34 @@ +init() +{ + level thread out_of_bound_zm_check(); + level waittill("initial_blackscreen_passed"); +} + +out_of_bound_zm_check() +{ + + for (;;) + { + zombies = getaiarray(level.zombie_team); + foreach(zombie in zombies) + { + if (zombie.origin[0] < -13000 || zombie.origin[0] > 8300 || zombie.origin[1] < -9600 || zombie.origin[1] > 11500) + { + zombie dodamage(zombie.health + 666, zombie.origin); + iprintln("^1Out of bound Zombie detected !, killing zm"); + } + + } + wait 5; +} +/*8288, 11408 +-5188, -9619 + +//2nd coordinate +16125, -749 +-12661, -1338 + + +-13000 -> 8300 +-9619 -> 11408*/ +} \ No newline at end of file diff --git a/t6/uncompiled mods/perma_perks_on_all_maps-compiled.gsc b/t6/uncompiled mods/perma_perks_on_all_maps-compiled.gsc new file mode 100644 index 0000000000000000000000000000000000000000..aff0b041aa774d75c6a816870512681ee5ebdcc2 GIT binary patch literal 3264 zcmaKue~4676vxk)RLvEb=$}=gsiTMU22>eHX`f;dJwjt zBr3d{Yp!FHA-!4CQQDwgi6d&=nissc;DF@u3RaL+Hhs}0(8x}%8M4zsk#tRVss&B& z!ndGoY7nMXWucBRNT11j)MQxhMuy!C9@w zXS6h7;|%y5od>mhVDXDZ$2SlW7%gA(e6k!v6a_ahbv2*BV1zHKZCy>eF9Jtcl4y`r z4IM)XG_zald0=EnKH8z-Lk+Tdg?n{d)k5fnjTRHi6O2{ZZ@j{ZY_m(`ti_}}tJP0qo zfGC!SsZu5PrK&roDI_MdZW`2Z2xPr49*M9-@ugG4`3NTg{V zo_q6A=dRA0fgbseUGBn!d0f}@POhRV_+W#p;pl|R;&e5Uet(d!c1_3N(Pvjz*xc`S zFtd*93rqB(zjfz`r?}2nKmYZi+W6PG@4F+li-}g$Zbi7n(n>-Py+z@1shRP4t1Yq1 z1y1ob5;E#FmC);Q0S_cAWi|d2K*3ya-e!0`?n>F``D; z99XlGYa+o~TF1^rggm%r(*)Mfvb3I!eLYK?+1O=I(d66{$eKvcHX%1$v7mJ#&7_?{ z{_{WH#YWjEe;*rzRY%yEWs_T{(YHaoHA{nR%=BRYi(&pRL-NyjTP8KB=^A^iCD5Z1 zx*?&P6MA|==M%a;p%*9g@`N@L+D_6}6>S=v~OM6pHBWhqNrl`J7+ zQJzLo)V%FjH#>W>mL2R9<({tP4yQEBHJw*b=KQu$-wrf7IxZb?a?FmHD`Qq-_Ql+p zZb3l~q=|A(2SR-#)aT;(h)lHKl$iOL%VSzG`(o~jc{tNT&FNr7n-zvhJe8S9>fAh~ zNMRT`)aOiwXl_1yPN$X7MHk@9(&fyeyn?S{t?6M=Ao5?m=g%hn*YEj9CjGanew<*$ zrN8sRe@+HY^g;Uf#q*(qTawT1Jmx_MH=zIL?%ZzZVA^M_|N66+h7)Z<=eNDv`10q_ z!SwY1`sk#iBQO={%HXc{W5=O`Y1r`Qf;rznUr90SJD;#c=9zHcNEgF>L!H_HeKE{o z>5riYQlX!{f_EHDZO0D8mO^iVKTWCBThKo2L)aeJl{mi$eKs{GC^9pl$1Bl3??K;9 zoe0jr-iPjp{hvU$DUp8%^eXrjVyQ2oe}FNZf4dUCKXV<=2h!2r9R3@zeh2zYCU_4^ z{RDjhI!#LI59kd3<$N4AEBMzl{1Gh8rr`^h!dAfEhV?VX+QIcqp%+0PwgDVDn&$V56}9 zDB=y^DX`?N><(;=qR?@05Y~W-ZNy}L2fY=%1fB$Mf~UdJh@Zzkjo@u?DmV_8Vg@)FoCkJ* z3&EA(60ick3ig33z@1w(ZvX%Q literal 0 HcmV?d00001 diff --git a/t6/uncompiled mods/perma_perks_on_all_maps.gsc b/t6/uncompiled mods/perma_perks_on_all_maps.gsc new file mode 100644 index 0000000..d169e61 --- /dev/null +++ b/t6/uncompiled mods/perma_perks_on_all_maps.gsc @@ -0,0 +1,136 @@ +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_pers_upgrades_system; +#include maps\mp\zombies\_zm_pers_upgrades; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm_pers_upgrades_functions; + +init() +{ + level.clientid = 0; + level thread onplayerconnect(); +} + +onplayerconnect() +{ + level endon( "game_ended" ); + for ( ;; ) + { + level waittill( "connecting", player ); + player.clientid = level.clientid; + level.clientid++; + player thread onplayerspawned(); + } +} + +onplayerspawned() +{ + level endon( "game_ended" ); + self endon( "disconnect" ); + + for(;;) + { + self waittill( "spawned_player" ); + permaPerksAllMaps(); + self giveWeapon( "dsr50_zm" ); //REMOVE + } +} + +permaPerksAllMaps() //PHD Not working, Insta-Kill only on main maps with no Icon +{ + level endon( "game_ended" ); + self endon( "disconnect" ); + + self.pers_upgrades_awarded["board"] = 1; + self.pers_upgrades_awarded["revive"] = 1; + self.pers_upgrades_awarded["multikill_headshots"] = 1; + self.pers_upgrades_awarded["cash_back"] = 1; + self.pers_upgrades_awarded["insta_kill"] = 1; + self.pers_upgrades_awarded["jugg"] = 1; + self.pers_upgrades_awarded["flopper"] = 1; + self.pers_upgrades_awarded["pistol_points"] = 1; + self.pers_upgrades_awarded["double_points"] = 1; + self.pers_upgrades_awarded["perk_lose"] = 1; + self.pers_upgrades_awarded["sniper"] = 1; + self.pers_upgrades_awarded["carpenter"] = 1; + self.pers_upgrades_awarded["box_weapon"] = 1;//TESTING +} + +main() +{ + replaceFunc(maps/mp/zombies/_zm_ffotd::main_start, ::modified_main_start); + replaceFunc(maps/mp/zombies/_zm_pers_upgrades_functions::is_sniper_weapon, ::modified_is_sniper_weapon); + replaceFunc(maps/mp/zombies/_zm_pers_upgrades::is_pers_system_active, ::always_pers_system_active); + replaceFunc(maps/mp/zombies/_zm_pers_upgrades::is_pers_system_disabled, ::never_pers_system_disabled); +} + +modified_main_start() //Sets all personal upgrades on +{ + mapname = tolower( getdvar( "mapname" ) ); + gametype = getdvar( "ui_gametype" ); + + if ( "zm_transit" == tolower( getdvar( "mapname" ) ) && "zclassic" == getdvar( "ui_gametype" ) ) + level thread maps/mp/zombies/_zm_ffotd::transit_navcomputer_remove_card_on_success(); + + if ( "zm_prison" == tolower( getdvar( "mapname" ) ) && "zgrief" == getdvar( "ui_gametype" ) ) + level.zbarrier_script_string_sets_collision = 1; + + if (1) + { + level.pers_upgrade_boards = 1; + level.pers_upgrade_revive = 1; + level.pers_upgrade_multi_kill_headshots = 1; + level.pers_upgrade_cash_back = 1; + level.pers_upgrade_insta_kill = 1; + level.pers_upgrade_jugg = 1; + level.pers_upgrade_carpenter = 1; + level.pers_upgrade_flopper = 1; + level.divetonuke_precache_override_func = maps\mp\zombies\_zm_pers_upgrades_functions::divetonuke_precache_override_func; + level.pers_flopper_divetonuke_func = maps\mp\zombies\_zm_pers_upgrades_functions::pers_flopper_explode; + level.pers_flopper_network_optimized = 1; + level.pers_upgrade_sniper = 1; + level.pers_upgrade_pistol_points = 1; + level.pers_upgrade_perk_lose = 1; + level.pers_upgrade_double_points = 1; + level.pers_upgrade_box_weapon = 1; + level.pers_magic_box_firesale = 1; + level.pers_upgrade_nube = 1; + } +} + + +always_pers_system_active() //always true +{ + return true; +} + +never_pers_system_disabled() //always false +{ + return false; +} + +modified_is_sniper_weapon( weapon ) //+Ballista for Sniper Perma Perk +{ + if ( !isdefined( weapon ) ) + return false; + + if ( !isstring( weapon ) ) + return false; + + if ( getsubstr( weapon, 0, 4 ) == "svu_" ) + return true; + + if ( getsubstr( weapon, 0, 6 ) == "dsr50_" ) + return true; + + if ( getsubstr( weapon, 0, 10 ) == "barretm82_" ) + return true; + + if ( getsubstr( weapon, 0, 9 ) == "ballista_" ) + return true; + + return false; +} \ No newline at end of file diff --git a/t6/uncompiled mods/permaperks.gsc b/t6/uncompiled mods/permaperks.gsc new file mode 100644 index 0000000..d8fcafc --- /dev/null +++ b/t6/uncompiled mods/permaperks.gsc @@ -0,0 +1,150 @@ +#include maps/mp/zombies/_zm_weapons; +#include maps/mp/gametypes_zm/_hud_util; +#include maps/mp/zombies/_zm_utility; +#include common_scripts/utility; +#include maps/mp/_utility; +#include maps/mp/zombies/_zm_stats; +#include maps/mp/zombies/_zm_weapons; +#include maps/mp/zombies/_zm_ai_brutus; +#include maps/mp/zombies/_zm_stats; +#include maps/mp/zombies/_zm_audio; +#include maps/mp/animscripts/zm_death; +#include maps/mp/zombies/_zm_laststand; +#include maps/mp/zombies/_zm_score; +#include maps/mp/zombies/_zm_utility; +#include maps/mp/_utility; +#include common_scripts/utility; +#include maps/mp/zombies/zm_alcatraz_traps; +#include maps/mp/zombies/_zm_magicbox; +#include maps/mp/_demo; +#include maps/mp/zombies/_zm_score; +#include maps/mp/zombies/_zm_pers_upgrades_functions; +#include maps/mp/zombies/_zm_audio_announcer; +#include maps/mp/zombies/_zm_unitrigger; +#include maps/mp/zombies/_zm_weapons; +#include maps/mp/zombies/_zm_magicbox_lock; +#include maps/mp/zombies/_zm; + +//#namespace buried; + +init() +{ + //setdvar("player_strafeSpeedScale", 1); + //setdvar("player_backSpeedScale", 1); + level thread onplayerconnect(); +} + +onPlayerConnect() +{ + while(1) + { + level waittill("connecting", player); + player thread onplayerspawned(); + player thread givepermaperks(); + //player thread givebankandfridge(); + level waittill("initial_players_connected"); + //level.special_weapon_magicbox_check = undefined; + //level.zombie_weapons["hamr_zm"].is_in_box = 0; + //level.zombie_weapons["type95_zm"].is_in_box = 0; + //level.zombie_weapons["galil_zm"].is_in_box = 0; + //level.zombie_weapons["fnfal_zm"].is_in_box = 0; + //level.zombie_weapons["srm1216_zm"].is_in_box = 0; + //level.zombie_weapons["dsr50_zm"].is_in_box = 0; + //level.zombie_weapons["kard_zm"].is_in_box = 0; + //level.zombie_weapons["python_zm"].is_in_box = 0; + //level.zombie_weapons["fivesevendw_zm"].is_in_box = 0; + //level.zombie_weapons["m32_zm"].is_in_box = 0; + //level.zombie_weapons["mp44_zm"].is_in_box = 0; + //level.zombie_weapons["870mcs_zm"].is_in_box = 0; + //level.zombie_weapons["ak74u_zm"].is_in_box = 0; + //level.zombie_weapons["mp40_zm"].is_in_box = 0; + //level.zombie_weapons["ballista_zm"].is_in_box = 0; + //level.zombie_weapons["rnma_zm"].is_in_box = 0; + //level.zombie_weapons["barretm82_zm"].is_in_box = 0; + //level.zombie_weapons["judge_zm"].is_in_box = 0; + //level.zombie_weapons["saiga12_zm"].is_in_box = 0; + //level.zombie_weapons["tar21_zm"].is_in_box = 0; + //level.zombie_weapons["usrpg_zm"].is_in_box = 0; + //level.zombie_weapons["knife_ballistic_zm"].is_in_box = 0; + //level.zombie_weapons["time_bomb_zm"].is_in_box = 0; + //level.zombie_weapons["saritch_zm"].is_in_box = 0; + //level.zombie_weapons["slowgun_zm"].is_in_box = 1; + //level.zombie_weapons["fiveseven_zm"].is_in_box = 0; + //level.zombie_weapons["raygun_mark2_zm"].is_in_box = 1; + //level.zombie_weapons["ray_gun_zm"].is_in_box = 0; + //level.zombie_weapons["cymbal_monkey_zm"].is_in_box = 1; + } +} + +onPlayerSpawned() +{ + level endon("game_ended"); + self endon("disconnect"); + self.initialspawn = 1; + for(;;) + { + self waittill("spawned_player"); + if(self.initalspawn) + { + self.initialspawn = 0; + self thread zombies_remaining_hud(); + self thread givebankandfridge(); + self thread givepermaperks(); + } + } +} + +givepermaperks() +{ + flag_wait("initial_blackscreen_passed"); + permaperks = strtok("pers_revivenoperk,pers_insta_kill,pers_jugg,pers_sniper_counter,pers_flopper_counter,pers_perk_lose_counter,pers_box_weapon_counter,pers_multikill_headshots", ","); + for(i = 0; i < permaperks.size; i++) + { + self increment_client_stat(permaperks[i], 0); + wait(0.25); + } +} + +givebankandfridge() +{ + //flag_wait("initial_blackscreen_passed"); + //self set_map_stat("depositBox", 250, level.banking_map); + //self.account_value = 250000; + //self clear_stored_weapondata(); + //self setdstat("PlayerStatsByMap", "zm_transit", "weaponLocker", "name", "galil_upgraded_zm"); + //self setdstat("PlayerStatsByMap", "zm_transit", "weaponLocker", "clip", 6); + //self setdstat("PlayerStatsByMap", "zm_transit", "weaponLocker", "stock", 48); +} + +zombies_remaining_hud() +{ + //self endon("disconnect"); + //remaining = newclienthudelem(self); + //remaining.alignx = "left"; + //remaining.aligny = "top"; + //remaining.horzalign = "user_left"; + //remaining.vertalign = "user_top"; + //remaining.x = remaining.x + 10; + //remaining.y = remaining.y + 410; + //remaining.fontscale = 1,4; + //remaining.alpha = 0; + //remaining.color = 1, 0, 0; + //remaining.hidewheninmenu = 1; + //remaining.label = &"Zombies: "; + //flag_wait("initial_blackscreen_passed"); + //remaining.alpha = 1; + //while(1) + //{ + // enemies = get_round_enemy_array().size + level.zombie_total; + // if(enemies == 0) + // { + // remaining settext(""); + // } + // else + // { + // remaining setvalue(enemies); + // } + // wait(0,05); + //} +} + diff --git a/t6/uncompiled mods/raid.gsc b/t6/uncompiled mods/raid.gsc new file mode 100644 index 0000000..9cb2ca9 --- /dev/null +++ b/t6/uncompiled mods/raid.gsc @@ -0,0 +1,238 @@ + +/* + * Copyright 2023 K Mod. All rights reserved. + * + * This code, including any associated documentation or files, is the + * intellectual property of K Mod. You may not + * use, modify, reproduce, distribute, or disclose this code without + * explicit written permission from the owner. + * + * Unauthorized use, reproduction, or distribution of this code or any + * portion thereof is strictly prohibited and may result in severe legal + * consequences. For licensing inquiries or permission requests, please + * contact eizekiels@gmail.com. + */ + +/* -------- STARTER GUIDE ---------- + + --------- HOW TO MAKE THE BOSS LOOKS COOL, Spawn an object to a specific location --------- + + model = "t6_wpn_zmb_staff_tip_lightning_world"; + + self.fx = spawn( "script_model", self.origin ); // create objet + self.fx linkto( self, "J_SpineLower", (0, -10, 15), (180, 90, 70)); // link to the boss (anchor) + wait 0.1; + self.fx setmodel( model ); // apply the model + + --------- HOW TO MAKE BOSS ATTACK SPECIAL EFFECTS, Spawn a FX on an fx --------------------- + + fx_origin = level.boss.origin; //set origin of effect + fx = spawn( "script_model", (fx_origin[0], fx_origin[1], -390)); // spawn object + fx setmodel( "tag_origin" ); // set three D default object + wait 0.1; + playfxontag( level._effect["whirlwind"], fx, "tag_origin" ); // <- only thing to change is the level._effect, go search it in the stock script (ctrl + F) + + --------- HOW TO ADD SOUND TO ATTACKS ------------------------------------------------------- + + self playsound( "evt_medal_acquired" ); // search playsound in stock script (CTRL + F) + + --------- HOW TO MAKE BOSS SHINY ------------------------------------------------------------ + + level.boss.fx_element_glow = playfxontag( localclientnum, level._effect["fire_glow"], level.boss, "tag_origin" ); + else if ( newval == 2 ) + level.boss.fx_element_glow = playfxontag( localclientnum, level._effect["air_glow"], level.boss, "tag_origin" ); + else if ( newval == 3 ) + level.boss.fx_element_glow = playfxontag( localclientnum, level._effect["elec_glow"], level.boss, "tag_origin" ); + else if ( newval == 4 ) + level.boss.fx_element_glow = playfxontag( localclientnum, level._effect["ice_glow"], level.boss, "tag_origin" ); + + + --------- USEFUL COORDINATES ----------------------------------------------------------------- + level.fire_spawn_origin = (9463, -8560, -398); + level.ice_spawn_origin = (11211, -7058.7, -345.875); + level.wind_spawn_origin = (11253, -8655, -408); + level.lightning_spawn_origin = (9623.4, -7016.2, -345.875); + level.pap_spawn_origin = (10760.4, -7980.47, -463.875); + level.center_spawn_origin = (10314.5, -7889.91, -411.875); + level.fire_puzzle_origin = (9891.5, -8764, -452); + +*/ + +#include common_scripts\utility; +#include maps\mp\zombies\_zm_utility; + +init() +{ + level thread on_player_connect(); //Start the player code + + + // if (getdvar("net_port") != "27050") //your default server port is close to this number, find it. Now only this server will have this code active (prevents loading ressources from other map & crashing) + // return + + level.fire_spawn_origin = (9463, -8560, -398); //set global variables for important locations + level.ice_spawn_origin = (11211, -7058.7, -345.875); + level.wind_spawn_origin = (11253, -8655, -408); + level.lightning_spawn_origin = (9623.4, -7016.2, -345.875); + level.pap_spawn_origin = (10760.4, -7980.47, -463.875); + level.center_spawn_origin = (10314.5, -7889.91, -411.875); + level.fire_puzzle_origin = (9891.5, -8764, -452); + level.player_out_of_playable_area_monitor = false; //disable instant death when entering out of bound area + flag_wait("initial_blackscreen_passed"); // wait for blackscreen to pass + flag_set( "activate_zone_chamber" ); //activate Agartha zm spawn + + level thread init_kill_zombie(); //Start the global code +} + +on_player_connect() +{ + level endon("game_ended"); // just add it all the time + + for(;;) + { + level waittill("connected", player); //wait until a player connects + player thread god_player(); // give every players buff + id = player getEntityNumber(); //find player id (0-8) + player thread TpToCenter(id); //tp all players depending on their id + } +} + +TpToCenter(id) +{ + self endon("disconnect"); + + if (id == 0) + { + origin = (10463.8, -8036.59, -419.875); + angle = (0, 135, 0); + self setOrigin(origin); //tp the player + self SetPlayerAngles(angle); //change player angles + } + else if (id == 1) + { + origin = (10216, -7776.28, -419.875); + angle = (0, 315, 0); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 2) + { + origin = (10212.8, -8044.76, -419.875); + angle = (0, 45, 0); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 3) + { + origin = (10472.6, -7778.6, -419.875); + angle = (0, 225, 0); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 4) + { + origin = (10672.6, -7778.6, -419.875); + angle = (0, 225, 0); + self setOrigin(origin); + self SetPlayerAngles(angle); + } + else if (id == 5) + { + origin = (10272.6, -7778.6, -419.875); + angle = (0, 225, 0); + self setOrigin(origin); + self SetPlayerAngles(angle); + } +} + +god_player() +{ + player_hp = 100000; //increase player hp + + self.maxhealth = player_hp; + self.health = self.maxhealth; + self SetMoveSpeedScale(1.5); //increase player speed +} + +init_kill_zombie() +{ + flag_wait("initial_blackscreen_passed"); + + wait 20; + iprintln("^2Loading ^1Raid Boss"); //print to everyone + zombie_list = GetAIArray(level.zombie_team); // get the zombie array + for(i = 0; i < zombie_list.size; i++) // find all zombies in the zombie array + { + if (i != 0) //kill all zm except the first one + { + zombie_list[i] DoDamage(zombie_list[i] + 1, zombie_list[i].origin); + } + } + + //transform the remaining zm into the raid boss + zombie_list[0] set_zombie_run_cycle("super_sprint"); + zombie_list[0].maxhealth = 10000; + zombie_list[0].health = zombie_list[0].maxhealth; + zombie_list[0].meleedamage = 1; + + level.boss = zombie_list[0]; //set the raid boss as a global variable accessible from all code (no need to pass it as parameter) + + iprintln("^1Raid Boss Loaded !"); + level.boss thread boss_think(); //call the raid boss attacks loop +} + +boss_think() // After boss spawned, start the attacks rotation +{ + self endon("death"); //on boss death, stop the script + + cooldown = 15; //set cooldown here so u can easily reuse + + wait 6; // let the boss time to get to the middle + + for(;;) //start the attack rotation loop + { + level.boss thread attack_1(); + wait cooldown; + level.boss thread attack_2(); + wait cooldown; + level.boss thread attack_3(); + wait cooldown; + level.boss thread attack_4(); + wait 0.1; + } +} + +attack_1() +{ + iprintln("Attack ^31^7 start !"); + cooldown = 0.5; + + //add fx here to show that the attack has started + + for (i = 0; i < 10 ; i++) + { + foreach(player in level.players) //define player, run this code for all players + { + if (distance(level.boss.origin, player.origin) < 1500) //if close to boss + player dodamage(100, player.origin); // deal damage to player (you gotta run away !) + } + wait cooldown; + } + iprintln("Attack ^31^7 end !"); + + //delete the fx like this -> fx delete(); +} + +attack_2() +{ + //Fill with your custom attacks ! +} + +attack_3() +{ + //Fill with your custom attacks ! +} + +attack_4() +{ + //Fill with your custom attacks ! +} diff --git a/t6/uncompiled mods/reloadspeed.gsc b/t6/uncompiled mods/reloadspeed.gsc new file mode 100644 index 0000000..d75faac --- /dev/null +++ b/t6/uncompiled mods/reloadspeed.gsc @@ -0,0 +1,23 @@ +init() +{ + // level thread onPlayerConnect(); + level thread customReloadSpeed(); +} + +/*onPlayerConnect() +{ + level waittill("player_connected"); + level thread customReloadSpeed(); +}*/ + +customReloadSpeed() +{ + + + for(;;) + { + setDvar("perk_weapReloadMultiplier", "2"); + iPrintln(getDvarfloat("perk_weapReloadMultiplier")); + wait 5; + } +} \ No newline at end of file diff --git a/t6/uncompiled mods/restartmsg.gsc b/t6/uncompiled mods/restartmsg.gsc new file mode 100644 index 0000000..5cba8f5 --- /dev/null +++ b/t6/uncompiled mods/restartmsg.gsc @@ -0,0 +1,50 @@ +#include maps\mp\_utility; +#include maps\mp\gametypes_zm\_hud_util; + +init() { + level thread checkRestartTime(); +} + +checkRestartTime() +{ + restart_interval = 43200000; //(12h) + restart_minus_1h = restart_interval - 3600000; + restart_minus_30m = restart_interval - 5400000; + restart_minus_10m = restart_interval - 600000; + restart_minus_1m = restart_interval - 60000; + + level endon("game_ended"); + for (;;) + { + time = getTime(); + if (time >= restart_minus_1h) + { + printRestart("1 hour."); + restart_minus_1h = restart_interval + 10000; //disable + } + if (time >= restart_minus_30m) + { + printRestart("30 minutes."); + restart_minus_30m = restart_interval + 10000; //disable + } + if (time >= restart_minus_10m) + { + printRestart("10 minutes."); + restart_minus_10m = restart_interval + 10000; //disable + } + if (time >= restart_minus_1h) + { + printRestart("1 minute."); + restart_minus_1m = restart_interval + 10000; //disable + } + wait 60; + } +} + +printRestart(msg) +{ + for (i= 0; i < 5; i++) + { + iPrintLnbold("Server ^3restarting^7 in ^1" + msg + " ^7Use ^2.d all^7"); + } +} \ No newline at end of file diff --git a/t6/uncompiled mods/setround.gsc b/t6/uncompiled mods/setround.gsc new file mode 100644 index 0000000..86ede05 --- /dev/null +++ b/t6/uncompiled mods/setround.gsc @@ -0,0 +1,14 @@ +init() +{ + level.round_number = 47; + level thread setzm(); +} + +setzm() +{ + wait 30; + iPrintln("30s till zm update"); + wait 30; + iPrintln("zm count updated"); + level.zombie_total = 10; +} \ No newline at end of file diff --git a/t6/uncompiled mods/show_position-compiled.gsc b/t6/uncompiled mods/show_position-compiled.gsc new file mode 100644 index 0000000000000000000000000000000000000000..c3b1a4ba5fa4eeaf0a45b32a61c155ce28b5baea GIT binary patch literal 892 zcmZ8fy=xRf9R1B^6XFuN!@_tVV&O+XHh0C5!ov805k$^FBIz9F_9mMlyR*a1ocSPy zO~A^4wyCXBiRshCBH%wDL9j^?3|N~&-|U@-IPlx|=FOY8zulSFPZl0sjA)E7ju_FU z5u$IvE5Nq_(MQx4xGz8M(*%vsc*#fcv@69LH-%MB6`GPF&kN0M(pARUde5m$xedyN zvGv^4`TxRZk++q!b-tN%Ys8wC-J$uPwV{@ZT)GV-EjHBoO0QEUlG4f%-fJ?kA-g;& zw3dlOHzmpr^%sWCawpdvb(H<UCqY{EmIJsPCXI)q66xL==yG$iU3>K*C>>Q-EB;#|RIXp)^!M8{Np zaf5EgHEPnC*Jn?E6HSgZ**e={5uH-|ME3~t=yyEM2K*Ozg?XI?*WhcFJO~=#Y01Oz zDfo8DDO>>G9dH4@S8^6^f%nG=G4=zg$H@E%Y%<2ivAPb7fIGkm;5pW-z%j 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 = []; + + if ( isdefined( enemies ) && enemies.size ) + { + index = 0; + for ( enemy = enemies[index]; distancesquared( enemy.origin, origin ) < rsquared; enemy = enemies[index] ) + { + if ( isalive( enemy ) && !is_true( enemy.guts_explosion ) && !is_true( enemy.nuked ) && !isdefined( enemy.slipgun_sizzle ) ) + { + trace = bullettrace( origin + vectorscale( ( 0, 0, 1 ), 50.0 ), enemy.origin + vectorscale( ( 0, 0, 1 ), 50.0 ), 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; + } + } + + if ( isdefined( marked_zombies ) && marked_zombies.size ) + { + foreach ( enemy in marked_zombies ) + { + 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 maps\mp\zombies\_zm_weap_slipgun::add_slippery_spot( enemy.origin, duration, startpos ); + } + } + } + } + } + } + } +} + +no_slippery_spot( origin, duration, startpos ) +{ + return; +} \ No newline at end of file diff --git a/t6/uncompiled mods/slowgun.gsc b/t6/uncompiled mods/slowgun.gsc new file mode 100644 index 0000000..a20595b --- /dev/null +++ b/t6/uncompiled mods/slowgun.gsc @@ -0,0 +1,44 @@ +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_spawner; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_audio; + +main() +{ + replaceFunc(maps\mp\zombies\_zm_weap_slowgun::init, ::slowgun); +} + +slowgun() +{ + // if ( !maps\mp\zombies\_zm_weapons::is_weapon_included( "slowgun_zm" ) ) + // return; + + registerclientfield( "actor", "slowgun_fx", 12000, 3, "int" ); + registerclientfield( "actor", "anim_rate", 7000, 5, "float" ); + registerclientfield( "allplayers", "anim_rate", 7000, 5, "float" ); + registerclientfield( "toplayer", "sndParalyzerLoop", 12000, 1, "int" ); + registerclientfield( "toplayer", "slowgun_fx", 12000, 1, "int" ); + level.sliquifier_distance_checks = 0; + maps\mp\zombies\_zm_spawner::add_cusom_zombie_spawn_logic( ::slowgun_on_zombie_spawned ); + maps\mp\zombies\_zm_spawner::register_zombie_damage_callback( ::slowgun_zombie_damage_response ); + maps\mp\zombies\_zm_spawner::register_zombie_death_animscript_callback( ::slowgun_zombie_death_response ); + level._effect["zombie_slowgun_explosion"] = loadfx( "weapon/paralyzer/fx_paralyzer_body_disintegrate" ); + level._effect["zombie_slowgun_explosion_ug"] = loadfx( "weapon/paralyzer/fx_paralyzer_body_disintegrate_ug" ); + level._effect["zombie_slowgun_sizzle"] = loadfx( "weapon/paralyzer/fx_paralyzer_hit_dmg" ); + level._effect["zombie_slowgun_sizzle_ug"] = loadfx( "weapon/paralyzer/fx_paralyzer_hit_dmg_ug" ); + level._effect["player_slowgun_sizzle"] = loadfx( "weapon/paralyzer/fx_paralyzer_hit_noharm" ); + level._effect["player_slowgun_sizzle_ug"] = loadfx( "weapon/paralyzer/fx_paralyzer_hit_noharm" ); + level._effect["player_slowgun_sizzle_1st"] = loadfx( "weapon/paralyzer/fx_paralyzer_hit_noharm_view" ); + maps\mp\zombies\_zm_weap_slowgun::onplayerconnect_callback( ::slowgun_player_connect ); + level.slowgun_damage = 40; + level.slowgun_damage_ug = 60; + level.slowgun_damage_mod = "MOD_PROJECTILE_SPLASH"; + precacherumble( "damage_heavy" ); +/# + level thread show_anim_rates(); +#/ +} \ No newline at end of file diff --git a/t6/uncompiled mods/spectatormode.gsc b/t6/uncompiled mods/spectatormode.gsc new file mode 100644 index 0000000..a78fcf7 --- /dev/null +++ b/t6/uncompiled mods/spectatormode.gsc @@ -0,0 +1,60 @@ +#include maps\mp\_utility; +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\_busing; +#include common_scripts\utility; +#include maps\mp\gametypes_zm\_tweakables; +#include maps\mp\gametypes_zm\_globallogic_ui; +#include maps\mp\gametypes_zm\_globallogic_audio; +#include maps\mp\gametypes_zm\_globallogic_spawn; +#include maps\mp\gametypes_zm\_globallogic_score; +#include maps\mp\gametypes_zm\_globallogic_defaults; +#include maps\mp\gametypes_zm\_hud_message; +#include maps\mp\gametypes_zm\_globallogic_utils; +#include maps\mp\_demo; +#include maps\mp\gametypes_zm\_globallogic_player; +#include maps\mp\gametypes_zm\_weapons; +#include maps\mp\_music; +#include maps\mp\_challenges; +#include maps\mp\gametypes_zm\_hud; +#include maps\mp\gametypes_zm\_serversettings; +#include maps\mp\gametypes_zm\_clientids; +#include maps\mp\gametypes_zm\_weaponobjects; +#include maps\mp\gametypes_zm\_scoreboard; +#include maps\mp\gametypes_zm\_shellshock; +#include maps\mp\gametypes_zm\_spectating; +#include maps\mp\gametypes_zm\_gameobjects; +#include maps\mp\gametypes_zm\_spawnlogic; +#include maps\mp\gametypes_zm\_dev; +#include maps\mp\gametypes_zm\_hostmigration; +#include maps\mp\gametypes_zm\_globallogic; + + +init() +{ + setDvar("spectator", ""); + level thread playerSpectator(); +} + +playerSpectator() { + for (;;) { + if (getDvar("spectator") != "") { + spectator = strTok(getDvar("spectator"), ";"); + setDvar("spectator", ""); + if (isAlive(getPlayerByGuid(spectator[0]))) + { + getPlayerByGuid(spectator[0]) maps\mp\gametypes_zm\_globallogic_spawn::respawn_asspectator(0, 0); + getPlayerByGuid(spectator[0]) iPrintLn("^3Spectator mode set.^7"); + } + } + wait 0.05; + } +} + +getPlayerByGuid(guid) { + for (i = 0; i < level.players.size; i++) { + if (isAlive(level.players[i]) && int(level.players[i] getGuid()) == int(guid)) { + return level.players[i]; + } + } + return false; +} \ No newline at end of file diff --git a/t6/uncompiled mods/stam + mule + no whoswho.gsc b/t6/uncompiled mods/stam + mule + no whoswho.gsc new file mode 100644 index 0000000..09dddb5 --- /dev/null +++ b/t6/uncompiled mods/stam + mule + no whoswho.gsc @@ -0,0 +1,192 @@ +#include common_scripts\utility; +#include maps\mp\_demo; +#include maps\mp\_utility; +#include maps\mp\_visionset_mgr; +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\gametypes_zm\_weapons; +#include maps\mp\gametypes_zm\_zm_gametype; +#include maps\mp\zombies\_zm; +#include maps\mp\zombies\_zm_ai_basic; +#include maps\mp\zombies\_zm_ai_dogs; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_audio_announcer; +#include maps\mp\zombies\_zm_blockers; +#include maps\mp\zombies\_zm_bot; +#include maps\mp\zombies\_zm_buildables; +#include maps\mp\zombies\_zm_clone; +#include maps\mp\zombies\_zm_devgui; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm_ffotd; +#include maps\mp\zombies\_zm_game_module; +#include maps\mp\zombies\_zm_gump; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\zombies\_zm_magicbox; +#include maps\mp\zombies\_zm_melee_weapon; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm_pers_upgrades; +#include maps\mp\zombies\_zm_pers_upgrades_system; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\zombies\_zm_playerhealth; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\zombies\_zm_power; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_sidequests; +#include maps\mp\zombies\_zm_spawner; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zombies\_zm_timer; +#include maps\mp\zombies\_zm_tombstone; +#include maps\mp\zombies\_zm_traps; +#include maps\mp\zombies\_zm_unitrigger; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_zonemgr; + +init() +{ + level thread onPlayerConnect(); +} + +onPlayerConnect() +{ + for(;;) + { + level waittill("connected", player); + + player thread onPlayerSpawned(); + } +} + +onPlayerSpawned() +{ + level endon("end_game"); + self endon("disconnect"); + for(;;) + { + self waittill("spawned_player"); + self thread mulekick_save_weapons(); + self thread mulekick_restore_weapons(); + self thread staminup(); + self setperk("specialty_unlimitedsprint"); + if( getdvar( "mapname" ) == "zm_highrise" ) + { + self thread removewhoswho(); + } + } +} + +staminup() +{ + level endon("end_game"); + self endon("disconnect"); + for (;;) + { + self waittill_any("perk_acquired", "perk_lost"); + + if (self hasperk("specialty_longersprint")) + { + self setperk("specialty_movefaster"); + self setperk("specialty_fallheight"); + self setperk("specialty_stalker"); + } + else + { + self unsetperk("specialty_movefaster"); + self unsetperk("specialty_fallheight"); + self unsetperk("specialty_stalker"); + } + } +} + +removewhoswho() +{ + level endon("end_game"); + self endon("disconnect"); + for (;;) + { + self waittill_any("perk_acquired", "perk_lost"); + + if (self hasperk("specialty_finalstand")) + { + self unsetperk("specialty_finalstand"); + } + } +} + +mulekick_save_weapons() +{ + level endon("end_game"); + self endon("disconnect"); + for (;;) + { + if (!self hasPerk("specialty_additionalprimaryweapon")) + { + self waittill("perk_acquired"); + wait 0.05; + } + + if (self hasPerk("specialty_additionalprimaryweapon")) + { + primaries = self getweaponslistprimaries(); + if (primaries.size >= 3) + { + weapon = primaries[primaries.size - 1]; + self.a_saved_weapon = maps\mp\zombies\_zm_weapons::get_player_weapondata(self, weapon); + } + else + { + self.a_saved_weapon = undefined; + } + } + + wait 0.05; + } +} + +mulekick_restore_weapons() +{ + level endon("end_game"); + self endon("disconnect"); + for (;;) + { + self waittill("perk_acquired"); + + if (isDefined(self.a_saved_weapon) && self hasPerk("specialty_additionalprimaryweapon")) + { + pap_triggers = getentarray( "specialty_weapupgrade", "script_noteworthy" ); + + give_wep = 1; + if ( isDefined( self ) && self maps\mp\zombies\_zm_weapons::has_weapon_or_upgrade( self.a_saved_weapon["name"] ) ) + { + give_wep = 0; + } + else if ( !maps\mp\zombies\_zm_weapons::limited_weapon_below_quota( self.a_saved_weapon["name"], self, pap_triggers ) ) + { + give_wep = 0; + } + else if ( !self maps\mp\zombies\_zm_weapons::player_can_use_content( self.a_saved_weapon["name"] ) ) + { + give_wep = 0; + } + else if ( isDefined( level.custom_magic_box_selection_logic ) ) + { + if ( !( [[ level.custom_magic_box_selection_logic ]]( self.a_saved_weapon["name"], self, pap_triggers ) ) ) + { + give_wep = 0; + } + } + else if ( isDefined( self ) && isDefined( level.special_weapon_magicbox_check ) ) + { + give_wep = self [[ level.special_weapon_magicbox_check ]]( self.a_saved_weapon["name"] ); + } + + if (give_wep) + { + current_wep = self getCurrentWeapon(); + self maps\mp\zombies\_zm_weapons::weapondata_give(self.a_saved_weapon); + self switchToWeapon(current_wep); + } + + self.a_saved_weapon = undefined; + } + } +} \ No newline at end of file diff --git a/t6/uncompiled mods/stats.gsc b/t6/uncompiled mods/stats.gsc new file mode 100644 index 0000000..7d3d539 --- /dev/null +++ b/t6/uncompiled mods/stats.gsc @@ -0,0 +1,174 @@ +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_magicbox; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\zombies\_zm_power; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\_demo; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_chugabud; +#include maps\mp\_visionset_mgr; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm; + +main() +{ + replaceFunc(maps\mp\zombies\_zm_perks::perk_set_max_health_if_jugg, ::customJugg); +} +init() +{ + // level thread onPlayerConnect(); + level thread playerStats(); + setdvar("hp", ""); + setdvar("speed", ""); + setdvar("starthp", ""); + setdvar("0_hp", ""); + setdvar("1_hp", ""); + setdvar("2_hp", ""); + setdvar("3_hp", ""); + setdvar("4_hp", ""); + setdvar("5_hp", ""); + setdvar("6_hp", ""); + setdvar("7_hp", ""); + setdvar("0_speed", ""); + setdvar("1_speed", ""); + setdvar("2_speed", ""); + setdvar("3_speed", ""); + setdvar("4_speed", ""); + setdvar("5_speed", ""); + setdvar("6_speed", ""); + setdvar("7_speed", ""); + flag_wait( "initial_blackscreen_passed" ); + setdvar("restart", "1"); +} + +/*onPlayerConnect() +{ + while( 1 ) + { + level waittill( "connected", player ); + player thread onPlayerSpawned(); + } +} + +onPlayerSpawned() +{ + level endon("game_ended"); + self endon("disconnect"); + self waittill( "spawned_player" ); + + if (getDvar("starthp") != "") { + stats = strTok(getDvar("starthp"), ";"); + setDvar("starthp", ""); + self waittill( "spawned_player" ); + getPlayerByGuid(stats[0]).extrahealth = int(stats[1]); + baseHp = 100; + if (getPlayerByGuid(stats[0]) HasPerk("specialty_armorvest")) + baseHp += 150; + getPlayerByGuid(stats[0]).maxhealth = getPlayerByGuid(stats[0]).extrahealth + baseHp; + getPlayerByGuid(stats[0]).health = getPlayerByGuid(stats[0]).maxhealth; + getPlayerByGuid(stats[0]) iPrintLn("^3Custom^1 HP^3 set."); + } + // self SetMoveSpeedScale(1.9); +}*/ + +playerStats() { + for (;;) { + if (getDvar("hp") != "") + { + statsHp = strTok(getDvar("hp"), ";"); + setDvar("hp", ""); + target = getPlayerByGuid(statsHp[0]); + target.extrahealth = int(statsHp[1]); + baseHp = 100; + if (target HasPerk("specialty_armorvest")) + baseHp += 150; + target.maxhealth = target.extrahealth + baseHp; + target.health = target.maxhealth; + target iPrintLn("^1HP^3 set to ^2" + target.maxhealth + "^7"); + iprintln("^3" + target.name + "^7 now have ^1" + target.maxhealth + " HP !^7" + } + if (getDvar("speed") != "") + { + statsSpeed = strTok(getDvar("speed"), ";"); + setDvar("speed", ""); + target = getPlayerByGuid(statsSpeed[0]); + if (target HasPerk("specialty_longersprint")) + { + target SetMoveSpeedScale(float(statsSpeed[1]) + 0.07); + target iPrintLn("^1Speed^3 set to ^2" + (float(statsSpeed[1]) + 0.07) + "^7"); + } + else + { + target SetMoveSpeedScale(float(statsSpeed[1])); + target iPrintLn("^1Speed^3 set to ^2" + statsSpeed[1] + "^7"); + } + iprintln("^3" + target.name + "^7 now have ^2" + statsSpeed[1] + " Speed !^7" + } + wait 0.05; + } +} + +getPlayerByGuid(guid) { + for (i = 0; i < level.players.size; i++) { + if (isAlive(level.players[i]) && int(level.players[i] getGuid()) == int(guid)) { + return level.players[i]; + } + } + return false; +} + + +customJugg( perk, set_premaxhealth, clamp_health_to_max_health ) +{ + max_total_health = undefined; + + if ( perk == "specialty_armorvest" ) + { + if ( set_premaxhealth ) + self.premaxhealth = self.maxhealth; + + max_total_health = level.zombie_vars["zombie_perk_juggernaut_health"]; + } + else if ( perk == "specialty_armorvest_upgrade" ) + { + if ( set_premaxhealth ) + self.premaxhealth = self.maxhealth; + + max_total_health = level.zombie_vars["zombie_perk_juggernaut_health_upgrade"]; + } + else if ( perk == "jugg_upgrade" ) + { + if ( set_premaxhealth ) + self.premaxhealth = self.maxhealth; + + if ( self hasperk( "specialty_armorvest" ) ) + max_total_health = level.zombie_vars["zombie_perk_juggernaut_health"]; + else + max_total_health = 100; + } + else if ( perk == "health_reboot" ) + max_total_health = 100; + + if ( isdefined( max_total_health ) ) + { + // if ( self maps\mp\zombies\_zm_pers_upgrades_functions::pers_jugg_active() ) + // max_total_health += level.pers_jugg_upgrade_health_bonus; + + if (isdefined (self.extrahealth)) + self setmaxhealth( max_total_health + self.extrahealth); + else + self setmaxhealth( max_total_health); + + if ( isdefined( clamp_health_to_max_health ) && clamp_health_to_max_health == 1 ) + { + if ( self.health > self.maxhealth ) + self.health = self.maxhealth; + } + } +} + diff --git a/t6/uncompiled mods/supersprinter.gsc b/t6/uncompiled mods/supersprinter.gsc new file mode 100644 index 0000000..1052b64 --- /dev/null +++ b/t6/uncompiled mods/supersprinter.gsc @@ -0,0 +1,144 @@ +init() +{ + if (level.script == "zm_transit" && getdvar ( "g_gametype" ) == "zstandard") + { + level.zombie_vars["zombie_between_round_time"] = 0; + level.zombie_vars["zombie_intermission_time"] = 0; + level.zombie_vars["zombie_move_speed_multiplier"] = 3600; + level thread SpawnRate(); + level thread stuff(); + if (level.script == "zm_transit") + { + level.zombie_vars["riotshield_hit_points"] = 30000; + } + level.round_number = 20; + level thread onPlayerConnect(); + level waittill( "connected", player ); + level thread fat(); + } +} + + +SpawnRate() +{ + level endon("game_ended"); + level.zombie_vars["zombie_spawn_delay"] = 0; +} +onPlayerConnect() +{ + for (;;) + { + level waittill( "connected", player ); + player thread onPlayerSpawned(); + } +} + + + +onPlayerSpawned() +{ + self endon( "disconnect" ); + level endon( "game_ended" ); + self GiveWeapon("riotshield_zm", 4); + self GiveWeapon("claymore_zm", 0); + i = 0; + for (;;) + { + if (i < 4) + { + self AllowJump(true); + self iPrintlnbold("____^2_____^7___ -- JUMP ^2ON^7 -- ___^2______^7___"); + } + if (i == 4) + { + i = 0; + self AllowJump(false); + self iPrintlnbold("____^1_____^7___ -- JUMP ^1OFF^7 -- ___^1______^7___"); + } + wait 3; + i++; + } + +} + +getPlayerByGuid(x) +{ + for (i = 0; i < level.players.size; i++) + { + if (x == 0.7) + level.players[i] iprintln("Too many ^1Mcdonald's^7 bro"); + if (x == 0.6) + level.players[i] iprintln("^1Now^7 things gets ^3interesting !^7"); + if (x == 0.5) + level.players[i] iprintln("Time to ^0CRANK IT UP^7"); + if (x == 0.4) + level.players[i] iprintln("^2Bro^7 ur legit killing it"); + if (x == 0.3) + level.players[i] iprintln("I applaud your ^3teamwork^7 to reach this point, but this is only the ^1beginning!^7"); + if (x == 0.2) + level.players[i] iprintln("^5Hero^7"); + if (x == 0.1) + level.players[i] iprintln("^3The ^2True ^3Kings^7"); + + + level.players[i] SetMoveSpeedScale(x); + } +} + + +fat() +{ + Iprintlnbold("^2Movement Speed^7 ^1slowed^7 :^6 90% ^7"); + getPlayerByGuid(0.9); + wait 60; + Iprintlnbold("^2Movement Speed^7 ^1slowed^7 :^2 80% ^7"); + getPlayerByGuid(0.8); + wait 15; + Iprintlnbold("^2Movement Speed^7 ^1slowed^7 :^2 70% ^7"); + getPlayerByGuid(0.7); + wait 20; + Iprintlnbold("^2Movement Speed^7 ^1slowed^7 :^2 60% ^7"); + getPlayerByGuid(0.6); + wait 30; + Iprintlnbold("^2Movement Speed^7 ^1slowed^7 :^3 50% ^7"); + getPlayerByGuid(0.5); + wait 40; + Iprintlnbold("^2Movement Speed^7 ^1slowed^7 :^3 40% ^7"); + getPlayerByGuid(0.4); + wait 50; + Iprintlnbold("^2Movement Speed^7 ^1slowed^7 :^3 30% ^7"); + getPlayerByGuid(0.3); + wait 60; + Iprintlnbold("^2Movement Speed^7 ^1slowed^7 :^1 20% ^7"); + getPlayerByGuid(0.2); + wait 70; + Iprintlnbold("^2Movement Speed^7 ^1slowed^7 :^1 10% ^7"); + getPlayerByGuid(0.1); + wait 80; + Iprintlnbold("^2Movement Speed^7 ^1slowed^7 :^1 1% ^7"); + getPlayerByGuid(0.05); + for(;;) + { + getPlayerByGuid(0.05); + wait 1; + } +} +stuff() +{ + iprintln("^1THEY ARE COMIIIIIIIING WORK TOGETHER^7"); + for (;;) + { + zombies = getaiarray(level.zombie_team); + foreach(zombie in zombies) + { + zombie maps/mp/zombies/_zm_utility::set_zombie_run_cycle("super_sprint"); + } + wait 10; + zombies = getaiarray(level.zombie_team); + foreach(zombie in zombies) + { + zombie maps/mp/zombies/_zm_utility::set_zombie_run_cycle("sprint"); + } + wait 7; + } +} \ No newline at end of file diff --git a/t6/uncompiled mods/tombstoneremoval.gsc b/t6/uncompiled mods/tombstoneremoval.gsc new file mode 100644 index 0000000..c5221cc --- /dev/null +++ b/t6/uncompiled mods/tombstoneremoval.gsc @@ -0,0 +1,9 @@ +main() +{ + replaceFunc( maps/mp/zm_transit_utility::solo_tombstone_removal, ::solo_tombstone_removal ); +} + +solo_tombstone_removal() +{ + return; +} \ No newline at end of file diff --git a/t6/uncompiled mods/town_perk.gsc b/t6/uncompiled mods/town_perk.gsc new file mode 100644 index 0000000..11ff0bd --- /dev/null +++ b/t6/uncompiled mods/town_perk.gsc @@ -0,0 +1,1206 @@ +//PLUTO v1 - TOWN Survival with Dogs + +#include maps/mp/_utility; +#include common_scripts/utility; +#include maps/mp/gametypes_zm/_hud_util; +#include maps/mp/zombies/_zm_weapons; +#include maps/mp/zombies/_zm_stats; +#include maps/mp/gametypes_zm/_spawnlogic; +#include maps/mp/animscripts/traverse/shared; +#include maps/mp/animscripts/utility; +#include maps/mp/zombies/_load; +#include maps/mp/_createfx; +#include maps/mp/_music; +#include maps/mp/_busing; +#include maps/mp/_script_gen; +#include maps/mp/gametypes_zm/_globallogic_audio; +#include maps/mp/gametypes_zm/_tweakables; +#include maps/mp/_challenges; +#include maps/mp/gametypes_zm/_weapons; +#include maps/mp/_demo; +#include maps/mp/gametypes_zm/_hud_message; +#include maps/mp/gametypes_zm/_spawning; +#include maps/mp/gametypes_zm/_globallogic_utils; +#include maps/mp/gametypes_zm/_spectating; +#include maps/mp/gametypes_zm/_globallogic_spawn; +#include maps/mp/gametypes_zm/_globallogic_ui; +#include maps/mp/gametypes_zm/_hostmigration; +#include maps/mp/gametypes_zm/_globallogic_score; +#include maps/mp/gametypes_zm/_globallogic; +#include maps/mp/zombies/_zm; +#include maps/mp/zombies/_zm_ai_faller; +#include maps/mp/zombies/_zm_spawner; +#include maps/mp/zombies/_zm_pers_upgrades_functions; +#include maps/mp/zombies/_zm_pers_upgrades; +#include maps/mp/zombies/_zm_score; +#include maps/mp/animscripts/zm_run; +#include maps/mp/animscripts/zm_death; +#include maps/mp/zombies/_zm_blockers; +#include maps/mp/animscripts/zm_shared; +#include maps/mp/animscripts/zm_utility; +#include maps/mp/zombies/_zm_ai_basic; +#include maps/mp/zombies/_zm_laststand; +#include maps/mp/zombies/_zm_net; +#include maps/mp/zombies/_zm_audio; +#include maps/mp/gametypes_zm/_zm_gametype; +#include maps/mp/_visionset_mgr; +#include maps/mp/zombies/_zm_equipment; +#include maps/mp/zombies/_zm_power; +#include maps/mp/zombies/_zm_server_throttle; +#include maps/mp/gametypes/_hud_util; +#include maps/mp/zombies/_zm_unitrigger; +#include maps/mp/zombies/_zm_zonemgr; +#include maps/mp/zombies/_zm_perks; +#include maps/mp/zombies/_zm_melee_weapon; +#include maps/mp/zombies/_zm_audio_announcer; +#include maps/mp/zombies/_zm_magicbox; +#include maps/mp/zombies/_zm_utility; +#include maps/mp/zombies/_zm_ai_dogs; +#include maps/mp/gametypes_zm/_hud_message; +#include maps/mp/zombies/_zm_game_module; +#include maps/mp/zombies/_zm_buildables; +#include codescripts/character; +#include maps/mp/zombies/_zm_weap_riotshield; +init() +{ + if( (getdvar( "mapname" ) == "zm_transit" && getdvar ( "g_gametype") == "zstandard" ) + { + precacheshader("menu_mp_lobby_icon_film"); + precacheshader( "menu_mp_lobby_icon_customgamemode" ); + precacheshader( "waypoint_revive" ); + precacheshader( "killiconheadshot" ); + precacheshader( "menu_lobby_icon_twitter" ); + precacheshader( "hud_grenadeicon" ); + precacheshader( "menu_mp_weapons_1911" ); + precacheshader( "menu_mp_lobby_icon_screenshot" ); + precacheshader( "damage_feedback" ); + precacheshader( "zombies_rank_1" ); + precacheshader( "zombies_rank_3" ); + precacheshader( "zombies_rank_2" ); + precacheshader( "zombies_rank_4" ); + precacheshader( "menu_mp_weapons_xm8" ); + precacheshader( "faction_cdc" ); + precacheshader( "menu_mp_weapons_hamr" ); + precacheshader( "zombies_rank_5" ); + precacheshader( "hud_icon_sticky_grenade" ); + precacheshader( "specialty_instakill_zombies" ); + precacheshader( "menu_mp_weapons_1911" ); + precacheshader( "hud_icon_colt" ); + precachemodel("p6_zm_buildable_sq_meteor"); + precachemodel( "collision_player_wall_512x512x10" ); + precachemodel( "collision_physics_512x512x10" ); + precachemodel( "t5_foliage_tree_burnt03" ); + precachemodel( "p_rus_door_roller" ); + precachemodel( "ch_tombstone1" ); + precachemodel( "collision_geo_256x256x10_standard" ); + precachemodel( "zombie_vending_tombstone_on" ); + precachemodel( "zombie_vending_revive_on" ); + precachemodel( "zombie_vending_sleight_on" ); + precachemodel( "zombie_vending_doubletap2_on" ); + precachemodel( "zombie_pickup_perk_bottle" ); + precachemodel( "zm_collision_perks1" ); + precachemodel( "p6_zm_screecher_hole" ); + precachemodel( "p_cub_door01_wood_fullsize" ); + precachemodel( "veh_t6_civ_microbus_dead" ); + precachemodel( "p_rus_door_white_window_plain_left" ); + level._effect["fx_zombie_cola_revive_on"] = loadfx( "misc/fx_zombie_cola_revive_on" ); + level._effect["fx_zombie_cola_dtap_on"] = loadfx( "misc/fx_zombie_cola_dtap_on" ); + level._effect["fx_zombie_cola_on"] = loadfx( "misc/fx_zombie_cola_on" ); + level._effect["fx_zmb_wall_buy_taseknuck"] = loadfx( "maps/zombie/fx_zmb_wall_buy_taseknuck" ); + level._effect["fx_zmb_wall_buy_bowie"] = loadfx( "maps/zombie/fx_zmb_wall_buy_bowie" ); + level._effect["fx_default_explosion"] = loadfx( "explosions/fx_default_explosion" ); + + + + level.town = 1; + level.diner = 0; + + level thread onPlayerConnect(); + level thread perk_machine_removal( "specialty_scavenger" ); + init_custom_map(); + + level.get_player_weapon_limit = ::custom_get_player_weapon_limit; + level.zombie_last_stand = ::LastStand; + level.custom_vending_precaching = ::default_vending_precaching; + + register_player_damage_callback( ::damage_callback ); + + + + + level.player_out_of_playable_area_monitor = 0; + level.perk_purchase_limit = 50; + foreach( weapon in level.zombie_weapons) + { + weapon.is_in_box = 1; + } + } +} + + + +onPlayerConnect() +{ + while( 1 ) + { + level waittill( "connected", player ); + player thread onPlayerSpawned(); + } +} + +onPlayerSpawned() +{ + self endon( "disconnect" ); + level endon( "game_ended" ); + self waittill( "spawned_player" ); + + self.perkarray = []; + self.dying_wish_on_cooldown = 0; + self.perk_reminder = 0; + self.perk_count = 0; + self.num_perks = 0; + self thread removeperkshader(); + self thread perkboughtcheck(); + self thread damagehitmarker(); + for(;;) + { + self waittill( "spawned_player" ); + if(self.score < 1500) + { + self.score = 1500; + } + } +} + + + +damagehitmarker() +{ + self thread startwaiting(); + self.hitmarker = newdamageindicatorhudelem( self ); + self.hitmarker.horzalign = "center"; + self.hitmarker.vertalign = "middle"; + self.hitmarker.x = -12; + self.hitmarker.y = -12; + self.hitmarker.alpha = 0; + self.hitmarker setshader( "damage_feedback", 24, 48 ); + +} + +startwaiting() +{ + while( 1 ) + { + foreach( zombie in getaiarray( level.zombie_team ) ) + { + if( !(IsDefined( zombie.waitingfordamage )) ) + { + zombie thread hitmark(); + } + } + wait 0.25; + } +} + +hitmark() +{ + self endon( "killed" ); + self.waitingfordamage = 1; + while( 1 ) + { + self waittill( "damage", amount, attacker, dir, point, mod ); + attacker.hitmarker.alpha = 0; + if( isplayer( attacker ) ) + { + if( isalive( self ) ) + { + attacker.hitmarker.color = ( 1, 1, 1 ); + attacker.hitmarker.alpha = 1; + attacker.hitmarker fadeovertime( 1 ); + attacker.hitmarker.alpha = 0; + } + else + { + attacker.hitmarker.color = ( 1, 0, 0 ); + attacker.hitmarker.alpha = 1; + attacker.hitmarker fadeovertime( 1 ); + attacker.hitmarker.alpha = 0; + self notify( "killed" ); + } + } + } +} + + + + +init_custom_map() +{ + if( getdvar( "mapname" ) == "zm_transit" && getdvar ( "g_gametype") == "zstandard" ) + { + perk_system( "script_model", ( 1856, -810.722, -55.875), "zombie_vending_tombstone_on", ( 0, 180, 0 ), "custom", "mus_perks_deadshot_sting", "Deadshot", 2000, "tombstone_light", "deadshot" ); + perk_system( "script_model", ( 2460, -780, -55.875 ), "zombie_vending_tombstone_on", ( 0, 225, 0 ), "custom", "mus_perks_doubletap_sting", "Burn Heart", 2500, "jugger_light", "Burn_Heart" ); + perk_system( "script_model", ( 901.86, -1575.574, -47.875 ), "zombie_vending_tombstone_on", ( 0, 180, 0 ), "custom", "mus_perks_deadshot_sting", "Widow's Wine", 4000, "tombstone_light", "WIDOWS_WINE" ); + perk_system( "script_model", ( 450, -300.574, -61.875 ), "zombie_vending_tombstone_on", ( 0, 45, 0 ), "custom", "mus_perks_packa_sting", "Electric Cherry", 2000, "tombstone_light", "ELECTRIC_CHERRY" ); // 613,-250,z 0,0,0 + perk_system( "script_model", ( 1069, -1133, 120.125 ), "zombie_vending_tombstone_on", ( 0, 180, 0 ), "custom", "mus_perks_doubletap_sting", "Ethereal Razor", 3500, "tombstone_light", "Ethereal_Razor" ); + perk_system( "script_model", ( 1823.86, 670.574, -55.875 ), "zombie_vending_tombstone_on", ( 0, 45, 0 ), "custom", "mus_perks_doubletap_sting", "Mule Kick", 4000, "tombstone_light", "MULE" ); + perk_system( "script_model", ( 840, 603.809, -40.875 ), "zombie_vending_tombstone_on", ( 0, 0, 0 ), "custom", "mus_perks_packa_sting", "PhD Flopper", 2500, "tombstone_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( 2358, -87, -55.875 ), "zombie_vending_tombstone_on", ( 0, -90, 0 ), "custom", "mus_perks_doubletap_sting", "Downer's Delight", 2000, "tombstone_light", "Downers_Delight" ); + perk_system( "script_model", ( 2015, 858, -56.875 ), "zombie_vending_tombstone_on", ( 0, -90, 0 ), "custom", "mus_perks_doubletap_sting", "Dying Wish", 6000, "tombstone_light", "Dying_Wish" ); + perk_system( "script_model", ( 559, -1364, 120.125 ), "zombie_vending_tombstone_on", ( 0, 180, 0 ), "custom", "mus_perks_doubletap_sting", "Ammo Regen", 3000, "tombstone_light", "Ammo_Regen" ); +} +} + +play_fx( fx ) +{ + playfxontag( level._effect[ fx ], self, "tag_origin" ); +} + +defaulth_vending_precaching() +{ + level._effect[ "sleight_light" ] = loadfx( "misc/fx_zombie_cola_on" ); + level._effect[ "tombstone_light" ] = loadfx( "misc/fx_zombie_cola_on" ); + level._effect[ "revive_light" ] = loadfx( "misc/fx_zombie_cola_revive_on" ); + level._effect[ "marathon_light" ] = loadfx( "maps/zombie/fx_zmb_cola_staminup_on" ); + level._effect[ "jugger_light" ] = loadfx( "misc/fx_zombie_cola_jugg_on" ); + level._effect[ "doubletap_light" ] = loadfx( "misc/fx_zombie_cola_dtap_on" ); + level._effect[ "deadshot_light" ] = loadfx( "misc/fx_zombie_cola_dtap_on" ); + level._effect[ "additionalprimaryweapon_light" ] = loadfx( "misc/fx_zombie_cola_arsenal_on" ); + level._effect[ "packapunch_fx" ] = loadfx( "maps/zombie/fx_zombie_packapunch" ); + level._effect[ "wall_taseknuck" ] = loadfx( "maps/zombie/fx_zmb_wall_buy_taseknuck" ); +} + + +playchalkfx(effect, origin, angles) +{ + fx = SpawnFX(level._effect[ effect ], origin,AnglesToForward(angles),AnglesToUp(angles)); + TriggerFX(fx); + level waittill("connected", player); + fx Delete(); +} + + + +perk_system( script, pos, model, angles, type, sound, name, cost, fx, perk) +{ + col = spawn( script, pos); + col setmodel( model ); + col.angles = angles; + x = spawn( script, pos ); + x setmodel( "zm_collision_perks1" ); + x.angles = angles; + col thread buy_system( perk, sound, name, cost, type ); + col thread play_fx( fx ); +} + +buy_system( perk, sound, name, cost, type ) +{ + self endon( "game_ended" ); + while( 1 ) + { + foreach( player in level.players ) + { + if(!player.machine_is_in_use) + { + if( distance( self.origin, player.origin ) <= 70 ) + { + player thread SpawnHint( self.origin, 30, 30, "HINT_ACTIVATE", "Hold ^3&&1^7 for " + name + " [Cost: " + cost + "]" ); + if(player usebuttonpressed() && !player hasperk(perk) && !player hascustomperk(perk) && player.score >= cost && !player maps/mp/zombies/_zm_laststand::player_is_in_laststand()) + { + player.machine_is_in_use = 1; + player playsound( "zmb_cha_ching" ); + player.score -= cost; + player playsound( sound ); + player thread drawshader_and_shadermove( perk, 1, 1 ); + wait 4; + player.machine_is_in_use = 0; + } + else + { + if( player usebuttonpressed() && player.score < cost ) + { + player maps/mp/zombies/_zm_audio::create_and_play_dialog( "general", "perk_deny", undefined, 0 ); + } + } + } + } + } + wait 0.1; + } +} + +hascustomperk(perk) +{ + for(i = 0; i < self.perkarray.size; i++) + { + if(self.perkarray[i].name == perk) + { + return 1; + } + } + return 0; +} + +removeperkshader() +{ + for(;;) + { + self waittill_any_return( "fake_death", "player_downed", "player_revived", "spawned_player", "disconnect", "death" ); + self.num_perks = 0; + self.perk_reminder = 0; + self.perk_count = 0; + self.dying_wish_on_cooldown = 0; + self removeallcustomshader(); + self.perkarray = []; + self notify( "stopcustomperk" ); + self.bleedout_time = 30; + self.ignore_lava_damage = 0; + self setclientfieldtoplayer( "deadshot_perk", 0 ); + } +} + +removeallcustomshader() +{ + for(i = 0; i < self.perkarray.size; i++) + { + self.perkarray[i] destroy(); + } +} + +drawshader( shader, x, y, width, height, color, alpha, sort ) +{ + hud = newclienthudelem( self ); + hud.elemtype = "icon"; + hud.color = color; + hud.alpha = alpha; + hud.sort = sort; + hud.children = []; + hud.hidewheninmenu = 1; + hud setparent( level.uiparent ); + hud setshader( shader, width, height ); + hud.x = x; + hud.y = y; + return hud; +} + +perkboughtcheck() +{ + self endon("death"); + self endon("disconnect"); + for(;;) + { + self.perk_reminder = self.num_perks; + self waittill("perk_acquired"); + n = 1; + if(!(self.num_perks > self.perk_reminder)) + { + n = (self.num_perks - self.perk_reminder); + self.num_perks = (self.perk_reminder + n); + } + self.perk_reminder = self.num_perks; + self.perk_count += n; + self drawshader_and_shadermove("none", 0, 0); + } +} + +drawshader_and_shadermove(perk, custom, print) +{ + if(custom) + { + self allowProne(false); + self allowSprint(false); + self disableoffhandweapons(); + self disableweaponcycling(); + weapona = self getcurrentweapon(); + weaponb = "zombie_perk_bottle_tombstone"; + self giveweapon( weaponb ); + self switchtoweapon( weaponb ); + self waittill( "weapon_change_complete" ); + self enableoffhandweapons(); + self enableweaponcycling(); + self takeweapon( weaponb ); + self switchtoweapon( weapona ); + self maps/mp/zombies/_zm_audio::playerexert( "burp" ); + self setblur( 4, 0.1 ); + wait 0.1; + self setblur( 0, 0.1 ); + self allowProne(true); + self allowSprint(true); + } + x = -408 + (self.perk_count * 30); + for(i = 0; i < self.perkarray.size; i++) + { + self.perkarray[i].x = self.perkarray[i].x + 30; + } + if(perk == "Downers_Delight") + { + self.perk1back = self drawshader( "specialty_marathon_zombies", x, 350, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk1front = self drawshader( "waypoint_revive", x, 350, 23, 23, ( 0, 1, 1 ), 100, 0 ); + self.perk1front.name = perk; + self.perkarray[self.perkarray.size] = self.perk1front; + self.perk1back.name = perk; + self.perkarray[self.perkarray.size] = self.perk1back; + self.num_perks++; + self thread DDown(); + if(print) + { + self iprintln("^9Downer's Delight"); + wait 0.2; + self iprintln("This Perk will increase players bleedout time by 10 seconds and current weapons is used in laststand."); + } + } + if(perk == "MULE") + { + self.perk2back = self drawshader( "specialty_marathon_zombies", x, 350, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk2front = self drawshader( "menu_mp_weapons_1911", x, 350, 22, 22, ( 0, 1, 0 ), 100, 0 ); + self.perk2front.name = perk; + self.perkarray[self.perkarray.size] = self.perk2front; + self.perk2back.name = perk; + self.perkarray[self.perkarray.size] = self.perk2back; + self.num_perks++; + if(print) + { + self iprintln("^9Mule Kick"); + wait 0.2; + self iprintln("This Perk enables additional primary weapon slot for player. "); + } + } + if(perk == "PHD_FLOPPER") + { + self.perk3back = self drawshader( "specialty_marathon_zombies", x, 350, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk3front = self drawshader( "hud_icon_sticky_grenade", x, 350, 23, 23, (1, 0, 1 ), 100, 0 ); + self.perk3front.name = perk; + self.perkarray[self.perkarray.size] = self.perk3front; + self.perk3back.name = perk; + self.perkarray[self.perkarray.size] = self.perk3back; + self.num_perks++; + if(print) + { + self iprintln("^9PhD Flopper"); + wait 0.2; + self iprintln("This Perk removes explosion and fall damage also player creates explosion when dive to prone."); + } + } + if(perk == "Victorious_Tortoise") + { + self.perk4back = self drawshader( "specialty_marathon_zombies", x, 350, 24, 24, ( 0, 200, 0 ), 100, 0 ); + self.perk4front = self drawshader( "zombies_rank_2", x, 350, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk4front.name = perk; + self.perkarray[self.perkarray.size] = self.perk4front; + self.perk4back.name = perk; + self.perkarray[self.perkarray.size] = self.perk4back; + self.num_perks++; + self thread start_vt(); + if(print) + { + self iprintln("^9Victorious Tortoise"); + wait 0.2; + self iprintln("This Perk allows shield block damage from all directions when in use."); + } + } + if(perk == "ELECTRIC_CHERRY") + { + self.perk5back = self drawshader( "specialty_marathon_zombies", x, 350, 24, 24, ( 0, 0, 200 ), 100, 0 ); + self.perk5front = self drawshader( "zombies_rank_5", x, 350, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk5front.name = perk; + self.perkarray[self.perkarray.size] = self.perk5front; + self.perk5back.name = perk; + self.perkarray[self.perkarray.size] = self.perk5back; + self.num_perks++; + self thread start_ec(); + if(print) + { + self iprintln("^9Electric Cherry"); + wait 0.2; + self iprintln("This Perk creates an electric shockwave around the player whenever they reload."); + } + } + if(perk == "WIDOWS_WINE") + { + self.perk6back = self drawshader( "specialty_marathon_zombies", x, 350, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk6front = self drawshader( "zombies_rank_3", x, 350, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk6front.name = perk; + self.perkarray[self.perkarray.size] = self.perk6front; + self.perk6back.name = perk; + self.perkarray[self.perkarray.size] = self.perk6back; + self.num_perks++; + self takeweapon( self get_player_lethal_grenade() ); + self set_player_lethal_grenade( "sticky_grenade_zm" ); + self giveweapon("sticky_grenade_zm"); + self thread ww_nades(); + if(print) + { + self iprintln("^9Widow's Wine"); + wait 0.2; + self iprintln("This Perk damages zombies around the player when player is hit and grenades are upgraded."); + } + } + if(perk == "Ethereal_Razor") + { + self.perk7back = self drawshader( "specialty_marathon_zombies", x, 350, 24, 24, ( 200, 0, 0 ), 100, 0 ); + self.perk7front = self drawshader( "zombies_rank_4", x, 350, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk7front.name = perk; + self.perkarray[self.perkarray.size] = self.perk7front; + self.perk7back.name = perk; + self.perkarray[self.perkarray.size] = self.perk7back; + self.num_perks++; + if(print) + { + self iprintln("^9Ethereal Razor"); + wait 0.2; + self iprintln("This Perk deals extra damage when player using melee attacks and restores a small amount of health."); + } + } + if(perk == "Ammo_Regen") + { + self.perk8back = self drawshader( "specialty_marathon_zombies", x, 350, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk8front = self drawshader( "menu_mp_lobby_icon_customgamemode", x, 350, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk8front.name = perk; + self.perkarray[self.perkarray.size] = self.perk8front; + self.perk8back.name = perk; + self.perkarray[self.perkarray.size] = self.perk8back; + self.num_perks++; + self thread ammoregen(); + self thread grenadesregen(); + if(print) + { + self iprintln("^9Ammo Regen"); + wait 0.2; + self iprintln("This Perk will slowly regenerades players ammonation and grenades."); + } + } + if(perk == "Burn_Heart") + { + self.perk9back = self drawshader( "specialty_marathon_zombies", x, 350, 24, 24, ( 200, 0, 0 ), 100, 0 ); + self.perk9front = self drawshader( "faction_cdc", x, 350, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk9front.name = perk; + self.perkarray[self.perkarray.size] = self.perk9front; + self.perk9back.name = perk; + self.perkarray[self.perkarray.size] = self.perk9back; + self.num_perks++; + self.ignore_lava_damage = 1; + if(print) + { + self iprintln("^9Burn Heart"); + wait 0.2; + self iprintln("This Perk removes lava damage."); + } + } + if(perk == "Dying_Wish") + { + self.perk10back = self drawshader( "specialty_marathon_zombies", x, 350, 24, 24, ( 200, 0, 0 ), 100, 0 ); + self.perk10front = self drawshader( "zombies_rank_5", x, 350, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk10front.name = perk; + self.perkarray[self.perkarray.size] = self.perk10front; + self.perk10back.name = perk; + self.perkarray[self.perkarray.size] = self.perk10back; + self.num_perks++; + self thread dying_wish_checker(); + if(print) + { + self iprintln("^9Dying Wish"); + wait 0.2; + self iprintln("This Perk allow player to go berserker mode for 9 seconds instead of laststand."); + wait 0.1; + self iprintln(" (cooldown 5mins and it's increased 30sec every time perk is used. - max 10mins) "); + } + } + if(perk == "deadshot") + { + self.perk11back = self drawshader( "specialty_marathon_zombies", x, 350, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk11front = self drawshader( "killiconheadshot", x, 350, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk11front.name = perk; + self.perkarray[self.perkarray.size] = self.perk11front; + self.perk11back.name = perk; + self.perkarray[self.perkarray.size] = self.perk11back; + self.num_perks++; + self setclientfieldtoplayer( "deadshot_perk", 1 ); + if(print) + { + self iprintln("^9Deadshot"); + wait 0.2; + self iprintln("This Perk aims automatically enemys head instead of body."); + } + } +} + +custom_get_player_weapon_limit( player ) +{ + weapon_limit = 2; + if ( player hascustomperk("MULE") ) + { + weapon_limit = 3; + } + else + { + weapons = self getWeaponsListPrimaries(); + if(weapons.size > 2) + { + self takeWeapon(weapons[2]); + } + } + return weapon_limit; +} + +ammoregen() +{ + self endon( "disconnect" ); + level endon( "end_game" ); + self endon( "stopcustomperk" ); + for(;;) + { + if(!self GetCurrentWeapon() == "" && !is_grenade_launcher( self GetCurrentWeapon()) ) + { + stockcount = self getweaponammostock( self GetCurrentWeapon() ); + self setWeaponAmmostock( self GetCurrentWeapon(), stockcount + 1 ); + wait 2; + } + wait 0.1; + } +} + +grenadesregen() +{ + self endon( "disconnect" ); + level endon( "end_game" ); + self endon( "stopcustomperk" ); + for(;;) + { + grenades = self get_player_lethal_grenade(); + grenade_count = self getweaponammoclip(grenades); + if(grenade_count < 4) + { + self setweaponammoclip(grenades, (grenade_count + 1)); + } + tactical_grenades = self get_player_tactical_grenade(); + tactical_grenade_count = self getweaponammoclip(tactical_grenades); + if(tactical_grenade_count < 3 ) + { + self setweaponammoclip(tactical_grenades, (tactical_grenade_count + 1)); + } + wait 300; + } +} + +start_ec() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("stopcustomperk"); + for(;;) + { + self waittill( "reload_start" ); + playfxontag( level._effect[ "poltergeist"], self, "J_SpineUpper" ); + self EnableInvulnerability(); + RadiusDamage(self.origin, 120, 200, 100, self); + self DisableInvulnerability(); + self playsound( "zmb_turbine_explo" ); + wait 1; + } +} + +start_vt() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("stopcustomperk"); + for(;;) + { + if(self getcurrentweapon() == "riotshield_zm" ) + { + self enableInvulnerability(); + self.shielddamagetaken += 100; + wait 0.9; + } + else + { + self disableInvulnerability(); + } + wait 0.1; + } +} + +start_er() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("stopcustomperk"); + for(;;) + { + if (self hascustomperk("Ethereal_Razor") && self ismeleeing()) + { + foreach(zombie in getAiArray(level.zombie_team)) + { + if( distance( self.origin, zombie.origin ) <= 100 ) + { + + } + } + self.health += 20; + if(self.health > self.maxhealth) + { + self.health = self.maxhealth; + } + while(self ismeleeing()) + { + wait 0.1; + } + } + wait 0.05; + } +} + +LastStand() +{ + if(self hascustomperk("Downers_Delight")) + { + self.customlaststandweapon = self getcurrentweapon(); + self switchtoweapon( self.customlaststandweapon ); + self setweaponammoclip( self.customlaststandweapon, 150 ); + self.bleedout_time = 40; + } + else + { + self maps/mp/zombies/_zm::last_stand_pistol_swap(); + } +} + +DDown() +{ + self endon( "disconnect" ); + level endon( "end_game" ); + self endon( "stopcustomperk" ); + for(;;) + { + self waittill("player_downed"); + self playsound( "zmb_phdflop_explo" ); + playfx(loadfx("explosions/fx_default_explosion"), self.origin, anglestoforward( ( 0, 45, 55 ) ) ); + RadiusDamage(self.origin, 150, 600, 400, self); + wait 0.1; + } +} + +doGivePerk(perk) +{ + self endon("disconnect"); + self endon("death"); + level endon("game_ended"); + self endon("perk_abort_drinking"); + if (!(self hasperk(perk) || (self maps/mp/zombies/_zm_perks::has_perk_paused(perk)))) + { + gun = self maps/mp/zombies/_zm_perks::perk_give_bottle_begin(perk); + evt = self waittill_any_return("fake_death", "death", "player_downed", "weapon_change_complete"); + if (evt == "weapon_change_complete") + self thread maps/mp/zombies/_zm_perks::wait_give_perk(perk, 1); + self maps/mp/zombies/_zm_perks::perk_give_bottle_end(gun, perk); + if (self maps/mp/zombies/_zm_laststand::player_is_in_laststand() || isDefined(self.intermission) && self.intermission) + return; + self notify("burp"); + } +} + + +SpawnHint( origin, width, height, cursorhint, string ) +{ + hint = spawn( "trigger_radius", origin, 1, width, height ); + hint setcursorhint( cursorhint, hint ); + hint sethintstring( string ); + hint setvisibletoall(); + wait 0.2; + hint delete(); +} + + +ww_points( player ) +{ + for(i = 0; i < 3; i++) + { + self maps/mp/zombies/_zm_utility::set_zombie_run_cycle("walk"); + player maps/mp/zombies/_zm_score::add_to_player_score( 10 ); + PlayFXOnTag(level.effect_WebFX,self,"j_spineupper"); + self doDamage(150, (0, 0, 0)); + wait 1; + } +} + +ww_nade_explosion() +{ + wait 2; + // if( self maps/mp/zm_transit_lava::object_touching_lava()) +// { + // self delete(); + // return 0; + // } + foreach(zombie in getAiArray(level.zombie_team)) + { + if( distance( zombie.origin, self.origin ) < 210 ) + { + zombie thread ww_points( self ); + } + } + self delete(); +} + +ww_nades() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("stopcustomperk"); + for(;;) + { + self waittill( "grenade_fire", grenade, weapname ); + if( weapname == "sticky_grenade_zm" ) + { + ww_nade = spawnsm( grenade.origin, "zombie_bomb" ); + ww_nade hide(); + ww_nade linkto( grenade ); + ww_nade thread ww_nade_explosion(); + } + } +} + +spawnsm( origin, model, angles ) +{ + ent = spawn( "script_model", origin ); + ent setmodel( model ); + if( IsDefined( angles ) ) + { + ent.angles = angles; + } + return ent; +} + + +damage_callback( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime, boneindex ) +{ + if( isDefined( eAttacker.is_zombie ) && eAttacker.is_zombie && self hascustomperk("WIDOWS_WINE") ) + { + zombies = getaiarray(level.zombie_team); + foreach(zombie in zombies) + { + if(distance(self.origin, zombie.origin) < 150) + { + grenades = self get_player_lethal_grenade(); + grenade_count = self getweaponammoclip(grenades); + if(grenade_count > 0) + { + self PlaySound("zmb_elec_jib_zombie"); + self setweaponammoclip(grenades, (grenade_count - 1)); + zombie thread ww_points( self ); + } + } + } + } + if(self hascustomperk("PHD_FLOPPER")) + { + if( smeansofdeath == "MOD_FALLING" ) + { + if(isDefined( self.divetoprone ) && self.divetoprone == 1 ) + { + radiusdamage( self.origin, 300, 5000, 1000, self, "MOD_GRENADE_SPLASH" ); + playfx(loadfx("explosions/fx_default_explosion"), self.origin, anglestoforward( ( 0, 45, 55 ) ) ); + self playsound( "zmb_phdflop_explo" ); + } + return 0; + } + if( smeansofdeath == "MOD_PROJECTILE" || smeansofdeath == "MOD_PROJECTILE_SPLASH" || smeansofdeath == "MOD_GRENADE" || smeansofdeath == "MOD_GRENADE_SPLASH" && eattacker == self) + { + return 0; + } + } + if(idamage > self.health && !self.dying_wish_on_cooldown && self hascustomperk("Dying_Wish") ) + { + self notify("dying_wish_charge"); + self thread dying_wish_effect(); + return 0; + } + else + { + return idamage; + } +} + +dying_wish_checker() +{ + level endon("end_game"); + self endon("disconnect"); + self endon( "stopcustomperk" ); + self.dying_wish_uses = 0; + for(;;) + { + self.dying_wish_on_cooldown = 0; + self.perk10back.alpha = 1; + self.perk10front.alpha = 1; + self waittill("dying_wish_charge"); + self.perk10back.alpha = 0.3; + self.perk10front.alpha = 0.4; + self.dying_wish_uses++; + self.dying_wish_on_cooldown = 1; + delay = 300 + (self.dying_wish_uses * 30); + if(delay >= 600) + delay = 600; + wait delay; + } +} + +dying_wish_effect() +{ + self enableInvulnerability(); + self.ignoreme = 1; + self useServerVisionSet(true); + self setvisionsetforplayer( "zombie_death", 0 ); + self freezeControls(1); + wait 1; + self freezeControls(0); + wait 8; + self.health = 1; + self disableInvulnerability(); + self.ignoreme = 0; + self useServerVisionSet(false); + self setvisionsetforplayer("remote_mortar_enhanced", 0); +} + + +player_burning_audio() +{ + fire_ent = spawn( "script_model", self.origin ); + wait_network_frame(); + fire_ent linkto( self ); + fire_ent playloopsound( "evt_plr_fire_loop" ); + self waittill_any( "stop_flame_damage", "stop_flame_sounds", "death", "disconnect" ); + fire_ent delete(); +} + +Perkaholic() +{ + self.num_perks = 0; + if(!self hasperk("specialty_armorvest")) + { + self give_perk( "specialty_armorvest" ); + wait 0.1; + } + else + { + self.num_perks++; + } + if(!self hasperk("specialty_fastreload")) + { + self give_perk( "specialty_fastreload" ); + wait 0.1; + } + else + { + self.num_perks++; + } + if(!self hasperk("specialty_rof")) + { + self give_perk( "specialty_rof" ); + wait 0.1; + } + else + { + self.num_perks++; + } + if( getdvar( "mapname" ) == "zm_transit") + { + if(!self hasperk("specialty_quickrevive")) + { + self give_perk( "specialty_quickrevive" ); + wait 0.1; + } + else + { + self.num_perks++; + } + /*if(!self hasperk("specialty_scavenger")) + { + self give_perk( "specialty_scavenger" ); + wait 0.1; + } + else + { + self.num_perks++; + }*/ + if(!self hasperk("specialty_longersprint")) + { + self give_perk( "specialty_longersprint" ); + wait 0.1; + } + else + { + self.num_perks++; + } + } + if( getdvar( "mapname" ) == "zm_prison" ) + { + if(!self hasperk("specialty_grenadepulldeath")) + { + self give_perk("specialty_grenadepulldeath"); + } + if(!self hasperk("specialty_deadshot")) + { + self give_perk("specialty_deadshot"); + } + } + if( getdvar( "mapname" ) == "zm_nuked" ) + { + if(!self hasperk("specialty_quickrevive")) + { + self give_perk("specialty_quickrevive"); + } + } + if( getdvar( "mapname" ) == "zm_tomb") + { + if(!self hasperk("specialty_deadshot")) + { + self give_perk( "specialty_deadshot" ); + } + if(!self hasperk("specialty_grenadepulldeath")) + { + self give_perk( "specialty_grenadepulldeath" ); + } + if(!self hasperk("specialty_flakjacket")) + { + self give_perk( "specialty_flakjacket" ); + } + if(!self hasperk("specialty_quickrevive")) + { + self give_perk( "specialty_quickrevive" ); + } + if(!self hasperk("specialty_additionalprimaryweapon")) + { + self give_perk( "specialty_additionalprimaryweapon" ); + } + if(!self hasperk("specialty_longersprint")) + { + self give_perk( "specialty_longersprint" ); + } + } + if( getdvar( "mapname" ) == "zm_buried") + { + if(!self hasperk("specialty_nomotionsensor")) + { + self give_perk("specialty_nomotionsensor"); + } + if(!self hasperk("specialty_additionalprimaryweapon")) + { + self give_perk( "specialty_additionalprimaryweapon" ); + } + if(!self hasperk("specialty_quickrevive")) + { + self give_perk( "specialty_quickrevive" ); + } + if(!self hasperk("specialty_longersprint")) + { + self give_perk( "specialty_longersprint" ); + } + } + if( getdvar( "mapname" ) == "zm_highrise" ) + { + if(!self hasperk("specialty_quickrevive")) + { + self give_perk("specialty_quickrevive"); + } + if(!self hasperk("specialty_finalstand")) + { + self give_perk( "specialty_finalstand" ); + } + if(!self hasperk("specialty_additionalprimaryweapon")) + { + self give_perk("specialty_additionalprimaryweapon"); + } + } + self.perk_reminder = self.num_perks; + self.perk_count = self.num_perks; + wait 0.2; + if(level.town) + { + if(!self hascustomperk("Downers_Delight")) + { + self drawshader_and_shadermove( "Downers_Delight", 0, 0 ); + wait 0.15; + } + if(!self hascustomperk("MULE")) + { + self drawshader_and_shadermove( "MULE", 0, 0 ); + wait 0.15; + } + if(!self hascustomperk("PHD_FLOPPER")) + { + self drawshader_and_shadermove( "PHD_FLOPPER", 0, 0 ); + wait 0.15; + } + if(!self hascustomperk("Victorious_Tortoise")) + { + self drawshader_and_shadermove( "Victorious_Tortoise", 0, 0 ); + wait 0.15; + } + if(!self hascustomperk("ELECTRIC_CHERRY")) + { + self drawshader_and_shadermove( "ELECTRIC_CHERRY", 0, 0 ); + wait 0.15; + } + if(!self hascustomperk("WIDOWS_WINE")) + { + self drawshader_and_shadermove( "WIDOWS_WINE", 0, 0 ); + wait 0.15; + } + if(!self hascustomperk("Ethereal_Razor")) + { + self drawshader_and_shadermove( "Ethereal_Razor", 0, 0 ); + wait 0.15; + } + if(!self hascustomperk("Ammo_Regen")) + { + self drawshader_and_shadermove( "Ammo_Regen", 0, 0 ); + wait 0.15; + } + if(!self hascustomperk("Burn_Heart")) + { + self drawshader_and_shadermove( "Burn_Heart", 0, 0 ); + wait 0.15; + } + if(!self hascustomperk("Dying_Wish")) + { + self drawshader_and_shadermove( "Dying_Wish", 0, 0 ); + wait 0.15; + } + if(!self hascustomperk("deadshot")) + { + self drawshader_and_shadermove( "deadshot", 0, 0 ); + wait 0.15; + } + } + if(level.diner) + { + if(!self hascustomperk("Downers_Delight")) + { + self thread drawshader_and_shadermove( "Downers_Delight", 0, 0 ); + } + if(!self hascustomperk("MULE")) + { + self thread drawshader_and_shadermove( "MULE", 0, 0 ); + } + if(!self hascustomperk("PHD_FLOPPER")) + { + self thread drawshader_and_shadermove( "PHD_FLOPPER", 0, 0 ); + } + if(!self hascustomperk("Victorious_Tortoise")) + { + self thread drawshader_and_shadermove( "Victorious_Tortoise", 0, 0 ); + } + if(!self hascustomperk("ELECTRIC_CHERRY")) + { + self thread drawshader_and_shadermove( "ELECTRIC_CHERRY", 0, 0 ); + } + if(!self hascustomperk("WIDOWS_WINE")) + { + self thread drawshader_and_shadermove( "WIDOWS_WINE", 0, 0 ); + } + if(!self hascustomperk("Ethereal_Razor")) + { + self thread drawshader_and_shadermove( "Ethereal_Razor", 0, 0 ); + } + } +} + diff --git a/t6/uncompiled mods/town_perkMODIFIED.gsc b/t6/uncompiled mods/town_perkMODIFIED.gsc new file mode 100644 index 0000000..2c874ea --- /dev/null +++ b/t6/uncompiled mods/town_perkMODIFIED.gsc @@ -0,0 +1,1020 @@ +//PLUTO v1 - TOWN Survival with Dogs + +#include maps/mp/_utility; +#include common_scripts/utility; +#include maps/mp/gametypes_zm/_hud_util; +#include maps/mp/zombies/_zm_weapons; +#include maps/mp/zombies/_zm_stats; +#include maps/mp/gametypes_zm/_spawnlogic; +#include maps/mp/animscripts/traverse/shared; +#include maps/mp/animscripts/utility; +#include maps/mp/zombies/_load; +#include maps/mp/_createfx; +#include maps/mp/_music; +#include maps/mp/_busing; +#include maps/mp/_script_gen; +#include maps/mp/gametypes_zm/_globallogic_audio; +#include maps/mp/gametypes_zm/_tweakables; +#include maps/mp/_challenges; +#include maps/mp/gametypes_zm/_weapons; +#include maps/mp/_demo; +#include maps/mp/gametypes_zm/_hud_message; +#include maps/mp/gametypes_zm/_spawning; +#include maps/mp/gametypes_zm/_globallogic_utils; +#include maps/mp/gametypes_zm/_spectating; +#include maps/mp/gametypes_zm/_globallogic_spawn; +#include maps/mp/gametypes_zm/_globallogic_ui; +#include maps/mp/gametypes_zm/_hostmigration; +#include maps/mp/gametypes_zm/_globallogic_score; +#include maps/mp/gametypes_zm/_globallogic; +#include maps/mp/zombies/_zm; +#include maps/mp/zombies/_zm_ai_faller; +#include maps/mp/zombies/_zm_spawner; +#include maps/mp/zombies/_zm_pers_upgrades_functions; +#include maps/mp/zombies/_zm_pers_upgrades; +#include maps/mp/zombies/_zm_score; +#include maps/mp/animscripts/zm_run; +#include maps/mp/animscripts/zm_death; +#include maps/mp/zombies/_zm_blockers; +#include maps/mp/animscripts/zm_shared; +#include maps/mp/animscripts/zm_utility; +#include maps/mp/zombies/_zm_ai_basic; +#include maps/mp/zombies/_zm_laststand; +#include maps/mp/zombies/_zm_net; +#include maps/mp/zombies/_zm_audio; +#include maps/mp/gametypes_zm/_zm_gametype; +#include maps/mp/_visionset_mgr; +#include maps/mp/zombies/_zm_equipment; +#include maps/mp/zombies/_zm_power; +#include maps/mp/zombies/_zm_server_throttle; +#include maps/mp/gametypes/_hud_util; +#include maps/mp/zombies/_zm_unitrigger; +#include maps/mp/zombies/_zm_zonemgr; +#include maps/mp/zombies/_zm_perks; +#include maps/mp/zombies/_zm_melee_weapon; +#include maps/mp/zombies/_zm_audio_announcer; +#include maps/mp/zombies/_zm_magicbox; +#include maps/mp/zombies/_zm_utility; +#include maps/mp/zombies/_zm_ai_dogs; +#include maps/mp/gametypes_zm/_hud_message; +#include maps/mp/zombies/_zm_game_module; +#include maps/mp/zombies/_zm_buildables; +#include codescripts/character; +#include maps/mp/zombies/_zm_weap_riotshield; +init() +{ + // if( (getdvar( "mapname" ) == "zm_transit" || getdvar( "mapname" ) == "zm_highrise") && getdvar ( "g_gametype") == "zstandard" ) + // { + precacheshader("menu_mp_lobby_icon_film"); + precacheshader( "menu_mp_lobby_icon_customgamemode" ); + precacheshader( "waypoint_revive" ); + precacheshader( "killiconheadshot" ); + precacheshader( "menu_lobby_icon_twitter" ); + precacheshader( "hud_grenadeicon" ); + precacheshader( "menu_mp_weapons_1911" ); + precacheshader( "menu_mp_lobby_icon_screenshot" ); + precacheshader( "damage_feedback" ); + precacheshader( "zombies_rank_1" ); + precacheshader( "zombies_rank_3" ); + precacheshader( "zombies_rank_2" ); + precacheshader( "zombies_rank_4" ); + precacheshader( "menu_mp_weapons_xm8" ); + precacheshader( "faction_cdc" ); + precacheshader( "menu_mp_weapons_hamr" ); + precacheshader( "zombies_rank_5" ); + precacheshader( "hud_icon_sticky_grenade" ); + precacheshader( "specialty_instakill_zombies" ); + precacheshader( "menu_mp_weapons_1911" ); + precacheshader( "hud_icon_colt" ); + precachemodel("p6_zm_buildable_sq_meteor"); + precachemodel( "collision_player_wall_512x512x10" ); + precachemodel( "collision_physics_512x512x10" ); + precachemodel( "t5_foliage_tree_burnt03" ); + precachemodel( "p_rus_door_roller" ); + precachemodel( "ch_tombstone1" ); + precachemodel( "collision_geo_256x256x10_standard" ); + precachemodel( "zombie_vending_tombstone_on" ); + precachemodel( "zombie_vending_revive_on" ); + precachemodel( "zombie_vending_sleight_on" ); + precachemodel( "zombie_vending_doubletap2_on" ); + precachemodel( "zombie_pickup_perk_bottle" ); + precachemodel( "zm_collision_perks1" ); + precachemodel( "p6_zm_screecher_hole" ); + precachemodel( "p_cub_door01_wood_fullsize" ); + precachemodel( "veh_t6_civ_microbus_dead" ); + precachemodel( "p_rus_door_white_window_plain_left" ); + level._effect["fx_zombie_cola_revive_on"] = loadfx( "misc/fx_zombie_cola_revive_on" ); + level._effect["fx_zombie_cola_dtap_on"] = loadfx( "misc/fx_zombie_cola_dtap_on" ); + level._effect["fx_zombie_cola_on"] = loadfx( "misc/fx_zombie_cola_on" ); + level._effect["fx_zmb_wall_buy_taseknuck"] = loadfx( "maps/zombie/fx_zmb_wall_buy_taseknuck" ); + level._effect["fx_zmb_wall_buy_bowie"] = loadfx( "maps/zombie/fx_zmb_wall_buy_bowie" ); + // level._effect["fx_default_explosion"] = loadfx( "explosions/fx_default_explosion" ); + + + if( level.script == "zm_buried" || level.script == "zm_tomb" ) + { + level._effect["fx_default_explosion"] = level._effect[ "divetonuke_groundhit"]; + } + else + { + level._effect["fx_default_explosion"] = loadfx( "explosions/fx_default_explosion" ); + } + + + level.town = 1; + level.diner = 0; + + level thread onPlayerConnect(); + level thread perk_machine_removal( "specialty_scavenger" ); + init_custom_map(); + + level.get_player_weapon_limit = ::custom_get_player_weapon_limit; + level.zombie_last_stand = ::LastStand; + level.custom_vending_precaching = ::default_vending_precaching; + + register_player_damage_callback( ::damage_callback ); + + + + + level.player_out_of_playable_area_monitor = 0; + level.perk_purchase_limit = 50; + foreach( weapon in level.zombie_weapons) + { + weapon.is_in_box = 1; + } +// } +} + + + +onPlayerConnect() +{ + while( 1 ) + { + level waittill( "connected", player ); + player thread onPlayerSpawned(); + } +} + +onPlayerSpawned() +{ + self endon( "disconnect" ); + level endon( "game_ended" ); + self waittill( "spawned_player" ); + + self.perkarray = []; + self.dying_wish_on_cooldown = 0; + self.perk_reminder = 0; + self.perk_count = 0; + self.num_perks = 0; + self thread removeperkshader(); + self thread perkboughtcheck(); + self thread damagehitmarker(); + for(;;) + { + self waittill( "spawned_player" ); + if(self.score < 1500) + { + self.score = 1500; + } + } +} + + + +damagehitmarker() +{ + self thread startwaiting(); + self.hitmarker = newdamageindicatorhudelem( self ); + self.hitmarker.horzalign = "center"; + self.hitmarker.vertalign = "middle"; + self.hitmarker.x = -12; + self.hitmarker.y = -12; + self.hitmarker.alpha = 0; + self.hitmarker setshader( "damage_feedback", 24, 48 ); + +} + +startwaiting() +{ + while( 1 ) + { + foreach( zombie in getaiarray( level.zombie_team ) ) + { + if( !(IsDefined( zombie.waitingfordamage )) ) + { + zombie thread hitmark(); + } + } + wait 0.25; + } +} + +hitmark() +{ + self endon( "killed" ); + self.waitingfordamage = 1; + while( 1 ) + { + self waittill( "damage", amount, attacker, dir, point, mod ); + attacker.hitmarker.alpha = 0; + if( isplayer( attacker ) ) + { + if( isalive( self ) ) + { + attacker.hitmarker.color = ( 1, 1, 1 ); + attacker.hitmarker.alpha = 1; + attacker.hitmarker fadeovertime( 1 ); + attacker.hitmarker.alpha = 0; + } + else + { + attacker.hitmarker.color = ( 1, 0, 0 ); + attacker.hitmarker.alpha = 1; + attacker.hitmarker fadeovertime( 1 ); + attacker.hitmarker.alpha = 0; + self notify( "killed" ); + } + } + } +} + + + + +init_custom_map() +{ + if( getdvar( "mapname" ) == "zm_transit" && getdvar ( "g_gametype" ) == "zstandard" ) + { + perk_system( "script_model", ( 1856, -810.722, -55.875), "zombie_vending_tombstone_on", ( 0, 180, 0 ), "custom", "mus_perks_deadshot_sting", "Deadshot", 2000, "tombstone_light", "deadshot" ); + perk_system( "script_model", ( 2460, -780, -55.875 ), "zombie_vending_tombstone_on", ( 0, 225, 0 ), "custom", "mus_perks_doubletap_sting", "Burn Heart", 2500, "jugger_light", "Burn_Heart" ); + perk_system( "script_model", ( 901.86, -1575.574, -47.875 ), "zombie_vending_tombstone_on", ( 0, 180, 0 ), "custom", "mus_perks_deadshot_sting", "Widow's Wine", 4000, "tombstone_light", "WIDOWS_WINE" ); + perk_system( "script_model", ( 450, -300.574, -61.875 ), "zombie_vending_tombstone_on", ( 0, 45, 0 ), "custom", "mus_perks_packa_sting", "Electric Cherry", 2000, "tombstone_light", "ELECTRIC_CHERRY" ); // 613,-250,z 0,0,0 + perk_system( "script_model", ( 1069, -1133, 120.125 ), "zombie_vending_tombstone_on", ( 0, 180, 0 ), "custom", "mus_perks_doubletap_sting", "Ethereal Razor", 3500, "tombstone_light", "Ethereal_Razor" ); + perk_system( "script_model", ( 1823.86, 670.574, -55.875 ), "zombie_vending_tombstone_on", ( 0, 45, 0 ), "custom", "mus_perks_doubletap_sting", "Mule Kick", 4000, "tombstone_light", "MULE" ); + perk_system( "script_model", ( 840, 603.809, -40.875 ), "zombie_vending_tombstone_on", ( 0, 0, 0 ), "custom", "mus_perks_packa_sting", "PhD Flopper", 2500, "tombstone_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( 2358, -87, -55.875 ), "zombie_vending_tombstone_on", ( 0, -90, 0 ), "custom", "mus_perks_doubletap_sting", "Downer's Delight", 2000, "tombstone_light", "Downers_Delight" ); + perk_system( "script_model", ( 2015, 858, -56.875 ), "zombie_vending_tombstone_on", ( 0, -90, 0 ), "custom", "mus_perks_doubletap_sting", "Dying Wish", 6000, "tombstone_light", "Dying_Wish" ); + perk_system( "script_model", ( 559, -1364, 120.125 ), "zombie_vending_tombstone_on", ( 0, 180, 0 ), "custom", "mus_perks_doubletap_sting", "Ammo Regen", 3000, "tombstone_light", "Ammo_Regen" ); + } + if( level.script == "zm_highrise") + { + perk_system( "script_model", ( 1884.42, 491.946, 1298.72), "zombie_vending_jugg_on", ( 0, 418.728, 0 ), "custom", "mus_perks_deadshot_sting", "Deadshot", 2000, "tombstone_light", "deadshot" ); +// perk_system( "script_model", ( 2764.64, 1868.03, 1391.01 ), "zombie_vending_jugg_on", ( 0, 384.236, 0 ), "custom", "mus_perks_doubletap_sting", "Burn Heart", 2500, "jugger_light", "Burn_Heart" ); + perk_system( "script_model", ( 1978.25, 597.657, 2704.13 ), "zombie_vending_jugg_on", ( 0, 329.291, 0 ), "custom", "mus_perks_deadshot_sting", "Widow's Wine", 4000, "tombstone_light", "WIDOWS_WINE" ); + perk_system( "script_model", ( 1478.64, 1529.64, 3216.13 ), "zombie_vending_jugg_on", ( 0, 182.54, 0 ), "custom", "mus_perks_packa_sting", "Electric Cherry", 2000, "tombstone_light", "ELECTRIC_CHERRY" ); // 613,-250,z 0,0,0 + perk_system( "script_model", ( 1901.97, 1431.36, 3216.13 ), "zombie_vending_jugg_on", ( 0, 404.762, 0 ), "custom", "mus_perks_doubletap_sting", "Ethereal Razor", 3500, "tombstone_light", "Ethereal_Razor" ); +// perk_system( "script_model", ( 1891.64, 1119.64, 3048.36 ), "zombie_vending_jugg_on", ( 0, 45, 0 ), "custom", "mus_perks_doubletap_sting", "Mule Kick", 4000, "tombstone_light", "MULE" ); + perk_system( "script_model", ( 1429.29, -453.397, 2880.13 ), "zombie_vending_jugg_on", ( 0, 149.1426, 0 ), "custom", "mus_perks_packa_sting", "PhD Flopper", 2500, "tombstone_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( 1109.64, 2701.36, 3043.82 ), "zombie_vending_jugg_on", ( 0, 394.926, 0 ), "custom", "mus_perks_doubletap_sting", "Downer's Delight", 2000, "tombstone_light", "Downers_Delight" ); + perk_system( "script_model", ( 1706.28, 1055.64, 3395.1 ), "zombie_vending_jugg_on", ( 0, 180, 0 ), "custom", "mus_perks_doubletap_sting", "Dying Wish", 6000, "tombstone_light", "Dying_Wish" ); + perk_system( "script_model", ( 2269.17, 182.377, 2880.13 ), "zombie_vending_jugg_on", ( 0, 418.596, 0 ), "custom", "mus_perks_doubletap_sting", "Ammo Regen", 3000, "tombstone_light", "Ammo_Regen" ); + } + if( level.script == "zm_buried") + { + perk_system( "script_model", ( 1618.14, 1513.46, 200.62), "zombie_vending_jugg_on", ( 0, 250.147, 0 ), "custom", "mus_perks_deadshot_sting", "Deadshot", 2000, "sleight_light", "deadshot" ); +// perk_system( "script_model", ( -1176.36, 508.26, 144.125 ), "zombie_vending_jugg_on", ( 0, 448.269, 0 ), "custom", "mus_perks_doubletap_sting", "Burn Heart", 2500, "sleight_light", "Burn_Heart" ); + perk_system( "script_model", ( -1176.36, 510.625, 144.125 ), "zombie_vending_jugg_on", ( 0, 449.412, 0 ), "custom", "mus_perks_deadshot_sting", "Widow's Wine", 4000, "sleight_light", "WIDOWS_WINE" ); + perk_system( "script_model", ( -448.859, 131.435, 143.491 ), "zombie_vending_jugg_on", ( 0, 180.3, 0 ), "custom", "mus_perks_packa_sting", "Electric Cherry", 2000, "sleight_light", "ELECTRIC_CHERRY" ); // 613,-250,z 0,0,0 + perk_system( "script_model", ( 890.359, -840.206, -22.8006 ), "zombie_vending_jugg_on", ( 0, 270.367, 0 ), "custom", "mus_perks_doubletap_sting", "Ethereal Razor", 3500, "sleight_light", "Ethereal_Razor" ); +// perk_system( "script_model", ( 1891.64, 1119.64, 3048.36 ), "zombie_vending_jugg_on", ( 0, 45, 0 ), "custom", "mus_perks_doubletap_sting", "Mule Kick", 4000, "sleight_light", "MULE" ); + perk_system( "script_model", ( 572.507, -712.359, 149.95 ), "zombie_vending_jugg_on", ( 0, 178.4505, 0 ), "custom", "mus_perks_packa_sting", "PhD Flopper", 2500, "sleight_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( 488.324, 727.641, 176.125 ), "zombie_vending_jugg_on", ( 0, 178.9998, 0 ), "custom", "mus_perks_doubletap_sting", "Downer's Delight", 2000, "sleight_light", "Downers_Delight" ); + perk_system( "script_model", ( -1298.32, -837.178, -23.875 ), "zombie_vending_jugg_on", ( 0, 91.37286, 0 ), "custom", "mus_perks_doubletap_sting", "Dying Wish", 6000, "sleight_light", "Dying_Wish" ); + perk_system( "script_model", ( -122.161, -1469.21, 168.125 ), "zombie_vending_jugg_on", ( 0, 448.841, 0 ), "custom", "mus_perks_doubletap_sting", "Ammo Regen", 3000, "sleight_light", "Ammo_Regen" ); + } + if( level.script == "zm_nuked") + { + perk_system( "script_model", ( 28.8155, -356.18, -65.8346 ), "zombie_vending_jugg_on", ( 0, 129.8755, 0 ), "custom", "mus_perks_deadshot_sting", "Deadshot", 2000, "sleight_light", "deadshot" ); +// perk_system( "script_model", ( ), "zombie_vending_jugg_on", ( ), "custom", "mus_perks_doubletap_sting", "Burn Heart", 2500, "sleight_light", "Burn_Heart" ); + perk_system( "script_model", ( -954.194, 714.594, 84.0385 ), "zombie_vending_jugg_on", ( 0, 429.46, 0 ), "custom", "mus_perks_deadshot_sting", "Widow's Wine", 4000, "sleight_light", "WIDOWS_WINE" ); + perk_system( "script_model", ( 683.524, 618.635, -56.875 ), "zombie_vending_jugg_on", ( 0, 102.5635, 0 ), "custom", "mus_perks_packa_sting", "Electric Cherry", 2000, "sleight_light", "ELECTRIC_CHERRY" ); // 613,-250,z 0,0,0 + perk_system( "script_model", ( 1420.35, -21.4313, -63.8849 ), "zombie_vending_jugg_on", ( 0, 194.085, 0 ), "custom", "mus_perks_doubletap_sting", "Ethereal Razor", 3500, "sleight_light", "Ethereal_Razor" ); +// perk_system( "script_model", ( ), "zombie_vending_jugg_on", ( 0, 283.349, 0 ), "custom", "mus_perks_doubletap_sting", "Mule Kick", 4000, "sleight_light", "MULE" ); + perk_system( "script_model", ( 1152.5, 160.6, 79.125 ), "zombie_vending_jugg_on", ( 0, 283.349, 0 ), "custom", "mus_perks_packa_sting", "PhD Flopper", 2500, "sleight_light", "PHD_FLOPPER" ); + perk_system( "script_model", ( 156.738, 513.899, -62.3141 ), "zombie_vending_jugg_on", ( 0, 101.8164, 0 ), "custom", "mus_perks_doubletap_sting", "Downer's Delight", 2000, "sleight_light", "Downers_Delight" ); + perk_system( "script_model", ( -646.863, 271.522, -55.875 ), "zombie_vending_jugg_on", ( 0, 160.8405, 0 ), "custom", "mus_perks_doubletap_sting", "Dying Wish", 6000, "sleight_light", "Dying_Wish" ); + perk_system( "script_model", ( -1582.46, 112.604, -63.2092 ), "zombie_vending_jugg_on", ( 0, 250.829, 0 ), "custom", "mus_perks_doubletap_sting", "Ammo Regen", 3000, "sleight_light", "Ammo_Regen" ); + } +} + +play_fx( fx ) +{ + playfxontag( level._effect[ fx ], self, "tag_origin" ); +} + +defaulth_vending_precaching() +{ + level._effect[ "sleight_light" ] = loadfx( "misc/fx_zombie_cola_on" ); + level._effect[ "tombstone_light" ] = loadfx( "misc/fx_zombie_cola_on" ); + level._effect[ "revive_light" ] = loadfx( "misc/fx_zombie_cola_revive_on" ); + level._effect[ "marathon_light" ] = loadfx( "maps/zombie/fx_zmb_cola_staminup_on" ); + level._effect[ "jugger_light" ] = loadfx( "misc/fx_zombie_cola_jugg_on" ); + level._effect[ "doubletap_light" ] = loadfx( "misc/fx_zombie_cola_dtap_on" ); + level._effect[ "deadshot_light" ] = loadfx( "misc/fx_zombie_cola_dtap_on" ); + level._effect[ "additionalprimaryweapon_light" ] = loadfx( "misc/fx_zombie_cola_arsenal_on" ); + level._effect[ "packapunch_fx" ] = loadfx( "maps/zombie/fx_zombie_packapunch" ); + level._effect[ "wall_taseknuck" ] = loadfx( "maps/zombie/fx_zmb_wall_buy_taseknuck" ); +} + + +playchalkfx(effect, origin, angles) +{ + fx = SpawnFX(level._effect[ effect ], origin,AnglesToForward(angles),AnglesToUp(angles)); + TriggerFX(fx); + level waittill("connected", player); + fx Delete(); +} + + + +perk_system( script, pos, model, angles, type, sound, name, cost, fx, perk) +{ + col = spawn( script, pos); + col setmodel( model ); + col.angles = angles; + x = spawn( script, pos ); + x setmodel( "zm_collision_perks1" ); + x.angles = angles; + col thread buy_system( perk, sound, name, cost, type ); + col thread play_fx( fx ); +} + +buy_system( perk, sound, name, cost, type ) +{ + self endon( "game_ended" ); + while( 1 ) + { + foreach( player in level.players ) + { + if(!player.machine_is_in_use) + { + if( distance( self.origin, player.origin ) <= 70 ) + { + player thread SpawnHint( self.origin, 30, 30, "HINT_ACTIVATE", "Hold ^3&&1^7 for " + name + " [Cost: " + cost + "]" ); + if(player usebuttonpressed() && !player hasperk(perk) && !player hascustomperk(perk) && player.score >= cost && !player maps/mp/zombies/_zm_laststand::player_is_in_laststand()) + { + player.machine_is_in_use = 1; + player playsound( "zmb_cha_ching" ); + player.score -= cost; + player playsound( sound ); + player thread drawshader_and_shadermove( perk, 1, 1 ); + wait 4; + player.machine_is_in_use = 0; + } + else + { + if( player usebuttonpressed() && player.score < cost ) + { + player maps/mp/zombies/_zm_audio::create_and_play_dialog( "general", "perk_deny", undefined, 0 ); + } + } + } + } + } + wait 0.1; + } +} + +hascustomperk(perk) +{ + for(i = 0; i < self.perkarray.size; i++) + { + if(self.perkarray[i].name == perk) + { + return 1; + } + } + return 0; +} + +removeperkshader() +{ + for(;;) + { + self waittill_any_return( "fake_death", "player_downed", "player_revived", "spawned_player", "disconnect", "death" ); + self.num_perks = 0; + self.perk_reminder = 0; + self.perk_count = 0; + self.dying_wish_on_cooldown = 0; + self removeallcustomshader(); + self.perkarray = []; + self notify( "stopcustomperk" ); + self.bleedout_time = 30; + self.ignore_lava_damage = 0; + self setclientfieldtoplayer( "deadshot_perk", 0 ); + } +} + +removeallcustomshader() +{ + for(i = 0; i < self.perkarray.size; i++) + { + self.perkarray[i] destroy(); + } +} + +drawshader( shader, x, y, width, height, color, alpha, sort ) +{ + hud = newclienthudelem( self ); + hud.elemtype = "icon"; + hud.color = color; + hud.alpha = alpha; + hud.sort = sort; + hud.children = []; + hud.hidewheninmenu = 1; + hud setparent( level.uiparent ); + hud setshader( shader, width, height ); + hud.x = x; + hud.y = y; + return hud; +} + +perkboughtcheck() +{ + self endon("death"); + self endon("disconnect"); + for(;;) + { + self.perk_reminder = self.num_perks; + self waittill("perk_acquired"); + n = 1; + if(!(self.num_perks > self.perk_reminder)) + { + n = (self.num_perks - self.perk_reminder); + self.num_perks = (self.perk_reminder + n); + } + self.perk_reminder = self.num_perks; + self.perk_count += n; + self drawshader_and_shadermove("none", 0, 0); + } +} + +drawshader_and_shadermove(perk, custom, print) +{ + if(custom) + { + self allowProne(false); + self allowSprint(false); + self disableoffhandweapons(); + self disableweaponcycling(); + weapona = self getcurrentweapon(); + weaponb = "zombie_perk_bottle_jugg"; + self giveweapon( weaponb ); + self switchtoweapon( weaponb ); + self waittill( "weapon_change_complete" ); + self enableoffhandweapons(); + self enableweaponcycling(); + self takeweapon( weaponb ); + self switchtoweapon( weapona ); + self maps/mp/zombies/_zm_audio::playerexert( "burp" ); + self setblur( 4, 0.1 ); + wait 0.1; + self setblur( 0, 0.1 ); + self allowProne(true); + self allowSprint(true); + } + x = -408 + (self.perk_count * 30); + for(i = 0; i < self.perkarray.size; i++) + { + self.perkarray[i].x = self.perkarray[i].x + 30; + } + if(perk == "Downers_Delight") + { + self.perk1back = self drawshader( "specialty_marathon_zombies", x, 350, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk1front = self drawshader( "waypoint_revive", x, 350, 23, 23, ( 0, 1, 1 ), 100, 0 ); + self.perk1front.name = perk; + self.perkarray[self.perkarray.size] = self.perk1front; + self.perk1back.name = perk; + self.perkarray[self.perkarray.size] = self.perk1back; + self.num_perks++; + self thread DDown(); + if(print) + { + self iprintln("^9Downer's Delight"); + wait 0.2; + self iprintln("This Perk will increase players bleedout time by 10 seconds and current weapons is used in laststand."); + } + } + if(perk == "MULE") + { + self.perk2back = self drawshader( "specialty_marathon_zombies", x, 350, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk2front = self drawshader( "menu_mp_weapons_1911", x, 350, 22, 22, ( 0, 1, 0 ), 100, 0 ); + self.perk2front.name = perk; + self.perkarray[self.perkarray.size] = self.perk2front; + self.perk2back.name = perk; + self.perkarray[self.perkarray.size] = self.perk2back; + self.num_perks++; + if(print) + { + self iprintln("^9Mule Kick"); + wait 0.2; + self iprintln("This Perk enables additional primary weapon slot for player. "); + } + } + if(perk == "PHD_FLOPPER") + { + self.perk3back = self drawshader( "specialty_marathon_zombies", x, 350, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk3front = self drawshader( "hud_icon_sticky_grenade", x, 350, 23, 23, (1, 0, 1 ), 100, 0 ); + self.perk3front.name = perk; + self.perkarray[self.perkarray.size] = self.perk3front; + self.perk3back.name = perk; + self.perkarray[self.perkarray.size] = self.perk3back; + self.num_perks++; + if(print) + { + self iprintln("^9PhD Flopper"); + wait 0.2; + self iprintln("This Perk removes explosion and fall damage also player creates explosion when dive to prone."); + } + } + if(perk == "Victorious_Tortoise") + { + self.perk4back = self drawshader( "specialty_marathon_zombies", x, 350, 24, 24, ( 0, 200, 0 ), 100, 0 ); + self.perk4front = self drawshader( "zombies_rank_2", x, 350, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk4front.name = perk; + self.perkarray[self.perkarray.size] = self.perk4front; + self.perk4back.name = perk; + self.perkarray[self.perkarray.size] = self.perk4back; + self.num_perks++; + self thread start_vt(); + if(print) + { + self iprintln("^9Victorious Tortoise"); + wait 0.2; + self iprintln("This Perk allows shield block damage from all directions when in use."); + } + } + if(perk == "ELECTRIC_CHERRY") + { + self.perk5back = self drawshader( "specialty_marathon_zombies", x, 350, 24, 24, ( 0, 0, 200 ), 100, 0 ); + self.perk5front = self drawshader( "zombies_rank_5", x, 350, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk5front.name = perk; + self.perkarray[self.perkarray.size] = self.perk5front; + self.perk5back.name = perk; + self.perkarray[self.perkarray.size] = self.perk5back; + self.num_perks++; + self thread start_ec(); + if(print) + { + self iprintln("^9Electric Cherry"); + wait 0.2; + self iprintln("This Perk creates an electric shockwave around the player whenever they reload."); + } + } + if(perk == "WIDOWS_WINE") + { + self.perk6back = self drawshader( "specialty_marathon_zombies", x, 350, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk6front = self drawshader( "zombies_rank_3", x, 350, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk6front.name = perk; + self.perkarray[self.perkarray.size] = self.perk6front; + self.perk6back.name = perk; + self.perkarray[self.perkarray.size] = self.perk6back; + self.num_perks++; + self takeweapon( self get_player_lethal_grenade() ); + self set_player_lethal_grenade( "sticky_grenade_zm" ); + self giveweapon("sticky_grenade_zm"); + self thread ww_nades(); + if(print) + { + self iprintln("^9Widow's Wine"); + wait 0.2; + self iprintln("This Perk damages zombies around the player when player is hit and grenades are upgraded."); + } + } + if(perk == "Ethereal_Razor") + { + self.perk7back = self drawshader( "specialty_marathon_zombies", x, 350, 24, 24, ( 200, 0, 0 ), 100, 0 ); + self.perk7front = self drawshader( "zombies_rank_4", x, 350, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk7front.name = perk; + self.perkarray[self.perkarray.size] = self.perk7front; + self.perk7back.name = perk; + self.perkarray[self.perkarray.size] = self.perk7back; + self.num_perks++; + if(print) + { + self iprintln("^9Ethereal Razor"); + wait 0.2; + self iprintln("This Perk deals extra damage when player using melee attacks and restores a small amount of health."); + } + } + if(perk == "Ammo_Regen") + { + self.perk8back = self drawshader( "specialty_marathon_zombies", x, 350, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk8front = self drawshader( "menu_mp_lobby_icon_customgamemode", x, 350, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk8front.name = perk; + self.perkarray[self.perkarray.size] = self.perk8front; + self.perk8back.name = perk; + self.perkarray[self.perkarray.size] = self.perk8back; + self.num_perks++; + self thread ammoregen(); + self thread grenadesregen(); + if(print) + { + self iprintln("^9Ammo Regen"); + wait 0.2; + self iprintln("This Perk will slowly regenerades players ammonation and grenades."); + } + } + if(perk == "Burn_Heart") + { + self.perk9back = self drawshader( "specialty_marathon_zombies", x, 350, 24, 24, ( 200, 0, 0 ), 100, 0 ); + self.perk9front = self drawshader( "faction_cdc", x, 350, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk9front.name = perk; + self.perkarray[self.perkarray.size] = self.perk9front; + self.perk9back.name = perk; + self.perkarray[self.perkarray.size] = self.perk9back; + self.num_perks++; + self.ignore_lava_damage = 1; + if(print) + { + self iprintln("^9Burn Heart"); + wait 0.2; + self iprintln("This Perk removes lava damage."); + } + } + if(perk == "Dying_Wish") + { + self.perk10back = self drawshader( "specialty_marathon_zombies", x, 350, 24, 24, ( 200, 0, 0 ), 100, 0 ); + self.perk10front = self drawshader( "zombies_rank_5", x, 350, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk10front.name = perk; + self.perkarray[self.perkarray.size] = self.perk10front; + self.perk10back.name = perk; + self.perkarray[self.perkarray.size] = self.perk10back; + self.num_perks++; + self thread dying_wish_checker(); + if(print) + { + self iprintln("^9Dying Wish"); + wait 0.2; + self iprintln("This Perk allow player to go berserker mode for 9 seconds instead of laststand."); + wait 0.1; + self iprintln(" (cooldown 5mins and it's increased 30sec every time perk is used. - max 10mins) "); + } + } + if(perk == "deadshot") + { + self.perk11back = self drawshader( "specialty_marathon_zombies", x, 350, 24, 24, ( 0, 0, 0 ), 100, 0 ); + self.perk11front = self drawshader( "killiconheadshot", x, 350, 23, 23, ( 1, 1, 1 ), 100, 0 ); + self.perk11front.name = perk; + self.perkarray[self.perkarray.size] = self.perk11front; + self.perk11back.name = perk; + self.perkarray[self.perkarray.size] = self.perk11back; + self.num_perks++; + self setclientfieldtoplayer( "deadshot_perk", 1 ); + if(print) + { + self iprintln("^9Deadshot"); + wait 0.2; + self iprintln("This Perk aims automatically enemys head instead of body."); + } + } +} + +custom_get_player_weapon_limit( player ) +{ + weapon_limit = 2; + if ( player hascustomperk("MULE") ) + { + weapon_limit = 3; + } + else + { + weapons = self getWeaponsListPrimaries(); + if(weapons.size > 2) + { + self takeWeapon(weapons[2]); + } + } + return weapon_limit; +} + +ammoregen() +{ + self endon( "disconnect" ); + level endon( "end_game" ); + self endon( "stopcustomperk" ); + for(;;) + { + if(!self GetCurrentWeapon() == "" && !is_grenade_launcher( self GetCurrentWeapon()) ) + { + stockcount = self getweaponammostock( self GetCurrentWeapon() ); + self setWeaponAmmostock( self GetCurrentWeapon(), stockcount + 1 ); + wait 2; + } + wait 0.1; + } +} + +grenadesregen() +{ + self endon( "disconnect" ); + level endon( "end_game" ); + self endon( "stopcustomperk" ); + for(;;) + { + grenades = self get_player_lethal_grenade(); + grenade_count = self getweaponammoclip(grenades); + if(grenade_count < 4) + { + self setweaponammoclip(grenades, (grenade_count + 1)); + } + tactical_grenades = self get_player_tactical_grenade(); + tactical_grenade_count = self getweaponammoclip(tactical_grenades); + if(tactical_grenade_count < 3 ) + { + self setweaponammoclip(tactical_grenades, (tactical_grenade_count + 1)); + } + wait 300; + } +} + +start_ec() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("stopcustomperk"); + for(;;) + { + self waittill( "reload_start" ); + playfxontag( level._effect[ "poltergeist"], self, "J_SpineUpper" ); + self EnableInvulnerability(); + RadiusDamage(self.origin, 120, 200, 100, self); + self DisableInvulnerability(); + self playsound( "zmb_turbine_explo" ); + wait 1; + } +} + +start_vt() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("stopcustomperk"); + for(;;) + { + if(self getcurrentweapon() == "riotshield_zm" ) + { + self enableInvulnerability(); + self.shielddamagetaken += 100; + wait 0.9; + } + else + { + self disableInvulnerability(); + } + wait 0.1; + } +} + +start_er() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("stopcustomperk"); + for(;;) + { + if (self hascustomperk("Ethereal_Razor") && self ismeleeing()) + { + foreach(zombie in getAiArray(level.zombie_team)) + { + if( distance( self.origin, zombie.origin ) <= 100 ) + { + + } + } + self.health += 20; + if(self.health > self.maxhealth) + { + self.health = self.maxhealth; + } + while(self ismeleeing()) + { + wait 0.1; + } + } + wait 0.05; + } +} + +LastStand() +{ + if(self hascustomperk("Downers_Delight")) + { + self.customlaststandweapon = self getcurrentweapon(); + self switchtoweapon( self.customlaststandweapon ); + self setweaponammoclip( self.customlaststandweapon, 150 ); + self.bleedout_time = 40; + } + else + { + self maps/mp/zombies/_zm::last_stand_pistol_swap(); + } +} + +DDown() +{ + self endon( "disconnect" ); + level endon( "end_game" ); + self endon( "stopcustomperk" ); + for(;;) + { + self waittill("player_downed"); + self playsound( "zmb_phdflop_explo" ); + playfx(loadfx("explosions/fx_default_explosion"), self.origin, anglestoforward( ( 0, 45, 55 ) ) ); + RadiusDamage(self.origin, 150, 600, 400, self); + wait 0.1; + } +} + +doGivePerk(perk) +{ + self endon("disconnect"); + self endon("death"); + level endon("game_ended"); + self endon("perk_abort_drinking"); + if (!(self hasperk(perk) || (self maps/mp/zombies/_zm_perks::has_perk_paused(perk)))) + { + gun = self maps/mp/zombies/_zm_perks::perk_give_bottle_begin(perk); + evt = self waittill_any_return("fake_death", "death", "player_downed", "weapon_change_complete"); + if (evt == "weapon_change_complete") + self thread maps/mp/zombies/_zm_perks::wait_give_perk(perk, 1); + self maps/mp/zombies/_zm_perks::perk_give_bottle_end(gun, perk); + if (self maps/mp/zombies/_zm_laststand::player_is_in_laststand() || isDefined(self.intermission) && self.intermission) + return; + self notify("burp"); + } +} + + +SpawnHint( origin, width, height, cursorhint, string ) +{ + hint = spawn( "trigger_radius", origin, 1, width, height ); + hint setcursorhint( cursorhint, hint ); + hint sethintstring( string ); + hint setvisibletoall(); + wait 0.2; + hint delete(); +} + + +ww_points( player ) +{ + for(i = 0; i < 3; i++) + { + self maps/mp/zombies/_zm_utility::set_zombie_run_cycle("walk"); + player maps/mp/zombies/_zm_score::add_to_player_score( 10 ); + PlayFXOnTag(level.effect_WebFX,self,"j_spineupper"); + self doDamage(150, (0, 0, 0)); + wait 1; + } +} + +ww_nade_explosion() +{ + wait 2; + // if( self maps/mp/zm_transit_lava::object_touching_lava()) +// { + // self delete(); + // return 0; + // } + foreach(zombie in getAiArray(level.zombie_team)) + { + if( distance( zombie.origin, self.origin ) < 210 ) + { + zombie thread ww_points( self ); + } + } + self delete(); +} + +ww_nades() +{ + level endon("end_game"); + self endon("disconnect"); + self endon("stopcustomperk"); + for(;;) + { + self waittill( "grenade_fire", grenade, weapname ); + if( weapname == "sticky_grenade_zm" ) + { + ww_nade = spawnsm( grenade.origin, "zombie_bomb" ); + ww_nade hide(); + ww_nade linkto( grenade ); + ww_nade thread ww_nade_explosion(); + } + } +} + +spawnsm( origin, model, angles ) +{ + ent = spawn( "script_model", origin ); + ent setmodel( model ); + if( IsDefined( angles ) ) + { + ent.angles = angles; + } + return ent; +} + + +damage_callback( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime, boneindex ) +{ + if( isDefined( eAttacker.is_zombie ) && eAttacker.is_zombie && self hascustomperk("WIDOWS_WINE") ) + { + zombies = getaiarray(level.zombie_team); + foreach(zombie in zombies) + { + if(distance(self.origin, zombie.origin) < 150) + { + grenades = self get_player_lethal_grenade(); + grenade_count = self getweaponammoclip(grenades); + if(grenade_count > 0) + { + self PlaySound("zmb_elec_jib_zombie"); + self setweaponammoclip(grenades, (grenade_count - 1)); + zombie thread ww_points( self ); + } + } + } + } + if(self hascustomperk("PHD_FLOPPER")) + { + if( smeansofdeath == "MOD_FALLING" ) + { + if(isDefined( self.divetoprone ) && self.divetoprone == 1 ) + { + radiusdamage( self.origin, 300, 5000, 1000, self, "MOD_GRENADE_SPLASH" ); + playfx(loadfx("explosions/fx_default_explosion"), self.origin, anglestoforward( ( 0, 45, 55 ) ) ); + self playsound( "zmb_phdflop_explo" ); + } + return 0; + } + if( smeansofdeath == "MOD_PROJECTILE" || smeansofdeath == "MOD_PROJECTILE_SPLASH" || smeansofdeath == "MOD_GRENADE" || smeansofdeath == "MOD_GRENADE_SPLASH" && eattacker == self) + { + return 0; + } + } + if(idamage > self.health && !self.dying_wish_on_cooldown && self hascustomperk("Dying_Wish") ) + { + self notify("dying_wish_charge"); + self thread dying_wish_effect(); + return 0; + } + else + { + return idamage; + } +} + +dying_wish_checker() +{ + level endon("end_game"); + self endon("disconnect"); + self endon( "stopcustomperk" ); + self.dying_wish_uses = 0; + for(;;) + { + self.dying_wish_on_cooldown = 0; + self.perk10back.alpha = 1; + self.perk10front.alpha = 1; + self waittill("dying_wish_charge"); + self.perk10back.alpha = 0.3; + self.perk10front.alpha = 0.4; + self.dying_wish_uses++; + self.dying_wish_on_cooldown = 1; + delay = 300 + (self.dying_wish_uses * 30); + if(delay >= 600) + delay = 600; + wait delay; + } +} + +dying_wish_effect() +{ + self enableInvulnerability(); + self.ignoreme = 1; + self useServerVisionSet(true); + self setvisionsetforplayer( "zombie_death", 0 ); + self freezeControls(1); + wait 1; + self freezeControls(0); + wait 8; + self.health = 1; + self disableInvulnerability(); + self.ignoreme = 0; + self useServerVisionSet(false); + self setvisionsetforplayer("remote_mortar_enhanced", 0); +} + + +player_burning_audio() +{ + fire_ent = spawn( "script_model", self.origin ); + wait_network_frame(); + fire_ent linkto( self ); + fire_ent playloopsound( "evt_plr_fire_loop" ); + self waittill_any( "stop_flame_damage", "stop_flame_sounds", "death", "disconnect" ); + fire_ent delete(); +} diff --git a/t6/uncompiled mods/trials-compiled.gsc b/t6/uncompiled mods/trials-compiled.gsc new file mode 100644 index 0000000000000000000000000000000000000000..c3ad118e69218e6d4290025051e878cf4a0664a9 GIT binary patch literal 55272 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 literal 0 HcmV?d00001 diff --git a/t6/uncompiled mods/trials.gsc b/t6/uncompiled mods/trials.gsc new file mode 100644 index 0000000..f211a61 --- /dev/null +++ b/t6/uncompiled mods/trials.gsc @@ -0,0 +1,1844 @@ +#include codescripts/struct; +#include maps/mp/_utility; +#include common_scripts/utility; +#include maps/mp/gametypes_zm/_hud; +#include maps/mp/gametypes_zm/_hud_util; +#include maps/mp/gametypes_zm/_hud_message; +#include maps/mp/gametypes_zm/_weapons; +#include maps/mp/zombies/_zm_powerups; +#include maps/mp/zombies/_zm_buildables; +#include maps/mp/zombies/_zm_score; +#include maps/mp/zombies/_zm_utility; +#include maps/mp/zombies/_zm_weapons; +#include maps/mp/gametypes_zm/_spawning; +#include maps/mp/zombies/_zm_unitrigger; +#include maps/mp/zombies/_zm_spawner; +#include maps/mp/zombies/_zm; +#include maps/mp/zombies/_zm_perks; +#include maps/mp/zombies/_zm_zonemgr; +#include maps/mp/zombies/_zm_magicbox; +#include maps/mp/zombies/_zm_power; +#include maps/mp/zombies/_zm_powerups; +#include maps/mp/animscripts/zm_utility; + +// Trials System by ZECxR3ap3r & John Kramer +// V1.0.1 + +init() { + // Precaching Models + precachemodel("t6_wpn_zmb_jet_gun_world"); + precachemodel("zombie_pickup_perk_bottle"); + precachemodel("t6_wpn_zmb_raygun_view"); + precachemodel("p6_anim_zm_buildable_pap"); + precachemodel("collision_wall_256x256x10_standard"); + precachemodel("p6_zm_hr_lion_statue_base"); + precachemodel("p6_zm_hr_lion_statue"); + // Precaching Shaders + precacheshader("gradient"); + precacheshader("white"); + precacheshader("menu_mp_star_rating"); + precacheshader("gradient_fadein"); + precacheshader("scorebar_zom_1"); + precacheshader("codtv_info"); + // Settings + setDvar("TrialsCost", 100);// How Much the trials will cost + setDvar("TrialsAllowFreePerk", 1);// Adds a Free Perk Powerup to the Trials Rewards + setDvar("TrialsEnableWonderweapons", 1);// Adds Legendary Wonderweapon Rewards + setDvar("TrialsEnablePapDrop", 1);// Adds Legendary Pap Powerup Reward + // Setup + if(level.script == "zm_transit") { + if(getDvar( "ui_zm_mapstartlocation" ) == "transit" && getDvar( "ui_zm_gamemodegroup" ) != "zsurvival"|| getDvar( "ui_zm_mapstartlocation" ) == "town"){ + Collision = spawn( "script_model", (655.126, -281.746, -61.875)); + Collision.angles = (0, 0, 0); + Collision setmodel("collision_wall_512x512x10_standard"); + PodiumModel = "t6_wpn_zmb_jet_gun_world"; + PodiumOrigin = array((495.129, -289.81, -39.875), (595.129, -289.81, -39.875), (775.129, -289.81, -39.875), (875.129, -289.81, -39.875)); + PodiumAngles = array((90, 270, 0), (90, 270, 0), (90,270,0), (90,270,0)); + TrialsMainModel = "zombie_teddybear"; + TrialsMainOrigin = (685.358, -277.641, -33.0248); + TrialsMainAngles = (0, -90, 0); + FXOriginOffset = (0,10,18); + } + else if ( getDvar( "ui_zm_mapstartlocation" ) == "farm" ) { + Collision = spawn( "script_model", (7070.82, -5715.47, -46.2625)); + Collision.angles = (0, 90, 0); + Collision setmodel("collision_wall_256x256x10_standard"); + PodiumModel = "t6_wpn_zmb_jet_gun_world"; + PodiumOrigin = array((7070.94, -5798.61, -28.2646), (7070.94, -5744.61, -28.2646), (7070.94, -5692.61, -28.2646), (7070.94, -5638.61, -28.2646)); + PodiumAngles = array((90, 0, 0), (90, 0, 0), (90,0,0), (90,0,0)); + TrialsMainModel = "zombie_teddybear"; + TrialsMainOrigin = (7670.15, -5562.8, 50.5099); + TrialsMainAngles = (0, -50, 0); + FXOriginOffset = (-12,0,20); + } + else if ( getDvar( "ui_zm_mapstartlocation" ) == "transit" && getDvar( "ui_zm_gamemodegroup" ) == "zsurvival") { + Collision = spawn( "script_model", (-6289.62, 5455.29, 74.125)); + Collision.angles = (0, 90, 0); + Collision setmodel("collision_wall_256x256x10_standard"); + PodiumModel = "t6_wpn_zmb_jet_gun_world"; + PodiumOrigin = array((-6284.36, 5347.11, -35.875), (-6284.36, 5407.11, -35.875), (-6284.36, 5467.11, -35.875), (-6284.36, 5527.11, -35.875)); + PodiumAngles = array((90, 0, 0), (90, 0, 0), (90,0,0), (90,0,0)); + TrialsMainModel = "zombie_teddybear"; + TrialsMainOrigin = (-6097.18, 5610.29, -3.875); + TrialsMainAngles = (0, -130, 0); + FXOriginOffset = (-12,0,20); + } + } + else if(level.script == "zm_prison") { + Collision = spawn( "script_model", (2250.64, 9891.08, 1964.13)); + Collision.angles = (0, 90, 0); + Collision setmodel("collision_wall_512x512x10_standard"); + PodiumModel = "p6_zm_al_electric_chair"; + PodiumOrigin = array((2232.09, 9754.98, 1704.13), (2232.09, 9844.98, 1704.13), (2232.09, 9934.98, 1704.13), (2232.09, 10025, 1704.13)); + PodiumAngles = array((0, 0, 0), (0, 0, 0), (0,0,0), (0,0,0)); + TrialsMainModel = "p6_zm_al_wall_trap_control_red"; + TrialsMainOrigin = (2470.36, 9752.72, 1764.13); + TrialsMainAngles = (0, -180, 0); + FXOriginOffset = (17,0,15); + } + else if(level.script == "zm_buried") { + Collision = spawn( "script_model", (1355.53, 1397.91, 336.474)); + Collision.angles = (0, -20, 0); + Collision setmodel("collision_wall_256x256x10_standard"); + PodiumModel = "p6_zm_bu_ether_amplifier"; + PodiumOrigin = array((1416.2, 1364.68, 200.125), (1365.2, 1383.68, 200.125), (1307.2, 1403.68, 200.125), (1247.2, 1425.68, 200.125)); + PodiumAngles = array((0, 0, 0), (0, 0, 0), (0,0,0), (0,0,0)); + TrialsMainModel = "zombie_teddybear"; + TrialsMainOrigin = (1405.07, 1651.54, 250.32); + TrialsMainAngles = (0, -100, 0); + FXOriginOffset = (0,0,43); + } + else if(level.script == "zm_tomb") { + Collision = spawn( "script_model", (401.108, 2118.76, -122.744)); + Collision.angles = (0, 0, 0); + Collision setmodel("zm_collision_perks1"); + PodiumModel = "p6_zm_tm_challenge_box"; + PodiumOrigin = array((538.473, 2119.9, -127.875), (458.473, 2119.9, -127.875), (348.473, 2119.9, -127.875), (268.473, 2119.9, -127.875)); + PodiumAngles = array((0, 0, 0), (0, 0, 0), (0,0,0), (0,0,0)); + TrialsMainModel = "p6_zm_tm_puzzle_lever_switch"; + TrialsMainOrigin = (401.108, 2118.76, -122.744); + TrialsMainAngles = (0, 0, 0); + FXOriginOffset = (0,0,30); + } + else if(level.script == "zm_nuked") { + Collision = spawn( "script_model", (578.573, 742.585, -64.1112)); + Collision.angles = (0, -164, 0); + Collision setmodel("collision_wall_256x256x10_standard"); + PodiumModel = "dest_zm_nuked_male_01_d0"; + PodiumOrigin = array((665.924, 740.986, -56.875), (617.924, 726.986, -56.875), (565.924, 712.986, -56.875), (515.924, 698.986, -56.875)); + PodiumAngles = array((0, -250, 0), (0, -250, 0), (0,-250,0), (0,-250,0)); + TrialsMainModel = "zombie_teddybear"; + TrialsMainOrigin = (661.327, 983.586, -52.875); + TrialsMainAngles = (0, -150, 0); + FXOriginOffset = (-4,15,14); + } + else if(level.script == "zm_highrise") { + Collision = spawn( "script_model", (1430.19, -348.386, 2624.13)); + Collision.angles = (0, 60, 0); + Collision setmodel("collision_wall_512x512x10_standard"); + Lion1 = spawn( "script_model", (1347.93, -459.859, 2742.13)); + Lion1.angles = (0, 60, 0); + Lion1 setmodel("p6_zm_hr_lion_statue"); + Lion2 = spawn( "script_model", (1400.9, -368.924, 2742.13)); + Lion2.angles = (0, 60, 0); + Lion2 setmodel("p6_zm_hr_lion_statue"); + Lion3 = spawn( "script_model", (1483.22, -226.259, 2742.13)); + Lion3.angles = (0, 60, 0); + Lion3 setmodel("p6_zm_hr_lion_statue"); + Lion4 = spawn( "script_model", (1534.45, -137.528, 2742.13)); + Lion4.angles = (0, 60, 0); + Lion4 setmodel("p6_zm_hr_lion_statue"); + PodiumModel = "p6_zm_hr_lion_statue_base"; + PodiumOrigin = array((1347.93, -459.859, 2704.13), (1400.9, -368.924, 2704.13), (1483.22, -226.259, 2704.13), (1534.45, -137.528, 2704.13)); + PodiumAngles = array((0, 60, 0), (0, 60, 0), (0,60,0), (0,60,0)); + TrialsMainModel = "zombie_teddybear"; + TrialsMainOrigin = (1434.69, -296.901, 2749.13); + TrialsMainAngles = (0, -35, 0); + FXOriginOffset = (0,2,55); + } + // Main Setup + level.ReaperTrialsActive = 0; + level thread TrialsSystem(FXOriginOffset,PodiumModel, PodiumOrigin, PodiumAngles, TrialsMainModel, TrialsMainOrigin, TrialsMainAngles); + level thread on_connect(); + level thread EndGameListener(); + // Rewards Map Specific + switch(level.script) { + case "zm_transit": + AddReward("Legendary", undefined, "Skullcrusher", "m16_gl_upgraded_zm", 0); + AddReward("Legendary", "zombie_z_money_icon", "Bonus Points", "Bonus_Points", 1); + AddReward("Legendary", undefined, "SLDG HAMR", "hamr_upgraded_zm", 0); + AddReward("Epic", "zombie_z_money_icon", "Bonus Points", "Bonus_Points", 1); + AddReward("Epic", undefined, "M16", "m16_zm", 0); + AddReward("Rare", "zombie_carpenter", "Carpenter", "carpenter", 1); + AddReward("Rare", "zombie_z_money_icon", "Bonus Points", "Bonus_Points", 1); + AddReward("Rare", undefined, "KAP-40", "kard_zm", 0); + AddReward("Rare", undefined, "M1911", "m1911_zm", 0); + AddReward("Rare", undefined, "RPG", "usrpg_zm", 0); + AddReward("Common", "zombie_z_money_icon", "Bonus Points", "Lose_Points", 1); + AddReward("Common", "zombie_carpenter", "Carpenter", "carpenter", 1); + AddReward("Common", undefined, "SMR", "saritch_zm", 0); + AddReward("Common", undefined, "RPG", "usrpg_zm", 0); + AddReward("Epic", undefined, "MP5", "mp5k_zm", 0); + AddReward("Rare", undefined, "MP5", "mp5k_zm", 0); + AddReward("Common", undefined, "MP5", "mp5k_zm", 0); + AddReward("Common", undefined, "M1911", "m1911_zm", 0); + AddReward("Common", undefined, "Olympia", "rottweil72_zm", 0); + AddReward("Legendary", undefined, "RPD", "rpd_zm", 0); + break; + + case "zm_nuked": + AddReward("Legendary", undefined, "Skullcrusher", "m16_gl_upgraded_zm", 0); + AddReward("Legendary", undefined, "SLDG HAMR", "hamr_upgraded_zm", 0); + AddReward("Epic", undefined, "M16", "m16_zm", 0); + AddReward("Rare", undefined, "KAP-40", "kard_zm", 0); + AddReward("Rare", undefined, "M1911", "m1911_zm", 0); + AddReward("Rare", undefined, "RPG", "usrpg_zm", 0); + AddReward("Common", undefined, "SMR", "saritch_zm", 0); + AddReward("Common", undefined, "RPG", "usrpg_zm", 0); + AddReward("Epic", undefined, "MP5", "mp5k_zm", 0); + AddReward("Rare", undefined, "MP5", "mp5k_zm", 0); + AddReward("Common", undefined, "MP5", "mp5k_zm", 0); + AddReward("Common", undefined, "M1911", "m1911_zm", 0); + AddReward("Common", undefined, "Olympia", "rottweil72_zm", 0); + AddReward("Legendary", undefined, "RPD", "rpd_zm", 0); + break; + + case "zm_highrise": + AddReward("Legendary", undefined, "Skullcrusher", "m16_gl_upgraded_zm", 0); + AddReward("Legendary", undefined, "SLDG HAMR", "hamr_upgraded_zm", 0); + AddReward("Epic", undefined, "M16", "m16_zm", 0); + AddReward("Rare", "zombie_carpenter", "Carpenter", "carpenter", 1); + AddReward("Rare", undefined, "KAP-40", "kard_zm", 0); + AddReward("Rare", undefined, "M1911", "m1911_zm", 0); + AddReward("Rare", undefined, "RPG", "usrpg_zm", 0); + AddReward("Common", "zombie_carpenter", "Carpenter", "carpenter", 1); + AddReward("Common", undefined, "SMR", "saritch_zm", 0); + AddReward("Common", undefined, "RPG", "usrpg_zm", 0); + AddReward("Epic", undefined, "MP5", "mp5k_zm", 0); + AddReward("Rare", undefined, "MP5", "mp5k_zm", 0); + AddReward("Common", undefined, "MP5", "mp5k_zm", 0); + AddReward("Common", undefined, "M1911", "m1911_zm", 0); + AddReward("Common", undefined, "Olympia", "rottweil72_zm", 0); + AddReward("Legendary", undefined, "RPD", "rpd_zm", 0); + break; + + case "zm_prison": + if(getdvarint("TrialsEnableWonderweapons") == 1) + AddReward("Legendary", undefined, "Blundergat", "blundergat_zm", 0); + AddReward("Rare", "zombie_carpenter", "Carpenter", "carpenter", 1); + AddReward("Rare", undefined, "M1911", "m1911_zm", 0); + AddReward("Rare", undefined, "RPG", "usrpg_zm", 0); + AddReward("Common", "zombie_carpenter", "Carpenter", "carpenter", 1); + AddReward("Common", undefined, "RPG", "usrpg_zm", 0); + AddReward("Epic", undefined, "MP5", "mp5k_zm", 0); + AddReward("Rare", undefined, "MP5", "mp5k_zm", 0); + AddReward("Common", undefined, "MP5", "mp5k_zm", 0); + AddReward("Common", undefined, "M1911", "m1911_zm", 0); + AddReward("Common", undefined, "Olympia", "rottweil72_zm", 0); + break; + + case "zm_buried": + if(getdvarint("TrialsEnableWonderweapons") == 1) + AddReward("Legendary", undefined, "Paralyzer", "slowgun_zm", 0); + AddReward("Legendary", "zombie_z_money_icon", "Bonus Points", "Bonus_Points", 1); + AddReward("Legendary", undefined, "Skullcrusher", "m16_gl_upgraded_zm", 0); + AddReward("Legendary", undefined, "SLDG HAMR", "hamr_upgraded_zm", 0); + AddReward("Epic", "zombie_z_money_icon", "Bonus Points", "Bonus_Points", 1); + AddReward("Epic", undefined, "M16", "m16_zm", 0); + AddReward("Rare", "zombie_carpenter", "Carpenter", "carpenter", 1); + AddReward("Rare", "zombie_z_money_icon", "Bonus Points", "Bonus_Points", 1); + AddReward("Rare", undefined, "KAP-40", "kard_zm", 0); + AddReward("Rare", undefined, "M1911", "m1911_zm", 0); + AddReward("Rare", undefined, "RPG", "usrpg_zm", 0); + AddReward("Common", "zombie_z_money_icon", "Bonus Points", "Lose_Points", 1); + AddReward("Common", "zombie_carpenter", "Carpenter", "carpenter", 1); + AddReward("Common", undefined, "SMR", "saritch_zm", 0); + AddReward("Common", undefined, "RPG", "usrpg_zm", 0); + AddReward("Epic", undefined, "MP5", "mp5k_zm", 0); + AddReward("Rare", undefined, "MP5", "mp5k_zm", 0); + AddReward("Common", undefined, "MP5", "mp5k_zm", 0); + AddReward("Common", undefined, "M1911", "m1911_zm", 0); + AddReward("Common", undefined, "Olympia", "rottweil72_zm", 0); + AddReward("Legendary", undefined, "RPD", "rpd_zm", 0); + break; + + case "zm_tomb": + AddReward("Legendary", undefined, "SLDG HAMR", "hamr_upgraded_zm", 0); + AddReward("Legendary", "zombie_z_money_icon", "Bonus Points", "Bonus_Points", 1); + AddReward("Legendary", undefined, "Agarthan Reaper", "scar_upgraded_zm", 0); + AddReward("Epic", "p6_zm_tm_blood_power_up", "Zombie Blood", "zombie_blood", 1); + AddReward("Epic", undefined, "STG44", "mp44_zm", 0); + AddReward("Epic", "zombie_z_money_icon", "Bonus Points", "Bonus_Points", 1); + AddReward("Epic", undefined, "Scar-H", "scar_zm", 0); + AddReward("Rare", "zombie_carpenter", "Carpenter", "carpenter", 1); + AddReward("Rare", "zombie_z_money_icon", "Bonus Points", "Bonus_Points", 1); + AddReward("Rare", undefined, "KAP-40", "kard_zm", 0); + AddReward("Rare", "p6_zm_tm_blood_power_up", "Zombie Blood", "zombie_blood", 1); + AddReward("Common", "zombie_z_money_icon", "Bonus Points", "Lose_Points", 1); + AddReward("Common", "zombie_carpenter", "Carpenter", "carpenter", 1); + AddReward("Common", "p6_zm_tm_blood_power_up", "Zombie Blood", "zombie_blood", 1); + AddReward("Common", undefined, "Mauser C96", "c96_zm", 0); + AddReward("Common", undefined, "Ballista", "ballista_zm", 0); + break; + } + } + // Everything that works on all Maps + if(getdvarint("TrialsEnableWonderweapons") == 1) { + AddReward("Legendary", undefined, "Ray Gun Mark 2", "raygun_mark2_zm", 0); + if(getdvarint("TrialsAllowFreePerk") == 1) + AddReward("Legendary", "zombie_pickup_perk_bottle", "Free Perk", "free_perk", 1); + if(getdvarint("TrialsEnablePapDrop") == 1) + AddReward("Legendary", "p6_anim_zm_buildable_pap", "Weapon Upgrade", "WeaponUpgrade", 1); + AddReward("Legendary", "t6_wpn_zmb_raygun_view", "Ray Gun", "ray_gun_zm", 0); + AddReward("Legendary", "zombie_z_money_icon", "Bonus Points", "Bonus_Points", 1); + AddReward("Legendary", "Zombie_Skull", "Insta Kill", "insta_kill", 1); + AddReward("Legendary", "zombie_ammocan", "Max Ammo", "full_ammo", 1); + AddReward("Legendary", undefined, "Lamentation", "galil_upgraded_zm", 0); + AddReward("Legendary", undefined, "Mnesia", "m14_upgraded_zm", 0); + AddReward("Epic", "Zombie_Skull", "Insta Kill", "insta_kill", 1); + AddReward("Epic", "zombie_x2_icon", "Double Points", "double_points", 1); + AddReward("Epic", undefined, "DSR-50", "dsr50_zm", 0); + AddReward("Epic", undefined, "Galil", "galil_zm", 0); + AddReward("Epic", undefined, "B23r", "beretta93r_zm", 0); + AddReward("Epic", undefined, "Mnesia", "m14_upgraded_zm", 0); + AddReward("Rare", "zombie_x2_icon", "Double Points", "double_points", 1); + AddReward("Rare", "zombie_bomb", "Nuke", "nuke", 1); + AddReward("Rare", undefined, "Remington", "870mcs_zm", 0); + AddReward("Common", "zombie_bomb", "Nuke", "nuke", 1); + AddReward("Common", undefined, "M14", "m14_zm", 0); + // Lights for Origins Player Podiums + if(level.script == "zm_tomb") { + flag_wait("initial_blackscreen_passed"); + playfx(level._effect[ "fx_tomb_chamber_glow_blue" ], PodiumOrigin[0] - (0,0,10), (0,90,0), (0,90,0)); + playfx(level._effect[ "fx_tomb_chamber_glow_yellow" ], PodiumOrigin[1] - (0,0,10), (0,0,0), (0,90,0)); + playfx(level._effect[ "fx_tomb_crafting_chamber_glow" ], PodiumOrigin[2] - (0,0,10)); + playfx(level._effect[ "fx_tomb_chamber_glow_red" ], PodiumOrigin[3] - (0,0,10)); + } +} + +on_connect() { + level endon("end_game"); + for ( ;; ) { + level waittill( "connected", player ); + player thread on_spawned(); + } +} + +on_spawned() { + level endon("end_game"); + self endon( "disconnect" ); + self.initial_spawn_c = 0; + for ( ;; ) { + self waittill( "spawned_player" ); + if(self.initial_spawn_c == 0) { + self.initial_spawn_c = 1; + self.board_repair = 0; + self.ReaperTrialsCurrentMagic = 0; + self init_trial_hud(); + } + } +} + +init_trial_hud() { + // HUD settings such as sizes, position and fallbacks + self.trials_height = 28; + self.trials_width = int(self.trials_height * 5); + self.trials_space = int(self.trials_height * .115); + self.trials_star = int(self.trials_space * 2.35); + self.trials_x = 5; + if(level.script == "zm_tomb") + self.trials_y = -180 - self.trials_height; + else + self.trials_y = -120 - self.trials_height; + self.trials_reward_color = (.8, 0, 0); + self.trials_reward_code = "none"; + self.trials_reward_color_code = "^1"; + self.trials_reward_level = "^1None"; + self.do_trial_progress = false; + self.trials_init = true; +} + +TriggerRewardHandler(player, Name, Powerup, Hint) { + level endon("end_game"); + self endon("Timeout"); + self endon("Grabbed"); + players = getplayers(); + while(1) { + self waittill("trigger", player); + if(player usebuttonpressed()) { + if(isdefined(self.sharedreward)) + self.sharedreward = undefined;// Trigger Again only Visible for that Specific Player + if(Powerup == 0){ + if(Name == "ray_gun_zm" && player has_weapon_or_upgrade("raygun_mark2_zm") || Name == "Mark2" && player has_weapon_or_upgrade("ray_gun_zm")) { + player playlocalsound( level.zmb_laugh_alias ); + self notify("Grabbed"); + } + if(player has_weapon_or_upgrade(Name)){ + player playlocalsound( level.zmb_laugh_alias ); + self notify("Grabbed"); + } + weapon_limit = get_player_weapon_limit( player ); + primaryweapons = player getweaponslistprimaries(); + if ( isDefined( primaryweapons ) && primaryweapons.size >= weapon_limit ) + player takeweapon(player getcurrentweapon()); + wait 0.1; + player giveweapon(Name); + player switchtoweapon(Name); + self notify("Grabbed"); + } + else { + wait 0.1; + if(Name == "free_perk") + free_perk = player maps/mp/zombies/_zm_perks::give_random_perk(); + else if(Name == "Bonus_Points") + player.score += randomintrange( 1, 50 ) * 100; + else if(Name == "Lose_Points") + player.score -= randomintrange( 1, 50 ) * 100; + else if(Name == "WeaponUpgrade") { + weapon = player get_upgrade_weapon( player getcurrentweapon(), 0 ); + if(IsDefined( weapon )) { + player takeweapon( player getcurrentweapon()); + player giveweapon( weapon, 0, player get_pack_a_punch_weapon_options( weapon ) ); + player givestartammo( weapon ); + player givemaxammo( weapon ); + player switchtoweapon( weapon ); + } + else + player playlocalsound( level.zmb_laugh_alias ); + } + else + specific_powerup_drop(Name, player.origin); + self notify("Grabbed"); + } + } + if(players.size != 1) { + if(player meleebuttonpressed()){ + if(!isdefined(self.sharedreward)) { + self.sharedreward = true; // To Disable the Setinvisible Loop + self playsound("zmb_powerup_grabbed"); + self setvisibletoall(); + self SetHintString("Press ^3&&1^7 To Take "+Hint); + } + } + } + } +} + +Random_Reward(TrialLevel) { + Choosen = []; + for(i = 0; i < level.Rewards_List.size;i++){ + if(isdefined(level.Rewards_List[i].Rank) && level.Rewards_List[i].Rank == TrialLevel){ + Choosen[Choosen.size] = i; + } + } + return Choosen[randomint(Choosen.size)]; +} + +RewardModelMain() { + self endon("Done"); + level endon("end_game"); + if(level.script == "zm_tomb") + playfxontag(level._effect[ "ice_glow" ], self, "tag_origin"); + else + playfxontag(level._effect["powerup_on_solo"], self, "tag_origin"); + 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 ); + wait randomfloat( waittime - 0.1 ); + } +} + +TrialsSystem(CalculatedOrigin,SelectedModel, Origin, Angles, ActivatiorModel, ActivatiorOrigim, ActivatorAngles) { + level endon("end_game"); + // Challenges Setup + Challenges = []; + Challenges[Challenges.size] = "K_Trial";// Regular Kills + Challenges[Challenges.size] = "HK_Trial";// Headshot Kills + Challenges[Challenges.size] = "MK_Trial";// Melee Kills + Challenges[Challenges.size] = "GO_Trial";// Kill Zombies With Grenades + Challenges[Challenges.size] = "C_Trial";// Kill Zombies While Crouched + Challenges[Challenges.size] = "NH_Trial";// No Hits + Challenges[Challenges.size] = "BRS_Trial";// Buy Stuff + Challenges[Challenges.size] = "NAIM_Trial";// No Aim + Challenges[Challenges.size] = "CR_Trial";// Close Range Kills + Challenges[Challenges.size] = "BR_Trial";// Big Range Kills + Challenges[Challenges.size] = "TD_Trial";// Take Damage + Challenges[Challenges.size] = "PK_Trial";// Prone Kills + Challenges[Challenges.size] = "SGK_Trial";// Shotgun Kills + Challenges[Challenges.size] = "SMGK_Trial";// SMG Kills + Challenges[Challenges.size] = "ASTK_Trial";// Assualt Kills + Challenges[Challenges.size] = "HSK_Trial";// Higher Spot Kills + Challenges[Challenges.size] = "JUMP_Trial";// Jump Kills + Challenges[Challenges.size] = "LEGK_Trial";// Leg Kills + Challenges[Challenges.size] = "ARMK_Trial";// Arm Kills + switch(level.script) { + case "zm_transit": + Challenges[Challenges.size] = "REPA_Trial";// Rebuild Barriers + if(getDvar( "ui_zm_mapstartlocation" ) != "farm") + Challenges[Challenges.size] = "LAVAK_Trial";// Lava Kills + if(getDvar( "ui_zm_mapstartlocation" ) == "town") { + Challenges[Challenges.size] = "KISZ_Trial";// Kill In Random Zone + Challenges[Challenges.size] = "SISZ_Trial";// Stay In Random Zone + Challenges[Challenges.size] = "NPAP_Trial";// Kill With no Pap Weapon + } + if(getDvar( "ui_zm_mapstartlocation" ) == "transit") + Challenges[Challenges.size] = "ESHK_Trial";// Shield Kills + break; + + case "zm_highrise": + Challenges[Challenges.size] = "SPPADK_Trial";// Springpad Kills + Challenges[Challenges.size] = "REPA_Trial";// Rebuild Barriers + Challenges[Challenges.size] = "KISZ_Trial";// Kill In Random Zone + Challenges[Challenges.size] = "SISZ_Trial";// Stay In Random Zone + Challenges[Challenges.size] = "NPAP_Trial";// Kill With no Pap Weapon + break; + + case "zm_prison": + Challenges[Challenges.size] = "ESHK_Trial";// Shield Kills + Challenges[Challenges.size] = "REPA_Trial";// Rebuild Barriers + Challenges[Challenges.size] = "KISZ_Trial";// Kill In Random Zone + Challenges[Challenges.size] = "SISZ_Trial";// Stay In Random Zone + Challenges[Challenges.size] = "NPAP_Trial";// Kill With no Pap Weapon + break; + + case "zm_buried": + Challenges[Challenges.size] = "SPPADK_Trial";// Springpad Kills + Challenges[Challenges.size] = "BASSK_Trial";// Subwoofer Kills + Challenges[Challenges.size] = "REPA_Trial";// Rebuild Barriers + Challenges[Challenges.size] = "KISZ_Trial";// Kill In Random Zone + Challenges[Challenges.size] = "SISZ_Trial";// Stay In Random Zone + Challenges[Challenges.size] = "NPAP_Trial";// Kill With no Pap Weapon + break; + + case "zm_tomb": + Challenges[Challenges.size] = "ESHK_Trial";// Shield Kills + Challenges[Challenges.size] = "KISZ_Trial";// Kill In Random Zone + Challenges[Challenges.size] = "SISZ_Trial";// Stay In Random Zone + Challenges[Challenges.size] = "NPAP_Trial";// Kill With no Pap Weapon + break; + } + + TrialPodium_Player1 = spawn( "script_model", Origin[0]); + TrialPodium_Player1.angles = Angles[0]; + TrialPodium_Player1 setmodel(SelectedModel); + TrialPodium_Player1 thread PodiumSetupTrigger(Origin[0] + CalculatedOrigin,0); + TrialPodium_Player1 thread PodiumSetupTrigger(Origin[0] + CalculatedOrigin,4); + + TrialPodium_Player2 = spawn( "script_model", Origin[1]); + TrialPodium_Player2.angles = Angles[1]; + TrialPodium_Player2 setmodel(SelectedModel); + TrialPodium_Player2 thread PodiumSetupTrigger(Origin[1] + CalculatedOrigin,1); + TrialPodium_Player2 thread PodiumSetupTrigger(Origin[1] + CalculatedOrigin,5); + + TrialPodium_Player3 = spawn( "script_model", Origin[2]); + TrialPodium_Player3.angles = Angles[2]; + TrialPodium_Player3 setmodel(SelectedModel); + TrialPodium_Player3 thread PodiumSetupTrigger(Origin[2] + CalculatedOrigin,2); + TrialPodium_Player3 thread PodiumSetupTrigger(Origin[2] + CalculatedOrigin,6); + + TrialPodium_Player4 = spawn( "script_model", Origin[3]); + TrialPodium_Player4.angles = Angles[3]; + TrialPodium_Player4 setmodel(SelectedModel); + TrialPodium_Player4 thread PodiumSetupTrigger(Origin[3] + CalculatedOrigin,3); + TrialPodium_Player4 thread PodiumSetupTrigger(Origin[3] + CalculatedOrigin,7); + + TrialMainModel = spawn( "script_model", ActivatiorOrigim); + TrialMainModel.angles = ActivatorAngles; + TrialMainModel setmodel(ActivatiorModel); + + if(level.script != "zm_prison" && level.script != "zm_tomb") + TrialMainModel thread MainModelAnimation(); + + TrialsMainTrigger = spawn("trigger_radius", ActivatiorOrigim, 1, 50, 50); + TrialsMainTrigger SetCursorHint( "HINT_NOICON" ); + // All Zones For Challenges + Zones = GetEntArray("player_volume", "script_noteworthy"); + // Zones check for Town + if (level.script == "zm_transit" && getDvar( "ui_zm_mapstartlocation" ) == "town" ){ + for(i = 0;i < Zones.size;i++){ + if(Zones[i].targetname == "zone_tow" || Zones[i].targetname == "zone_bar" || Zones[i].targetname == "zone_ban" || Zones[i].targetname == "zone_town_north" || Zones[i].targetname == "zone_town_west" || Zones[i].targetname == "zone_town_east" || Zones[i].targetname == "zone_town_barber" || Zones[i].targetname == "zone_town_south" ){ + if(!isdefined(ZonesForSurvival)) + ZonesForSurvival = []; + ZonesForSurvival[ZonesForSurvival.size] = Zones[i]; + } + } + } + TrialsCost = getDvarInt("TrialsCost"); + Challenges = array_randomize(Challenges); + Num = 0; + while(1){ + if(level.ReaperTrialsActive == 0) + TrialsMainTrigger SetHintString("Hold ^3&&1^7 to Activate Trial [Cost: " + TrialsCost + "]"); + else + TrialsMainTrigger SetHintString("Trial is already Running!"); + TrialsMainTrigger waittill("trigger", player); + if(level.ReaperTrialsActive == 0){ + if(player UseButtonPressed()){ + if(player.score < TrialsCost){ + player playsound("evt_perk_deny"); + wait 1; + } + else if(player.score >= TrialsCost){ + player minus_to_player_score(TrialsCost); + player playsound("zmb_cha_ching"); + if(Num >= Challenges.size) { + Challenges = cycle_randomize(Challenges); + Num = 0; + } + if(isdefined(ZonesForSurvival)) + level thread ChallengeHandler(ZonesForSurvival,Challenges[Num]); + else + level thread ChallengeHandler(Zones,Challenges[Num]); + foreach(player in level.players) + player playsound( "zmb_meteor_activate" ); + Num++; + level.ReaperTrialsActive++; + } + } + } + } +} + +cycle_randomize(indices) { + li = indices.size - 1; + last = indices[li]; + new_indices = array_randomize(indices); + + while (last == new_indices[0]) + new_indices = array_randomize(indices); + + return new_indices; +} + +MainModelAnimation(){// Teddy Floating + level endon("end_game"); + flag_wait( "start_zombie_round_logic" ); + if(level.script == "zm_nuked") { + for( f = 0; f < 4; f++ ) { + playfxontag( level._effect[ "fx_ash_embers_up_lg" ], self, "tag_origin" ); + wait randomfloatrange( 0.1, 0.72 ); + } + } + if(level.script == "zm_highrise") + playfx( level._effect[ "fx_highrise_dragon_tower_glow_ric" ], self.origin); + if(level.script == "zm_buried") + playfx( level._effect[ "sq_tower_bolts" ], self.origin, (0,0,180), (0,0,180)); + while(1) { + self moveto(self.origin + (0,0,20),randomfloatrange(0.5,4)); + self waittill("movedone"); + self moveto(self.origin + (0,0,-20),randomfloatrange(0.5,4)); + self waittill("movedone"); + } +} + +ChallengeHandler(Zones,Challenge){ + if(Challenge == "K_Trial") + ChallengeDescription = "Kill Zombies"; + else if(Challenge == "HK_Trial"){ + ChallengeDescription = "Kill Zombies\n^3Headshots"; + ChallengePoints = 2; + } + else if(Challenge == "MK_Trial"){ + ChallengeDescription = "Kill Zombies with Melee Attacks"; + ChallengePoints = 2; + } + else if(Challenge == "KISZ_Trial"){ + Num = randomintrange(0, Zones.size); + ChoosenZone = Zones[Num]; + ZoneName = get_zone_name(ChoosenZone.targetname); + if(!isdefined(ZoneName) || isdefined(ZoneName) && ZoneName == "") { + Num = randomintrange(0, Zones.size); + ChoosenZone = Zones[Num]; + ZoneName = get_zone_name(ChoosenZone.targetname); + } + ChallengeDescription = "Kill Zombies at Location\n^8"+ZoneName; + PositiveChallengeDescription = "Kill Zombies at Location\n^2"+ZoneName; + Time = 120; + } + else if(Challenge == "SISZ_Trial"){ + Num = randomintrange(0, Zones.size); + ChoosenZone = Zones[Num]; + ZoneName = get_zone_name(ChoosenZone.targetname); + if(!isdefined(ZoneName) || isdefined(ZoneName) && ZoneName == "") { + Num = randomintrange(0, Zones.size); + ChoosenZone = Zones[Num]; + ZoneName = get_zone_name(ChoosenZone.targetname); + } + ChallengeDescription = "Stay at Location\n^8"+ZoneName; + PositiveChallengeDescription = "Stay at Location\n^2"+ZoneName; + Time = 120; + } + else if(Challenge == "GO_Trial") + ChallengeDescription = "Kill Zombies with Grenades"; + else if(Challenge == "C_Trial") + ChallengeDescription = "Kill Zombies while Crouching"; + else if(Challenge == "TD_Trial"){ + ChallengeDescription = "Take Damage"; + ChallengePoints = 1.5; + } + else if(Challenge == "NH_Trial"){ + ChallengeDescription = "Take No Damage"; + ChallengePoints = 1.5; + } + else if(Challenge == "BRS_Trial"){ + ChallengeDescription = "Spend Points"; + Time = 120; + } + else if(Challenge == "NPAP_Trial") + ChallengeDescription = "Kill Zombies with a Non-Upgraded Weapon"; + else if(Challenge == "NAIM_Trial") + ChallengeDescription = "Kill Zombies without Aiming"; + else if(Challenge == "CR_Trial") + ChallengeDescription = "Kill Zombies in Close Range"; + else if(Challenge == "BR_Trial") + ChallengeDescription = "Kill Zombies in Long Range"; + else if(Challenge == "PK_Trial") + ChallengeDescription = "Kill Zombies while Prone"; + else if(Challenge == "SGK_Trial") + ChallengeDescription = "Kill Zombies with Shotguns"; + else if(Challenge == "SMGK_Trial") + ChallengeDescription = "Kill Zombies with SMGs"; + else if(Challenge == "ASTK_Trial") + ChallengeDescription = "Kill Zombies with Assault Rifles"; + else if(Challenge == "HSK_Trial") + ChallengeDescription = "Kill Zombies at a Higher Position"; + else if(Challenge == "JUMP_Trial") + ChallengeDescription = "Kill Zombies While in Air"; + else if(Challenge == "LEGK_Trial") + ChallengeDescription = "Kill Zombies\n^3Legshots"; + else if(Challenge == "ARMK_Trial") + ChallengeDescription = "Kill Zombies\n^3Armshots"; + else if(Challenge == "ESHK_Trial") + ChallengeDescription = "Kill Zombies with a Riotshield"; + else if(Challenge == "LAVAK_Trial") + ChallengeDescription = "Kill Zombies while Burning"; + else if(Challenge == "REPA_Trial") { + ChallengeDescription = "Repair Barricades"; + ChallengePoints = 0.5; + Time = 120; + } + else if(Challenge == "SPPADK_Trial") + ChallengeDescription = "Kill Zombies with a Tramplesteam"; + else if(Challenge == "BASSK_Trial") + ChallengeDescription = "Kill Zombies with a Subwoofer"; + + if(!isdefined(ChallengePoints))// Default + ChallengePoints = 1; + + if(!isdefined(time))// Default + time = 90; + + // Setup Challenge For Players + players = get_players(); + for(i = 0;i < players.size;i++){ + if(Challenge == "SISZ_Trial" || Challenge == "TD_Trial" || Challenge == "NH_Trial" || Challenge == "BRS_Trial" || Challenge == "REPA_Trial"){ + players[i] thread PlayerTrialHandlerTime(Challenge, ChallengePoints, ChoosenZone); + } + else { + if(Challenge == "SPPADK_Trial" || Challenge == "BASSK_Trial") + players[i] thread PlayerTrialHandlerBuildableKill(Challenge, ChallengePoints); + else + players[i] thread PlayerTrialHandlerKill(Challenge, ChallengePoints, ChoosenZone); + } + players[i] toggle_trial_challenge_hud(); + players[i] set_trial_challenge(ChallengeDescription); + players[i] set_trial_timer(time); + if(isdefined(ChoosenZone)) + players[i] thread set_trial_location(ChoosenZone, ChallengeDescription, PositiveChallengeDescription); + } + wait time + 1; + for(i = 0;i < players.size;i++){ + players[i] notify("TrialOver"); + players[i] toggle_trial_challenge_hud(); + } + level.ReaperTrialsActive = 0; +} + +set_trial_location(zone, out_text, in_text) { + self endon("TrialOver"); + self endon("disconnect"); + level endon("end_game"); + before = false; + + while (true) { + in_zone = self istouching(zone); + + if(before != in_zone) { + text = in_zone ? in_text : out_text; + self set_trial_challenge(text); + before = in_zone; + } + wait 1; + } +} +// All Buildable Based Challenges Come in here +PlayerTrialHandlerBuildableKill(Trial, Points) { + self endon("TrialOver"); + self endon("disconnect"); + level endon("end_game"); + while(1) { + TrialNotify = self waittill_any_return("zombie_flung", "zombie_subwoofer_kill"); + if(TrialNotify == "zombie_flung") { + if(Trial == "SPPADK_Trial") + self thread AddPlayerMagicPoints(Points); + } + else if(TrialNotify == "zombie_subwoofer_kill") { + if(Trial == "BASSK_Trial") + self thread AddPlayerMagicPoints(Points); + } + } +} + +// All Kill Based Challenges Come in here +PlayerTrialHandlerKill(trial, Points, SpecificZone){ + self endon("TrialOver"); + self endon("disconnect"); + level endon("end_game"); + while(1) { + self waittill( "zom_kill", zombie); + if(trial == "K_Trial") + self thread AddPlayerMagicPoints(Points); + else if(trial == "HK_Trial") { + if(zombie damagelocationisany( "head", "helmet", "neck")) + self thread AddPlayerMagicPoints(Points); + } + else if(trial == "MK_Trial") { + if(zombie.damagemod == "MOD_MELEE" || zombie.damagemod == "MOD_IMPACT") + self thread AddPlayerMagicPoints(Points); + } + else if(trial == "KISZ_Trial") { + if(self istouching(SpecificZone) && zombie istouching(SpecificZone)) + self thread AddPlayerMagicPoints(Points); + } + else if(trial == "GO_Trial") { + if(zombie.damagemod == "MOD_GRENADE" || zombie.damagemod == "MOD_GRENADE_SPLASH" || zombie.damagemod == "MOD_EXPLOSIVE" ) { + self thread AddPlayerMagicPoints(Points); + } + } + else if(trial == "C_Trial") { + if(self GetStance() == "crouch") + self thread AddPlayerMagicPoints(Points); + } + else if(trial == "NPAP_Trial") { + if(!self has_upgrade(self getcurrentweapon()) && zombie.damagemod == "MOD_RIFLE_BULLET" || !self has_upgrade(self getcurrentweapon()) && zombie.damagemod == "MOD_PISTOL_BULLET") + self thread AddPlayerMagicPoints(Points); + } + else if(trial == "NAIM_Trial") { + if(!isads(self)) + self thread AddPlayerMagicPoints(Points); + } + else if(trial == "CR_Trial") { + if(distancesquared(self.origin,zombie.origin) <= 20000) + self thread AddPlayerMagicPoints(Points); + } + else if(trial == "BR_Trial") { + if(distancesquared(self.origin,zombie.origin) >= 180000) + self thread AddPlayerMagicPoints(Points); + } + else if(trial == "PK_Trial") { + if(self GetStance() == "prone") + self thread AddPlayerMagicPoints(Points); + } + else if(trial == "SGK_Trial") { + if(weaponclass(self getcurrentweapon()) == "spread") + self thread AddPlayerMagicPoints(Points); + } + else if(trial == "SMGK_Trial") { + if(weaponclass(self getcurrentweapon()) == "smg") + self thread AddPlayerMagicPoints(Points); + } + else if(trial == "ASTK_Trial") { + if(weaponclass(self getcurrentweapon()) == "rifle") + self thread AddPlayerMagicPoints(Points); + } + else if(trial == "HSK_Trial") { + if(self.origin[2] >= (zombie.origin[2] + 30)) + self thread AddPlayerMagicPoints(Points); + } + else if(trial == "JUMP_Trial") { + if(!isdefined(self getgroundent())) + self thread AddPlayerMagicPoints(Points); + } + else if(trial == "LEGK_Trial") { + if(zombie damagelocationisany( "left_leg_upper", "left_leg_lower", "right_leg_upper", "right_leg_lower" )) + self thread AddPlayerMagicPoints(Points); + } + else if(trial == "ARMK_Trial") { + if(zombie damagelocationisany( "right_arm_upper", "left_arm_upper", "right_arm_lower", "left_arm_lower" )) + self thread AddPlayerMagicPoints(Points); + } + else if(trial == "ESHK_Trial") { + if(zombie.damagemod == "MOD_MELEE" && self getcurrentweapon() == level.riotshield_name || zombie.damagemod == "MOD_IMPACT" && self getcurrentweapon() == level.riotshield_name ) + self thread AddPlayerMagicPoints(Points); + } + else if(trial == "LAVAK_Trial") { + if(isdefined(self.is_burning) && self.is_burning == 1) + self thread AddPlayerMagicPoints(Points); + } + } +} + +// All Time Based Challenges Come in here +PlayerTrialHandlerTime(trial, Points, SpecificZone) { + self endon("TrialOver"); + self endon("disconnect"); + level endon("end_game"); + while(1){ + if(trial == "SISZ_Trial") { + if(isdefined(SpecificZone) && self istouching(SpecificZone)) { + self thread AddPlayerMagicPoints(Points); + } + } + else if(trial == "TD_Trial") { + if((self.health / self.maxhealth) <= 0.8) { + self thread AddPlayerMagicPoints(Points); + } + } + else if(trial == "NH_Trial") { + if(self.health == self.maxhealth) { + self thread AddPlayerMagicPoints(Points); + } + else { + wait 10; + } + } + else if(trial == "BRS_Trial") { + level waittill("spent_points", player, PointsSpent); + if(Player == self) { + if(PointsSpent >= 100) { + self thread AddPlayerMagicPoints(Points); + } + } + } + else if(trial == "REPA_Trial") { + if(self.board_repair > 0) { + self thread AddPlayerMagicPoints(Points); + self.board_repair = 0; + } + } + wait 2.5; + } +} + +PodiumSetupTrigger(CalculatedOrigin,Index){ + level endon("end_game"); + if(level.script == "zm_nuked") + trigger = Spawn( "trigger_radius", self.origin + (0, 0, 30), 0, 45, 45 ); + else + trigger = Spawn( "trigger_radius", self.origin + (0, 0, 30), 0, 30, 30 ); + trigger SetCursorHint( "HINT_NOICON" ); + trigger thread ShowToSpecific(CalculatedOrigin,Index); + while(1) { + players = GetPlayers(); + if(players[Index].ReaperTrialsCurrentMagic >= 25) + reward_level = "^2Common"; + if(players[Index].ReaperTrialsCurrentMagic >= 50) + reward_level = "^4Rare"; + if(players[Index].ReaperTrialsCurrentMagic >= 75) + reward_level = "^6Epic"; + if(players[Index].ReaperTrialsCurrentMagic == 100) + reward_level = "^3Legendary"; + if(players[Index].ReaperTrialsCurrentMagic >= 25) + trigger SetHintString("Press ^3&&1^7 To Claim " + reward_level + "^7 Reward"); + else + trigger SetHintString("Reward Level Too Low"); + trigger waittill( "trigger", player); + if(player == players[Index]){ + if(!player UseButtonPressed()){ + wait .1; + continue; + } + if(players[Index].ReaperTrialsCurrentMagic < 25){ + wait .1; + continue; + } + if(players[Index].ReaperTrialsCurrentMagic >= 25) + Reward = Random_Reward("Common"); + if(players[Index].ReaperTrialsCurrentMagic >= 50) + Reward = Random_Reward("Rare"); + if(players[Index].ReaperTrialsCurrentMagic >= 75) + Reward = Random_Reward("Epic"); + if(players[Index].ReaperTrialsCurrentMagic == 100) + Reward = Random_Reward("Legendary"); + players[Index].ReaperTrialsCurrentMagic = 0; + players[Index] toggle_trial_reward_hud(); + players[Index] set_trial_reward("none"); + trigger SetHintString("Generating Reward!"); + wait 1; + RewardModel = Spawn( "script_model", CalculatedOrigin + (0,0,28)); + RewardModel setmodel(level.Rewards_List[Reward].Model); + RewardModel thread RewardModelMain(); + if(players.size == 1)// To Disable the Sharing Hint in Solo Games + trigger SetHintString( "Press ^3&&1^7 To Take "+level.Rewards_List[Reward].Hint); + else + trigger SetHintString( "Press ^3&&1^7 To Take "+level.Rewards_List[Reward].Hint+"\nPress ^3[{+melee}]^7 To Share Reward"); + trigger thread TriggerRewardHandler(players[Index], level.Rewards_List[Reward].Name, level.Rewards_List[Reward].Powerup, level.Rewards_List[Reward].Hint); + trigger waittill_any_timeout(30, "Grabbed"); + trigger notify("Timeout"); + RewardModel notify("Done"); + RewardModel delete(); + } + } +} + +toggle_trial_challenge_hud() { + if (!isdefined(self.trials_init)) + return; + + sq_size = self.trials_height; + sq_wide = self.trials_width; + sq_dot = self.trials_space; + sq_star = self.trials_star; + x = self.trials_x; + y = self.trials_y; + + if (isdefined(self.trials_show_challenge) && self.trials_show_challenge) { + + // Wait for last trial progress animation before hide + while (self.do_trial_progress) + wait .1; + + self.trials_show_challenge = false; + self.trials_bg.alpha = 0; + self.trials_timer_bg.alpha = 0; + self.trials_timer_bar.alpha = 0; + self.trials_timer.alpha = 0; + self.trials_challenge destroy(); // This will glitch if a new challenge starts too fast + // self.trials_challenge.alpha = 0; + } + else { + self.trials_show_challenge = true; + + // Main background + if (!isdefined(self.trials_bg)) { + self.trials_bg = newclienthudelem(self); + self.trials_bg.horzalign = "user_left"; + self.trials_bg.alignx = "left"; + self.trials_bg.vertalign = "user_center"; + self.trials_bg.aligny = "middle"; + self.trials_bg.x = x + sq_dot + sq_size; + self.trials_bg.y = y; + self.trials_bg.sort = 1; + self.trials_bg.foreground = true; + self.trials_bg.hidewheninmenu = true; + self.trials_bg setshader("gradient", sq_wide, sq_size); + } + self.trials_bg.alpha = .6; + + // Timer background + if (!isdefined(self.trials_timer_bg)) { + self.trials_timer_bg = newclienthudelem(self); + self.trials_timer_bg.horzalign = "user_left"; + self.trials_timer_bg.alignx = "left"; + self.trials_timer_bg.vertalign = "user_center"; + self.trials_timer_bg.aligny = "middle"; + self.trials_timer_bg.x = x + sq_dot; + self.trials_timer_bg.y = y; + self.trials_timer_bg.sort = 2; + self.trials_timer_bg.foreground = true; + self.trials_timer_bg.hidewheninmenu = true; + self.trials_timer_bg setshader("black", sq_size, sq_size); + } + self.trials_timer_bg.alpha = .8; + + // Left timer bar + if (!isdefined(self.trials_timer_bar)) { + self.trials_timer_bar = newclienthudelem(self); + self.trials_timer_bar.horzalign = "user_left"; + self.trials_timer_bar.alignx = "left"; + self.trials_timer_bar.vertalign = "user_center"; + self.trials_timer_bar.aligny = "middle"; + self.trials_timer_bar.x = x; + self.trials_timer_bar.y = y; + self.trials_timer_bar.color = self.trials_reward_color; + self.trials_timer_bar.sort = 3; + self.trials_timer_bar.foreground = true; + self.trials_timer_bar.hidewheninmenu = true; + self.trials_timer_bar setshader("white", sq_dot, sq_size); + } + self.trials_timer_bar.alpha = 1; + + // Timer + if (!isdefined(self.trials_timer)) { + self.trials_timer = newclienthudelem(self); + self.trials_timer.horzalign = "user_left"; + self.trials_timer.alignx = "center"; + self.trials_timer.vertalign = "user_center"; + self.trials_timer.aligny = "middle"; + self.trials_timer.x = x + sq_dot + (sq_size / 2); + self.trials_timer.y = y; + self.trials_timer.color = self.trials_reward_color; + self.trials_timer.font = "small"; + self.trials_timer.sort = 3; + self.trials_timer.foreground = true; + self.trials_timer.hidewheninmenu = true; + } + self.trials_timer.alpha = 1; + + // Challenge text + if (!isdefined(self.trials_challenge)) { + self.trials_challenge = newclienthudelem(self); + self.trials_challenge.horzalign = "user_left"; + self.trials_challenge.alignx = "left"; + self.trials_challenge.vertalign = "user_center"; + self.trials_challenge.aligny = "middle"; + self.trials_challenge.x = x + (sq_dot * 3) + sq_size; + self.trials_challenge.y = y; + self.trials_challenge.real_y = self.trials_challenge.y; + self.trials_challenge.sort = 3; + self.trials_challenge.foreground = true; + self.trials_challenge.hidewheninmenu = true; + } + self.trials_challenge.alpha = 1; + } +} + +toggle_trial_reward_hud() { + if (!isdefined(self.trials_init)) + return; + + sq_size = self.trials_height; + sq_wide = self.trials_width; + sq_dot = self.trials_space; + sq_star = self.trials_star; + x = self.trials_x; + y = self.trials_y; + + if (isdefined(self.trials_show_reward) && self.trials_show_reward) { + + // Wait for last trial progress animation before hide + while (self.do_trial_progress) + wait .1; + + self.trials_show_reward = false; + self.trials_reward.alpha = 0; + self.trials_common.alpha = 0; + self.trials_rare.alpha = 0; + self.trials_epic.alpha = 0; + self.trials_legend.alpha = 0; + } + + else { + self.trials_show_reward = true; + + // Reward text + if (!isdefined(self.trials_reward)) { + self.trials_reward = newclienthudelem(self); + self.trials_reward.horzalign = "user_left"; + self.trials_reward.alignx = "left"; + self.trials_reward.vertalign = "user_center"; + self.trials_reward.aligny = "top"; + self.trials_reward.x = x + (sq_dot * 3) + sq_size; + self.trials_reward.y = y + (sq_size / 2) - 1; + self.trials_reward.font = "small"; + self.trials_reward.color = (.75, .75, .75); + self.trials_reward.sort = 3; + self.trials_reward.foreground = true; + self.trials_reward.hidewheninmenu = true; + self.trials_reward.label = &"Reward Available: "; + } + self.trials_reward.alpha = 1; + + // Common tier dot + if (!isdefined(self.trials_common)) { + self.trials_common = newclienthudelem(self); + self.trials_common.horzalign = "user_left"; + self.trials_common.alignx = "left"; + self.trials_common.vertalign = "user_center"; + self.trials_common.aligny = "top"; + self.trials_common.x = x - 1; + self.trials_common.y = y + (sq_size / 2) + sq_dot; + self.trials_common.color = (0, 0, 0); + self.trials_common.sort = 3; + self.trials_common.foreground = true; + self.trials_common.hidewheninmenu = true; + self.trials_common setshader("menu_mp_star_rating", sq_star, sq_star); + } + self.trials_common.alpha = .8; + + // Rare tier dot + if (!isdefined(self.trials_rare)) { + self.trials_rare = newclienthudelem(self); + self.trials_rare.horzalign = "user_left"; + self.trials_rare.alignx = "left"; + self.trials_rare.vertalign = "user_center"; + self.trials_rare.aligny = "top"; + self.trials_rare.x = x + sq_dot + (sq_dot * 2) - 1; + self.trials_rare.y = y + (sq_size / 2) + sq_dot; + self.trials_rare.color = (0, 0, 0); + self.trials_rare.sort = 3; + self.trials_rare.foreground = true; + self.trials_rare.hidewheninmenu = true; + self.trials_rare setshader("menu_mp_star_rating", sq_star, sq_star); + } + self.trials_rare.alpha = .8; + + // Epic tier dot + if (!isdefined(self.trials_epic)) { + self.trials_epic = newclienthudelem(self); + self.trials_epic.horzalign = "user_left"; + self.trials_epic.alignx = "left"; + self.trials_epic.vertalign = "user_center"; + self.trials_epic.aligny = "top"; + self.trials_epic.x = x + (sq_dot * 2) + (sq_dot * 4) - 1; + self.trials_epic.y = y + (sq_size / 2) + sq_dot; + self.trials_epic.color = (0, 0, 0); + self.trials_epic.sort = 3; + self.trials_epic.foreground = true; + self.trials_epic.hidewheninmenu = true; + self.trials_epic setshader("menu_mp_star_rating", sq_star, sq_star); + } + self.trials_epic.alpha = .8; + + // Legendary tier dot + if (!isdefined(self.trials_legend)) { + self.trials_legend = newclienthudelem(self); + self.trials_legend.horzalign = "user_left"; + self.trials_legend.alignx = "left"; + self.trials_legend.vertalign = "user_center"; + self.trials_legend.aligny = "top"; + self.trials_legend.x = x + (sq_dot * 3) + (sq_dot * 6) - 1; + self.trials_legend.y = y + (sq_size / 2) + sq_dot; + self.trials_legend.color = (0, 0, 0); + self.trials_legend.sort = 3; + self.trials_legend.foreground = true; + self.trials_legend.hidewheninmenu = true; + self.trials_legend setshader("menu_mp_star_rating", sq_star, sq_star); + } + self.trials_legend.alpha = .8; + } +} + +draw_reward_alert(text) { + if (!isdefined(self.trials_init)) + return; + + if (!isdefined(text)) + text = "REWARD UPGRADED"; + + width = int(self.trials_height * 6.25); + height = self.trials_height; + + // Reward upgrade background + if (!isdefined(self.trials_upgrade_shadow)) { + self.trials_upgrade_shadow = newclienthudelem(self); + self.trials_upgrade_shadow.horzalign = "user_center"; + self.trials_upgrade_shadow.alignx = "center"; + self.trials_upgrade_shadow.vertalign = "user_center"; + self.trials_upgrade_shadow.aligny = "middle"; + self.trials_upgrade_shadow.x = 0; + self.trials_upgrade_shadow.y = -160; + self.trials_upgrade_shadow.color = (0, 0, 0); + self.trials_upgrade_shadow.sort = 0; + self.trials_upgrade_shadow.foreground = true; + self.trials_upgrade_shadow.hidewheninmenu = true; + self.trials_upgrade_shadow setshader("scorebar_zom_1", width, height); + } + + // Reward upgrade background 2 + if (!isdefined(self.trials_upgrade_bg)) { + self.trials_upgrade_bg = newclienthudelem(self); + self.trials_upgrade_bg.horzalign = "user_center"; + self.trials_upgrade_bg.alignx = "center"; + self.trials_upgrade_bg.vertalign = "user_center"; + self.trials_upgrade_bg.aligny = "middle"; + self.trials_upgrade_bg.x = 0; + self.trials_upgrade_bg.y = -160; + self.trials_upgrade_bg.color = (1, 0, 0); + self.trials_upgrade_bg.sort = 1; + self.trials_upgrade_bg.foreground = true; + self.trials_upgrade_bg.hidewheninmenu = true; + self.trials_upgrade_bg setshader("scorebar_zom_1", width, height); + } + + // Reward upgrade text + if (!isdefined(self.trials_upgrade)) { + self.trials_upgrade = newclienthudelem(self); + self.trials_upgrade.horzalign = "user_center"; + self.trials_upgrade.alignx = "center"; + self.trials_upgrade.vertalign = "user_center"; + self.trials_upgrade.aligny = "middle"; + self.trials_upgrade.x = 0; + self.trials_upgrade.y = -160; + self.trials_upgrade.fontscale = 1.3; + self.trials_upgrade.sort = 2; + self.trials_upgrade.foreground = true; + self.trials_upgrade.hidewheninmenu = true; + } + self.trials_upgrade settext(text); + + // Animation + self playlocalsound("zmb_cha_ching"); + self.trials_upgrade_shadow.alpha = 0; + self.trials_upgrade_bg.alpha = 0; + self.trials_upgrade.alpha = 0; + self.trials_upgrade_shadow fadeovertime(.5); + self.trials_upgrade_shadow.alpha = 1; + self.trials_upgrade_bg fadeovertime(.5); + self.trials_upgrade_bg.alpha = 1; + self.trials_upgrade fadeovertime(.5); + self.trials_upgrade.alpha = 1; + wait 5; + self.trials_upgrade_shadow fadeovertime(.25); + self.trials_upgrade_shadow.alpha = 0; + self.trials_upgrade_bg fadeovertime(.25); + self.trials_upgrade_bg.alpha = 0; + self.trials_upgrade fadeovertime(.25); + self.trials_upgrade.alpha = 0; + wait .25; +} + +draw_trial_progress() { + if (!isdefined(self.trials_init)) + return; + + // Drop incoming animation call if the previous one is not completed + if (self.do_trial_progress) + return; + + // Drop incoming animation call when highest trial level (legendary) is reached + if (self.trials_reward_code == "legendary") + return; + + self.do_trial_progress = true; + sq_size = self.trials_height; + sq_wide = self.trials_width + sq_size; + sq_dot = self.trials_space; + sq_star = self.trials_star; + x = self.trials_x; + y = self.trials_y; + + // Top gradient line + if (!isdefined(self.trials_top_bar)) { + self.trials_top_bar = newclienthudelem(self); + self.trials_top_bar.horzalign = "user_left"; + self.trials_top_bar.vertalign = "user_center"; + self.trials_top_bar.aligny = "top"; + self.trials_top_bar.y = y - int(sq_size / 2); + self.trials_top_bar.color = self.trials_reward_color; + self.trials_top_bar.sort = 3; + self.trials_top_bar.foreground = true; + self.trials_top_bar.hidewheninmenu = true; + } + + // Bottom gradient line + if (!isdefined(self.trials_bottom_bar)) { + self.trials_bottom_bar = newclienthudelem(self); + self.trials_bottom_bar.horzalign = "user_left"; + self.trials_bottom_bar.vertalign = "user_center"; + self.trials_bottom_bar.aligny = "bottom"; + self.trials_bottom_bar.y = y + int(sq_size / 2); + self.trials_bottom_bar.color = self.trials_reward_color; + self.trials_bottom_bar.sort = 3; + self.trials_bottom_bar.foreground = true; + self.trials_bottom_bar.hidewheninmenu = true; + } + + // Animation + self playlocalsound("cac_cmn_beep"); + self.trials_top_bar setshader("gradient_fadein", 0, 1); + self.trials_bottom_bar setshader("gradient_fadein", 0, 1); + self.trials_top_bar.alignx = "left"; + self.trials_top_bar.x = x + sq_dot; + self.trials_bottom_bar.alignx = "left"; + self.trials_bottom_bar.x = x + sq_dot; + self.trials_top_bar.alpha = 1; + self.trials_bottom_bar.alpha = 1; + self.trials_top_bar scaleovertime(.25, sq_wide, 1); + self.trials_bottom_bar scaleovertime(.25, sq_wide, 1); + wait .5; + self.trials_top_bar.alignx = "right"; + self.trials_bottom_bar.alignx = "right"; + self.trials_top_bar.x = x + sq_dot + sq_wide; + self.trials_bottom_bar.x = x + sq_dot + sq_wide; + self.trials_top_bar scaleovertime(.25, 1, 1); + self.trials_bottom_bar scaleovertime(.25, 1, 1); + self.trials_top_bar fadeovertime(.25); + self.trials_bottom_bar fadeovertime(.25); + self.trials_top_bar.alpha = 0; + self.trials_bottom_bar.alpha = 0; + wait .25; + + self.do_trial_progress = false; +} + +set_trial_reward(tier) { + if (!isdefined(self.trials_init)) + return; + + if (isdefined(self.trials_reward_code) && self.trials_reward_code == tier) + return; + + switch(tier) { + case "none": + text = "^1None"; + color = array((.8, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0)); + alpha = array(0, 0, 0, 0); + break; + + case "common": + text = "^2Common"; + color = array((0, 1, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0)); + alpha = array(1, .8, .8, .8); + break; + + case "rare": + text = "^4Rare"; + color = array((0, .5, 1), (0, .5, 1), (0, 0, 0), (0, 0, 0)); + alpha = array(1, 1, .8, .8); + break; + + case "epic": + text = "^6Epic"; + color = array((0.345, 0, 0.576), (0.345, 0, 0.576), (0.345, 0, 0.576), (0, 0, 0)); + alpha = array(1, 1, 1, .8); + break; + + case "legendary": + text = "^3Legendary"; + color = array((1, 0.478, 0), (1, 0.478, 0), (1, 0.478, 0), (1, 0.478, 0)); + alpha = array(1, 1, 1, 1); + break; + + default: + return; + } + previous = self.trials_reward_code; + self.trials_reward_color = color[0]; + self.trials_reward_code = tier; + self.trials_reward_color_code = getsubstr(text, 0, 2); + self.trials_reward_level = text; + self.trials_reward settext(text); + self.trials_reward.alpha = alpha[0]; + self.trials_timer.color = color[0]; + self.trials_timer_bar.color = color[0]; + self.trials_top_bar.color = color[0]; + self.trials_bottom_bar.color = color[0]; + self.trials_common.color = color[0]; + self.trials_common.alpha = alpha[0]; + self.trials_rare.color = color[1]; + self.trials_rare.alpha = alpha[1]; + self.trials_epic.color = color[2]; + self.trials_epic.alpha = alpha[2]; + self.trials_legend.color = color[3]; + self.trials_legend.alpha = alpha[3]; + + // Trigger trial challenge text overwrite or reset + if (tier == "legendary" || previous == "legendary") + set_trial_challenge(self.trials_challenge_text); +} + +set_trial_challenge(text) { + if (!isdefined(self.trials_init) || !isdefined(text)) + return; + + self.trials_challenge_text = text; + + // Overwrite trial challenge text if highest trial level (legendary) is reached + if (self.trials_reward_code == "legendary") + text = self.trials_reward_color_code + "CLAIM REWARD"; + + line_shift = issubstr(text, "\n") ? 6 : 0; + self.trials_challenge.y = self.trials_challenge.real_y - line_shift; + self.trials_challenge settext(text); +} + +set_trial_timer(time) { + if (!isdefined(self.trials_init) || !isdefined(time)) + return; + + self.trials_timer settimer(time); +} + +AddPlayerMagicPoints(num){ + if(isdefined(self.revivetrigger)) { + return; + } + self.ReaperTrialsCurrentMagic += num; + self draw_trial_progress(); + if(self.ReaperTrialsCurrentMagic >= 100) + self.ReaperTrialsCurrentMagic = 100; + if(self.ReaperTrialsCurrentMagic >= 25){ + if(self.ReaperTrialsCurrentMagic >= 25 && self.ReaperTrialsCurrentMagic < 50){ + if(self.trials_reward_code != "common"){ + self toggle_trial_reward_hud(); + self set_trial_reward("common"); + self thread draw_reward_alert("REWARD AVAILABLE"); + } + } + if(self.ReaperTrialsCurrentMagic >= 50 && self.ReaperTrialsCurrentMagic < 75){ + if(self.trials_reward_code != "rare"){ + self set_trial_reward("rare"); + self thread draw_reward_alert(); + } + } + if(self.ReaperTrialsCurrentMagic >= 75 && self.ReaperTrialsCurrentMagic < 100){ + if(self.trials_reward_code != "epic"){ + self set_trial_reward("epic"); + self thread draw_reward_alert(); + } + } + if(self.ReaperTrialsCurrentMagic == 100){ + if(self.trials_reward_code != "legendary"){ + self set_trial_reward("legendary"); + self thread draw_reward_alert(); + } + } + } +} + +ShowToSpecific(FXOrigin,Index){ + level endon("game_ended"); + while(1){ + if(!isdefined(self.sharedreward)) { + self SetInvisibleToAll(); + self SetVisibleToPlayer( GetPlayers()[Index] ); + if(isdefined(GetPlayers()[Index])){ + if(isdefined(GetPlayers()[Index].ReaperTrialsCurrentMagic) && GetPlayers()[Index].ReaperTrialsCurrentMagic >= 25){ + if(level.script == "zm_transit") + playfx( level._effect[ "character_fire_death_sm" ], FXOrigin); + else if(level.script == "zm_prison") + playfx(level._effect[ "fx_alcatraz_elec_chair" ],FXOrigin - (17,0,15),anglesToForward(0,0,0), anglesToUp(0,0,0));// Too Lazy + else if(level.script == "zm_buried") + playfx( level._effect[ "character_fire_death_sm" ], FXOrigin); + else if(level.script == "zm_highrise") + playfx( level._effect[ "character_fire_death_sm" ], FXOrigin); + } + } + } + wait 5; + } +} + +EndGameListener() { + while(1) { + level waittill("intermission"); + foreach(player in level.players) { + player.trials_show_challenge = false; + player.trials_show_reward = false; + player.trials_bg destroy(); + player.trials_timer_bg destroy(); + player.trials_timer_bar destroy(); + player.trials_timer destroy(); + player.trials_challenge destroy(); + player.trials_reward destroy(); + player.trials_common destroy(); + player.trials_rare destroy(); + player.trials_epic destroy(); + player.trials_legend destroy(); + } + } +} + +AddReward(TrialRank, RewardModel, RewardHintname, RewardCodename, Powerup) { + if(!isdefined(level.Rewards_List)) + level.Rewards_List = []; + + Reward = SpawnStruct(); + Reward.Rank = TrialRank; + if(isdefined(RewardModel)) + Reward.Model = RewardModel; + else + Reward.Model = getweaponmodel(RewardCodename); + Reward.Hint = RewardHintname; + Reward.Name = RewardCodename; + Reward.Powerup = Powerup; + + level.Rewards_List[level.Rewards_List.size] = Reward; +} + +get_zone_name(key) { + // Caching and array lookup is way more efficient + if (isdefined(level.zone_names)) + return level.zone_names[key]; + + level.zone_names = []; + + switch(level.script) { + case "zm_transit": + level.zone_names["zone_pri"] = "Bus Depot"; + level.zone_names["zone_pri2"] = "Bus Depot Hallway"; + level.zone_names["zone_station_ext"] = "Outside Bus Depot"; + level.zone_names["zone_trans_2b"] = "Road After Bus Depot"; + level.zone_names["zone_trans_2"] = "Tunnel Entrance"; + level.zone_names["zone_amb_tunnel"] = "Tunnel"; + level.zone_names["zone_trans_3"] = "Tunnel Exit"; + level.zone_names["zone_roadside_west"] = "Outside Diner"; + level.zone_names["zone_gas"] = "Gas Station"; + level.zone_names["zone_roadside_east"] = "Outside Garage"; + level.zone_names["zone_trans_diner"] = "Road Outside Diner"; + level.zone_names["zone_trans_diner2"] = "Road Outside Garage"; + level.zone_names["zone_gar"] = "Garage"; + level.zone_names["zone_din"] = "Diner"; + level.zone_names["zone_diner_roof"] = "Diner Roof"; + level.zone_names["zone_trans_4"] = "Road After Diner"; + level.zone_names["zone_amb_forest"] = "Forest"; + level.zone_names["zone_trans_10"] = "Outside Church"; + level.zone_names["zone_town_church"] = "Upper South Town"; + level.zone_names["zone_trans_5"] = "Road Before Farm"; + level.zone_names["zone_far"] = "Outside Farm"; + level.zone_names["zone_far_ext"] = "Farm"; + level.zone_names["zone_brn"] = "Barn"; + level.zone_names["zone_farm_house"] = "Farmhouse"; + level.zone_names["zone_trans_6"] = "Road After Farm"; + level.zone_names["zone_amb_cornfield"] = "Cornfield"; + level.zone_names["zone_cornfield_prototype"] = "Nacht der Untoten"; + level.zone_names["zone_trans_7"] = "Upper Road Before Power"; + level.zone_names["zone_trans_pow_ext1"] = "Road Before Power"; + level.zone_names["zone_pow"] = "Outside Power Station"; + level.zone_names["zone_prr"] = "Power Station"; + level.zone_names["zone_pcr"] = "Power Control Room"; + level.zone_names["zone_pow_warehouse"] = "Warehouse"; + level.zone_names["zone_trans_8"] = "Road After Power"; + level.zone_names["zone_amb_power2town"] = "Cabin"; + level.zone_names["zone_trans_9"] = "Road Before Town"; + level.zone_names["zone_town_north"] = "North Town"; + level.zone_names["zone_tow"] = "Center Town"; + level.zone_names["zone_town_east"] = "East Town"; + level.zone_names["zone_town_west"] = "West Town"; + level.zone_names["zone_town_west2"] = "West Town 2"; + level.zone_names["zone_town_south"] = "South Town"; + level.zone_names["zone_bar"] = "Bar"; + level.zone_names["zone_town_barber"] = "Above Barbershop"; + level.zone_names["zone_ban"] = "Bank"; + level.zone_names["zone_ban_vault"] = "Bank Vault"; + level.zone_names["zone_tbu"] = "Laboratory"; + level.zone_names["zone_trans_11"] = "Road After Town"; + level.zone_names["zone_amb_bridge"] = "Bridge"; + level.zone_names["zone_trans_1"] = "Road Before Bus Depot"; + break; + + case "zm_nuked": + level.zone_names["culdesac_yellow_zone"] = "Yellow House Cul-de-sac"; + level.zone_names["culdesac_green_zone"] = "Green House Cul-de-sac"; + level.zone_names["truck_zone"] = "Truck"; + level.zone_names["openhouse1_f1_zone"] = "Green House Downstairs"; + level.zone_names["openhouse1_f2_zone"] = "Green House Upstairs"; + level.zone_names["openhouse1_backyard_zone"] = "Green House Backyard"; + level.zone_names["openhouse2_f1_zone"] = "Yellow House Downstairs"; + level.zone_names["openhouse2_f2_zone"] = "Yellow House Upstairs"; + level.zone_names["openhouse2_backyard_zone"] = "Yellow House Backyard"; + level.zone_names["ammo_door_zone"] = "Yellow House Backyard Door"; + break; + + case "zm_highrise": + level.zone_names["zone_green_start"] = "Green Highrise Level 3b"; + level.zone_names["zone_green_escape_pod"] = "Escape Pod"; + level.zone_names["zone_green_escape_pod_ground"] = "Escape Pod Shaft"; + level.zone_names["zone_green_level1"] = "Green Highrise Level 3a"; + level.zone_names["zone_green_level2a"] = "Green Highrise Level 2a"; + level.zone_names["zone_green_level2b"] = "Green Highrise Level 2b"; + level.zone_names["zone_green_level3a"] = "Green Highrise Restaurant"; + level.zone_names["zone_green_level3b"] = "Green Highrise Level 1a"; + level.zone_names["zone_green_level3c"] = "Green Highrise Level 1b"; + level.zone_names["zone_green_level3d"] = "Green Highrise Behind Restaurant"; + level.zone_names["zone_orange_level1"] = "Upper Orange Highrise Level 2"; + level.zone_names["zone_orange_level2"] = "Upper Orange Highrise Level 1"; + level.zone_names["zone_orange_elevator_shaft_top"] = "Elevator Shaft Level 3"; + level.zone_names["zone_orange_elevator_shaft_middle_1"] = "Elevator Shaft Level 2"; + level.zone_names["zone_orange_elevator_shaft_middle_2"] = "Elevator Shaft Level 1"; + level.zone_names["zone_orange_elevator_shaft_bottom"] = "Elevator Shaft Bottom"; + level.zone_names["zone_orange_level3a"] = "Lower Orange Highrise Level 1a"; + level.zone_names["zone_orange_level3b"] = "Lower Orange Highrise Level 1b"; + level.zone_names["zone_blue_level5"] = "Lower Blue Highrise Level 1"; + level.zone_names["zone_blue_level4a"] = "Lower Blue Highrise Level 2a"; + level.zone_names["zone_blue_level4b"] = "Lower Blue Highrise Level 2b"; + level.zone_names["zone_blue_level4c"] = "Lower Blue Highrise Level 2c"; + level.zone_names["zone_blue_level2a"] = "Upper Blue Highrise Level 1a"; + level.zone_names["zone_blue_level2b"] = "Upper Blue Highrise Level 1b"; + level.zone_names["zone_blue_level2c"] = "Upper Blue Highrise Level 1c"; + level.zone_names["zone_blue_level2d"] = "Upper Blue Highrise Level 1d"; + level.zone_names["zone_blue_level1a"] = "Upper Blue Highrise Level 2a"; + level.zone_names["zone_blue_level1b"] = "Upper Blue Highrise Level 2b"; + level.zone_names["zone_blue_level1c"] = "Upper Blue Highrise Level 2c"; + break; + + case "zm_prison": + level.zone_names["zone_start"] = "D-Block"; + level.zone_names["zone_library"] = "Library"; + level.zone_names["zone_cellblock_west"] = "Cellblock 2nd Floor"; + level.zone_names["zone_cellblock_west_gondola"] = "Cellblock 3rd Floor"; + level.zone_names["zone_cellblock_west_gondola_dock"] = "Cellblock Gondola"; + level.zone_names["zone_cellblock_west_barber"] = "Michigan Avenue"; + level.zone_names["zone_cellblock_east"] = "Times Square"; + level.zone_names["zone_cafeteria"] = "Cafeteria"; + level.zone_names["zone_cafeteria_end"] = "Cafeteria End"; + level.zone_names["zone_infirmary"] = "Infirmary 1"; + level.zone_names["zone_infirmary_roof"] = "Infirmary 2"; + level.zone_names["zone_roof_infirmary"] = "Roof 1"; + level.zone_names["zone_roof"] = "Roof 2"; + level.zone_names["zone_cellblock_west_warden"] = "Sally Port"; + level.zone_names["zone_warden_office"] = "Warden's Office"; + level.zone_names["cellblock_shower"] = "Showers"; + level.zone_names["zone_citadel_shower"] = "Citadel To Showers"; + level.zone_names["zone_citadel"] = "Citadel"; + level.zone_names["zone_citadel_warden"] = "Citadel To Warden's Office"; + level.zone_names["zone_citadel_stairs"] = "Citadel Tunnels"; + level.zone_names["zone_citadel_basement"] = "Citadel Basement"; + level.zone_names["zone_citadel_basement_building"] = "China Alley"; + level.zone_names["zone_studio"] = "Building 64"; + level.zone_names["zone_dock"] = "Docks"; + level.zone_names["zone_dock_puzzle"] = "Docks Gates"; + level.zone_names["zone_dock_gondola"] = "Upper Docks"; + level.zone_names["zone_golden_gate_bridge"] = "Golden Gate Bridge"; + level.zone_names["zone_gondola_ride"] = "Gondola"; + break; + + case "zm_buried": + level.zone_names["zone_start"] = "Processing"; + level.zone_names["zone_start_lower"] = "Lower Processing"; + level.zone_names["zone_tunnels_center"] = "Center Tunnels"; + level.zone_names["zone_tunnels_north"] = "Courthouse Tunnels 2"; + level.zone_names["zone_tunnels_north2"] = "Courthouse Tunnels 1"; + level.zone_names["zone_tunnels_south"] = "Saloon Tunnels 3"; + level.zone_names["zone_tunnels_south2"] = "Saloon Tunnels 2"; + level.zone_names["zone_tunnels_south3"] = "Saloon Tunnels 1"; + level.zone_names["zone_street_lightwest"] = "Outside General Store & Bank"; + level.zone_names["zone_street_lightwest_alley"] = "Outside General Store & Bank Alley"; + level.zone_names["zone_morgue_upstairs"] = "Morgue"; + level.zone_names["zone_underground_jail"] = "Jail Downstairs"; + level.zone_names["zone_underground_jail2"] = "Jail Upstairs"; + level.zone_names["zone_general_store"] = "General Store"; + level.zone_names["zone_stables"] = "Stables"; + level.zone_names["zone_street_darkwest"] = "Outside Gunsmith"; + level.zone_names["zone_street_darkwest_nook"] = "Outside Gunsmith Nook"; + level.zone_names["zone_gun_store"] = "Gunsmith"; + level.zone_names["zone_bank"] = "Bank"; + level.zone_names["zone_tunnel_gun2stables"] = "Stables To Gunsmith Tunnel 2"; + level.zone_names["zone_tunnel_gun2stables2"] = "Stables To Gunsmith Tunnel"; + level.zone_names["zone_street_darkeast"] = "Outside Saloon & Toy Store"; + level.zone_names["zone_street_darkeast_nook"] = "Outside Saloon & Toy Store Nook"; + level.zone_names["zone_underground_bar"] = "Saloon"; + level.zone_names["zone_tunnel_gun2saloon"] = "Saloon To Gunsmith Tunnel"; + level.zone_names["zone_toy_store"] = "Toy Store Downstairs"; + level.zone_names["zone_toy_store_floor2"] = "Toy Store Upstairs"; + level.zone_names["zone_toy_store_tunnel"] = "Toy Store Tunnel"; + level.zone_names["zone_candy_store"] = "Candy Store Downstairs"; + level.zone_names["zone_candy_store_floor2"] = "Candy Store Upstairs"; + level.zone_names["zone_street_lighteast"] = "Outside Courthouse & Candy Store"; + level.zone_names["zone_underground_courthouse"] = "Courthouse Downstairs"; + level.zone_names["zone_underground_courthouse2"] = "Courthouse Upstairs"; + level.zone_names["zone_street_fountain"] = "Fountain"; + level.zone_names["zone_church_graveyard"] = "Graveyard"; + level.zone_names["zone_church_main"] = "Church Downstairs"; + level.zone_names["zone_church_upstairs"] = "Church Upstairs"; + level.zone_names["zone_mansion_lawn"] = "Mansion Lawn"; + level.zone_names["zone_mansion"] = "Mansion"; + level.zone_names["zone_mansion_backyard"] = "Mansion Backyard"; + level.zone_names["zone_maze"] = "Maze"; + level.zone_names["zone_maze_staircase"] = "Maze Staircase"; + break; + + case "zm_tomb": + level.zone_names["zone_start"] = "Lower Laboratory"; + level.zone_names["zone_start_a"] = "Upper Laboratory"; + level.zone_names["zone_start_b"] = "Generator 1"; + level.zone_names["zone_bunker_1a"] = "Generator 3 Bunker 1"; + level.zone_names["zone_fire_stairs"] = "Fire Tunnel"; + level.zone_names["zone_fire_stairs_1"] = "zone_fire_stairs_1"; + level.zone_names["zone_bunker_1"] = "Generator 3 Bunker 2"; + level.zone_names["zone_bunker_3a"] = "Generator 3"; + level.zone_names["zone_bunker_3b"] = "Generator 3 Bunker 3"; + level.zone_names["zone_bunker_2a"] = "Generator 2 Bunker 1"; + level.zone_names["zone_bunker_2"] = "Generator 2 Bunker 2"; + level.zone_names["zone_bunker_4a"] = "Generator 2"; + level.zone_names["zone_bunker_4b"] = "Generator 2 Bunker 3"; + level.zone_names["zone_bunker_4c"] = "Tank Station"; + level.zone_names["zone_bunker_4d"] = "Above Tank Station"; + level.zone_names["zone_bunker_tank_c"] = "Generator 2 Tank Route 1"; + level.zone_names["zone_bunker_tank_c1"] = "Generator 2 Tank Route 2"; + level.zone_names["zone_bunker_4e"] = "Generator 2 Tank Route 3"; + level.zone_names["zone_bunker_tank_d"] = "Generator 2 Tank Route 4"; + level.zone_names["zone_bunker_tank_d1"] = "Generator 2 Tank Route 5"; + level.zone_names["zone_bunker_4f"] = "zone_bunker_4f"; + level.zone_names["zone_bunker_5a"] = "Workshop Downstairs"; + level.zone_names["zone_bunker_5b"] = "Workshop Upstairs"; + level.zone_names["zone_nml_2a"] = "No Man's Land Walkway"; + level.zone_names["zone_nml_2"] = "No Man's Land Entrance"; + level.zone_names["zone_bunker_tank_e"] = "Generator 5 Tank Route 1"; + level.zone_names["zone_bunker_tank_e1"] = "Generator 5 Tank Route 2"; + level.zone_names["zone_bunker_tank_e2"] = "zone_bunker_tank_e2"; + level.zone_names["zone_bunker_tank_f"] = "Generator 5 Tank Route 3"; + level.zone_names["zone_nml_1"] = "Generator 5 Tank Route 4"; + level.zone_names["zone_nml_4"] = "Generator 5 Tank Route 5"; + level.zone_names["zone_nml_0"] = "Generator 5 Left Footstep"; + level.zone_names["zone_nml_5"] = "Generator 5 Right Footstep Walkway"; + level.zone_names["zone_nml_farm"] = "Generator 5"; + level.zone_names["zone_nml_farm_1"] = "zone_nml_farm_1"; + level.zone_names["zone_nml_celllar"] = "Generator 5 Cellar"; + level.zone_names["zone_bolt_stairs"] = "Lightning Tunnel"; + level.zone_names["zone_bolt_stairs_1"] = "zone_bolt_stairs_1"; + level.zone_names["zone_nml_3"] = "No Man's Land 1st Right Footstep"; + level.zone_names["zone_nml_2b"] = "No Man's Land Stairs"; + level.zone_names["zone_nml_6"] = "No Man's Land Left Footstep"; + level.zone_names["zone_nml_8"] = "No Man's Land 2nd Right Footstep"; + level.zone_names["zone_nml_10a"] = "Generator 4 Tank Route 1"; + level.zone_names["zone_nml_10"] = "Generator 4 Tank Route 2"; + level.zone_names["zone_nml_7"] = "Generator 4 Tank Route 3"; + level.zone_names["zone_nml_7a"] = "zone_nml_7a"; + level.zone_names["zone_bunker_tank_a"] = "Generator 4 Tank Route 4"; + level.zone_names["zone_bunker_tank_a1"] = "Generator 4 Tank Route 5"; + level.zone_names["zone_bunker_tank_a2"] = "zone_bunker_tank_a2"; + level.zone_names["zone_bunker_tank_b"] = "Generator 4 Tank Route 6"; + level.zone_names["zone_nml_9"] = "Generator 4 Left Footstep"; + level.zone_names["zone_nml_9a"] = "zone_nml_9a"; + level.zone_names["zone_air_stairs"] = "Wind Tunnel"; + level.zone_names["zone_air_stairs_1"] = "zone_air_stairs_1"; + level.zone_names["zone_nml_11"] = "Generator 4"; + level.zone_names["zone_nml_11a"] = "zone_nml_11a"; + level.zone_names["zone_nml_12"] = "Generator 4 Right Footstep"; + level.zone_names["zone_nml_12a"] = "zone_nml_12a"; + level.zone_names["zone_nml_16"] = "Excavation Site Front Path"; + //level.zone_names["zone_nml_16a"] = "zone_nml_16a"; + level.zone_names["zone_nml_17"] = "Excavation Site Back Path"; + //level.zone_names["zone_nml_17a"] = "zone_nml_17a"; + level.zone_names["zone_nml_18"] = "Excavation Site Level 3"; + level.zone_names["zone_nml_19"] = "Excavation Site Level 2"; + level.zone_names["ug_bottom_zone"] = "Excavation Site Level 1"; + level.zone_names["zone_nml_13"] = "Generator 5 To Generator 6 Path"; + level.zone_names["zone_nml_14"] = "Generator 4 To Generator 6 Path"; + level.zone_names["zone_nml_15"] = "Generator 6 Entrance"; + //level.zone_names["zone_nml_15a"] = "zone_nml_15a"; + level.zone_names["zone_village_0"] = "Generator 6 Left Footstep"; + level.zone_names["zone_village_5"] = "Generator 6 Tank Route 1"; + level.zone_names["zone_village_5a"] = "Generator 6 Tank Route 2"; + level.zone_names["zone_village_5b"] = "Generator 6 Tank Route 3"; + level.zone_names["zone_village_1"] = "Generator 6 Tank Route 4"; + //level.zone_names["zone_village_1a"] = "zone_village_1a"; + level.zone_names["zone_village_4b"] = "Generator 6 Tank Route 5"; + level.zone_names["zone_village_4a"] = "Generator 6 Tank Route 6"; + level.zone_names["zone_village_4"] = "Generator 6 Tank Route 7"; + level.zone_names["zone_village_2"] = "Church"; + level.zone_names["zone_village_3"] = "Generator 6 Right Footstep"; + level.zone_names["zone_village_3a"] = "Generator 6"; + level.zone_names["zone_village_3b"] = "zone_village_3b"; + level.zone_names["zone_ice_stairs"] = "Ice Tunnel"; + //level.zone_names["zone_ice_stairs_1"] = "zone_ice_stairs_1"; + level.zone_names["zone_bunker_6"] = "Above Generator 3 Bunker"; + level.zone_names["zone_nml_20"] = "Above No Man's Land"; + level.zone_names["zone_village_6"] = "Behind Church"; + //level.zone_names["zone_village_6a"] = "zone_village_6a"; + level.zone_names["zone_chamber_0"] = "The Crazy Place Lightning Chamber"; + level.zone_names["zone_chamber_1"] = "The Crazy Place Lightning & Ice"; + level.zone_names["zone_chamber_2"] = "The Crazy Place Ice Chamber"; + level.zone_names["zone_chamber_3"] = "The Crazy Place Fire & Lightning"; + level.zone_names["zone_chamber_4"] = "The Crazy Place Center"; + level.zone_names["zone_chamber_5"] = "The Crazy Place Ice & Wind"; + level.zone_names["zone_chamber_6"] = "The Crazy Place Fire Chamber"; + level.zone_names["zone_chamber_7"] = "The Crazy Place Wind & Fire"; + level.zone_names["zone_chamber_8"] = "The Crazy Place Wind Chamber"; + level.zone_names["zone_robot_head"] = "Robot's Head"; + break; + } + return level.zone_names[key]; +} diff --git a/t6/uncompiled mods/unlimitedsprint-compiled.gsc b/t6/uncompiled mods/unlimitedsprint-compiled.gsc new file mode 100644 index 0000000000000000000000000000000000000000..7a84188c5577d08d338578be35917ce7ca340601 GIT binary patch literal 408 zcmZp04|e9|Vqjwcg3~~p#0a4?fV314+X3+mC( zD`CjY%Pe8Y&nw7DtV}IR&d2Ko zv7E@Rzt?~?$n=LAiBX?`G|0qI20I2|;IN(p^C9eKK=w+oI3o);P!a<285kLF0GX*k d^>=`D8<742r2B#NFCaY&WDXE*1QHxT8UP`aU4Z}q literal 0 HcmV?d00001 diff --git a/t6/uncompiled mods/unlimitedsprint.gsc b/t6/uncompiled mods/unlimitedsprint.gsc new file mode 100644 index 0000000..30c086c --- /dev/null +++ b/t6/uncompiled mods/unlimitedsprint.gsc @@ -0,0 +1,25 @@ +init() +{ + level thread onPlayerConnect(); +} + +onPlayerConnect() +{ + for(;;) + { + level waittill("connected", player); + + player thread onPlayerSpawned(); + } +} + +onPlayerSpawned() +{ + level endon("end_game"); + self endon("disconnect"); + for(;;) + { + self waittill("spawned_player"); + self setperk("specialty_unlimitedsprint"); + } +} \ No newline at end of file diff --git a/t6/uncompiled mods/vipcommands.gsc b/t6/uncompiled mods/vipcommands.gsc new file mode 100644 index 0000000..1b710a5 --- /dev/null +++ b/t6/uncompiled mods/vipcommands.gsc @@ -0,0 +1,112 @@ + +#include maps\mp\_visionset_mgr; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\_demo; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_power; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\_utility; +#include common_scripts\utility; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\zombies\_zm_chugabud; +#include maps\mp\zombies\_zm_afterlife; +#include maps\mp\zombies\_zm_tombstone; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm_perk_vulture; +#include maps\mp\zombies\_zm_weap_time_bomb; +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\gametypes_zm\_gameobjects; +#include maps\mp\zombies\_zm_buildables; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm_clone; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_weap_cymbal_monkey; +#include maps\mp\zombies\_zm; + +init() +{ + setDvar("revive", ""); + setDvar("0_revivedRound", -10); + setDvar("1_revivedRound", -10); + setDvar("2_revivedRound", -10); + setDvar("3_revivedRound", -10); + setDvar("4_revivedRound", -10); + setDvar("5_revivedRound", -10); + setDvar("6_revivedRound", -10); + setDvar("7_revivedRound", -10); + setDvar("currentRound", 0); + level thread playerReviveCommand(); +} + +playerReviveCommand() +{ + level endon("game_ended"); + + for (;;) + { + if (getdvar("currentRound") != level.round_number) + setdvar("currentRound", level.round_number); + if (getDvar("revive") != "") + { + content = strTok(getDvar("revive"), ";"); + setDvar("revive", ""); + revivePlayers(content); + iPrintLn(getPlayerByGuid(content[0]).name + "^7 has ^3revived everyone ^7!"); + if (content[1] == "1") + iPrintLn("^1Juggernog^7 granted to the fallens !"); + + } + wait 0.5; + } +} + +revivePlayers(content) +{ + for (i = 0; i < level.players.size; i++) + { + if(level.players[i] maps\mp\zombies\_zm_laststand::player_is_in_laststand()) + { + level.players[i] thread maps\mp\zombies\_zm_laststand::auto_revive(level.players[i]); + level.players[i] thread PlayerTempInvulnerability(); + if (content[1] == "1" && level.players[i] HasPerk("specialty_armorvest") == 0) + level.players[i] thread maps\mp\zombies\_zm_perks::wait_give_perk("specialty_armorvest", 1); + } + else if(level.players[i].sessionstate == "spectator") + { + level.players[i] [[ level.spawnplayer ]](); + level.players[i] thread PlayerTempInvulnerability(); + if (content[1] == "1" && level.players[i] HasPerk("specialty_armorvest") == 0) + level.players[i] thread maps\mp\zombies\_zm_perks::wait_give_perk("specialty_armorvest", 1); + } + } + if (level.script != "zm_tomb" || level.script != "zm_prison" || !is_classic()) + { + thread maps\mp\zombies\_zm::refresh_player_navcard_hud(); + } +} + +PlayerTempInvulnerability() +{ + level endon("game_ended"); + self endon("player_disconnected"); + self EnableInvulnerability(); + self.ignoreme = true; + self iPrintln("Invincibility ^2ON^7 for ^35 seconds^7"); + wait 5; + self iPrintln("Invincibility ^1OFF^7"); + self DisableInvulnerability(); + self.ignoreme = false; + self Destroy(); +} + +getPlayerByGuid(guid) { + for (i = 0; i < level.players.size; i++) { + if (isAlive(level.players[i]) && int(level.players[i] getGuid()) == int(guid)) { + return level.players[i]; + } + } + return false; +} \ No newline at end of file diff --git a/t6/uncompiled mods/vipperks.gsc b/t6/uncompiled mods/vipperks.gsc new file mode 100644 index 0000000..fa82cd8 --- /dev/null +++ b/t6/uncompiled mods/vipperks.gsc @@ -0,0 +1,70 @@ +#include maps\mp\_visionset_mgr; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\_demo; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\zombies\_zm_power; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\_utility; +#include common_scripts\utility; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\zombies\_zm_chugabud; +#include maps\mp\zombies\_zm_afterlife; +#include maps\mp\zombies\_zm_tombstone; +#include maps\mp\zombies\_zm_perk_vulture; +#include maps\mp\zombies\_zm_weap_time_bomb; + +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\gametypes_zm\_gameobjects; +#include maps\mp\zombies\_zm_buildables; + + +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm_clone; +#include maps\mp\zombies\_zm_weap_cymbal_monkey; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm; + + +init() +{ + level thread onPlayerConnect(); +} + +onPlayerConnect() +{ + for (;;) + { + level waittill( "connected", player ); + player thread onPlayerSpawned(); + } +} + +onPlayerSpawned() +{ + self endon( "disconnect" ); + level endon( "game_ended" ); + flag_wait( "initial_blackscreen_passed" ); + for (;;) + { + tag = strTok(self.name, "]"); + if(tag[1] == "[^3VIP^7" || tag[1] == "^3[VIP" || tag[0] == "[^3SSS^7" ) + { + if(self.sessionstate != "spectator" && self HasPerk("specialty_armorvest") == 0 && self.afterlife != 1) + { + if (self player_is_in_laststand()) + { + } + else + { + self thread maps\mp\zombies\_zm_perks::wait_give_perk("specialty_armorvest", 1); + } + wait 2; + } + } + wait 0.5; + } +} \ No newline at end of file diff --git a/t6/uncompiled mods/witchspeed.gsc b/t6/uncompiled mods/witchspeed.gsc new file mode 100644 index 0000000..d6c5d72 --- /dev/null +++ b/t6/uncompiled mods/witchspeed.gsc @@ -0,0 +1,10 @@ +main() +{ + replaceFunc(maps/mp/zombies/_zm_ai_ghost::set_player_moving_speed_scale, ::customWitchSpeedScale); +} + +customWitchSpeedScale( player, move_speed_scale ) +{ + // if ( isdefined( player ) ) + // player setmovespeedscale( move_speed_scale ); +} \ No newline at end of file diff --git a/t6/uncompiled mods/zm_tomb-compiled.gsc b/t6/uncompiled mods/zm_tomb-compiled.gsc new file mode 100644 index 0000000000000000000000000000000000000000..2a9756b2c5760c52fe284063a465eb6eb6e11095 GIT binary patch literal 62878 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 50 ) + level.should_use_cia = 1; + + level.precachecustomcharacters = ::precache_team_characters; + level.givecustomcharacters = ::give_team_characters; + flag_wait( "start_zombie_round_logic" ); +} + +zstandard_preinit() +{ + +} + +createfx_callback() +{ + ents = getentarray(); + + for ( i = 0; i < ents.size; i++ ) + { + if ( ents[i].classname != "info_player_start" ) + ents[i] delete(); + } +} + +main() +{ + level._no_equipment_activated_clientfield = 1; + level._no_navcards = 1; + level._wallbuy_override_num_bits = 1; + maps\mp\zm_tomb_fx::main(); + level thread maps\mp\zm_tomb_ffotd::main_start(); + level.default_game_mode = "zclassic"; + level.default_start_location = "tomb"; + setup_rex_starts(); + maps\mp\zm_tomb_tank::init_animtree(); + maps\mp\zm_tomb_quest_fire::init_animtree(); + maps\mp\zm_tomb_capture_zones::init_pap_animtree(); + maps\mp\zm_tomb_teleporter::init_animtree(); + maps\mp\zm_tomb_giant_robot::init_animtree(); + level.fx_exclude_edge_fog = 1; + level.fx_exclude_tesla_head_light = 1; + level.fx_exclude_default_explosion = 1; + level.fx_exclude_footsteps = 1; + level._uses_sticky_grenades = 1; + level.disable_fx_zmb_wall_buy_semtex = 1; + level._uses_taser_knuckles = 0; + level.disable_fx_upgrade_aquired = 1; + level._uses_default_wallbuy_fx = 0; + maps\mp\zombies\_zm::init_fx(); + maps\mp\animscripts\zm_death::precache_gib_fx(); + level.zombiemode = 1; + level._no_water_risers = 1; + level.riser_fx_on_client = 1; + maps\mp\zm_tomb_amb::main(); + maps\mp\zombies\_zm_ai_mechz::precache(); + maps\mp\zombies\_zm_ai_quadrotor::precache(); + level.n_active_ragdolls = 0; + level.ragdoll_limit_check = ::ragdoll_attempt; + level._limited_equipment = []; + level._limited_equipment[level._limited_equipment.size] = "equip_dieseldrone_zm"; + level._limited_equipment[level._limited_equipment.size] = "staff_fire_zm"; + level._limited_equipment[level._limited_equipment.size] = "staff_air_zm"; + level._limited_equipment[level._limited_equipment.size] = "staff_lightning_zm"; + level._limited_equipment[level._limited_equipment.size] = "staff_water_zm"; + level.a_func_vehicle_damage_override = []; + level.callbackvehicledamage = ::tomb_vehicle_damage_override_wrapper; + level.level_specific_stats_init = ::init_tomb_stats; + maps\mp\zombies\_load::main(); + setdvar( "zombiemode_path_minz_bias", 13 ); + setdvar( "tu14_bg_chargeShotExponentialAmmoPerChargeLevel", 1 ); + + if ( getdvar( "createfx" ) == "1" ) + return; + + level_precache(); + maps\mp\gametypes_zm\_spawning::level_use_unified_spawning( 1 ); + level thread setup_tomb_spawn_groups(); + spawner_main_chamber_capture_zombies = getent( "chamber_capture_zombie_spawner", "targetname" ); + spawner_main_chamber_capture_zombies add_spawn_function( ::chamber_capture_zombie_spawn_init ); + level.has_richtofen = 0; + level.givecustomloadout = ::givecustomloadout; + level.precachecustomcharacters = ::precache_personality_characters; + level.givecustomcharacters = ::give_personality_characters; + level.setupcustomcharacterexerts = ::setup_personality_character_exerts; + level._zmbvoxlevelspecific = maps\mp\zm_tomb_vo::init_level_specific_audio; + level.custom_player_track_ammo_count = ::tomb_custom_player_track_ammo_count; + level.custom_player_fake_death = ::zm_player_fake_death; + level.custom_player_fake_death_cleanup = ::zm_player_fake_death_cleanup; + level.initial_round_wait_func = ::initial_round_wait_func; + level.zombie_init_done = ::zombie_init_done; + level._zombies_round_spawn_failsafe = ::tomb_round_spawn_failsafe; + level.random_pandora_box_start = 1; + level.zombiemode_using_pack_a_punch = 1; + level.zombiemode_reusing_pack_a_punch = 1; + level.zombiemode_using_juggernaut_perk = 1; + level.zombiemode_using_revive_perk = 1; + level.zombiemode_using_sleightofhand_perk = 1; + level.zombiemode_using_additionalprimaryweapon_perk = 1; + level.zombiemode_using_marathon_perk = 1; + level.zombiemode_using_deadshot_perk = 1; + level.zombiemode_using_doubletap_perk = 1; + level.zombiemode_using_random_perk = 1; + level.zombiemode_using_divetonuke_perk = 1; + maps\mp\zombies\_zm_perk_divetonuke::enable_divetonuke_perk_for_level(); + level.custom_electric_cherry_perk_threads = maps\mp\zombies\_zm_perks::register_perk_threads( "specialty_grenadepulldeath", ::tomb_custom_electric_cherry_reload_attack, maps\mp\zombies\_zm_perk_electric_cherry::electric_cherry_perk_lost ); + level.zombiemode_using_electric_cherry_perk = 1; + maps\mp\zombies\_zm_perk_electric_cherry::enable_electric_cherry_perk_for_level(); + level.flopper_network_optimized = 1; + level.perk_random_vo_func_usemachine = maps\mp\zm_tomb_vo::wunderfizz_used_vo; + maps\mp\zombies\_zm_weap_one_inch_punch::one_inch_precache(); + maps\mp\zombies\_zm_weap_staff_fire::precache(); + maps\mp\zombies\_zm_weap_staff_water::precache(); + maps\mp\zombies\_zm_weap_staff_lightning::precache(); + maps\mp\zombies\_zm_weap_staff_air::precache(); + level._custom_turn_packapunch_on = maps\mp\zm_tomb_capture_zones::pack_a_punch_dummy_init; + level.custom_vending_precaching = maps\mp\zm_tomb::custom_vending_precaching; + level.register_offhand_weapons_for_level_defaults_override = ::offhand_weapon_overrride; + level.zombiemode_offhand_weapon_give_override = ::offhand_weapon_give_override; + level._zombie_custom_add_weapons = ::custom_add_weapons; + level._allow_melee_weapon_switching = 1; + include_equipment( "equip_dieseldrone_zm" ); + include_equipment( "tomb_shield_zm" ); + level.custom_ai_type = []; + level.raygun2_included = 1; + include_weapons(); + include_powerups(); + include_perks_in_random_rotation(); + level maps\mp\zm_tomb_achievement::init(); + precacheitem( "death_throe_zm" ); + + if ( level.splitscreen && getdvarint( "splitscreen_playerCount" ) > 2 ) + level.optimise_for_splitscreen = 1; + else + level.optimise_for_splitscreen = 0; + + if ( isdefined( level.optimise_for_splitscreen ) && level.optimise_for_splitscreen ) + level.culldist = 2500; + else + level.culldist = 5500; + + setculldist( level.culldist ); + level thread maps\mp\zm_tomb_distance_tracking::zombie_tracking_init(); + maps\mp\zombies\_zm_magicbox_tomb::init(); + level.special_weapon_magicbox_check = ::tomb_special_weapon_magicbox_check; + maps\mp\zombies\_zm::init(); + level.callbackactordamage = ::tomb_actor_damage_override_wrapper; + level._weaponobjects_on_player_connect_override = ::tomb_weaponobjects_on_player_connect_override; + maps\mp\zombies\_zm_spawner::register_zombie_death_event_callback( ::tomb_zombie_death_event_callback ); + level.player_intersection_tracker_override = ::tomb_player_intersection_tracker_override; + maps\mp\zm_tomb_challenges::challenges_init(); + maps\mp\zombies\_zm_perk_random::init(); + tomb_register_client_fields(); + register_burn_overlay(); + level thread maps\mp\_sticky_grenade::init(); + maps\mp\zm_tomb_tank::init(); + maps\mp\zombies\_zm_weap_beacon::init(); + maps\mp\zombies\_zm_weap_claymore::init(); + maps\mp\zombies\_zm_weap_riotshield_tomb::init(); + maps\mp\zombies\_zm_weap_staff_air::init(); + maps\mp\zombies\_zm_weap_staff_fire::init(); + maps\mp\zombies\_zm_weap_staff_lightning::init(); + maps\mp\zombies\_zm_weap_staff_water::init(); + maps\mp\zombies\_zm_weap_staff_revive::init(); + maps\mp\zombies\_zm_weap_cymbal_monkey::init(); + //maps\mp\zombies\_zm_weap_slowgun::init(); + level._melee_weapons = []; + maps\mp\zm_tomb_giant_robot::init_giant_robot_glows(); + maps\mp\zm_tomb_giant_robot::init_giant_robot(); + level.can_revive = maps\mp\zm_tomb_giant_robot::tomb_can_revive_override; + maps\mp\zm_tomb_capture_zones::init_capture_zones(); + level.a_e_slow_areas = getentarray( "player_slow_area", "targetname" ); + maps\mp\zm_tomb_ambient_scripts::init_tomb_ambient_scripts(); + level thread maps\mp\zombies\_zm_ai_mechz::init(); + level thread maps\mp\zombies\_zm_perk_random::init_animtree(); + level thread maps\mp\zombies\_zm_ai_quadrotor::init(); + level.zombiemode_divetonuke_perk_func = ::tomb_custom_divetonuke_explode; + set_zombie_var( "zombie_perk_divetonuke_min_damage", 500 ); + set_zombie_var( "zombie_perk_divetonuke_max_damage", 2000 ); + level.custom_laststand_func = ::tomb_custom_electric_cherry_laststand; + maps\mp\zm_tomb_dig::init_shovel(); + level.n_crystals_pickedup = 0; + level thread maps\mp\zm_tomb_main_quest::main_quest_init(); + level thread maps\mp\zm_tomb_teleporter::teleporter_init(); + level thread maps\mp\zombies\_zm_perk_random::start_random_machine(); + level.closest_player_override = ::tomb_closest_player_override; + level.validate_enemy_path_length = ::tomb_validate_enemy_path_length; + level thread maps\mp\zm_tomb_ee_main::init(); + level thread maps\mp\zm_tomb_ee_side::init(); + level.zones = []; + level.zone_manager_init_func = ::working_zone_init; + init_zones[0] = "zone_start"; + level thread maps\mp\zombies\_zm_zonemgr::manage_zones( init_zones ); + + if ( isdefined( level.optimise_for_splitscreen ) && level.optimise_for_splitscreen ) + { + if ( is_classic() ) + level.zombie_ai_limit = 20; + + setdvar( "fx_marks_draw", 0 ); + setdvar( "disable_rope", 1 ); + setdvar( "cg_disableplayernames", 1 ); + setdvar( "disableLookAtEntityLogic", 1 ); + } + else + level.zombie_ai_limit = 24; + + level thread drop_all_barriers(); + level thread traversal_blocker(); + onplayerconnect_callback( ::on_player_connect ); + // maps\mp\zombies\_zm::register_player_damage_callback( ::tomb_player_damage_callback ); + maps\mp\zombies\_zm::register_player_damage_callback( scripts\zm\AATs_Perks::playerdamagelastcheck ); + level.custom_get_round_enemy_array_func = ::zm_tomb_get_round_enemy_array; + flag_wait( "start_zombie_round_logic" ); + wait_network_frame(); + level notify( "specialty_additionalprimaryweapon_power_on" ); + wait_network_frame(); + level notify( "additionalprimaryweapon_on" ); + set_zombie_var( "zombie_use_failsafe", 0 ); + level check_solo_status(); + level thread adjustments_for_solo(); + level thread zone_capture_powerup(); + level thread clean_up_bunker_doors(); + level setclientfield( "lantern_fx", 1 ); + level thread maps\mp\zm_tomb_chamber::tomb_watch_chamber_player_activity(); +/# + maps\mp\zm_tomb_utility::setup_devgui(); +#/ + init_weather_manager(); + level thread maps\mp\zm_tomb_ffotd::main_end(); +} + +tomb_register_client_fields() +{ + registerclientfield( "scriptmover", "stone_frozen", 14000, 1, "int" ); + n_bits = getminbitcountfornum( 5 ); + registerclientfield( "world", "rain_level", 14000, n_bits, "int" ); + registerclientfield( "world", "snow_level", 14000, n_bits, "int" ); + registerclientfield( "toplayer", "player_weather_visionset", 14000, 2, "int" ); + n_bits = getminbitcountfornum( 6 ); + registerclientfield( "toplayer", "player_rumble_and_shake", 14000, n_bits, "int" ); + registerclientfield( "scriptmover", "sky_pillar", 14000, 1, "int" ); + registerclientfield( "scriptmover", "staff_charger", 14000, 3, "int" ); + registerclientfield( "toplayer", "player_staff_charge", 14000, 2, "int" ); + registerclientfield( "toplayer", "player_tablet_state", 14000, 2, "int" ); + registerclientfield( "actor", "zombie_soul", 14000, 1, "int" ); + registerclientfield( "zbarrier", "magicbox_runes", 14000, 1, "int" ); + registerclientfield( "scriptmover", "barbecue_fx", 14000, 1, "int" ); + registerclientfield( "world", "cooldown_steam", 14000, 2, "int" ); + registerclientfield( "world", "mus_zmb_egg_snapshot_loop", 14000, 1, "int" ); + registerclientfield( "world", "sndMaelstromPlr0", 14000, 1, "int" ); + registerclientfield( "world", "sndMaelstromPlr1", 14000, 1, "int" ); + registerclientfield( "world", "sndMaelstromPlr2", 14000, 1, "int" ); + registerclientfield( "world", "sndMaelstromPlr3", 14000, 1, "int" ); + registerclientfield( "world", "sndChamberMusic", 14000, 3, "int" ); + registerclientfield( "actor", "foot_print_box_fx", 14000, 1, "int" ); + registerclientfield( "scriptmover", "foot_print_box_glow", 14000, 1, "int" ); + registerclientfield( "world", "crypt_open_exploder", 14000, 1, "int" ); + registerclientfield( "world", "lantern_fx", 14000, 1, "int" ); + registerclientfield( "allplayers", "oneinchpunch_impact", 14000, 1, "int" ); + registerclientfield( "actor", "oneinchpunch_physics_launchragdoll", 14000, 1, "int" ); +} + +register_burn_overlay() +{ + level.zm_transit_burn_max_duration = 2; + + if ( !isdefined( level.vsmgr_prio_overlay_zm_transit_burn ) ) + level.vsmgr_prio_overlay_zm_transit_burn = 20; + + maps\mp\_visionset_mgr::vsmgr_register_info( "overlay", "zm_transit_burn", 14000, level.vsmgr_prio_overlay_zm_transit_burn, 15, 1, maps\mp\_visionset_mgr::vsmgr_duration_lerp_thread_per_player, 0 ); +} + +tomb_closest_player_override( v_zombie_origin, a_players_to_check ) +{ + e_player_to_attack = undefined; + + while ( !isdefined( e_player_to_attack ) ) + { + e_player_to_attack = tomb_get_closest_player_using_paths( v_zombie_origin, a_players_to_check ); + a_players = maps\mp\zm_tomb_tank::get_players_on_tank( 1 ); + + if ( a_players.size > 0 ) + { + e_player_closest_on_tank = undefined; + n_dist_tank_min = 99999999; + + foreach ( e_player in a_players ) + { + n_dist_sq = distance2dsquared( self.origin, e_player.origin ); + + if ( n_dist_sq < n_dist_tank_min ) + { + n_dist_tank_min = n_dist_sq; + e_player_closest_on_tank = e_player; + } + } + + if ( is_player_valid( e_player_to_attack ) ) + { + n_dist_for_path = distance2dsquared( self.origin, e_player_to_attack.origin ); + + if ( n_dist_tank_min < n_dist_for_path ) + e_player_to_attack = e_player_closest_on_tank; + } + else if ( is_player_valid( e_player_closest_on_tank ) ) + e_player_to_attack = e_player_closest_on_tank; + } + + wait 0.5; + } + + return e_player_to_attack; +} + +zm_tomb_get_round_enemy_array() +{ + enemies = []; + valid_enemies = []; + enemies = getaispeciesarray( level.zombie_team, "all" ); + + for ( i = 0; i < enemies.size; i++ ) + { + if ( isdefined( enemies[i].ignore_enemy_count ) && enemies[i].ignore_enemy_count && ( !isdefined( enemies[i].script_noteworthy ) || enemies[i].script_noteworthy != "capture_zombie" ) ) + continue; + + valid_enemies[valid_enemies.size] = enemies[i]; + } + + return valid_enemies; +} + +tomb_player_damage_callback( e_inflictor, e_attacker, n_damage, n_dflags, str_means_of_death, str_weapon, v_point, v_dir, str_hit_loc, psoffsettime, b_damage_from_underneath, n_model_index, str_part_name ) +{ + if ( isdefined( str_weapon ) ) + { + if ( issubstr( str_weapon, "staff" ) ) + return 0; + else if ( str_weapon == "t72_turret" ) + return 0; + else if ( str_weapon == "quadrotorturret_zm" || str_weapon == "quadrotorturret_upgraded_zm" ) + return 0; + else if ( str_weapon == "zombie_markiv_side_cannon" ) + return 0; + else if ( str_weapon == "zombie_markiv_turret" ) + return 0; + else if ( str_weapon == "zombie_markiv_cannon" ) + return 0; + } + + return n_damage; +} + +tomb_random_perk_weights() +{ + temp_array = []; + + if ( randomint( 4 ) == 0 ) + arrayinsert( temp_array, "specialty_rof", 0 ); + + if ( randomint( 4 ) == 0 ) + arrayinsert( temp_array, "specialty_deadshot", 0 ); + + if ( randomint( 4 ) == 0 ) + arrayinsert( temp_array, "specialty_additionalprimaryweapon", 0 ); + + if ( randomint( 4 ) == 0 ) + arrayinsert( temp_array, "specialty_flakjacket", 0 ); + + if ( randomint( 4 ) == 0 ) + arrayinsert( temp_array, "specialty_grenadepulldeath", 0 ); + + temp_array = array_randomize( temp_array ); + level._random_perk_machine_perk_list = array_randomize( level._random_perk_machine_perk_list ); + level._random_perk_machine_perk_list = arraycombine( level._random_perk_machine_perk_list, temp_array, 1, 0 ); + keys = getarraykeys( level._random_perk_machine_perk_list ); + return keys; +} + +level_precache() +{ + precacheshader( "specialty_zomblood_zombies" ); + precachemodel( "c_zom_guard" ); + precachemodel( "p6_zm_tm_orb_fire" ); + precachemodel( "p6_zm_tm_orb_wind" ); + precachemodel( "p6_zm_tm_orb_lightning" ); + precachemodel( "p6_zm_tm_orb_ice" ); + precachemodel( "fx_tomb_vortex_beam_mesh" ); + precachemodel( "fxuse_sky_pillar_new" ); +} + +on_player_connect() +{ + self thread revive_watcher(); + wait_network_frame(); + self thread player_slow_movement_speed_monitor(); + self thread sndmeleewpnsound(); +} + +sndmeleewpnsound() +{ + self endon( "disconnect" ); + level endon( "end_game" ); + + while ( true ) + { + while ( !self ismeleeing() ) + wait 0.05; + + current_melee_weapon = self get_player_melee_weapon(); + current_weapon = self getcurrentweapon(); + + if ( current_weapon == "tomb_shield_zm" ) + { + self playsound( "fly_riotshield_zm_swing" ); + + while ( self ismeleeing() ) + wait 0.05; + + continue; + } + + alias = "zmb_melee_whoosh_"; + + if ( isdefined( self.is_player_zombie ) && self.is_player_zombie ) + alias = "zmb_melee_whoosh_zmb_"; + else if ( current_melee_weapon == "bowie_knife_zm" ) + alias = "zmb_bowie_swing_"; + else if ( current_melee_weapon == "one_inch_punch_zm" ) + alias = "wpn_one_inch_punch_"; + else if ( current_melee_weapon == "one_inch_punch_upgraded_zm" ) + alias = "wpn_one_inch_punch_"; + else if ( current_melee_weapon == "one_inch_punch_fire_zm" ) + alias = "wpn_one_inch_punch_fire_"; + else if ( current_melee_weapon == "one_inch_punch_air_zm" ) + alias = "wpn_one_inch_punch_air_"; + else if ( current_melee_weapon == "one_inch_punch_ice_zm" ) + alias = "wpn_one_inch_punch_ice_"; + else if ( current_melee_weapon == "one_inch_punch_lightning_zm" ) + alias = "wpn_one_inch_punch_lightning_"; + else if ( sndmeleewpn_isstaff( current_melee_weapon ) ) + alias = "zmb_melee_staff_upgraded_"; + + self playsoundtoplayer( alias + "plr", self ); + wait_network_frame(); + + if ( maps\mp\zombies\_zm_audio::sndisnetworksafe() ) + self playsound( alias + "npc" ); + + while ( self ismeleeing() ) + wait 0.05; + + wait 0.05; + } +} + +sndmeleewpn_isstaff( weapon ) +{ + switch ( weapon ) + { + case "staff_watermelee_zm": + case "staff_melee_zm": + case "staff_lightning_melee_zm": + case "staff_fire_melee_zm": + case "staff_air_melee_zm": + isstaff = 1; + break; + default: + isstaff = 0; + } + + return isstaff; +} + +revive_watcher() +{ + self endon( "death_or_disconnect" ); + + while ( true ) + { + self waittill( "do_revive_ended_normally" ); + + if ( self hasperk( "specialty_quickrevive" ) ) + self notify( "quick_revived_player" ); + else + self notify( "revived_player" ); + } +} + +setup_tomb_spawn_groups() +{ + level.use_multiple_spawns = 1; + level.spawner_int = 1; + + level waittill( "start_zombie_round_logic" ); + + level.zones["ug_bottom_zone"].script_int = 2; + level.zones["zone_nml_19"].script_int = 2; + level.zones["zone_chamber_0"].script_int = 3; + level.zones["zone_chamber_1"].script_int = 3; + level.zones["zone_chamber_2"].script_int = 3; + level.zones["zone_chamber_3"].script_int = 3; + level.zones["zone_chamber_4"].script_int = 3; + level.zones["zone_chamber_5"].script_int = 3; + level.zones["zone_chamber_6"].script_int = 3; + level.zones["zone_chamber_7"].script_int = 3; + level.zones["zone_chamber_8"].script_int = 3; + level.zones["zone_ice_stairs"].script_int = 2; + level.zones["zone_bolt_stairs"].script_int = 2; + level.zones["zone_air_stairs"].script_int = 2; + level.zones["zone_fire_stairs"].script_int = 2; + level.zones["zone_bolt_stairs_1"].script_int = 2; + level.zones["zone_air_stairs_1"].script_int = 2; + level.zones["zone_fire_stairs_1"].script_int = 2; +} + +chamber_capture_zombie_spawn_init() +{ + self endon( "death" ); + + self waittill( "completed_emerging_into_playable_area" ); + + self setclientfield( "zone_capture_zombie", 1 ); +} + +tomb_round_spawn_failsafe() +{ + self endon( "death" ); + prevorigin = self.origin; + + while ( true ) + { + if ( isdefined( self.ignore_round_spawn_failsafe ) && self.ignore_round_spawn_failsafe ) + return; + + wait 15; + + if ( isdefined( self.is_inert ) && self.is_inert ) + continue; + + if ( isdefined( self.lastchunk_destroy_time ) ) + { + if ( gettime() - self.lastchunk_destroy_time < 8000 ) + continue; + } + + if ( self.origin[2] < -3000 ) + { + if ( isdefined( level.put_timed_out_zombies_back_in_queue ) && level.put_timed_out_zombies_back_in_queue && !flag( "dog_round" ) && !( isdefined( self.isscreecher ) && self.isscreecher ) ) + { + level.zombie_total++; + level.zombie_total_subtract++; + } + + self dodamage( self.health + 100, ( 0, 0, 0 ) ); + break; + } + + if ( distancesquared( self.origin, prevorigin ) < 576 ) + { + if ( isdefined( level.put_timed_out_zombies_back_in_queue ) && level.put_timed_out_zombies_back_in_queue && !flag( "dog_round" ) ) + { + if ( !self.ignoreall && !( isdefined( self.nuked ) && self.nuked ) && !( isdefined( self.marked_for_death ) && self.marked_for_death ) && !( isdefined( self.isscreecher ) && self.isscreecher ) && ( isdefined( self.has_legs ) && self.has_legs ) && !( isdefined( self.is_brutus ) && self.is_brutus ) ) + { + level.zombie_total++; + level.zombie_total_subtract++; + } + } + + level.zombies_timeout_playspace++; + self dodamage( self.health + 100, ( 0, 0, 0 ) ); + break; + } + + prevorigin = self.origin; + } +} + +givecustomloadout( takeallweapons, alreadyspawned ) +{ + self giveweapon( "knife_zm" ); + self give_start_weapon( 1 ); +} + +precache_team_characters() +{ + precachemodel( "c_zom_player_cdc_fb" ); + precachemodel( "c_zom_hazmat_viewhands" ); + precachemodel( "c_zom_player_cia_fb" ); + precachemodel( "c_zom_suit_viewhands" ); +} + +precache_personality_characters() +{ + character\c_usa_dempsey_dlc4::precache(); + character\c_rus_nikolai_dlc4::precache(); + character\c_ger_richtofen_dlc4::precache(); + character\c_jap_takeo_dlc4::precache(); + precachemodel( "c_zom_richtofen_viewhands" ); + precachemodel( "c_zom_nikolai_viewhands" ); + precachemodel( "c_zom_takeo_viewhands" ); + precachemodel( "c_zom_dempsey_viewhands" ); +} + +give_personality_characters() +{ + if ( isdefined( level.hotjoin_player_setup ) && [[ level.hotjoin_player_setup ]]( "c_zom_arlington_coat_viewhands" ) ) + return; + + self detachall(); + + if ( !isdefined( self.characterindex ) ) + self.characterindex = assign_lowest_unused_character_index(); + + self.favorite_wall_weapons_list = []; + self.talks_in_danger = 0; +/# + if ( getdvar( _hash_40772CF1 ) != "" ) + self.characterindex = getdvarint( _hash_40772CF1 ); +#/ + switch ( self.characterindex ) + { + case 0: + self character\c_usa_dempsey_dlc4::main(); + self setviewmodel( "c_zom_dempsey_viewhands" ); + level.vox maps\mp\zombies\_zm_audio::zmbvoxinitspeaker( "player", "vox_plr_", self ); + self set_player_is_female( 0 ); + self.character_name = "Dempsey"; + break; + case 1: + self character\c_rus_nikolai_dlc4::main(); + self setviewmodel( "c_zom_nikolai_viewhands" ); + level.vox maps\mp\zombies\_zm_audio::zmbvoxinitspeaker( "player", "vox_plr_", self ); + self set_player_is_female( 0 ); + self.character_name = "Nikolai"; + break; + case 2: + self character\c_ger_richtofen_dlc4::main(); + self setviewmodel( "c_zom_richtofen_viewhands" ); + level.vox maps\mp\zombies\_zm_audio::zmbvoxinitspeaker( "player", "vox_plr_", self ); + self set_player_is_female( 0 ); + self.character_name = "Richtofen"; + break; + case 3: + self character\c_jap_takeo_dlc4::main(); + self setviewmodel( "c_zom_takeo_viewhands" ); + level.vox maps\mp\zombies\_zm_audio::zmbvoxinitspeaker( "player", "vox_plr_", self ); + self set_player_is_female( 0 ); + self.character_name = "Takeo"; + break; + } + + self setmovespeedscale( 1 ); + self setsprintduration( 4 ); + self setsprintcooldown( 0 ); + self thread set_exert_id(); +} + +set_exert_id() +{ + self endon( "disconnect" ); + wait_network_frame(); + wait_network_frame(); + self maps\mp\zombies\_zm_audio::setexertvoice( self.characterindex + 1 ); +} + +assign_lowest_unused_character_index() +{ + charindexarray = []; + charindexarray[0] = 0; + charindexarray[1] = 1; + charindexarray[2] = 2; + charindexarray[3] = 3; + players = get_players(); + + if ( players.size == 1 ) + { + charindexarray = array_randomize( charindexarray ); + + if ( charindexarray[0] == 2 ) + level.has_richtofen = 1; + + return charindexarray[0]; + } + else + { + n_characters_defined = 0; + + foreach ( player in players ) + { + if ( isdefined( player.characterindex ) ) + { + arrayremovevalue( charindexarray, player.characterindex, 0 ); + n_characters_defined++; + } + } + + if ( charindexarray.size > 0 ) + { + if ( n_characters_defined == players.size - 1 ) + { + if ( !( isdefined( level.has_richtofen ) && level.has_richtofen ) ) + { + level.has_richtofen = 1; + return 2; + } + } + + charindexarray = array_randomize( charindexarray ); + + if ( charindexarray[0] == 2 ) + level.has_richtofen = 1; + + return charindexarray[0]; + } + } + + return 0; +} + +give_team_characters() +{ + self detachall(); + self set_player_is_female( 0 ); + + if ( !isdefined( self.characterindex ) ) + { + self.characterindex = 1; + + if ( self.team == "axis" ) + self.characterindex = 0; + } + + switch ( self.characterindex ) + { + case 2: + case 0: + self setmodel( "c_zom_player_cia_fb" ); + self.voice = "american"; + self.skeleton = "base"; + self setviewmodel( "c_zom_suit_viewhands" ); + self.characterindex = 0; + break; + case 3: + case 1: + self setmodel( "c_zom_player_cdc_fb" ); + self.voice = "american"; + self.skeleton = "base"; + self setviewmodel( "c_zom_hazmat_viewhands" ); + self.characterindex = 1; + break; + } + + self setmovespeedscale( 1 ); + self setsprintduration( 4 ); + self setsprintcooldown( 0 ); +} + +initcharacterstartindex() +{ + level.characterstartindex = randomint( 4 ); +} + +zm_player_fake_death_cleanup() +{ + if ( isdefined( self._fall_down_anchor ) ) + { + self._fall_down_anchor delete(); + self._fall_down_anchor = undefined; + } +} + +zm_player_fake_death( vdir ) +{ + level notify( "fake_death" ); + self notify( "fake_death" ); + stance = self getstance(); + self.ignoreme = 1; + self enableinvulnerability(); + self takeallweapons(); + + if ( isdefined( self.insta_killed ) && self.insta_killed ) + { + self maps\mp\zombies\_zm::player_fake_death(); + self allowprone( 1 ); + self allowcrouch( 0 ); + self allowstand( 0 ); + wait 0.25; + self freezecontrols( 1 ); + } + else + { + self freezecontrols( 1 ); + self thread fall_down( vdir, stance ); + wait 1; + } +} + +fall_down( vdir, stance ) +{ + self endon( "disconnect" ); + level endon( "game_module_ended" ); + self ghost(); + origin = self.origin; + xyspeed = ( 0, 0, 0 ); + angles = self getplayerangles(); + angles = ( angles[0], angles[1], angles[2] + randomfloatrange( -5, 5 ) ); + + if ( isdefined( vdir ) && length( vdir ) > 0 ) + { + xyspeedmag = 40 + randomint( 12 ) + randomint( 12 ); + xyspeed = xyspeedmag * vectornormalize( ( vdir[0], vdir[1], 0 ) ); + } + + linker = spawn( "script_origin", ( 0, 0, 0 ) ); + linker.origin = origin; + linker.angles = angles; + self._fall_down_anchor = linker; + self playerlinkto( linker ); + self playsoundtoplayer( "zmb_player_death_fall", self ); + falling = stance != "prone"; + + if ( falling ) + { + origin = playerphysicstrace( origin, origin + xyspeed ); + eye = self get_eye(); + floor_height = 10 + origin[2] - eye[2]; + origin += ( 0, 0, floor_height ); + lerptime = 0.5; + linker moveto( origin, lerptime, lerptime ); + linker rotateto( angles, lerptime, lerptime ); + } + + self freezecontrols( 1 ); + + if ( falling ) + linker waittill( "movedone" ); + + self giveweapon( "death_throe_zm" ); + self switchtoweapon( "death_throe_zm" ); + + if ( falling ) + { + bounce = randomint( 4 ) + 8; + origin = origin + ( 0, 0, bounce ) - xyspeed * 0.1; + lerptime = bounce / 50.0; + linker moveto( origin, lerptime, 0, lerptime ); + + linker waittill( "movedone" ); + + origin = origin + ( 0, 0, bounce * -1 ) + xyspeed * 0.1; + lerptime /= 2.0; + linker moveto( origin, lerptime, lerptime ); + + linker waittill( "movedone" ); + + linker moveto( origin, 5, 0 ); + } + + wait 15; + linker delete(); +} + +initial_round_wait_func() +{ + flag_wait( "initial_blackscreen_passed" ); +} + +offhand_weapon_overrride() +{ + register_lethal_grenade_for_level( "frag_grenade_zm" ); + level.zombie_lethal_grenade_player_init = "frag_grenade_zm"; + register_lethal_grenade_for_level( "sticky_grenade_zm" ); + register_tactical_grenade_for_level( "cymbal_monkey_zm" ); + register_tactical_grenade_for_level( "emp_grenade_zm" ); + register_tactical_grenade_for_level( "beacon_zm" ); + register_placeable_mine_for_level( "claymore_zm" ); + register_melee_weapon_for_level( "knife_zm" ); + register_melee_weapon_for_level( "staff_air_melee_zm" ); + register_melee_weapon_for_level( "staff_fire_melee_zm" ); + register_melee_weapon_for_level( "staff_lightning_melee_zm" ); + register_melee_weapon_for_level( "staff_water_melee_zm" ); + level.zombie_melee_weapon_player_init = "knife_zm"; + register_equipment_for_level( "tomb_shield_zm" ); + level.zombie_equipment_player_init = undefined; + level.equipment_safe_to_drop = ::equipment_safe_to_drop; +} + +equipment_safe_to_drop( weapon ) +{ + if ( !isdefined( self.origin ) ) + return true; + + return true; +} + +offhand_weapon_give_override( str_weapon ) +{ + self endon( "death" ); + + if ( is_tactical_grenade( str_weapon ) && isdefined( self get_player_tactical_grenade() ) && !self is_player_tactical_grenade( str_weapon ) ) + { + self setweaponammoclip( self get_player_tactical_grenade(), 0 ); + self takeweapon( self get_player_tactical_grenade() ); + } + + return 0; +} + +tomb_weaponobjects_on_player_connect_override() +{ + level.retrievable_knife_init_names = []; + onplayerconnect_callback( ::weaponobjects_on_player_connect_override_internal ); +} + +tomb_player_intersection_tracker_override( e_player ) +{ + if ( isdefined( e_player.b_already_on_tank ) && e_player.b_already_on_tank || isdefined( self.b_already_on_tank ) && self.b_already_on_tank ) + return true; + + if ( isdefined( e_player.giant_robot_transition ) && e_player.giant_robot_transition || isdefined( self.giant_robot_transition ) && self.giant_robot_transition ) + return true; + + return false; +} + +init_tomb_stats() +{ + self maps\mp\zm_tomb_achievement::init_player_achievement_stats(); +} + +custom_add_weapons() +{ + level.laststandpistol = "c96_zm"; + level.default_laststandpistol = "c96_zm"; + level.default_solo_laststandpistol = "c96_upgraded_zm"; + level.start_weapon = "c96_zm"; + /* add_zombie_weapon( "slowgun_zm", "slowgun_upgraded_zm", &"ZOMBIE_WEAPON_SLOWGUN", 10, "wpck_paralyzer", "", undefined, 1 ); + add_zombie_weapon( "blundergat_zm", "blundergat_upgraded_zm", &"ZOMBIE_WEAPON_BLUNDERGAT", 500, "wpck_shot", "", undefined, 1 ); + add_zombie_weapon( "an94_zm", "an94_upgraded_zm", &"ZOMBIE_WEAPON_AN94", 1200, "", "", undefined );*/ + add_zombie_weapon( "mg08_zm", "mg08_upgraded_zm", &"ZOMBIE_WEAPON_MG08", 50, "wpck_mg", "", undefined, 1 ); + add_zombie_weapon( "hamr_zm", "hamr_upgraded_zm", &"ZOMBIE_WEAPON_HAMR", 50, "wpck_mg", "", undefined, 1 ); + add_zombie_weapon( "type95_zm", "type95_upgraded_zm", &"ZOMBIE_WEAPON_TYPE95", 50, "wpck_rifle", "", undefined, 1 ); + add_zombie_weapon( "galil_zm", "galil_upgraded_zm", &"ZOMBIE_WEAPON_GALIL", 50, "wpck_rifle", "", undefined, 1 ); + add_zombie_weapon( "fnfal_zm", "fnfal_upgraded_zm", &"ZOMBIE_WEAPON_FNFAL", 50, "wpck_rifle", "", undefined, 1 ); + add_zombie_weapon( "m14_zm", "m14_upgraded_zm", &"ZOMBIE_WEAPON_M14", 500, "wpck_rifle", "", undefined, 1 ); + add_zombie_weapon( "mp44_zm", "mp44_upgraded_zm", &"ZMWEAPON_MP44_WALLBUY", 1400, "wpck_rifle", "", undefined, 1 ); + add_zombie_weapon( "scar_zm", "scar_upgraded_zm", &"ZOMBIE_WEAPON_SCAR", 50, "wpck_rifle", "", undefined, 1 ); + add_zombie_weapon( "870mcs_zm", "870mcs_upgraded_zm", &"ZOMBIE_WEAPON_870MCS", 900, "wpck_shotgun", "", undefined, 1 ); + add_zombie_weapon( "srm1216_zm", "srm1216_upgraded_zm", &"ZOMBIE_WEAPON_SRM1216", 50, "wpck_shotgun", "", undefined, 1 ); + add_zombie_weapon( "ksg_zm", "ksg_upgraded_zm", &"ZOMBIE_WEAPON_KSG", 1100, "wpck_shotgun", "", undefined, 1 ); + add_zombie_weapon( "ak74u_zm", "ak74u_upgraded_zm", &"ZOMBIE_WEAPON_AK74U", 1200, "wpck_smg", "", undefined, 1 ); + add_zombie_weapon( "ak74u_extclip_zm", "ak74u_extclip_upgraded_zm", &"ZOMBIE_WEAPON_AK74U", 1200, "wpck_smg", "", undefined, 1 ); + add_zombie_weapon( "pdw57_zm", "pdw57_upgraded_zm", &"ZOMBIE_WEAPON_PDW57", 1000, "wpck_smg", "", undefined, 1 ); + add_zombie_weapon( "thompson_zm", "thompson_upgraded_zm", &"ZMWEAPON_THOMPSON_WALLBUY", 1500, "wpck_smg", "", 800, 1 ); + add_zombie_weapon( "qcw05_zm", "qcw05_upgraded_zm", &"ZOMBIE_WEAPON_QCW05", 50, "wpck_smg", "", undefined, 1 ); + add_zombie_weapon( "mp40_zm", "mp40_upgraded_zm", &"ZOMBIE_WEAPON_MP40", 1300, "wpck_smg", "", undefined, 1 ); + add_zombie_weapon( "mp40_stalker_zm", "mp40_stalker_upgraded_zm", &"ZOMBIE_WEAPON_MP40", 1300, "wpck_smg", "", undefined, 1 ); + add_zombie_weapon( "evoskorpion_zm", "evoskorpion_upgraded_zm", &"ZOMBIE_WEAPON_EVOSKORPION", 50, "wpck_smg", "", undefined, 1 ); + add_zombie_weapon( "ballista_zm", "ballista_upgraded_zm", &"ZMWEAPON_BALLISTA_WALLBUY", 500, "wpck_snipe", "", undefined, 1 ); + add_zombie_weapon( "dsr50_zm", "dsr50_upgraded_zm", &"ZOMBIE_WEAPON_DR50", 50, "wpck_snipe", "", undefined, 1 ); + add_zombie_weapon( "beretta93r_zm", "beretta93r_upgraded_zm", &"ZOMBIE_WEAPON_BERETTA93r", 1000, "wpck_pistol", "", undefined, 1 ); + add_zombie_weapon( "beretta93r_extclip_zm", "beretta93r_extclip_upgraded_zm", &"ZOMBIE_WEAPON_BERETTA93r", 1000, "wpck_pistol", "", undefined, 1 ); + add_zombie_weapon( "kard_zm", "kard_upgraded_zm", &"ZOMBIE_WEAPON_KARD", 50, "wpck_pistol", "", undefined, 1 ); + add_zombie_weapon( "fiveseven_zm", "fiveseven_upgraded_zm", &"ZOMBIE_WEAPON_FIVESEVEN", 1100, "wpck_pistol", "", undefined, 1 ); + add_zombie_weapon( "python_zm", "python_upgraded_zm", &"ZOMBIE_WEAPON_PYTHON", 50, "wpck_pistol", "", undefined, 1 ); + add_zombie_weapon( "c96_zm", "c96_upgraded_zm", &"ZOMBIE_WEAPON_C96", 50, "wpck_pistol", "", undefined, 1 ); + add_zombie_weapon( "fivesevendw_zm", "fivesevendw_upgraded_zm", &"ZOMBIE_WEAPON_FIVESEVENDW", 50, "wpck_duel", "", undefined, 1 ); + add_zombie_weapon( "m32_zm", "m32_upgraded_zm", &"ZOMBIE_WEAPON_M32", 50, "wpck_crappy", "", undefined, 1 ); + add_zombie_weapon( "beacon_zm", undefined, &"ZOMBIE_WEAPON_BEACON", 2000, "wpck_explo", "", undefined, 1 ); + add_zombie_weapon( "claymore_zm", undefined, &"ZOMBIE_WEAPON_CLAYMORE", 1000, "wpck_explo", "", undefined, 1 ); + add_zombie_weapon( "cymbal_monkey_zm", undefined, &"ZOMBIE_WEAPON_SATCHEL_2000", 2000, "wpck_monkey", "", undefined, 1 ); + add_zombie_weapon( "frag_grenade_zm", undefined, &"ZOMBIE_WEAPON_FRAG_GRENADE", 250, "wpck_explo", "", 250 ); + add_zombie_weapon( "ray_gun_zm", "ray_gun_upgraded_zm", &"ZOMBIE_WEAPON_RAYGUN", 10000, "wpck_ray", "", undefined, 1 ); + + if ( isdefined( level.raygun2_included ) && level.raygun2_included ) + add_zombie_weapon( "raygun_mark2_zm", "raygun_mark2_upgraded_zm", &"ZOMBIE_WEAPON_RAYGUN_MARK2", 10000, "wpck_raymk2", "", undefined ); + + add_zombie_weapon( "sticky_grenade_zm", undefined, &"ZOMBIE_WEAPON_STICKY_GRENADE", 250, "wpck_explo", "", 250 ); + add_zombie_weapon( "staff_air_zm", undefined, &"AIR_STAFF", 50, "wpck_rpg", "", undefined, 1 ); + add_zombie_weapon( "staff_air_upgraded_zm", undefined, &"AIR_STAFF_CHARGED", 50, "wpck_rpg", "", undefined, 1 ); + add_zombie_weapon( "staff_fire_zm", undefined, &"FIRE_STAFF", 50, "wpck_rpg", "", undefined, 1 ); + add_zombie_weapon( "staff_fire_upgraded_zm", undefined, &"FIRE_STAFF_CHARGED", 50, "wpck_rpg", "", undefined, 1 ); + add_zombie_weapon( "staff_lightning_zm", undefined, &"LIGHTNING_STAFF", 50, "wpck_rpg", "", undefined, 1 ); + add_zombie_weapon( "staff_lightning_upgraded_zm", undefined, &"LIGHTNING_STAFF_CHARGED", 50, "wpck_rpg", "", undefined, 1 ); + add_zombie_weapon( "staff_water_zm", undefined, &"WATER_STAFF", 50, "wpck_rpg", "", undefined, 1 ); + add_zombie_weapon( "staff_water_zm_cheap", undefined, &"WATER_STAFF", 50, "wpck_rpg", "", undefined, 1 ); + add_zombie_weapon( "staff_water_upgraded_zm", undefined, &"WATER_STAFF_CHARGED", 50, "wpck_rpg", "", undefined, 1 ); + add_zombie_weapon( "staff_revive_zm", undefined, &"ZM_TOMB_WEAP_STAFF_REVIVE", 50, "wpck_rpg", "", undefined, 1 ); + change_weapon_cost( "mp40_zm", 1300 ); + level.weapons_using_ammo_sharing = 1; + add_shared_ammo_weapon( "ak74u_extclip_zm", "ak74u_zm" ); + add_shared_ammo_weapon( "mp40_stalker_zm", "mp40_zm" ); + add_shared_ammo_weapon( "beretta93r_extclip_zm", "beretta93r_zm" ); +} + +include_weapons() +{ + + /* include_weapon( "slowgun_zm", 1 ); + include_weapon( "slowgun_upgraded_zm", 0 ); + add_limited_weapon( "slowgun_zm", 1 ); + add_limited_weapon( "slowgun_upgraded_zm", 1 ); + include_weapon( "blundergat_zm" ); + include_weapon( "an94_zm", 0 ); + include_weapon( "an94_upgraded_zm", 0 );*/ + + include_weapon( "hamr_zm" ); + include_weapon( "hamr_upgraded_zm", 0 ); + include_weapon( "mg08_zm" ); + include_weapon( "mg08_upgraded_zm", 0 ); + include_weapon( "type95_zm" ); + include_weapon( "type95_upgraded_zm", 0 ); + include_weapon( "galil_zm" ); + include_weapon( "galil_upgraded_zm", 0 ); + include_weapon( "fnfal_zm" ); + include_weapon( "fnfal_upgraded_zm", 0 ); + include_weapon( "m14_zm", 0 ); + include_weapon( "m14_upgraded_zm", 0 ); + include_weapon( "mp44_zm", 0 ); + include_weapon( "mp44_upgraded_zm", 0 ); + include_weapon( "scar_zm" ); + include_weapon( "scar_upgraded_zm", 0 ); + include_weapon( "870mcs_zm", 0 ); + include_weapon( "870mcs_upgraded_zm", 0 ); + include_weapon( "ksg_zm" ); + include_weapon( "ksg_upgraded_zm", 0 ); + include_weapon( "srm1216_zm" ); + include_weapon( "srm1216_upgraded_zm", 0 ); + include_weapon( "ak74u_zm", 0 ); + include_weapon( "ak74u_upgraded_zm", 0 ); + include_weapon( "ak74u_extclip_zm" ); + include_weapon( "ak74u_extclip_upgraded_zm", 0 ); + include_weapon( "pdw57_zm" ); + include_weapon( "pdw57_upgraded_zm", 0 ); + include_weapon( "thompson_zm" ); + include_weapon( "thompson_upgraded_zm", 0 ); + include_weapon( "qcw05_zm" ); + include_weapon( "qcw05_upgraded_zm", 0 ); + include_weapon( "mp40_zm", 0 ); + include_weapon( "mp40_upgraded_zm", 0 ); + include_weapon( "mp40_stalker_zm" ); + include_weapon( "mp40_stalker_upgraded_zm", 0 ); + include_weapon( "evoskorpion_zm" ); + include_weapon( "evoskorpion_upgraded_zm", 0 ); + include_weapon( "ballista_zm", 0 ); + include_weapon( "ballista_upgraded_zm", 0 ); + include_weapon( "dsr50_zm" ); + include_weapon( "dsr50_upgraded_zm", 0 ); + include_weapon( "beretta93r_zm", 0 ); + include_weapon( "beretta93r_upgraded_zm", 0 ); + include_weapon( "beretta93r_extclip_zm" ); + include_weapon( "beretta93r_extclip_upgraded_zm", 0 ); + include_weapon( "kard_zm" ); + include_weapon( "kard_upgraded_zm", 0 ); + include_weapon( "fiveseven_zm", 0 ); + include_weapon( "fiveseven_upgraded_zm", 0 ); + include_weapon( "python_zm" ); + include_weapon( "python_upgraded_zm", 0 ); + include_weapon( "c96_zm", 0 ); + include_weapon( "c96_upgraded_zm", 0 ); + include_weapon( "fivesevendw_zm" ); + include_weapon( "fivesevendw_upgraded_zm", 0 ); + include_weapon( "m32_zm" ); + include_weapon( "m32_upgraded_zm", 0 ); + include_weapon( "beacon_zm", 0 ); + include_weapon( "claymore_zm", 0 ); + include_weapon( "cymbal_monkey_zm" ); + include_weapon( "frag_grenade_zm", 0 ); + include_weapon( "knife_zm", 0 ); + include_weapon( "ray_gun_zm" ); + include_weapon( "ray_gun_upgraded_zm", 0 ); + include_weapon( "sticky_grenade_zm", 0 ); + include_weapon( "tomb_shield_zm", 0 ); + add_limited_weapon( "c96_zm", 0 ); + add_limited_weapon( "ray_gun_zm", 4 ); + add_limited_weapon( "ray_gun_upgraded_zm", 4 ); + include_weapon( "staff_air_zm", 0 ); + include_weapon( "staff_air_upgraded_zm", 0 ); + precacheitem( "staff_air_upgraded2_zm" ); + precacheitem( "staff_air_upgraded3_zm" ); + include_weapon( "staff_fire_zm", 0 ); + include_weapon( "staff_fire_upgraded_zm", 0 ); + precacheitem( "staff_fire_upgraded2_zm" ); + precacheitem( "staff_fire_upgraded3_zm" ); + include_weapon( "staff_lightning_zm", 0 ); + include_weapon( "staff_lightning_upgraded_zm", 0 ); + precacheitem( "staff_lightning_upgraded2_zm" ); + precacheitem( "staff_lightning_upgraded3_zm" ); + include_weapon( "staff_water_zm", 0 ); + include_weapon( "staff_water_zm_cheap", 0 ); + include_weapon( "staff_water_upgraded_zm", 0 ); + precacheitem( "staff_water_upgraded2_zm" ); + precacheitem( "staff_water_upgraded3_zm" ); + include_weapon( "staff_revive_zm", 0 ); + add_limited_weapon( "staff_air_zm", 0 ); + add_limited_weapon( "staff_air_upgraded_zm", 0 ); + add_limited_weapon( "staff_fire_zm", 0 ); + add_limited_weapon( "staff_fire_upgraded_zm", 0 ); + add_limited_weapon( "staff_lightning_zm", 0 ); + add_limited_weapon( "staff_lightning_upgraded_zm", 0 ); + add_limited_weapon( "staff_water_zm", 0 ); + add_limited_weapon( "staff_water_zm_cheap", 0 ); + add_limited_weapon( "staff_water_upgraded_zm", 0 ); + + if ( isdefined( level.raygun2_included ) && level.raygun2_included ) + { + include_weapon( "raygun_mark2_zm", 1 ); + include_weapon( "raygun_mark2_upgraded_zm", 0 ); + add_weapon_to_content( "raygun_mark2_zm", "dlc3" ); + add_limited_weapon( "raygun_mark2_zm", 1 ); + add_limited_weapon( "raygun_mark2_upgraded_zm", 1 ); + } +} + +include_powerups() +{ + include_powerup( "nuke" ); + include_powerup( "insta_kill" ); + include_powerup( "double_points" ); + include_powerup( "full_ammo" ); + include_powerup( "fire_sale" ); + include_powerup( "free_perk" ); + include_powerup( "zombie_blood" ); + include_powerup( "bonus_points_player" ); + include_powerup( "bonus_points_team" ); + level.level_specific_init_powerups = ::tomb_powerup_init; + level._zombiemode_powerup_grab = ::tomb_powerup_grab; +/# + setup_powerup_devgui(); +#/ +/# + setup_oneinchpunch_devgui(); +#/ +/# + setup_tablet_devgui(); +#/ +} + +include_perks_in_random_rotation() +{ + include_perk_in_random_rotation( "specialty_armorvest" ); + include_perk_in_random_rotation( "specialty_quickrevive" ); + include_perk_in_random_rotation( "specialty_fastreload" ); + include_perk_in_random_rotation( "specialty_rof" ); + include_perk_in_random_rotation( "specialty_longersprint" ); + include_perk_in_random_rotation( "specialty_deadshot" ); + include_perk_in_random_rotation( "specialty_additionalprimaryweapon" ); + include_perk_in_random_rotation( "specialty_flakjacket" ); + include_perk_in_random_rotation( "specialty_grenadepulldeath" ); + level.custom_random_perk_weights = ::tomb_random_perk_weights; +} + +tomb_powerup_init() +{ + maps\mp\zombies\_zm_powerup_zombie_blood::init( "c_zom_tomb_german_player_fb" ); +} + +tomb_powerup_grab( s_powerup, e_player ) +{ + if ( s_powerup.powerup_name == "zombie_blood" ) + level thread maps\mp\zombies\_zm_powerup_zombie_blood::zombie_blood_powerup( s_powerup, e_player ); +} + +setup_powerup_devgui() +{ +/# + setdvar( "zombie_blood", "off" ); + adddebugcommand( "devgui_cmd \"Zombies:2/Power Ups:2/Now:1/Drop Zombie Blood:1\" \"zombie_blood on\"\n" ); + level thread watch_devgui_zombie_blood(); +#/ +} + +setup_oneinchpunch_devgui() +{ +/# + setdvar( "test_oneinchpunch", "off" ); + adddebugcommand( "devgui_cmd \"Zombies:2/Tomb:1/OneInchPunch:2/OneInchPunch:1\" \"test_oneinchpunch on\"\n" ); + setdvar( "test_oneinchpunch_upgraded", "off" ); + adddebugcommand( "devgui_cmd \"Zombies:2/Tomb:1/OneInchPunch:2/OneInchPunch_Upgraded:1\" \"test_oneinchpunch_upgraded on\"\n" ); + setdvar( "test_oneinchpunch_air", "off" ); + adddebugcommand( "devgui_cmd \"Zombies:2/Tomb:1/OneInchPunch:2/OneInchPunch_Air:1\" \"test_oneinchpunch_air on\"\n" ); + setdvar( "test_oneinchpunch_fire", "off" ); + adddebugcommand( "devgui_cmd \"Zombies:2/Tomb:1/OneInchPunch:2/OneInchPunch_Fire:1\" \"test_oneinchpunch_fire on\"\n" ); + setdvar( "test_oneinchpunch_ice", "off" ); + adddebugcommand( "devgui_cmd \"Zombies:2/Tomb:1/OneInchPunch:2/OneInchPunch_Ice:1\" \"test_oneinchpunch_ice on\"\n" ); + setdvar( "test_oneinchpunch_lightning", "off" ); + adddebugcommand( "devgui_cmd \"Zombies:2/Tomb:1/OneInchPunch:2/OneInchPunch_Lightning:1\" \"test_oneinchpunch_lightning on\"\n" ); + level thread watch_devgui_oneinchpunch(); +#/ +} + +watch_devgui_oneinchpunch() +{ +/# + while ( true ) + { + if ( getdvar( _hash_A3C7E066 ) == "on" ) + { + setdvar( "test_oneinchpunch", "off" ); + player = get_players()[0]; + player thread maps\mp\zombies\_zm_weap_one_inch_punch::one_inch_punch_melee_attack(); + } + else if ( getdvar( _hash_8921AB91 ) == "on" ) + { + setdvar( "test_oneinchpunch_upgraded", "off" ); + player = get_players()[0]; + player.b_punch_upgraded = 1; + player.str_punch_element = "upgraded"; + player thread maps\mp\zombies\_zm_weap_one_inch_punch::one_inch_punch_melee_attack(); + } + else if ( getdvar( _hash_C236601 ) == "on" ) + { + setdvar( "test_oneinchpunch_air", "off" ); + player = get_players()[0]; + player.b_punch_upgraded = 1; + player.str_punch_element = "air"; + player thread maps\mp\zombies\_zm_weap_one_inch_punch::one_inch_punch_melee_attack(); + } + else if ( getdvar( _hash_9092E46B ) == "on" ) + { + setdvar( "test_oneinchpunch_fire", "off" ); + player = get_players()[0]; + player.b_punch_upgraded = 1; + player.str_punch_element = "fire"; + player thread maps\mp\zombies\_zm_weap_one_inch_punch::one_inch_punch_melee_attack(); + } + else if ( getdvar( _hash_C238736 ) == "on" ) + { + setdvar( "test_oneinchpunch_ice", "off" ); + player = get_players()[0]; + player.b_punch_upgraded = 1; + player.str_punch_element = "ice"; + player thread maps\mp\zombies\_zm_weap_one_inch_punch::one_inch_punch_melee_attack(); + } + else if ( getdvar( _hash_9341C49 ) == "on" ) + { + setdvar( "test_oneinchpunch_lightning", "off" ); + player = get_players()[0]; + player.b_punch_upgraded = 1; + player.str_punch_element = "lightning"; + player thread maps\mp\zombies\_zm_weap_one_inch_punch::one_inch_punch_melee_attack(); + } + + wait 0.1; + } +#/ +} + +setup_tablet_devgui() +{ +/# + setdvar( "test_player_tablet", "3" ); + adddebugcommand( "devgui_cmd \"Zombies:2/Tomb:1/Easter Ann:3/Tablet-None:1\" \"test_player_tablet 0\"\n" ); + adddebugcommand( "devgui_cmd \"Zombies:2/Tomb:1/Easter Ann:3/Tablet-Clean:1\" \"test_player_tablet 1\"\n" ); + adddebugcommand( "devgui_cmd \"Zombies:2/Tomb:1/Easter Ann:3/Tablet-Dirty:1\" \"test_player_tablet 2\"\n" ); + level thread watch_devgui_tablet(); +#/ +} + +watch_devgui_tablet() +{ +/# + while ( true ) + { + if ( getdvar( _hash_4806208C ) != "3" ) + { + player = get_players()[0]; + n_tablet_state = int( getdvar( _hash_4806208C ) ); + player setclientfieldtoplayer( "player_tablet_state", n_tablet_state ); + setdvar( "test_player_tablet", "3" ); + } + + wait 0.1; + } +#/ +} + +watch_devgui_zombie_blood() +{ +/# + while ( true ) + { + if ( getdvar( _hash_FA71C6BA ) == "on" ) + { + setdvar( "zombie_blood", "off" ); + level thread maps\mp\zombies\_zm_devgui::zombie_devgui_give_powerup( "zombie_blood", 1 ); + } + + wait 0.1; + } +#/ +} + +watch_devgui_double_points() +{ +/# + while ( true ) + { + if ( getdvar( _hash_1FB6003C ) == "on" ) + { + setdvar( "double_points", "off" ); + level thread maps\mp\zombies\_zm_devgui::zombie_devgui_give_powerup( "double_points", 1 ); + iprintlnbold( "change" ); + } + + wait 0.1; + } +#/ +} + +setup_rex_starts() +{ + add_gametype( "zclassic", ::dummy, "zclassic", ::dummy ); + add_gameloc( "tomb", ::dummy, "tomb", ::dummy ); +} + +dummy() +{ + +} + +working_zone_init() +{ + flag_init( "always_on" ); + flag_set( "always_on" ); + add_adjacent_zone( "zone_robot_head", "zone_robot_head", "always_on" ); + add_adjacent_zone( "zone_start", "zone_start_a", "always_on" ); + add_adjacent_zone( "zone_start", "zone_start_b", "always_on" ); + add_adjacent_zone( "zone_start_a", "zone_start_b", "always_on" ); + add_adjacent_zone( "zone_start_a", "zone_bunker_1a", "activate_zone_bunker_1" ); + add_adjacent_zone( "zone_bunker_1a", "zone_bunker_1", "activate_zone_bunker_1" ); + add_adjacent_zone( "zone_bunker_1a", "zone_bunker_1", "activate_zone_bunker_3a" ); + add_adjacent_zone( "zone_bunker_1", "zone_bunker_3a", "activate_zone_bunker_3a" ); + add_adjacent_zone( "zone_bunker_3a", "zone_bunker_3b", "activate_zone_bunker_3a" ); + add_adjacent_zone( "zone_bunker_3a", "zone_bunker_3b", "activate_zone_bunker_3b" ); + add_adjacent_zone( "zone_bunker_3b", "zone_bunker_5a", "activate_zone_bunker_3b" ); + add_adjacent_zone( "zone_bunker_5a", "zone_bunker_5b", "activate_zone_bunker_3b" ); + add_adjacent_zone( "zone_start_b", "zone_bunker_2a", "activate_zone_bunker_2" ); + add_adjacent_zone( "zone_bunker_2a", "zone_bunker_2", "activate_zone_bunker_2" ); + add_adjacent_zone( "zone_bunker_2a", "zone_bunker_2", "activate_zone_bunker_4a" ); + add_adjacent_zone( "zone_bunker_2", "zone_bunker_4a", "activate_zone_bunker_4a" ); + add_adjacent_zone( "zone_bunker_4a", "zone_bunker_4b", "activate_zone_bunker_4a" ); + add_adjacent_zone( "zone_bunker_4a", "zone_bunker_4c", "activate_zone_bunker_4a" ); + add_adjacent_zone( "zone_bunker_4b", "zone_bunker_4f", "activate_zone_bunker_4a" ); + add_adjacent_zone( "zone_bunker_4c", "zone_bunker_4d", "activate_zone_bunker_4a" ); + add_adjacent_zone( "zone_bunker_4c", "zone_bunker_4e", "activate_zone_bunker_4a" ); + add_adjacent_zone( "zone_bunker_4e", "zone_bunker_tank_c1", "activate_zone_bunker_4a" ); + add_adjacent_zone( "zone_bunker_4e", "zone_bunker_tank_d", "activate_zone_bunker_4a" ); + add_adjacent_zone( "zone_bunker_tank_c", "zone_bunker_tank_c1", "activate_zone_bunker_4a" ); + add_adjacent_zone( "zone_bunker_tank_d", "zone_bunker_tank_d1", "activate_zone_bunker_4a" ); + add_adjacent_zone( "zone_bunker_4a", "zone_bunker_4b", "activate_zone_bunker_4b" ); + add_adjacent_zone( "zone_bunker_4a", "zone_bunker_4c", "activate_zone_bunker_4b" ); + add_adjacent_zone( "zone_bunker_4b", "zone_bunker_4f", "activate_zone_bunker_4b" ); + add_adjacent_zone( "zone_bunker_4c", "zone_bunker_4d", "activate_zone_bunker_4b" ); + add_adjacent_zone( "zone_bunker_4c", "zone_bunker_4e", "activate_zone_bunker_4b" ); + add_adjacent_zone( "zone_bunker_4b", "zone_bunker_5a", "activate_zone_bunker_4b" ); + add_adjacent_zone( "zone_bunker_5a", "zone_bunker_5b", "activate_zone_bunker_4b" ); + add_adjacent_zone( "zone_bunker_4e", "zone_bunker_tank_c1", "activate_zone_bunker_4b" ); + add_adjacent_zone( "zone_bunker_4e", "zone_bunker_tank_d", "activate_zone_bunker_4b" ); + add_adjacent_zone( "zone_bunker_tank_c", "zone_bunker_tank_c1", "activate_zone_bunker_4b" ); + add_adjacent_zone( "zone_bunker_tank_d", "zone_bunker_tank_d1", "activate_zone_bunker_4b" ); + add_adjacent_zone( "zone_bunker_tank_a", "zone_nml_7", "activate_zone_nml" ); + add_adjacent_zone( "zone_bunker_tank_a", "zone_nml_7a", "activate_zone_nml" ); + add_adjacent_zone( "zone_bunker_tank_a", "zone_bunker_tank_a1", "activate_zone_nml" ); + add_adjacent_zone( "zone_bunker_tank_a1", "zone_bunker_tank_a2", "activate_zone_nml" ); + add_adjacent_zone( "zone_bunker_tank_a1", "zone_bunker_tank_b", "activate_zone_nml" ); + add_adjacent_zone( "zone_bunker_tank_b", "zone_bunker_tank_c", "activate_zone_nml" ); + add_adjacent_zone( "zone_bunker_tank_c", "zone_bunker_tank_c1", "activate_zone_nml" ); + add_adjacent_zone( "zone_bunker_tank_d", "zone_bunker_tank_d1", "activate_zone_nml" ); + add_adjacent_zone( "zone_bunker_tank_d1", "zone_bunker_tank_e", "activate_zone_nml" ); + add_adjacent_zone( "zone_bunker_tank_e", "zone_bunker_tank_e1", "activate_zone_nml" ); + add_adjacent_zone( "zone_bunker_tank_e1", "zone_bunker_tank_e2", "activate_zone_nml" ); + add_adjacent_zone( "zone_bunker_tank_e1", "zone_bunker_tank_f", "activate_zone_nml" ); + add_adjacent_zone( "zone_bunker_tank_f", "zone_nml_1", "activate_zone_nml" ); + add_adjacent_zone( "zone_bunker_5b", "zone_nml_2a", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_0", "zone_nml_1", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_0", "zone_nml_farm", "activate_zone_farm" ); + add_adjacent_zone( "zone_nml_1", "zone_nml_2", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_1", "zone_nml_4", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_1", "zone_nml_20", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_2", "zone_nml_2a", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_2", "zone_nml_2b", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_2", "zone_nml_3", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_3", "zone_nml_4", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_3", "zone_nml_13", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_4", "zone_nml_5", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_4", "zone_nml_13", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_5", "zone_nml_farm", "activate_zone_farm" ); + add_adjacent_zone( "zone_nml_6", "zone_nml_2b", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_6", "zone_nml_7", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_6", "zone_nml_7a", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_6", "zone_nml_8", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_7", "zone_nml_7a", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_7", "zone_nml_9", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_7", "zone_nml_10", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_8", "zone_nml_10a", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_8", "zone_nml_14", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_8", "zone_nml_16", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_9", "zone_nml_7a", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_9", "zone_nml_9a", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_9", "zone_nml_11", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_10", "zone_nml_10a", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_10", "zone_nml_11", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_10a", "zone_nml_12", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_10a", "zone_village_4", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_11", "zone_nml_9a", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_11", "zone_nml_11a", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_11", "zone_nml_12", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_12", "zone_nml_11a", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_12", "zone_nml_12a", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_13", "zone_nml_15", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_14", "zone_nml_15", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_15", "zone_nml_17", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_15a", "zone_nml_14", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_15a", "zone_nml_15", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_16", "zone_nml_2b", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_16", "zone_nml_16a", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_16", "zone_nml_18", "activate_zone_ruins" ); + add_adjacent_zone( "zone_nml_17", "zone_nml_17a", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_17", "zone_nml_18", "activate_zone_ruins" ); + add_adjacent_zone( "zone_nml_18", "zone_nml_19", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_farm", "zone_nml_celllar", "activate_zone_farm" ); + add_adjacent_zone( "zone_nml_farm", "zone_nml_farm_1", "activate_zone_farm" ); + add_adjacent_zone( "zone_nml_19", "ug_bottom_zone", "activate_zone_crypt" ); + add_adjacent_zone( "zone_village_0", "zone_nml_15", "activate_zone_village_0" ); + add_adjacent_zone( "zone_village_0", "zone_village_4b", "activate_zone_village_0" ); + add_adjacent_zone( "zone_village_1", "zone_village_1a", "activate_zone_village_0" ); + add_adjacent_zone( "zone_village_1", "zone_village_2", "activate_zone_village_1" ); + add_adjacent_zone( "zone_village_1", "zone_village_4b", "activate_zone_village_0" ); + add_adjacent_zone( "zone_village_1", "zone_village_5b", "activate_zone_village_0" ); + add_adjacent_zone( "zone_village_2", "zone_village_3", "activate_zone_village_1" ); + add_adjacent_zone( "zone_village_3", "zone_village_3a", "activate_zone_village_1" ); + add_adjacent_zone( "zone_village_3", "zone_ice_stairs", "activate_zone_village_1" ); + add_adjacent_zone( "zone_ice_stairs", "zone_ice_stairs_1", "activate_zone_village_1" ); + add_adjacent_zone( "zone_village_3a", "zone_village_3b", "activate_zone_village_1" ); + add_adjacent_zone( "zone_village_4", "zone_nml_14", "activate_zone_village_0" ); + add_adjacent_zone( "zone_village_4", "zone_village_4a", "activate_zone_village_0" ); + add_adjacent_zone( "zone_village_4", "zone_village_4b", "activate_zone_village_0" ); + add_adjacent_zone( "zone_village_5", "zone_nml_4", "activate_zone_village_0" ); + add_adjacent_zone( "zone_village_5", "zone_village_5a", "activate_zone_village_0" ); + add_adjacent_zone( "zone_village_5a", "zone_village_5b", "activate_zone_village_0" ); + add_adjacent_zone( "zone_village_6", "zone_village_5b", "activate_zone_village_0" ); + add_adjacent_zone( "zone_village_6", "zone_village_6a", "activate_zone_village_0" ); + add_adjacent_zone( "zone_chamber_0", "zone_chamber_1", "activate_zone_chamber" ); + add_adjacent_zone( "zone_chamber_0", "zone_chamber_3", "activate_zone_chamber" ); + add_adjacent_zone( "zone_chamber_0", "zone_chamber_4", "activate_zone_chamber" ); + add_adjacent_zone( "zone_chamber_1", "zone_chamber_2", "activate_zone_chamber" ); + add_adjacent_zone( "zone_chamber_1", "zone_chamber_3", "activate_zone_chamber" ); + add_adjacent_zone( "zone_chamber_1", "zone_chamber_4", "activate_zone_chamber" ); + add_adjacent_zone( "zone_chamber_1", "zone_chamber_5", "activate_zone_chamber" ); + add_adjacent_zone( "zone_chamber_2", "zone_chamber_4", "activate_zone_chamber" ); + add_adjacent_zone( "zone_chamber_2", "zone_chamber_5", "activate_zone_chamber" ); + add_adjacent_zone( "zone_chamber_3", "zone_chamber_4", "activate_zone_chamber" ); + add_adjacent_zone( "zone_chamber_3", "zone_chamber_6", "activate_zone_chamber" ); + add_adjacent_zone( "zone_chamber_3", "zone_chamber_7", "activate_zone_chamber" ); + add_adjacent_zone( "zone_chamber_4", "zone_chamber_5", "activate_zone_chamber" ); + add_adjacent_zone( "zone_chamber_4", "zone_chamber_6", "activate_zone_chamber" ); + add_adjacent_zone( "zone_chamber_4", "zone_chamber_7", "activate_zone_chamber" ); + add_adjacent_zone( "zone_chamber_4", "zone_chamber_8", "activate_zone_chamber" ); + add_adjacent_zone( "zone_chamber_5", "zone_chamber_7", "activate_zone_chamber" ); + add_adjacent_zone( "zone_chamber_5", "zone_chamber_8", "activate_zone_chamber" ); + add_adjacent_zone( "zone_chamber_6", "zone_chamber_7", "activate_zone_chamber" ); + add_adjacent_zone( "zone_chamber_7", "zone_chamber_8", "activate_zone_chamber" ); + add_adjacent_zone( "zone_bunker_1", "zone_bunker_1a", "activate_zone_bunker_1_tank" ); + add_adjacent_zone( "zone_bunker_1a", "zone_fire_stairs", "activate_zone_bunker_1_tank" ); + add_adjacent_zone( "zone_fire_stairs", "zone_fire_stairs_1", "activate_zone_bunker_1_tank" ); + add_adjacent_zone( "zone_bunker_2", "zone_bunker_2a", "activate_zone_bunker_2_tank" ); + add_adjacent_zone( "zone_bunker_4a", "zone_bunker_4b", "activate_zone_bunker_4_tank" ); + add_adjacent_zone( "zone_bunker_4a", "zone_bunker_4c", "activate_zone_bunker_4_tank" ); + add_adjacent_zone( "zone_bunker_4c", "zone_bunker_4d", "activate_zone_bunker_4_tank" ); + add_adjacent_zone( "zone_bunker_4c", "zone_bunker_4e", "activate_zone_bunker_4_tank" ); + add_adjacent_zone( "zone_bunker_4e", "zone_bunker_tank_c1", "activate_zone_bunker_4_tank" ); + add_adjacent_zone( "zone_bunker_4e", "zone_bunker_tank_d", "activate_zone_bunker_4_tank" ); + add_adjacent_zone( "zone_bunker_tank_c", "zone_bunker_tank_c1", "activate_zone_bunker_4_tank" ); + add_adjacent_zone( "zone_bunker_tank_d", "zone_bunker_tank_d1", "activate_zone_bunker_4_tank" ); + add_adjacent_zone( "zone_bunker_tank_b", "zone_bunker_6", "activate_zone_bunker_6_tank" ); + add_adjacent_zone( "zone_bunker_1", "zone_bunker_6", "activate_zone_bunker_6_tank" ); + level thread activate_zone_trig( "trig_zone_bunker_1", "activate_zone_bunker_1_tank" ); + level thread activate_zone_trig( "trig_zone_bunker_2", "activate_zone_bunker_2_tank" ); + level thread activate_zone_trig( "trig_zone_bunker_4", "activate_zone_bunker_4_tank" ); + level thread activate_zone_trig( "trig_zone_bunker_6", "activate_zone_bunker_6_tank", "activate_zone_bunker_1_tank" ); + add_adjacent_zone( "zone_bunker_1a", "zone_fire_stairs", "activate_zone_bunker_1" ); + add_adjacent_zone( "zone_fire_stairs", "zone_fire_stairs_1", "activate_zone_bunker_1" ); + add_adjacent_zone( "zone_bunker_1a", "zone_fire_stairs", "activate_zone_bunker_3a" ); + add_adjacent_zone( "zone_fire_stairs", "zone_fire_stairs_1", "activate_zone_bunker_3a" ); + add_adjacent_zone( "zone_nml_9", "zone_air_stairs", "activate_zone_nml" ); + add_adjacent_zone( "zone_air_stairs", "zone_air_stairs_1", "activate_zone_nml" ); + add_adjacent_zone( "zone_nml_celllar", "zone_bolt_stairs", "activate_zone_farm" ); + add_adjacent_zone( "zone_bolt_stairs", "zone_bolt_stairs_1", "activate_zone_farm" ); +} + +activate_zone_trig( str_name, str_zone1, str_zone2 ) +{ + trig = getent( str_name, "targetname" ); + + trig waittill( "trigger" ); + + if ( isdefined( str_zone1 ) ) + flag_set( str_zone1 ); + + if ( isdefined( str_zone2 ) ) + flag_set( str_zone2 ); + + trig delete(); +} + +check_tank_platform_zone() +{ + while ( true ) + { + level waittill( "newzoneActive", activezone ); + + if ( activezone == "zone_bunker_3" ) + break; + + wait 1; + } + + flag_set( "activate_zone_nml" ); +} + +tomb_vehicle_damage_override_wrapper( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime, damagefromunderneath, modelindex, partname ) +{ + if ( isdefined( level.a_func_vehicle_damage_override[self.vehicletype] ) ) + return level.a_func_vehicle_damage_override[self.vehicletype]; + + return idamage; +} + +drop_all_barriers() +{ + zkeys = getarraykeys( level.zones ); + + for ( z = 0; z < level.zones.size; z++ ) + { + zbarriers = get_all_zone_zbarriers( zkeys[z] ); + + if ( !isdefined( zbarriers ) ) + continue; + + foreach ( zbarrier in zbarriers ) + { + zbarrier_pieces = zbarrier getnumzbarrierpieces(); + + for ( i = 0; i < zbarrier_pieces; i++ ) + { + zbarrier hidezbarrierpiece( i ); + zbarrier setzbarrierpiecestate( i, "open" ); + } + + wait 0.05; + } + } +} + +get_all_zone_zbarriers( zone_name ) +{ + if ( !isdefined( zone_name ) ) + return undefined; + + zone = level.zones[zone_name]; + return zone.zbarriers; +} + +tomb_special_weapon_magicbox_check( weapon ) +{ + if ( isdefined( level.raygun2_included ) && level.raygun2_included ) + { + if ( weapon == "ray_gun_zm" ) + { + if ( self has_weapon_or_upgrade( "raygun_mark2_zm" ) ) + return false; + } + + if ( weapon == "raygun_mark2_zm" ) + { + if ( self has_weapon_or_upgrade( "ray_gun_zm" ) ) + return false; + + if ( randomint( 100 ) >= 33 ) + return false; + } + } + + if ( weapon == "beacon_zm" ) + { + if ( isdefined( self.beacon_ready ) && self.beacon_ready ) + return true; + else + return false; + } + + if ( isdefined( level.zombie_weapons[weapon].shared_ammo_weapon ) ) + { + if ( self has_weapon_or_upgrade( level.zombie_weapons[weapon].shared_ammo_weapon ) ) + return false; + } + + return true; +} + +custom_vending_precaching() +{ + if ( level._custom_perks.size > 0 ) + { + a_keys = getarraykeys( level._custom_perks ); + + for ( i = 0; i < a_keys.size; i++ ) + { + if ( isdefined( level._custom_perks[a_keys[i]].precache_func ) ) + level [[ level._custom_perks[a_keys[i]].precache_func ]](); + } + } + + if ( isdefined( level.zombiemode_using_pack_a_punch ) && level.zombiemode_using_pack_a_punch ) + { + precacheitem( "zombie_knuckle_crack" ); + precachemodel( "p6_anim_zm_buildable_pap" ); + precachemodel( "p6_anim_zm_buildable_pap_on" ); + precachestring( &"ZOMBIE_PERK_PACKAPUNCH" ); + precachestring( &"ZOMBIE_PERK_PACKAPUNCH_ATT" ); + level._effect["packapunch_fx"] = loadfx( "maps/zombie/fx_zombie_packapunch" ); + level.machine_assets["packapunch"] = spawnstruct(); + level.machine_assets["packapunch"].weapon = "zombie_knuckle_crack"; + } + + if ( isdefined( level.zombiemode_using_additionalprimaryweapon_perk ) && level.zombiemode_using_additionalprimaryweapon_perk ) + { + precacheitem( "zombie_perk_bottle_additionalprimaryweapon" ); + precacheshader( "specialty_additionalprimaryweapon_zombies" ); + precachemodel( "p6_zm_tm_vending_three_gun" ); + precachestring( &"ZOMBIE_PERK_ADDITIONALWEAPONPERK" ); + level._effect["additionalprimaryweapon_light"] = loadfx( "misc/fx_zombie_cola_arsenal_on" ); + level.machine_assets["additionalprimaryweapon"] = spawnstruct(); + level.machine_assets["additionalprimaryweapon"].weapon = "zombie_perk_bottle_additionalprimaryweapon"; + level.machine_assets["additionalprimaryweapon"].off_model = "p6_zm_tm_vending_three_gun"; + level.machine_assets["additionalprimaryweapon"].on_model = "p6_zm_tm_vending_three_gun"; + level.machine_assets["additionalprimaryweapon"].power_on_callback = maps\mp\zm_tomb_capture_zones::custom_vending_power_on; + level.machine_assets["additionalprimaryweapon"].power_off_callback = maps\mp\zm_tomb_capture_zones::custom_vending_power_off; + } + + if ( isdefined( level.zombiemode_using_deadshot_perk ) && level.zombiemode_using_deadshot_perk ) + { + precacheitem( "zombie_perk_bottle_deadshot" ); + precacheshader( "specialty_ads_zombies" ); + precachemodel( "zombie_vending_ads" ); + precachemodel( "zombie_vending_ads_on" ); + precachestring( &"ZOMBIE_PERK_DEADSHOT" ); + level._effect["deadshot_light"] = loadfx( "misc/fx_zombie_cola_dtap_on" ); + level.machine_assets["deadshot"] = spawnstruct(); + level.machine_assets["deadshot"].weapon = "zombie_perk_bottle_deadshot"; + level.machine_assets["deadshot"].off_model = "zombie_vending_ads"; + level.machine_assets["deadshot"].on_model = "zombie_vending_ads_on"; + level.machine_assets["deadshot"].power_on_callback = maps\mp\zm_tomb_capture_zones::custom_vending_power_on; + level.machine_assets["deadshot"].power_off_callback = maps\mp\zm_tomb_capture_zones::custom_vending_power_off; + } + + if ( isdefined( level.zombiemode_using_divetonuke_perk ) && level.zombiemode_using_divetonuke_perk ) + { + precacheitem( "zombie_perk_bottle_nuke" ); + precacheshader( "specialty_divetonuke_zombies" ); + precachemodel( "zombie_vending_nuke" ); + precachemodel( "zombie_vending_nuke_on" ); + precachestring( &"ZOMBIE_PERK_DIVETONUKE" ); + level._effect["divetonuke_light"] = loadfx( "misc/fx_zombie_cola_dtap_on" ); + level.machine_assets["divetonuke"] = spawnstruct(); + level.machine_assets["divetonuke"].weapon = "zombie_perk_bottle_nuke"; + level.machine_assets["divetonuke"].off_model = "zombie_vending_nuke"; + level.machine_assets["divetonuke"].on_model = "zombie_vending_nuke_on"; + level.machine_assets["divetonuke"].power_on_callback = maps\mp\zm_tomb_capture_zones::custom_vending_power_on; + level.machine_assets["divetonuke"].power_off_callback = maps\mp\zm_tomb_capture_zones::custom_vending_power_off; + } + + if ( isdefined( level.zombiemode_using_doubletap_perk ) && level.zombiemode_using_doubletap_perk ) + { + precacheitem( "zombie_perk_bottle_doubletap" ); + precacheshader( "specialty_doubletap_zombies" ); + precachemodel( "zombie_vending_doubletap2" ); + precachemodel( "zombie_vending_doubletap2_on" ); + precachestring( &"ZOMBIE_PERK_DOUBLETAP" ); + level._effect["doubletap_light"] = loadfx( "misc/fx_zombie_cola_dtap_on" ); + level.machine_assets["doubletap"] = spawnstruct(); + level.machine_assets["doubletap"].weapon = "zombie_perk_bottle_doubletap"; + level.machine_assets["doubletap"].off_model = "zombie_vending_doubletap2"; + level.machine_assets["doubletap"].on_model = "zombie_vending_doubletap2_on"; + level.machine_assets["doubletap"].power_on_callback = maps\mp\zm_tomb_capture_zones::custom_vending_power_on; + level.machine_assets["doubletap"].power_off_callback = maps\mp\zm_tomb_capture_zones::custom_vending_power_off; + } + + if ( isdefined( level.zombiemode_using_juggernaut_perk ) && level.zombiemode_using_juggernaut_perk ) + { + precacheitem( "zombie_perk_bottle_jugg" ); + precacheshader( "specialty_juggernaut_zombies" ); + precachemodel( "zombie_vending_jugg" ); + precachemodel( "zombie_vending_jugg_on" ); + precachestring( &"ZOMBIE_PERK_JUGGERNAUT" ); + level._effect["jugger_light"] = loadfx( "misc/fx_zombie_cola_jugg_on" ); + level.machine_assets["juggernog"] = spawnstruct(); + level.machine_assets["juggernog"].weapon = "zombie_perk_bottle_jugg"; + level.machine_assets["juggernog"].off_model = "zombie_vending_jugg"; + level.machine_assets["juggernog"].on_model = "zombie_vending_jugg_on"; + level.machine_assets["juggernog"].power_on_callback = maps\mp\zm_tomb_capture_zones::custom_vending_power_on; + level.machine_assets["juggernog"].power_off_callback = maps\mp\zm_tomb_capture_zones::custom_vending_power_off; + } + + if ( isdefined( level.zombiemode_using_marathon_perk ) && level.zombiemode_using_marathon_perk ) + { + precacheitem( "zombie_perk_bottle_marathon" ); + precacheshader( "specialty_marathon_zombies" ); + precachemodel( "zombie_vending_marathon" ); + precachemodel( "zombie_vending_marathon_on" ); + precachestring( &"ZOMBIE_PERK_MARATHON" ); + level._effect["marathon_light"] = loadfx( "maps/zombie/fx_zmb_cola_staminup_on" ); + level.machine_assets["marathon"] = spawnstruct(); + level.machine_assets["marathon"].weapon = "zombie_perk_bottle_marathon"; + level.machine_assets["marathon"].off_model = "zombie_vending_marathon"; + level.machine_assets["marathon"].on_model = "zombie_vending_marathon_on"; + level.machine_assets["marathon"].power_on_callback = maps\mp\zm_tomb_capture_zones::custom_vending_power_on; + level.machine_assets["marathon"].power_off_callback = maps\mp\zm_tomb_capture_zones::custom_vending_power_off; + } + + if ( isdefined( level.zombiemode_using_revive_perk ) && level.zombiemode_using_revive_perk ) + { + precacheitem( "zombie_perk_bottle_revive" ); + precacheshader( "specialty_quickrevive_zombies" ); + precachemodel( "p6_zm_tm_vending_revive" ); + precachemodel( "p6_zm_tm_vending_revive_on" ); + precachestring( &"ZOMBIE_PERK_QUICKREVIVE" ); + level._effect["revive_light"] = loadfx( "misc/fx_zombie_cola_revive_on" ); + level._effect["revive_light_flicker"] = loadfx( "maps/zombie/fx_zmb_cola_revive_flicker" ); + level.machine_assets["revive"] = spawnstruct(); + level.machine_assets["revive"].weapon = "zombie_perk_bottle_revive"; + level.machine_assets["revive"].off_model = "p6_zm_tm_vending_revive"; + level.machine_assets["revive"].on_model = "p6_zm_tm_vending_revive_on"; + level.machine_assets["revive"].power_on_callback = maps\mp\zm_tomb_capture_zones::custom_vending_power_on; + level.machine_assets["revive"].power_off_callback = maps\mp\zm_tomb_capture_zones::custom_vending_power_off; + } + + if ( isdefined( level.zombiemode_using_sleightofhand_perk ) && level.zombiemode_using_sleightofhand_perk ) + { + precacheitem( "zombie_perk_bottle_sleight" ); + precacheshader( "specialty_fastreload_zombies" ); + precachemodel( "zombie_vending_sleight" ); + precachemodel( "zombie_vending_sleight_on" ); + precachestring( &"ZOMBIE_PERK_FASTRELOAD" ); + level._effect["sleight_light"] = loadfx( "misc/fx_zombie_cola_on" ); + level.machine_assets["speedcola"] = spawnstruct(); + level.machine_assets["speedcola"].weapon = "zombie_perk_bottle_sleight"; + level.machine_assets["speedcola"].off_model = "zombie_vending_sleight"; + level.machine_assets["speedcola"].on_model = "zombie_vending_sleight_on"; + level.machine_assets["speedcola"].power_on_callback = maps\mp\zm_tomb_capture_zones::custom_vending_power_on; + level.machine_assets["speedcola"].power_off_callback = maps\mp\zm_tomb_capture_zones::custom_vending_power_off; + } + + if ( isdefined( level.zombiemode_using_tombstone_perk ) && level.zombiemode_using_tombstone_perk ) + { + precacheitem( "zombie_perk_bottle_tombstone" ); + precacheshader( "specialty_tombstone_zombies" ); + precachemodel( "zombie_vending_tombstone" ); + precachemodel( "zombie_vending_tombstone_on" ); + precachemodel( "ch_tombstone1" ); + precachestring( &"ZOMBIE_PERK_TOMBSTONE" ); + level._effect["tombstone_light"] = loadfx( "misc/fx_zombie_cola_on" ); + level.machine_assets["tombstone"] = spawnstruct(); + level.machine_assets["tombstone"].weapon = "zombie_perk_bottle_tombstone"; + level.machine_assets["tombstone"].off_model = "zombie_vending_tombstone"; + level.machine_assets["tombstone"].on_model = "zombie_vending_tombstone_on"; + level.machine_assets["tombstone"].power_on_callback = maps\mp\zm_tomb_capture_zones::custom_vending_power_on; + level.machine_assets["tombstone"].power_off_callback = maps\mp\zm_tomb_capture_zones::custom_vending_power_off; + } + + if ( isdefined( level.zombiemode_using_chugabud_perk ) && level.zombiemode_using_chugabud_perk ) + { + precacheitem( "zombie_perk_bottle_whoswho" ); + precacheshader( "specialty_quickrevive_zombies" ); + precachemodel( "p6_zm_vending_chugabud" ); + precachemodel( "p6_zm_vending_chugabud_on" ); + precachemodel( "ch_tombstone1" ); + precachestring( &"ZOMBIE_PERK_TOMBSTONE" ); + level._effect["tombstone_light"] = loadfx( "misc/fx_zombie_cola_on" ); + level.machine_assets["whoswho"] = spawnstruct(); + level.machine_assets["whoswho"].weapon = "zombie_perk_bottle_whoswho"; + level.machine_assets["whoswho"].off_model = "p6_zm_vending_chugabud"; + level.machine_assets["whoswho"].on_model = "p6_zm_vending_chugabud_on"; + level.machine_assets["whoswho"].power_on_callback = maps\mp\zm_tomb_capture_zones::custom_vending_power_on; + level.machine_assets["whoswho"].power_off_callback = maps\mp\zm_tomb_capture_zones::custom_vending_power_off; + } +} + +tomb_actor_damage_override_wrapper( inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, shitloc, psoffsettime, boneindex ) +{ + if ( isdefined( self.b_zombie_blood_damage_only ) && self.b_zombie_blood_damage_only ) + { + if ( !isplayer( attacker ) || !attacker.zombie_vars["zombie_powerup_zombie_blood_on"] ) + return 0; + } + + if ( isdefined( self.script_noteworthy ) && self.script_noteworthy == "capture_zombie" && isdefined( attacker ) && isplayer( attacker ) ) + { + if ( damage >= self.health ) + { + if ( 100 * level.round_number > attacker.n_capture_zombie_points ) + { + attacker maps\mp\zombies\_zm_score::player_add_points( "rebuild_board", 10 ); + attacker.n_capture_zombie_points += 10; + } + } + } + + return_val = self maps\mp\zombies\_zm::actor_damage_override_wrapper( inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, shitloc, psoffsettime, boneindex ); + + if ( damage >= self.health ) + { + if ( weapon == "zombie_markiv_cannon" && meansofdeath == "MOD_CRUSH" ) + self thread zombie_gib_guts(); + else if ( isdefined( self.b_on_tank ) && self.b_on_tank || isdefined( self.b_climbing_tank ) && self.b_climbing_tank ) + self maps\mp\zm_tomb_tank::zombie_on_tank_death_animscript_callback( inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, shitloc, psoffsettime, boneindex ); + } + + return return_val; +} + +tomb_zombie_death_event_callback() +{ + if ( isdefined( self ) && isdefined( self.damagelocation ) && isdefined( self.damagemod ) && isdefined( self.damageweapon ) && isdefined( self.attacker ) && isplayer( self.attacker ) ) + { + if ( is_headshot( self.damageweapon, self.damagelocation, self.damagemod ) && maps\mp\zombies\_zm_challenges::challenge_exists( "zc_headshots" ) && !( !isdefined( self.script_noteworthy ) && !isdefined( "capture_zombie" ) || isdefined( self.script_noteworthy ) && isdefined( "capture_zombie" ) && self.script_noteworthy == "capture_zombie" ) ) + self.attacker maps\mp\zombies\_zm_challenges::increment_stat( "zc_headshots" ); + } +} + +zombie_init_done() +{ + self.allowpain = 0; + self thread maps\mp\zm_tomb_distance_tracking::escaped_zombies_cleanup_init(); +} + +tomb_validate_enemy_path_length( player ) +{ + max_dist = 1296; + d = distancesquared( self.origin, player.origin ); + + if ( d <= max_dist ) + return true; + + return false; +} + +show_zombie_count() +{ + self endon( "death_or_disconnect" ); + flag_wait( "start_zombie_round_logic" ); + + while ( true ) + { + n_round_zombies = get_current_zombie_count(); + str_hint = "Alive: " + n_round_zombies + "\\nTo Spawn: " + level.zombie_total; + iprintln( str_hint ); + wait 5; + } +} + +tomb_custom_divetonuke_explode( attacker, origin ) +{ + radius = level.zombie_vars["zombie_perk_divetonuke_radius"]; + min_damage = level.zombie_vars["zombie_perk_divetonuke_min_damage"]; + max_damage = level.zombie_vars["zombie_perk_divetonuke_max_damage"]; + + if ( isdefined( level.flopper_network_optimized ) && level.flopper_network_optimized ) + attacker thread tomb_custom_divetonuke_explode_network_optimized( origin, radius, max_damage, min_damage, "MOD_GRENADE_SPLASH" ); + else + radiusdamage( origin, radius, max_damage, min_damage, attacker, "MOD_GRENADE_SPLASH" ); + + playfx( level._effect["divetonuke_groundhit"], origin ); + attacker playsound( "zmb_phdflop_explo" ); + maps\mp\_visionset_mgr::vsmgr_activate( "visionset", "zm_perk_divetonuke", attacker ); + wait 1; + maps\mp\_visionset_mgr::vsmgr_deactivate( "visionset", "zm_perk_divetonuke", attacker ); +} + +tomb_custom_divetonuke_explode_network_optimized( origin, radius, max_damage, min_damage, damage_mod ) +{ + self endon( "disconnect" ); + a_all_zombies = getaispeciesarray( "axis", "all" ); + a_zombies = get_array_of_closest( origin, a_all_zombies, undefined, undefined, radius ); + network_stall_counter = 0; + + if ( isdefined( a_zombies ) ) + { + for ( i = 0; i < a_zombies.size; i++ ) + { + e_zombie = a_zombies[i]; + + if ( !isdefined( e_zombie ) || !isalive( e_zombie ) ) + continue; + + dist = distance( e_zombie.origin, origin ); + damage = min_damage + ( max_damage - min_damage ) * ( 1.0 - dist / radius ); + e_zombie dodamage( damage, e_zombie.origin, self, self, 0, damage_mod ); + network_stall_counter--; + + if ( network_stall_counter <= 0 ) + { + wait_network_frame(); + network_stall_counter = randomintrange( 1, 3 ); + } + } + } +} + +tomb_custom_electric_cherry_laststand() +{ + visionsetlaststand( "zombie_last_stand", 1 ); + + if ( isdefined( self ) ) + { + playfx( level._effect["electric_cherry_explode"], self.origin ); + self playsound( "zmb_cherry_explode" ); + self notify( "electric_cherry_start" ); + wait 0.05; + a_zombies = getaispeciesarray( "axis", "all" ); + a_zombies = get_array_of_closest( self.origin, a_zombies, undefined, undefined, 500 ); + + for ( i = 0; i < a_zombies.size; i++ ) + { + if ( isalive( self ) ) + { + if ( a_zombies[i].health <= 1000 ) + { + a_zombies[i] thread maps\mp\zombies\_zm_perk_electric_cherry::electric_cherry_death_fx(); + + if ( isdefined( self.cherry_kills ) ) + self.cherry_kills++; + + self maps\mp\zombies\_zm_score::add_to_player_score( 40 ); + } + else + { + a_zombies[i] thread maps\mp\zombies\_zm_perk_electric_cherry::electric_cherry_stun(); + a_zombies[i] thread maps\mp\zombies\_zm_perk_electric_cherry::electric_cherry_shock_fx(); + } + + wait 0.1; + a_zombies[i] dodamage( 1000, self.origin, self, self, "none" ); + } + } + + self notify( "electric_cherry_end" ); + } +} + +tomb_custom_electric_cherry_reload_attack() +{ + self endon( "death" ); + self endon( "disconnect" ); + self endon( "stop_electric_cherry_reload_attack" ); + self.wait_on_reload = []; + self.consecutive_electric_cherry_attacks = 0; + + while ( true ) + { + self waittill( "reload_start" ); + + str_current_weapon = self getcurrentweapon(); + + if ( isinarray( self.wait_on_reload, str_current_weapon ) ) + continue; + + self.wait_on_reload[self.wait_on_reload.size] = str_current_weapon; + self.consecutive_electric_cherry_attacks++; + n_clip_current = self getweaponammoclip( str_current_weapon ); + n_clip_max = weaponclipsize( str_current_weapon ); + n_fraction = n_clip_current / n_clip_max; + perk_radius = linear_map( n_fraction, 1.0, 0.0, 32, 128 ); + perk_dmg = linear_map( n_fraction, 1.0, 0.0, 1, 1045 ); + self thread maps\mp\zombies\_zm_perk_electric_cherry::check_for_reload_complete( str_current_weapon ); + + if ( isdefined( self ) ) + { + switch ( self.consecutive_electric_cherry_attacks ) + { + case 1: + case 0: + n_zombie_limit = undefined; + break; + case 2: + n_zombie_limit = 8; + break; + case 3: + n_zombie_limit = 4; + break; + case 4: + n_zombie_limit = 2; + break; + default: + n_zombie_limit = 0; + } + + self thread maps\mp\zombies\_zm_perk_electric_cherry::electric_cherry_cooldown_timer( str_current_weapon ); + + if ( isdefined( n_zombie_limit ) && n_zombie_limit == 0 ) + continue; + + self thread electric_cherry_reload_fx( n_fraction ); + self notify( "electric_cherry_start" ); + self playsound( "zmb_cherry_explode" ); + a_zombies = getaispeciesarray( "axis", "all" ); + a_zombies = get_array_of_closest( self.origin, a_zombies, undefined, undefined, perk_radius ); + n_zombies_hit = 0; + + for ( i = 0; i < a_zombies.size; i++ ) + { + if ( isalive( self ) && isalive( a_zombies[i] ) ) + { + if ( isdefined( n_zombie_limit ) ) + { + if ( n_zombies_hit < n_zombie_limit ) + n_zombies_hit++; + else + break; + } + + if ( a_zombies[i].health <= perk_dmg ) + { + a_zombies[i] thread maps\mp\zombies\_zm_perk_electric_cherry::electric_cherry_death_fx(); + + if ( isdefined( self.cherry_kills ) ) + self.cherry_kills++; + + self maps\mp\zombies\_zm_score::add_to_player_score( 40 ); + } + else + { + if ( !isdefined( a_zombies[i].is_mechz ) ) + a_zombies[i] thread maps\mp\zombies\_zm_perk_electric_cherry::electric_cherry_stun(); + + a_zombies[i] thread maps\mp\zombies\_zm_perk_electric_cherry::electric_cherry_shock_fx(); + } + + wait 0.1; + + if ( isalive( a_zombies[i] ) ) + a_zombies[i] dodamage( perk_dmg, self.origin, self, self, "none" ); + } + } + + self notify( "electric_cherry_end" ); + } + } +} + +tomb_custom_player_track_ammo_count() +{ + self notify( "stop_ammo_tracking" ); + self endon( "disconnect" ); + self endon( "stop_ammo_tracking" ); + ammolowcount = 0; + ammooutcount = 0; + + while ( true ) + { + wait 0.5; + weap = self getcurrentweapon(); + + if ( !isdefined( weap ) || weap == "none" || !tomb_can_track_ammo_custom( weap ) ) + continue; + + if ( self getammocount( weap ) > 5 || self maps\mp\zombies\_zm_laststand::player_is_in_laststand() ) + { + ammooutcount = 0; + ammolowcount = 0; + continue; + } + + if ( self getammocount( weap ) > 0 ) + { + if ( ammolowcount < 1 ) + { + self maps\mp\zombies\_zm_audio::create_and_play_dialog( "general", "ammo_low" ); + ammolowcount++; + } + } + else if ( ammooutcount < 1 ) + { + self maps\mp\zombies\_zm_audio::create_and_play_dialog( "general", "ammo_out" ); + ammooutcount++; + } + + wait 20; + } +} + +tomb_can_track_ammo_custom( weap ) +{ + if ( !isdefined( weap ) ) + return false; + + switch ( weap ) + { + case "zombie_tazer_flourish": + case "zombie_sickle_flourish": + case "zombie_one_inch_punch_upgrade_flourish": + case "zombie_one_inch_punch_flourish": + case "zombie_knuckle_crack": + case "zombie_fists_zm": + case "zombie_builder_zm": + case "zombie_bowie_flourish": + case "time_bomb_zm": + case "time_bomb_detonator_zm": + case "tazer_knuckles_zm": + case "tazer_knuckles_upgraded_zm": + case "staff_revive_zm": + case "slowgun_zm": + case "slowgun_upgraded_zm": + case "screecher_arms_zm": + case "riotshield_zm": + case "one_inch_punch_zm": + case "one_inch_punch_upgraded_zm": + case "one_inch_punch_lightning_zm": + case "one_inch_punch_ice_zm": + case "one_inch_punch_fire_zm": + case "one_inch_punch_air_zm": + case "none": + case "no_hands_zm": + case "lower_equip_gasmask_zm": + case "humangun_zm": + case "humangun_upgraded_zm": + case "falling_hands_tomb_zm": + case "equip_gasmask_zm": + case "equip_dieseldrone_zm": + case "death_throe_zm": + case "chalk_draw_zm": + case "alcatraz_shield_zm": + return false; + default: + if ( is_zombie_perk_bottle( weap ) || is_placeable_mine( weap ) || is_equipment( weap ) || issubstr( weap, "knife_ballistic_" ) || getsubstr( weap, 0, 3 ) == "gl_" || weaponfuellife( weap ) > 0 || weap == level.revive_tool ) + return false; + } + + return true; +} diff --git a/t6/uncompiled mods/zm_universal_bank_mod_main.gsc b/t6/uncompiled mods/zm_universal_bank_mod_main.gsc new file mode 100644 index 0000000..26ce181 --- /dev/null +++ b/t6/uncompiled mods/zm_universal_bank_mod_main.gsc @@ -0,0 +1,204 @@ +main() +{ + mapname = getDvar( "mapname" ); + if ( mapname != "zm_transit" && mapname != "zm_highrise" && mapname != "zm_buried" ) + { + level thread on_player_connect(); + } + level thread command_thread(); + level thread auto_deposit_on_end_game(); +} + +command_thread() +{ + level endon( "end_game" ); + while ( true ) + { + level waittill( "say", message, player, isHidden ); + args = strTok( message, " " ); + command = args[ 0 ]; + switch ( command ) + { + case "!w": + case "!with": + case "!withdraw": + case ".w": + case ".with": + case ".withdraw": + player withdraw_logic( args[ 1 ] ); + break; + case "!d": + case "!dep": + case "!deposit": + case ".d": + case ".dep": + case ".deposit": + player deposit_logic( args[ 1 ] ); + break; + case "!b": + case "!bal": + case "!balance": + case ".b": + case ".bal": + case ".balance": + player balance_logic(); + break; + default: + break; + } + } +} + +auto_deposit_on_end_game() +{ + //level waittill( "end_game" ); + //wait 1; + //foreach ( player in level.players ) + //{ + //player deposit_logic( "all" ); + //} +} + +on_player_connect() +{ + level endon( "end_game" ); + while ( true ) + { + level waittill( "connected", player ); + player.account_value = player maps\mp\zombies\_zm_stats::get_map_stat( "depositBox", "zm_transit" ); + } +} + +withdraw_logic( amount ) +{ + if ( !isDefined( self.account_value ) ) + { + self iPrintLn( "Map is not bank compatible" ); + return; + } + if ( self.account_value <= 0 ) + { + self iPrintln( "Withdraw failed: empty bank" ); + return; + } + if ( self.score >= 1000000 ) + { + self iPrintLn( "Withdraw failed: Max bank amount is 1000000" ); + return; + } + if ( !isDefined( amount ) ) + { + self iPrintLn( "Usage .w " ); + return; + } + num_score = int( floor( self.score / 1000 ) ); + num_amount = int( amount ); + if ( amount == "all" ) + { + num_amount = self.account_value; + } + else if ( num_amount > 0 ) + { + if ( num_amount < 1000 ) + { + self iPrintLn( "Withdraw failed: Value must be 1000 or greater" ); + return; + } + num_amount = int( floor( num_amount / 1000 ) ); + } + else + { + self iPrintLn( "Usage .w " ); + return; + } + //Clamp amount to account value + if ( num_amount > self.account_value ) + { + num_amount = self.account_value; + } + new_balance = self.account_value - num_amount; //250 - 250 + //If the withdraw amount + the player's current score is greater than 1000 clamp the withdraw amount + over_balance = num_score + num_amount - 1000; // 800 + 250 - 1000 + max_score_available = abs( num_score - 1000 ); // 800 - 1000 + if ( over_balance > 0 ) // 50 > 0 + { + new_balance = over_balance; + num_amount = max_score_available; + } + self.account_value = new_balance; + final_amount = num_amount * 1000; + self.score += final_amount; + self maps\mp\zombies\_zm_stats::set_map_stat( "depositBox", new_balance, "zm_transit" ); + self iPrintLn( "Successfuly withdrew " + final_amount ); +} + +deposit_logic( amount ) +{ + if ( !isDefined( self.account_value ) ) + { + self iPrintLn( "Map is not bank compatible" ); + return; + } + if ( self.score <= 999 ) + { + self iPrintLn( "Deposit failed: Not enough points" ); + } + if ( self.account_value >= 250 ) + { + self iPrintLn( "Deposit failed: Max bank is 250000" ); + return; + } + if ( !isDefined( amount ) ) + { + self iPrintLn( "Usage .d " ); + return; + } + num_score = int( floor( self.score / 1000 ) ); + num_amount = int( amount ); + if ( amount == "all" ) + { + num_amount = num_score; + } + else if ( num_amount > 0 ) + { + if ( num_amount < 1000 ) + { + self iPrintLn( "Deposit failed: Value must be 1000 or greater" ); + return; + } + num_amount = int( floor( num_amount / 1000 ) ); + } + else + { + self iPrintLn( "Usage .d " ); + return; + } + //Clamp deposit amount to player's score + if ( num_amount > num_score ) + { + num_amount = num_score; + } + //Clamp deposit amount to 250(max amount allowed in bank) + if ( num_amount > 250 ) + { + num_amount = 250; + } + //If the amount is greater than what can fit in the bank clamp the deposit amount to what can fit in the bank (250) + new_balance = self.account_value + num_amount; + over_balance = new_balance - 250; + if ( over_balance > 0 ) + { + num_amount -= over_balance; + new_balance -= over_balance; + } + self.account_value = new_balance; + final_amount = num_amount * 1000; + self.score -= final_amount; + self maps\mp\zombies\_zm_stats::set_map_stat( "depositBox", new_balance, "zm_transit" ); + self iPrintLn( "Successfully deposited " + final_amount ); +} + +balance_logic() +{ + self iPrintLn( "Current balance: " + self.account_value * 1000 + " Max: 250000" ); +} \ No newline at end of file diff --git a/t6/uncompiled mods/zm_universal_bank_transit_mod_main.gsc b/t6/uncompiled mods/zm_universal_bank_transit_mod_main.gsc new file mode 100644 index 0000000..af190c2 --- /dev/null +++ b/t6/uncompiled mods/zm_universal_bank_transit_mod_main.gsc @@ -0,0 +1,7 @@ +init() +{ + if ( getDvar( "ui_zm_gamemodegroup" ) == "zsurvival" ) + { + level thread maps\mp\zombies\_zm_banking::init(); + } +} \ No newline at end of file diff --git a/t6/uncompiled mods/zmafk.gsc b/t6/uncompiled mods/zmafk.gsc new file mode 100644 index 0000000..56b90f7 --- /dev/null +++ b/t6/uncompiled mods/zmafk.gsc @@ -0,0 +1,528 @@ +/* + MustBeAFK + A T6 Zombies AFK System by MustBeLeaving + You can find this script at https://github.com/garryspins/mustbeafk + + Requires: + t6-gsc-utils (https://github.com/fedddddd/t6-gsc-utils) + + DVars: + mafk_name [str = "[^6MAfk^7]"]- What text should be shown before chat messages? + mafk_prefix [str = ".afk"] - What should the prefix be for the chat commands? + + mafk_burps [bool = 1] - Should the player burp when the afk timer is up? + mafk_hud [bool = 1] - Should the message saying youre afk be shown on screen? + + mafk_user_times [bool = 0] - Should the user be able to specify a time to go afk for? + mafk_max_time [float = 15] - If user_times, what should the max time allowed be in minutes? + mafk_def_time [float = 15] - If user_times, what should the default time be if none is specified? + + mafk_time [float = 15] - If not user_times, what should the afk time be? if 0 then time is infinite. + + mafk_max_end [bool = 0] - End the game if everyone is either down or afk? + + mafk_cooldown [float = 15] - How many minutes should you have to wait before using afk again. +*/ + +#include maps\mp\_utility; +#include maps\mp\gametypes_zm\_hud_util; + +#include common_scripts\utility; +#include maps\mp\_demo; +#include maps\mp\_visionset_mgr; +#include maps\mp\gametypes_zm\_weapons; +#include maps\mp\gametypes_zm\_zm_gametype; +#include maps\mp\zombies\_zm; +#include maps\mp\zombies\_zm_ai_basic; +#include maps\mp\zombies\_zm_ai_dogs; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_audio_announcer; +#include maps\mp\zombies\_zm_blockers; +#include maps\mp\zombies\_zm_bot; +#include maps\mp\zombies\_zm_buildables; +#include maps\mp\zombies\_zm_clone; +#include maps\mp\zombies\_zm_devgui; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm_ffotd; +#include maps\mp\zombies\_zm_game_module; +#include maps\mp\zombies\_zm_gump; +#include maps\mp\zombies\_zm_laststand; +#include maps\mp\zombies\_zm_magicbox; +#include maps\mp\zombies\_zm_melee_weapon; +#include maps\mp\zombies\_zm_perks; +#include maps\mp\zombies\_zm_pers_upgrades; +#include maps\mp\zombies\_zm_pers_upgrades_system; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#include maps\mp\zombies\_zm_playerhealth; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\zombies\_zm_power; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_sidequests; +#include maps\mp\zombies\_zm_spawner; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zombies\_zm_timer; +#include maps\mp\zombies\_zm_tombstone; +#include maps\mp\zombies\_zm_traps; +#include maps\mp\zombies\_zm_unitrigger; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_zonemgr; + +// you know +init() { + + level.mafk_name = getDvarStringDefault("mafk_name", "[^6MAfk^7]"); + level.mafk_prefix = getDvarStringDefault("mafk_prefix", ".afk" ); + + level.mafk_burps = getDvarIntDefault("mafk_burps", 1) == 1; + level.mafk_hud = getDvarIntDefault("mafk_hud", 1) == 0; + + level.mafk_user_times = getDvarIntDefault("mafk_user_times", 0) == 1; + level.mafk_max_time = getDvarFloatDefault("mafk_max_time", 15); + level.mafk_def_time = getDvarFloatDefault("mafk_def_time", 15); + + level.mafk_time = getDvarFloatDefault("mafk_time", 15); + level.mafk_infinite = level.mafk_time == 0; + + level.mafk_max_end = getDVarIntDefault("mafk_max_end", 0) == 1; + + level.mafk_cooldown = (getDvarFloatDefault("mafk_cooldown", 15) * 60) * 1000; + + onPlayerSay(::hook_chat); + + /* if (level.mafk_max_end) { + level thread watchAllDownOrAFK(); + }*/ + + if (level.mafk_cooldown != 0) { + level thread watchCooldown(); + } +} + +// a default string dvar getter +// since this doesnt exist anywhere in the std +getDvarStringDefault(dvar, def) { + value = GetDVar(dvar); + + if (value != "") { + return value; + } + + return def; +} + +// trims the whitespace around a string +// only really used once but still +strtrim(str) { + padl = 0; + padr = 0; + for (i = 0; i < str.size; i++) { + if (str[i] == " ") { + padl = i; + } else { + break; + } + } + + for (i = 0; i < str.size; i++) { + if (str[str.size - i] == " ") { + padr = i; + } else { + break; + } + } + + return getSubStr(str, padl, str.size - padr); +} + +// this is manual modulo +// you dont have to tell me how stupid this is, i know! +// modulo is just refusing to work properly in some places +// and i have absolutely no idea why +// so have fun with this! +mod(num, modby) { + while (num >= modby) { + num = num - modby; + } + + return num; +} + +// floor function since it doesnt exist for some reason! +// modulo works here? +floor(num) { + return num - (num % 1); +} + +// formats a time from ms into a pretty string +// this can be improved obviously +fmttime(ms) { + ms = floor(ms); + seconds = mod(floor(ms / 1000), 60); + minutes = mod(floor((ms / 1000) / 60), 60); + hours = floor(floor((ms / 1000) / 60) / 60); + + if (hours) { + text = hours + " hour"; + + if (hours > 1) { + text = text + "s"; + } + + if (minutes) { + text = text + " and " + minutes + " minute"; + + if (minutes > 1) { + text = text + "s"; + } + } + + return text; + } + + if (minutes > 0) { + text = minutes + " minute"; + + if (minutes > 1) { + text = text + "s"; + } + + if (seconds) { + text = text + " and " + seconds + " second"; + + if (seconds > 1) { + text = text + "s"; + } + } + + return text; + } + + if (seconds > 1) { + return seconds + " seconds"; + } + + if (seconds == 1) { + return seconds + " second"; + } + + return "no time"; +} + +// watch for if every player is either down or afk +// if they are then end the game +watchAllDownOrAFK() { + level endon("game_ended"); + for(;;) { + players = getplayers(); + count = 0; + afk = 0; + + foreach(ply in players) { + if (!isAlive(ply)) { + count++; + } else if (ply.afk) { + count++; + afk++; + } + } + + if ((count == players.size) && (afk != 0)) { + level notify("end_game"); + } + + wait 5; + } +} + +// set the players cooldown +// this is separate from set_afk because +// we like to be a little efficient around these parts +watchCooldown() { + + for (;;) { + level endon("game_ended"); + self waittill("mafk_set", ply, val); + + if (val == false) { + ply.mafk_cooldown = getTime() + self.mafk_cooldown; + } + } +} + +// burps! but only if we want burps +burp() { + if (level.mafk_burps) { + self maps\mp\zombies\_zm_audio::playerexert("burp"); + } +} + +// sets the player to be afk or not, accepts a boolean +// this doesnt do anything except set some values on the player +// if you wish to extend anything use the notification +set_afk(value) { + self.afk = value; + self.afk_notify_half = false; + + if (value) + { + /* primaries = self getweaponslistprimaries(); + + if (primaries.size >= 1) + { + weapon1 = primaries[0]; + self.saved_weapon1 = maps/mp/zombies/_zm_weapons::get_player_weapondata(self, weapon1); + self Takeweapon(weapon1); + } + if (primaries.size >= 2) + { + weapon2 = primaries[1]; + self.saved_weapon2 = maps/mp/zombies/_zm_weapons::get_player_weapondata(self, weapon2); + self Takeweapon(weapon2); + } + if (primaries.size >= 3) + { + weapon3 = primaries[2]; + self.saved_weapon3 = maps/mp/zombies/_zm_weapons::get_player_weapondata(self, weapon3); + self Takeweapon(weapon3); + } + self setmovespeedscale(0); + self AllowMelee(0); + self AllowJump(0);*/ + self iPrintLn("Going ^3AFK^7 in ^23^7 seconds"); + wait 3; + iprintln(self.name + " ^7 is now ^3AFK^7"); + self thread keepPlayerFrozen(); + self.ignoreme = value; + self enableInvulnerability(); + self setplayercollision( 0 ); + } + else + { + /*if (primaries.size >= 1) + self maps/mp/zombies/_zm_weapons::weapondata_give(self.saved_weapon1); + if (primaries.size >= 2) + self maps/mp/zombies/_zm_weapons::weapondata_give(self.saved_weapon2); + if (primaries.size >= 3) + self maps/mp/zombies/_zm_weapons::weapondata_give(self.saved_weapon3); + self setmovespeedscale(1); + self AllowMelee(1); + self AllowJump(1); + + + weapon1 destroy(); + weapon2 destroy(); + weapon3 destroy(); + primaries destroy();*/ + iprintln(self.name + " ^7is no longer ^3AFK^7"); + self freezeControls(value); + self.ignoreme = value; + wait 3; + self disableInvulnerability(); + self setplayercollision( 1 ); + self notify("afkcancel"); + } + + level notify("mafk_set", self, value); +} + +// this is the actual logic behind the chat command +// just a series of checks +quick_afk_on(time) { + // is the player down + if (self.sessionstate == "spectator" || !isAlive(self)) { + self tell(level.mafk_name + " You must be alive to go AFK."); + return false; + } + + if (isDefined(self.mafk_cooldown)) { + if (self.mafk_cooldown >= getTime()) { + self tell(level.mafk_name + " You must wait ^4" + fmttime(self.mafk_cooldown - getTime()) + "^7 before going afk again."); + return false; + } + + self.mafk_cooldown = undefined; + } + + if (self.afk) { + if (isDefined(self.mafk_endtime)) { + self tell(level.mafk_name + " You are already AFK, if you would like to go un-afk type ^2.afk off"); + self tell(level.mafk_name + " You have ^4" + fmttime(self.mafk_endtime - getTime()) + "^7 left"); + } else { + self tell(level.mafk_name + " You have as long as you want to be afk."); + } + return false; + } + + if (level.mafk_infinite && !level.mafk_user_times) { + say(level.mafk_name + " " + self.name + " is going AFK in 3 seconds"); + wait 3; + say(level.mafk_name + " " + self.name + " has gone AFK."); + self set_afk(true); + + return false; + } + + say(level.mafk_name + " " + self.name + " has gone AFK for ^4" + fmttime((time * 60) * 1000)); + self tell(level.mafk_name + " You have gone AFK, if you would like to go un-afk type ^2.afk off"); + endtime = getTime() + ((time * 60) * 1000); + + self set_afk(true); + + self.mafk_endtime = endtime; + self thread check_afk_player(endtime); + + /* if (level.mafk_hud) { + self thread afk_player_hud(endtime, (time * 60) * 1000); + }*/ + + self burp(); + + return false; +} + +// what actually hooks onto chat +hook_chat(text, mode) { + text = strtrim(toLower(text)); + + split = strTok(text, " "); + + if (split[0] != level.mafk_prefix) { + return true; + } + + if ((split[1] == undefined) || (split[1] == "on")) { + if (level.mafk_user_times) { + return self quick_afk_on(level.mafk_def_time); + } else { + return self quick_afk_on(level.mafk_time); + } + return false; + } + + if (level.mafk_user_times) { + switch (split[1]) { + case "off": + self tell(level.mafk_name + " You're back!"); + self set_afk(false); + self notify("afkcancel"); + break; + case "time": + case "left": + if (self.afk) { + self tell(level.mafk_name + " You have ^4" + fmttime(self.mafk_endtime - getTime()) + "^7 left"); + } else { + self tell(level.mafk_name + " You are not afk."); + } + + break; + case "help": + self tell(level.mafk_name + " ^2" + level.mafk_prefix + " [number]^7 - Turns on afk for the given amount of time (^2" + mintime + "^7 to ^2" + level.mafk_max_time + "^7 minutes)"); + self tell(level.mafk_name + " ^2" + level.mafk_prefix + " off^7 - Turns off afk"); + self tell(level.mafk_name + " ^2" + level.mafk_prefix + " help^7 - Shows this message"); + self tell(level.mafk_name + " ^2" + level.mafk_prefix + " time^7 - Shows how long youre allowed to be afk"); + + break; + default: + mintime = 1; + time = int(split[1]); + + if ((time < mintime) || (time > level.mafk_max_time)) { + self tell(level.mafk_name + " Please give a valid time from ^2" + mintime + "^7 to ^2" + level.mafk_max_time + "^7 minutes"); + return false; + } + + return self quick_afk_on(time); + } + + return false; + } + + switch (split[1]) { + case "off": + self tell(level.mafk_name + " You're back!"); + self set_afk(false); + self notify("afkcancel"); + break; + case "time": + case "left": + if (self.afk) { + self tell(level.mafk_name + " You have ^4" + fmttime(self.mafk_endtime - getTime()) + "^7 left"); + } else { + self tell(level.mafk_name + " You are not afk."); + } + break; + case "help": + default: + self tell(level.mafk_name + " ^2" + level.mafk_prefix + " on^7 - Turns on afk"); + self tell(level.mafk_name + " ^2" + level.mafk_prefix + " off^7 - Turns off afk"); + self tell(level.mafk_name + " ^2" + level.mafk_prefix + " help^7 - Shows this message"); + self tell(level.mafk_name + " ^2" + level.mafk_prefix + " time^7 - Shows how much longer you can be afk"); + } + return false; +} + +// runs on the player to check if he should still be afk or not +check_afk_player(endtime) { + self endon("disconnect"); + self endon("afkcancel"); + level endon("game_ended"); + wait 1020; + self set_afk(false); + self tell(level.mafk_name + " Your AFK time has expired!"); + self burp(); + self.mafk_endtime = undefined; +} + +keepPlayerFrozen() +{ + self endon("disconnect"); + self endon("afkcancel"); + level endon ("game_ended"); + for (;;) + { + + if (self.afk == true) + { + self FreezeControls(1); + self.ignoreme = true; + self enableInvulnerability(); + self setplayercollision( 0 ); + } + else + { + self FreezeControls(0); + return; + } + wait 1; + } +} +/* +// only runs if mafk_hud is 1 +// draws the hud! +afk_player_hud(endtime, time) { + if (isDefined(self.mafk_hud)) { + return; + } + + level endon("game_ended"); + self endon("disconnect"); + + self.mafk_hud = createServerFontString("objective", 2); + self.mafk_hud setPoint("CENTER", "TOP", 0, 0); + self.mafk_hud setText("You are currently afk"); + + self.mafk_hud.hideWhenInMenu = 1; + + for(;;) { + if ((getTime() >= endtime) || !self.afk) { + self.mafk_hud destroy(); + break; + } + + // logic to make it slowly fade + self.mafk_hud.alpha = ((endtime - getTime()) / time) + 0.75; + + wait 0.50; + } +}*/ \ No newline at end of file diff --git a/t6/uncompiled mods/zmafkv2.gsc b/t6/uncompiled mods/zmafkv2.gsc new file mode 100644 index 0000000..38ebdd5 --- /dev/null +++ b/t6/uncompiled mods/zmafkv2.gsc @@ -0,0 +1,94 @@ +init() +{ + level thread onplayerconnect(); +} + +onplayerconnect() +{ + + for (;;) + { + level waittill( connecting, player ); + player.clientid = level.clientid; + level.clientid++; + player thread onplayerspawned(); + } + +} + +onplayerspawned() +{ + level endon( game_ended ); + self endon(disconnect); + old_origin = self.origin; + old_angles = self getPlayerAngles(); + wait 1; + afkc = 0; + cooldown = 0; + status = 1; + + for(;;) + { + old_origin = self.origin; + old_angles = self getPlayerAngles(); + wait 0.05; + + if(cooldown == 1) + { + wait 18000; + cooldown = 0; + status = 1; + } + else if(status == 1) + { + status = 0; + self thread print_to_all( self.name + is ^1AFK-Ready); + } + if(self adsbuttonpressed() && self ActionSlotTwoButtonPressed()) + { + self.ignoreme = 1; + self enableInvulnerability(); + old_origin = self.origin; + old_angles = self getPlayerAngles(); + self thread print_to_all( self.name + is ^1AFK ^7for ^1max. 5 Minutes); + afk = 0; + wait 5; + + + while(distance(old_origin, self.origin) = 20 old_angles != self getPlayerAngles() && afk == 0 && afkc < 18000) + { + if(self adsbuttonpressed() self ActionSlotFourButtonPressed() self attackbuttonpressed() self jumpbuttonpressed() self meleeButtonPressed() self throwbuttonpressed() self actionslotonebuttonpressed() self ActionSlotTwoButtonPressed() self ActionSlotThreeButtonPressed() self SprintButtonPressed() self ChangeSeatButtonPressed() self SecondaryOffhandButtonPressed() self FragButtonPressed() self UseButtonPressed()){afk = 1;} + old_angles = self getPlayerAngles(); + afkc++; + wait 0.05; + } + + self thread print_to_all( self.name + is no longer ^1AFK^7,^1 30^7 Minutes ^1cooldown); + self.sessionstate = playing; + self.ignoreme = 0; + self disableInvulnerability(); + afkc = 0; + cooldown = 1; + } + } +} + +endgame_fix(){ + self endon(disconnect); + level endon(end_game); + level waittill(connected, player); + for(;;){ + wait 1; + counter = 0; + foreach(player in level.players){ + if(player.sessionstate == spectator !isAlive(player)) + counter++; + } + if(counter == level.players.size) + level notify(end_game); + } +} +print_to_all( msg ){ + foreach( player in level.players) + player iprintln( msg ); +} \ No newline at end of file diff --git a/t6/uncompiled mods/zmcounterhealthwatermark.gsc b/t6/uncompiled mods/zmcounterhealthwatermark.gsc new file mode 100644 index 0000000..add9156 --- /dev/null +++ b/t6/uncompiled mods/zmcounterhealthwatermark.gsc @@ -0,0 +1,194 @@ +init() +{ + setDvar("hide", ""); + level thread onPlayerConnect(); + level thread hideHUD(); +} + +onPlayerConnect() +{ + for(;;) + { + level waittill("connected", player); + // player thread isLobbyClaimed(); + player thread healthCounter(); + player thread zombieCounter(); + player thread discordWatermark(); + } +} + +hideHUD() +{ + level endon("game_ended"); + for (;;) { + if (getDvar("hide") != "") + { + hide = strTok(getDvar("hide"), ";"); + setDvar("hide", ""); + client = getPlayerByGuid(hide[0]); + if (hide[1] == "off") + { + client.zombieText2.alpha = 0; + client.zombieText3.alpha = 0; + client.zombieText4.alpha = 0; + client.zombieText5.alpha = 0; + client.zombieText6.alpha = 0; + client.zombieText7.alpha = 0; + client.zombieText8.alpha = 0; + client.zombieText9.alpha = 0; + client.zombieText10.alpha = 0; + client.zombieText11.alpha = 0; + client iPrintLn("^3HUD ^1OFF^7"); + } + if (hide[1] == "on") + { + client.zombieText2.alpha = 0.7; + client.zombieText3.alpha = 0.7; + client.zombieText4.alpha = 0.7; + client.zombieText5.alpha = 0.7; + client.zombieText6.alpha = 0.7; + client.zombieText7.alpha = 0.7; + client.zombieText8.alpha = 0.7; + client.zombieText9.alpha = 0.7; + client.zombieText10.alpha = 0.7; + client.zombieText11.alpha = 0.7; + client iPrintLn("^3HUD ^2ON^7"); + } + } + wait 0.5; + } +} +/*isLobbyClaimed() +{ + self endon ("disconnect"); + level endon( "end_game" ); + + common_scripts\utility::flag_wait( "initial_blackscreen_passed" ); + self.zombieText12 = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1 ); + self.zombieText12 maps\mp\gametypes_zm\_hud_util::setPoint( "TOP", "LEFT", 0, -145 ); + self.zombieText12.label = &"^5 Is Lobby Claimed ?^7 ~ ^1[NO] ^7YES ~"; + self.zombieText12.alpha = 0.7; + + self.zombieText13 = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1 ); + self.zombieText13 maps\mp\gametypes_zm\_hud_util::setPoint( "TOP", "LEFT", 0, -135 ); + self.zombieText13.label = &"^3use ^2.save [1-2]^7 to ^3claim it!^7"; + self.zombieText13.alpha = 0.7; + + for (;;) + { + if (getDvar("isSaved") != "0") + { + self.zombieText12.alpha = 0; + self.zombieText13.alpha = 0; + } + wait 1; + } +}*/ + +healthCounter() +{ + self endon("disconnect"); + level endon( "end_game" ); + common_scripts\utility::flag_wait( "initial_blackscreen_passed" ); + self.healthText = maps\mp\gametypes_zm\_hud_util::createFontString ("hudsmall", 1.5); + self.healthText maps\mp\gametypes_zm\_hud_util::setPoint ("CENTER", "CENTER", 100, 220); + self.healthText.label = &"Health: ^2"; + while ( 1 ) + { + self.healthText setValue(self.health); + wait 0.25; + } +} + +zombieCounter() +{ + self endon( "disconnect" ); + level endon( "end_game" ); + common_scripts\utility::flag_wait( "initial_blackscreen_passed" ); + self.zombieText = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1.5 ); + self.zombieText maps\mp\gametypes_zm\_hud_util::setPoint( "CENTER", "CENTER", -100, 220 ); + while( 1 ) + { + self.zombieText setValue( ( maps\mp\zombies\_zm_utility::get_round_enemy_array().size + level.zombie_total ) ); + if( ( maps\mp\zombies\_zm_utility::get_round_enemy_array().size + level.zombie_total ) != 0 ) + { + self.zombieText.label = &"Zombies: ^1"; + } + else + { + self.zombieText.label = &"Zombies: ^6"; + } + wait 0.25; + } +} + +discordWatermark() +{ + self endon( "disconnect" ); + level endon( "end_game" ); + + common_scripts\utility::flag_wait( "initial_blackscreen_passed" ); + self.zombieText2 = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1.5 ); + self.zombieText2 maps\mp\gametypes_zm\_hud_util::setPoint( "TOP", "LEFT", 0, -230 ); + self.zombieText2.label = &"Join the ^3Tavern"; + self.zombieText2.alpha = 0.7; + + self.zombieText3 = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1.5 ); + self.zombieText3 maps\mp\gametypes_zm\_hud_util::setPoint( "TOP", "LEFT", 0, -214 ); + self.zombieText3.label = &"^5discord.gg/ZTavern"; + self.zombieText3.alpha = 0.7; + + self.zombieText4 = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1 ); + self.zombieText4 maps\mp\gametypes_zm\_hud_util::setPoint( "TOP", "LEFT", 0, -195 ); + self.zombieText4.label = &"to get ^2200K POINTS"; + self.zombieText4.alpha = 0.7; + + self.zombieText5 = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1 ); + self.zombieText5 maps\mp\gametypes_zm\_hud_util::setPoint( "TOP", "RIGHT", 0, -225 ); + self.zombieText5.label = &"Use ^3.c ^7for commands"; + self.zombieText5.alpha = 0.7; + + self.zombieText6 = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1 ); + self.zombieText6 maps\mp\gametypes_zm\_hud_util::setPoint( "TOP", "RIGHT", 0, -212 ); + self.zombieText6.label = &"FR ^3.c fr ^7pour les commandes^7"; + self.zombieText6.alpha = 0.7; + + self.zombieText7 = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1 ); + self.zombieText7 maps\mp\gametypes_zm\_hud_util::setPoint( "TOP", "RIGHT", 0, -195 ); + self.zombieText7.label = &"^3[.rank] [.rankup] ^6[.d] [.w] ^2[.afk]"; + self.zombieText7.alpha = 0.7; + + self.zombieText8 = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1 ); + self.zombieText8 maps\mp\gametypes_zm\_hud_util::setPoint( "TOP", "RIGHT", 0, -185 ); + self.zombieText8.label = &"^5[.buy] [.buy hp] [.buy speed] [.^1flex^5]^7"; + self.zombieText8.alpha = 0.7; + + self.zombieText9 = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1 ); + self.zombieText9 maps\mp\gametypes_zm\_hud_util::setPoint( "TOP", "RIGHT", 0, -172 ); + self.zombieText9.label = &"^3[.save] [.load] ^6[.hud] [.kill]"; + self.zombieText9.alpha = 0.7; + + self.zombieText10 = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1 ); + self.zombieText10 maps\mp\gametypes_zm\_hud_util::setPoint( "TOP", "RIGHT", 0, -160 ); + self.zombieText10.label = &"^3VIP/HIGH RANK COMMANDS^7"; + self.zombieText10.alpha = 0.7; + + self.zombieText11 = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1 ); + self.zombieText11 maps\mp\gametypes_zm\_hud_util::setPoint( "TOP", "RIGHT", 0, -145 ); + self.zombieText11.label = &"^1[.rev] [.drop] [.king]"; + self.zombieText11.alpha = 0.7; + + /* self.zombieText11 = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1 ); + self.zombieText11 maps\mp\gametypes_zm\_hud_util::setPoint( "TOP", "RIGHT", 0, -130 ); + self.zombieText11.label = &"^5 SEASON 1 -20 ON ALL SHOP"; + self.zombieText11.alpha = 0.7;*/ +} + +getPlayerByGuid(guid) { + for (i = 0; i < level.players.size; i++) { + if (isAlive(level.players[i]) && int(level.players[i] getGuid()) == int(guid)) { + return level.players[i]; + } + } + return false; +} \ No newline at end of file diff --git a/t6/uncompiled mods/zombiecounter-compiled.gsc b/t6/uncompiled mods/zombiecounter-compiled.gsc new file mode 100644 index 0000000000000000000000000000000000000000..b289e59d6e10205166bd9dd6741e246ec778d5a6 GIT binary patch literal 780 zcmZXSKWGzS7{;G3e+r&j0~zF|reI2zG}`zFL5v_)k)mRvf=a^m@|j$`f81Sa+Cht> zQ*{tDj={k}oE^kjgl-+BIFxqHkiic6e7QgsKX~{(@B4o5bGdNqSF4wgYM27gc>#11 zF@18HTA+?3W2rlrFpVTq%8t*P=PX;&^tx^&16ZyV!E=4vSe1e4xvn%LvmD6*R5T^n&ISgWHY~JdPXj9#aAZWKm=<+i{{=oq$*P)5FIxe;nNZ(-@mVhy&jENxt8GZ(dGu3oMgD>86l z*nZpi>!Ay%pPBs5`Bv-xs0C;{Vo-s9)!5Y%4Eh8>5{j}4bmq2WI%2+>nZt- z8XzTJkZ-9E)MskM`781VHKcz{{-lHucu(#lAwH77sH{kcFQmqASr;j>MZZIhs44dH I+!@mU0dvf!*Z=?k literal 0 HcmV?d00001 diff --git a/t6/uncompiled mods/zombiecounter.gsc b/t6/uncompiled mods/zombiecounter.gsc new file mode 100644 index 0000000..b1333bf --- /dev/null +++ b/t6/uncompiled mods/zombiecounter.gsc @@ -0,0 +1,32 @@ +init() +{ + level thread onPlayerConnect(); +} + +onPlayerConnect() +{ + level endon("game_ended"); + for(;;) + { + level waittill("connected", player); + player thread discordWatermark(); + } +} + + +discordWatermark() +{ + self endon( "disconnect" ); + level endon( "end_game" ); + + self.zombieText1 = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1.5 ); + self.zombieText1 maps\mp\gametypes_zm\_hud_util::setPoint( "TOP", "LEFT", 0, -230 ); + self.zombieText1.label = &"Join the ^3Tavern"; + self.zombieText1.alpha = 0.7; + + self.zombieText2 = maps\mp\gametypes_zm\_hud_util::createFontString( "hudsmall" , 1.5 ); + self.zombieText2 maps\mp\gametypes_zm\_hud_util::setPoint( "TOP", "LEFT", 0, -214 ); + self.zombieText2.label = &"^5discord.gg\ZTavern"; + self.zombieText2.alpha = 0.7; + +}