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 0000000..e5b1500 Binary files /dev/null and b/bo2/binkw32.dll differ 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 0000000..66725e7 Binary files /dev/null and b/bo2/getCmdPID.exe differ diff --git a/bo2/wlanapi.dll b/bo2/wlanapi.dll new file mode 100644 index 0000000..07a84d3 Binary files /dev/null and b/bo2/wlanapi.dll differ diff --git a/node-server-manager/Configuration/NSMConfiguration.json b/node-server-manager/Configuration/NSMConfiguration.json new file mode 100644 index 0000000..3cd30c4 --- /dev/null +++ b/node-server-manager/Configuration/NSMConfiguration.json @@ -0,0 +1,192 @@ +{ + "Webfront": false, + "WebfrontPort": 8000, + "WebfrontSSL": false, + "WebfrontSSL-Key": "", + "WebfrontSSL-Cert": "", + "webfrontHostname": "", + "discordHookUrl": "", + "discordSecret": "", + "discordClientId": "", + "discordOAuth2Url": "", + "discordBotToken": "", + "MOTD": "Welcome", + "Info": "", + "commandPrefixes": [ + "." + ], + "broadcastCommandPrefixes": [ + "@" + ], + "links": [ + "" + ], + "socialMedia": [], + "rules": [], + "locale": "en", + "autoMessagesInterval": 300, + "autoMessages": [ + "A total of ^5{TOTALCLIENTS}^7 players have played on this server", + "Server maintenance every ^36 hours^7 do ^3.ut", + "Server maintenance every ^36 hours^7 do ^3.ut", + "There are ^5{PLAYERCOUNT}^7 online players across ^5{SERVERCOUNT}^7 servers at the moment", + "^5{TOTALPLAYEDTIME}^7 hours have been wasted playing on this server" + ], + "Servers": [ + { + "IP": "127.0.0.1", + "PORT": "30001", + "PASSWORD": "rconAQW25wqa", + "LOGFILE": "C:\\Users\\Administrator\\AppData\\Local\\Plutonium\\storage\\t6\\logs\\games_zmbrutus.log", + "Gamename": "T6", + "reservedSlots": 0 + }, + { + "IP": "127.0.0.1", + "PORT": "30002", + "PASSWORD": "rconAQW25wqa", + "LOGFILE": "C:\\Users\\Administrator\\AppData\\Local\\Plutonium\\storage\\t6\\logs\\games_zmburied.log", + "Gamename": "T6", + "reservedSlots": 0 + }, + { + "IP": "127.0.0.1", + "PORT": "30003", + "PASSWORD": "rconAQW25wqa", + "LOGFILE": "C:\\Users\\Administrator\\AppData\\Local\\Plutonium\\storage\\t6\\logs\\games_zmdierise.log", + "Gamename": "T6", + "reservedSlots": 0 + }, + { + "IP": "127.0.0.1", + "PORT": "30004", + "PASSWORD": "rconAQW25wqa", + "LOGFILE": "C:\\Users\\Administrator\\AppData\\Local\\Plutonium\\storage\\t6\\logs\\games_zmmotd.log", + "Gamename": "T6", + "reservedSlots": 0 + }, + { + "IP": "127.0.0.1", + "PORT": "30005", + "PASSWORD": "rconAQW25wqa", + "LOGFILE": "C:\\Users\\Administrator\\AppData\\Local\\Plutonium\\storage\\t6\\logs\\games_zmprivate.log", + "Gamename": "T6", + "reservedSlots": 0 + }, + { + "IP": "127.0.0.1", + "PORT": "30006", + "PASSWORD": "rconAQW25wqa", + "LOGFILE": "C:\\Users\\Administrator\\AppData\\Local\\Plutonium\\storage\\t6\\logs\\games_zmnuketown.log", + "Gamename": "T6", + "reservedSlots": 0 + }, + { + "IP": "127.0.0.1", + "PORT": "30007", + "PASSWORD": "rconAQW25wqa", + "LOGFILE": "C:\\Users\\Administrator\\AppData\\Local\\Plutonium\\storage\\t6\\logs\\games_zmorigin.log", + "Gamename": "T6", + "reservedSlots": 0 + }, + { + "IP": "127.0.0.1", + "PORT": "30008", + "PASSWORD": "rconAQW25wqa", + "LOGFILE": "C:\\Users\\Administrator\\AppData\\Local\\Plutonium\\storage\\t6\\logs\\games_zmorigin2.log", + "Gamename": "T6", + "reservedSlots": 0 + }, + { + "IP": "127.0.0.1", + "PORT": "30009", + "PASSWORD": "rconAQW25wqa", + "LOGFILE": "C:\\Users\\Administrator\\AppData\\Local\\Plutonium\\storage\\t6\\logs\\games_zmorigin3.log", + "Gamename": "T6", + "reservedSlots": 0 + }, + { + "IP": "127.0.0.1", + "PORT": "30010", + "PASSWORD": "rconAQW25wqa", + "LOGFILE": "C:\\Users\\Administrator\\AppData\\Local\\Plutonium\\storage\\t6\\logs\\games_zmpanzer.log", + "Gamename": "T6", + "reservedSlots": 0 + }, + { + "IP": "127.0.0.1", + "PORT": "30011", + "PASSWORD": "rconAQW25wqa", + "LOGFILE": "C:\\Users\\Administrator\\AppData\\Local\\Plutonium\\storage\\t6\\logs\\games_zmtitb.log", + "Gamename": "T6", + "reservedSlots": 0 + }, + { + "IP": "127.0.0.1", + "PORT": "30012", + "PASSWORD": "rconAQW25wqa", + "LOGFILE": "C:\\Users\\Administrator\\AppData\\Local\\Plutonium\\storage\\t6\\logs\\games_zmtown.log", + "Gamename": "T6", + "reservedSlots": 0 + }, + { + "IP": "127.0.0.1", + "PORT": "30013", + "PASSWORD": "rconAQW25wqa", + "LOGFILE": "C:\\Users\\Administrator\\AppData\\Local\\Plutonium\\storage\\t6\\logs\\games_zmtown2.log", + "Gamename": "T6", + "reservedSlots": 0 + }, + { + "IP": "127.0.0.1", + "PORT": "30014", + "PASSWORD": "rconAQW25wqa", + "LOGFILE": "C:\\Users\\Administrator\\AppData\\Local\\Plutonium\\storage\\t6\\logs\\games_zmtown3.log", + "Gamename": "T6", + "reservedSlots": 0 + }, + { + "IP": "127.0.0.1", + "PORT": "30015", + "PASSWORD": "rconAQW25wqa", + "LOGFILE": "C:\\Users\\Administrator\\AppData\\Local\\Plutonium\\storage\\t6\\logs\\games_zmtranzit.log", + "Gamename": "T6", + "reservedSlots": 0 + } + ], + "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" + } + } +} \ No newline at end of file diff --git a/node-server-manager/Lib/CLICommands.js b/node-server-manager/Lib/CLICommands.js new file mode 100644 index 0000000..00e31f1 --- /dev/null +++ b/node-server-manager/Lib/CLICommands.js @@ -0,0 +1,84 @@ +const path = require('path') +const readline = require('readline') +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 + +const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, + terminal: false +}) + +class CLICommands { + constructor(Manager, Managers) { + this.Managers = Managers + this.Player = { + Name: 'Node Server Manager', + ClientId: 1, + inGame: false, + PermissionLevel: Permissions.Levels['ROLE_MANAGER'], + Tell: (msg) => { + 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 0000000..107a91b Binary files /dev/null and b/node-server-manager/Lib/Entity/give_tb-compiled.gsc differ 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 0000000..011a3d8 Binary files /dev/null and b/node-server-manager/Lib/Entity/setround-compiled.gsc differ diff --git a/node-server-manager/Lib/Entity/statsaprilfool-compiled.gsc b/node-server-manager/Lib/Entity/statsaprilfool-compiled.gsc new file mode 100644 index 0000000..818d69f Binary files /dev/null and b/node-server-manager/Lib/Entity/statsaprilfool-compiled.gsc differ diff --git a/node-server-manager/Lib/EventDispatcher.js b/node-server-manager/Lib/EventDispatcher.js new file mode 100644 index 0000000..11164b0 --- /dev/null +++ b/node-server-manager/Lib/EventDispatcher.js @@ -0,0 +1,118 @@ +const { randomInt } = require('crypto') +const ePlayer = require('./Entity/Player.js') +const wait = require('delay') + +class EventDispatcher { + constructor(Server, Manager) { + this.Server = Server + this.Manager = Manager + } + async dispatchCallback(event) { + if (!event) return + + try { + this.Server.emit('event', event) + this.Server.uptime = event.data.TimeOffset + + if (this.Server.previousUptime > 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 0000000..4c89869 Binary files /dev/null and b/node-server-manager/Plugins/.vs/Plugins/FileContentIndex/e799e520-62cc-4ff1-bc4c-1cb0816c9aaa.vsidx differ 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 0000000..7d063f7 Binary files /dev/null and b/node-server-manager/Plugins/.vs/Plugins/v17/.wsuo differ diff --git a/node-server-manager/Plugins/.vs/VSWorkspaceState.json b/node-server-manager/Plugins/.vs/VSWorkspaceState.json new file mode 100644 index 0000000..6b61141 --- /dev/null +++ b/node-server-manager/Plugins/.vs/VSWorkspaceState.json @@ -0,0 +1,6 @@ +{ + "ExpandedNodes": [ + "" + ], + "PreviewInSolutionExplorer": false +} \ No newline at end of file diff --git a/node-server-manager/Plugins/.vs/slnx.sqlite b/node-server-manager/Plugins/.vs/slnx.sqlite new file mode 100644 index 0000000..3c963ae Binary files /dev/null and b/node-server-manager/Plugins/.vs/slnx.sqlite differ 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 0000000..d4d34f6 Binary files /dev/null and b/t6/compiled/t6/_zm_ai_brutus.gsc differ diff --git a/t6/compiled/t6/panzerwave.gsc b/t6/compiled/t6/panzerwave.gsc new file mode 100644 index 0000000..b63c8c6 Binary files /dev/null and b/t6/compiled/t6/panzerwave.gsc differ diff --git a/t6/compiled/t6/zm_alcatraz_brutus.gsc b/t6/compiled/t6/zm_alcatraz_brutus.gsc new file mode 100644 index 0000000..7a96074 Binary files /dev/null and b/t6/compiled/t6/zm_alcatraz_brutus.gsc differ diff --git a/t6/dedicated_zmbrutus.cfg b/t6/dedicated_zmbrutus.cfg new file mode 100644 index 0000000..3a52239 --- /dev/null +++ b/t6/dedicated_zmbrutus.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 "Flawless" // 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_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 0000000..b68a159 Binary files /dev/null and b/t6/maps/mp/zombies/_zm_ai_avogadro.gsc differ 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 0000000..9a4fa25 Binary files /dev/null and b/t6/maps/mp/zombies/_zm_weap_slowgun.gsc differ diff --git a/t6/maps/zm_tomb_craftables.gsc b/t6/maps/zm_tomb_craftables.gsc new file mode 100644 index 0000000..fcfaec0 Binary files /dev/null and b/t6/maps/zm_tomb_craftables.gsc differ diff --git a/t6/plugins/ClanTagRank.dll b/t6/plugins/ClanTagRank.dll new file mode 100644 index 0000000..88ca1d2 Binary files /dev/null and b/t6/plugins/ClanTagRank.dll differ diff --git a/t6/plugins/t6-gsc-utils.dll b/t6/plugins/t6-gsc-utils.dll new file mode 100644 index 0000000..6127498 Binary files /dev/null and b/t6/plugins/t6-gsc-utils.dll differ diff --git a/t6/scripts/.vs/VSWorkspaceState.json b/t6/scripts/.vs/VSWorkspaceState.json new file mode 100644 index 0000000..3614325 --- /dev/null +++ b/t6/scripts/.vs/VSWorkspaceState.json @@ -0,0 +1,9 @@ +{ + "ExpandedNodes": [ + "", + "\\zm\\zm_prison", + "\\zm\\zm_tomb", + "\\zm\\zm_transit" + ], + "PreviewInSolutionExplorer": false +} \ No newline at end of file diff --git a/t6/scripts/.vs/scripts/FileContentIndex/c5d3733d-6424-4e4b-82ab-a8dda1e2dbef.vsidx b/t6/scripts/.vs/scripts/FileContentIndex/c5d3733d-6424-4e4b-82ab-a8dda1e2dbef.vsidx new file mode 100644 index 0000000..ed2b478 Binary files /dev/null and b/t6/scripts/.vs/scripts/FileContentIndex/c5d3733d-6424-4e4b-82ab-a8dda1e2dbef.vsidx differ diff --git a/t6/scripts/.vs/scripts/v17/.wsuo b/t6/scripts/.vs/scripts/v17/.wsuo new file mode 100644 index 0000000..32c435d Binary files /dev/null and b/t6/scripts/.vs/scripts/v17/.wsuo differ diff --git a/t6/scripts/.vs/scripts/v17/DocumentLayout.json b/t6/scripts/.vs/scripts/v17/DocumentLayout.json new file mode 100644 index 0000000..aa59dec --- /dev/null +++ b/t6/scripts/.vs/scripts/v17/DocumentLayout.json @@ -0,0 +1,12 @@ +{ + "Version": 1, + "WorkspaceRootPath": "C:\\Users\\Administrator\\AppData\\Local\\Plutonium\\storage\\t6\\scripts\\", + "Documents": [], + "DocumentGroupContainers": [ + { + "Orientation": 0, + "VerticalTabListWidth": 256, + "DocumentGroups": [] + } + ] +} \ No newline at end of file diff --git a/t6/scripts/.vs/slnx.sqlite b/t6/scripts/.vs/slnx.sqlite new file mode 100644 index 0000000..d332548 Binary files /dev/null and b/t6/scripts/.vs/slnx.sqlite differ 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 0000000..e296fee Binary files /dev/null and b/t6/scripts/zm/.vs/slnx.sqlite differ diff --git a/t6/scripts/zm/.vs/zm/FileContentIndex/1f61263b-7daa-48a5-a4a7-1c01623509e9.vsidx b/t6/scripts/zm/.vs/zm/FileContentIndex/1f61263b-7daa-48a5-a4a7-1c01623509e9.vsidx new file mode 100644 index 0000000..217ee77 Binary files /dev/null and b/t6/scripts/zm/.vs/zm/FileContentIndex/1f61263b-7daa-48a5-a4a7-1c01623509e9.vsidx differ diff --git a/t6/scripts/zm/.vs/zm/v17/.wsuo b/t6/scripts/zm/.vs/zm/v17/.wsuo new file mode 100644 index 0000000..9194483 Binary files /dev/null and b/t6/scripts/zm/.vs/zm/v17/.wsuo differ 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 0000000..b75ccba Binary files /dev/null and b/t6/uncompiled mods/8playerhud-compiled.gsc differ diff --git a/t6/uncompiled mods/8playerhud.gsc b/t6/uncompiled mods/8playerhud.gsc new file mode 100644 index 0000000..6632422 --- /dev/null +++ b/t6/uncompiled mods/8playerhud.gsc @@ -0,0 +1,59 @@ +#include maps/mp/gametypes_zm/_hud_message; +#include maps/mp/gametypes_zm/_hud_util; + +onplayerconnected() +{ + for ( ;; ) + { + level waittill( "connected", player ); + player thread displayScore(); //add this line + } +} + +toggleScore() +{ + //self waittill("spawned_player"); + if(!isDefined(self.scoretext)) + { + self.scoreText = CreateFontString("Objective", 1.5); + self.scoretext setPoint("CENTER", "RIGHT", "CENTER", "RIGHT"); + self.scoreText.label = &"^2Score: ^7"; + self.scoretext.alpha = 0; + } + else if(getplayers().size >= 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 0000000..7f57215 Binary files /dev/null and b/t6/uncompiled mods/Compiler.exe differ diff --git a/t6/uncompiled mods/Irony.dll b/t6/uncompiled mods/Irony.dll new file mode 100644 index 0000000..ebb1fe5 Binary files /dev/null and b/t6/uncompiled mods/Irony.dll differ 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 0000000..7f57215 Binary files /dev/null and b/t6/uncompiled mods/Zompiler.exe differ diff --git a/t6/uncompiled mods/_clientids.gsc b/t6/uncompiled mods/_clientids.gsc new file mode 100644 index 0000000..2b8c2ab --- /dev/null +++ b/t6/uncompiled mods/_clientids.gsc @@ -0,0 +1,198 @@ +#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() { + 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 -- + diff --git a/t6/uncompiled mods/_zm_magicbox.gsc b/t6/uncompiled mods/_zm_magicbox.gsc new file mode 100644 index 0000000..c604f4d Binary files /dev/null and b/t6/uncompiled mods/_zm_magicbox.gsc differ 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 0000000..2a7b44f Binary files /dev/null and b/t6/uncompiled mods/_zm_weapon_locker-compiled.gsc differ diff --git a/t6/uncompiled mods/_zm_weapon_locker.gsc b/t6/uncompiled mods/_zm_weapon_locker.gsc new file mode 100644 index 0000000..3a01107 --- /dev/null +++ b/t6/uncompiled mods/_zm_weapon_locker.gsc @@ -0,0 +1,530 @@ +#include maps/mp/zombies/_zm_audio; +#include maps/mp/zombies/_zm_unitrigger; +#include maps/mp/zombies/_zm_stats; +#include maps/mp/zombies/_zm_weapons; +#include maps/mp/zombies/_zm_magicbox; +#include maps/mp/zombies/_zm_utility; +#include maps/mp/_utility; +#include common_scripts/utility; + +saveLockerWeapon() { + level endon("eng_game"); + self endon("disconnect"); + for (;;) { + if (self.changedWeaponData) { + self.changedWeaponData = false; + self logWeaponData(); + } + wait 5; + } +} + +logWeaponData() { + lockerEvent = []; + lockerEvent["event"] = "locker_set"; + lockerEvent["player"] = []; + lockerEvent["player"]["Guid"] = self.guid; + lockerEvent["weapondata"] = self._weapondata; + + logPrint(json_encode(lockerEvent)); +} + +main() +{ + if (getDvar("g_gametype") != "zclassic") { + return; + } + if (getDvar("mapname") != "zm_buried" && getDvar("mapname") != "zm_highrise" && getDvar("mapname") != "zm_transit") { + return; + } + if ( !isDefined( level.weapon_locker_map ) ) + { + level.weapon_locker_map = level.script; + } + weapon_lockers = getstructarray( "weapons_locker", "targetname" ); + array_thread( weapon_lockers, ::triggerweaponslockerwatch ); +} + +updateLockerWeapon() { + level endon("end_game"); + self endon("disconnect"); + for (;;) { + if (getDvar(self getGuid() + "_update") != "") { + dvar = getDvar(self getGuid() + "_update"); + setDvar(self getGuid() + "_update", ""); + + self._weapondata = parseWeaponData(dvar); + self thread triggerweaponslockerweaponchangethink(); + } + wait 0.5; + } +} + +wl_has_stored_weapondata() +{ + if (!isDefined(self.gotweapondata)) { + self wl_get_stored_weapondata(); + self.changedWeaponData = false; + self thread updateLockerWeapon(); + self thread saveLockerWeapon(); + self.gotweapondata = true; + } + + return isDefined(self._weapondata); +} + +parseWeaponData(string) { + weaponraw = strTok(string, ","); + + if (weaponraw.size < 11) { + return undefined; + } + + weapondata = []; + + weapondata["alt_stock"] = weaponraw[0]; + weapondata["alt_clip"] = weaponraw[1]; + weapondata["lh_clip"] = weaponraw[2]; + weapondata["overheat"] = weaponraw[3]; + weapondata["heat"] = weaponraw[4]; + weapondata["fuel"] = weaponraw[5]; + weapondata["stock"] = weaponraw[6]; + weapondata["clip"] = weaponraw[7]; + weapondata["alt_name"] = weaponraw[8]; + weapondata["dw_name"] = weaponraw[9]; + weapondata["name"] = weaponraw[10]; + + return weapondata; +} + +wl_get_stored_weapondata() +{ + if (isDefined(self.gotdvar) || isDefined(self._weapondata)) { + return self._weapondata; + } + + dvarValue = getDvar(self getGuid() + "_weapondata"); + self.gotdvar = true; + + if (strTok(dvarValue, ",").size < 11) { + self._weapondata = undefined; + return self._weapondata; + } + + self._weapondata = parseWeaponData(dvarValue); + + return self._weapondata; +} + +wl_clear_stored_weapondata() +{ + self._weapondata = undefined; + self.canuselocker = false; + self logWeaponData(); + self thread resetLockerUse(); +} + +resetLockerUse() { + wait 3; + self.canuselocker = true; +} + +wl_set_stored_weapondata( weapondata ) +{ + self._weapondata = weapondata; + self.canuselocker = false; + self logWeaponData(); + self thread resetLockerUse(); +} + +triggerweaponslockerwatch() +{ + 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 ); +} + +is_weapon_included( weapon_name ) //checked matches cerberus output +{ + if ( !isDefined( level.zombie_weapons ) ) + { + return 0; + } + return isDefined( level.zombie_weapons[ weapon_name ] ); +} + +get_nonalternate_weapon( altweapon ) //checked changed to match cerberus output +{ + if ( is_alt_weapon( altweapon ) ) + { + alt = weaponaltweaponname( altweapon ); + if ( alt == "none" ) + { + primaryweapons = self getweaponslistprimaries(); + alt = primaryweapons[ 0 ]; + foreach ( weapon in primaryweapons ) + { + if ( weaponaltweaponname( weapon ) == altweapon ) + { + alt = weapon; + break; + } + } + } + return alt; + } + return altweapon; +} + +triggerweaponslockerisvalidweaponpromptupdate( player, weaponname ) +{ + if (isDefined(player.canuselocker) && !player.canuselocker) { + self sethintstring( &"ZOMBIE_WEAPON_LOCKER_DENY" ); + return; + } + + 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 + { + 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) + { + 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 0000000..34ac9ae Binary files /dev/null and b/t6/uncompiled mods/bo2_aats-compiled.gsc differ 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 0000000..5e55e00 Binary files /dev/null and b/t6/uncompiled mods/custom_perk_powerup-compiled.gsc differ diff --git a/t6/uncompiled mods/custom_perk_powerup.gsc b/t6/uncompiled mods/custom_perk_powerup.gsc new file mode 100644 index 0000000..c57210d --- /dev/null +++ b/t6/uncompiled mods/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 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.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") + { + 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 0000000..82a0312 Binary files /dev/null and b/t6/uncompiled mods/infinite_money-compiled.gsc differ 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 0000000..f619b02 Binary files /dev/null and b/t6/uncompiled mods/multiply_points-compiled.gsc differ 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 0000000..0cc1ec3 Binary files /dev/null and b/t6/uncompiled mods/no_fog-compiled.gsc differ 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 0000000..aff0b04 Binary files /dev/null and b/t6/uncompiled mods/perma_perks_on_all_maps-compiled.gsc differ 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 0000000..c3b1a4b Binary files /dev/null and b/t6/uncompiled mods/show_position-compiled.gsc differ diff --git a/t6/uncompiled mods/show_position.gsc b/t6/uncompiled mods/show_position.gsc new file mode 100644 index 0000000..41bb81d --- /dev/null +++ b/t6/uncompiled mods/show_position.gsc @@ -0,0 +1,42 @@ +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_spawner; +#include maps\mp\zombies\_zm; +#include maps\mp\gametypes_zm\_hud_util; + +init() { + level thread on_player_connect(); +} + +on_player_connect() { + for(;;) { + level waittill("connected", player); + player thread show_pos_text(); + } +} + +show_pos_text() { + self endon("disconnect"); + level endon("end_game"); + flag_wait( "initial_blackscreen_passed" ); + + debug_position_label_epic = createFontString("default", 1.5); + debug_position_label_epic setPoint("TOPLEFT", "TOPLEFT", 15, 15); + for (;;) { + /*self.str = ""; + if (isDefined(level.zombie_spawn_locations)) { + self.str += "level.zombie_spawn_locations:\n"; + foreach(position in level.zombie_spawn_locations) { + if (isDefined(position)) { + self.str += "Position: " + position.origin + "\n"; + } + } + }*/ + + local_origin = self getorigin(); + local_angles = self getplayerangles(); + self iprintln("Position: " + local_origin + "\nAngles: " + local_angles); + //debug_position_label_epic settext("Position: " + local_origin + "\nAngles: " + local_angles); + wait 5; + } +} diff --git a/t6/uncompiled mods/sliquifier.gsc b/t6/uncompiled mods/sliquifier.gsc new file mode 100644 index 0000000..eb2264f --- /dev/null +++ b/t6/uncompiled mods/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/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 0000000..c3ad118 Binary files /dev/null and b/t6/uncompiled mods/trials-compiled.gsc differ 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 0000000..7a84188 Binary files /dev/null and b/t6/uncompiled mods/unlimitedsprint-compiled.gsc differ 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 0000000..2a9756b Binary files /dev/null and b/t6/uncompiled mods/zm_tomb-compiled.gsc differ diff --git a/t6/uncompiled mods/zm_tomb.gsc b/t6/uncompiled mods/zm_tomb.gsc new file mode 100644 index 0000000..b2977cf --- /dev/null +++ b/t6/uncompiled mods/zm_tomb.gsc @@ -0,0 +1,2251 @@ +// 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\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; + +#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\zm_buried_amb; +#include maps\mp\zombies\_zm_ai_ghost; +#include maps\mp\zombies\_zm_ai_sloth; +#include maps\mp\teams\_teamset_cdc; +#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_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\zm_buried_classic; +#include maps\mp\zombies\_zm_pers_upgrades_functions; +#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_powerups; +#include maps\mp\zombies\_zm_ai_faller; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zombies\_zm_equip_headchopper; +#include maps\mp\zm_buried; + + +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(); + //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 0000000..b289e59 Binary files /dev/null and b/t6/uncompiled mods/zombiecounter-compiled.gsc differ 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; + +}