11 Commits
Author SHA1 Message Date
Rage 23dc6d93c3 Update Download Modpack.bat
Cleaned up some code; Automated the MO2 install fully with a new user input method to acquire the game path.
2025-01-16 02:24:37 -05:00
Rage a84001c8bf Updated MOAR Settings 2025-01-16 02:06:59 -05:00
Rage 4ccd8753d1 Updated ModOrganizer.ini 2025-01-16 02:06:42 -05:00
Rage 1d21d74bb9 Some Optimizations to the Modpack
Disabled a lot of client-side related mods, removed Performance Improvements and disabled some potentially bad mods.

Reinstalled a default version of MOAR with just the source code preset selection set to custom.
2025-01-16 01:26:40 -05:00
Rage 3ebaed3777 Removed Potential Mod Corrupting Game 2025-01-15 21:33:26 -05:00
Rage 5d24318a39 Added A Mod; Fixed One Mod Installation
Added
- Black Clothing Pack

Fixed
- Make Val/VSS Great Again
2025-01-15 20:59:57 -05:00
Rage a161750966 Added Mods
- New Trader Mod; Painter
  - Along with a new weapon attachment mod; Black Core
- Make Val/VSS Great Again
2025-01-15 20:53:42 -05:00
Rage c3fcfb84f8 Reduced Quantity Multipliers 2025-01-15 20:16:52 -05:00
Rage 35e1404f43 Reduced MOAR Bot Spawn Counts 2025-01-15 19:38:36 -05:00
Rage f004d53072 Fixed Version Number 2025-01-15 18:47:35 -05:00
Rage 4a1cdbcd20 Tweaked MOAR Map-Specific Spawns and Config 2025-01-15 18:47:15 -05:00
532 changed files with 9243 additions and 45059 deletions
+64 -16
View File
@@ -4,6 +4,12 @@
set "mo2_install=%cd%" set "mo2_install=%cd%"
set "repository=%mo2_install%\Fika-Tarkov" set "repository=%mo2_install%\Fika-Tarkov"
:: Specifying links to download for files
set "git_repository=https://files.moddinglounge.com/Rage/Fika-Tarkov.git"
set "git_file=https://github.com/git-for-windows/git/releases/download/v2.47.1.windows.1/PortableGit-2.47.1-64-bit.7z.exe"
set "SevenZ_file=https://www.7-zip.org/a/7zr.exe"
set "mo2_file=https://github.com/ModOrganizer2/modorganizer/releases/download/v2.5.2/Mod.Organizer-2.5.2.7z"
:: Set path to the portable Git executable :: Set path to the portable Git executable
set "portable_git=%mo2_install%\PortableGit\bin\git.exe" set "portable_git=%mo2_install%\PortableGit\bin\git.exe"
set "portable_7z=%mo2_install%\7zr.exe" set "portable_7z=%mo2_install%\7zr.exe"
@@ -22,7 +28,7 @@ if not exist "%mo2_install%\PortableGit\bin\git.exe" (
echo ---- echo ----
echo Installing Portable Git... echo Installing Portable Git...
:: Download Git Portable :: Download Git Portable
curl -L -o PortableGit-2.47.1-64-bit.7z.exe https://github.com/git-for-windows/git/releases/download/v2.47.1.windows.1/PortableGit-2.47.1-64-bit.7z.exe curl -L -o PortableGit-2.47.1-64-bit.7z.exe %git_file%
if %errorlevel% neq 0 ( if %errorlevel% neq 0 (
echo ERROR: Failed to download Git Portable. Check your internet connection and try again. echo ERROR: Failed to download Git Portable. Check your internet connection and try again.
@@ -41,7 +47,7 @@ if not exist "%mo2_install%\7zr.exe" (
echo ---- echo ----
echo Installing 7zip Portable... echo Installing 7zip Portable...
:: Download 7zip Portable :: Download 7zip Portable
curl -L -o 7zr.exe https://www.7-zip.org/a/7zr.exe curl -L -o 7zr.exe %SevenZ_file%
) )
:: Determining if an installation exists already :: Determining if an installation exists already
@@ -64,10 +70,10 @@ IF EXIST "%mo2_install%\ModOrganizer.exe" (
timeout 10 timeout 10
:: Clone or update the Git repository :: Clone or update the Git repository
if not exist "Fika-Tarkov\.git" ( if not exist "%repository%\.git" (
echo ---- echo ----
echo Cloning repository... echo Cloning repository...
"%portable_git%" clone https://files.moddinglounge.com/Rage/Fika-Tarkov.git "%portable_git%" clone %git_repository%
) else ( ) else (
echo ---- echo ----
echo Repository already exists. Pulling latest changes... echo Repository already exists. Pulling latest changes...
@@ -84,18 +90,11 @@ IF EXIST "%mo2_install%\ModOrganizer.exe" (
echo Synchronizing profiles folder... echo Synchronizing profiles folder...
robocopy "%repository%/profiles" "%mo2_install%/profiles" /MIR robocopy "%repository%/profiles" "%mo2_install%/profiles" /MIR
echo ----
echo Synchronizing stylesheets folder...
robocopy "%repository%/stylesheets" "%mo2_install%/stylesheets" /E
echo ----
echo Synchronizing plugins folder...
robocopy "%repository%/plugins" "%mo2_install%/plugins" /E
pause pause
exit /B 0 exit /B 0
:InstallModpack :InstallModpack
echo.
echo !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! echo !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
echo WARNING! The script will install the modpack in the folder this script is ran from! echo WARNING! The script will install the modpack in the folder this script is ran from!
echo Be sure that your folder is empty before continuing with the installation! echo Be sure that your folder is empty before continuing with the installation!
@@ -108,9 +107,19 @@ IF EXIST "%mo2_install%\ModOrganizer.exe" (
timeout 30 timeout 30
:: Requiring user input for game path :: Requiring user input for game path
echo ----
set /p "game_path=Please enter the path to your game installation: "
if "%game_path%"=="" (
echo.
echo No path entered. Exiting.
echo.
pause
exit /b 1
)
:: Download MO2 :: Download MO2
curl -L -o MO2.7z https://github.com/ModOrganizer2/modorganizer/releases/download/v2.5.2/Mod.Organizer-2.5.2.7z curl -L -o MO2.7z %mo2_file%
if %errorlevel% neq 0 ( if %errorlevel% neq 0 (
echo ERROR: Failed to download the archive. Check your internet connection and try again. echo ERROR: Failed to download the archive. Check your internet connection and try again.
pause pause
@@ -138,7 +147,7 @@ IF EXIST "%mo2_install%\ModOrganizer.exe" (
echo ---- echo ----
echo Cloning repository... echo Cloning repository...
"%portable_git%" clone https://files.moddinglounge.com/Rage/Fika-Tarkov.git "%portable_git%" clone %git_repository%
echo ---- echo ----
echo Synchronizing mods folder... echo Synchronizing mods folder...
@@ -148,13 +157,52 @@ IF EXIST "%mo2_install%\ModOrganizer.exe" (
echo Synchronizing profiles folder... echo Synchronizing profiles folder...
robocopy "%repository%/profiles" "%mo2_install%/profiles" /MIR robocopy "%repository%/profiles" "%mo2_install%/profiles" /MIR
echo ----
echo Synchronizing plugins folder...
robocopy "%repository%/plugins" "%mo2_install%/plugins" /E
echo ---- echo ----
echo Synchronizing stylesheets folder... echo Synchronizing stylesheets folder...
robocopy "%repository%/stylesheets" "%mo2_install%/stylesheets" /E robocopy "%repository%/stylesheets" "%mo2_install%/stylesheets" /E
:: Escape backslashes in the game path
setlocal enabledelayedexpansion
set "game_path=!game_path:\=/!"
set "escaped_path="
for /l %%i in (0,1,255) do (
for /f "tokens=1,* delims=" %%a in ("!game_path:~%%i,1!") do (
if "%%a"=="" goto path_done
if %%a==/ (
set "escaped_path=!escaped_path!//" :: Double the backslash
) else (
set "escaped_path=!escaped_path!%%a"
)
)
)
:path_done
echo Original Path: %game_path%
echo Escaped Path: %escaped_path%
:: Replace placeholders in ModOrganizer.ini
echo ---- echo ----
echo Synchronizing plugins folder... echo Updating ModOrganizer.ini...
robocopy "%repository%/plugins" "%mo2_install%/plugins" /E set "ini_file=%repository%\ModOrganizer.ini"
set "temp_ini=%ini_file%.tmp"
(for /f "usebackq delims=" %%A in ("%ini_file%") do (
set "line=%%A"
set "line=!line:game_path=%escaped_path%!"
set "line=!line:replace_me=%game_path%!"
echo(!line!
)) > "%temp_ini%"
move /y "%temp_ini%" "%mo2_install%\ModOrganizer.ini"
echo ----
echo ModOrganizer.ini updated successfully!
echo ---- echo ----
echo Installation complete. Launch ModOrganizer.exe and follow the remaining instructions. echo Installation complete. Launch ModOrganizer.exe and follow the remaining instructions.
+159 -2
View File
@@ -1,17 +1,75 @@
[General] [General]
gameName=SPT gameName=SPT
gamePath=@ByteArray(replace_me) gamePath=@ByteArray(game_path)
selected_profile=@ByteArray(Multiplayer) selected_profile=@ByteArray(Multiplayer)
version=2.5.2 version=2.5.2
first_start=false first_start=false
previousSeparatorColor=@Variant(\0\0\0\x43\x1\xff\xff\x44\x44\x36\x36))\0\0) previousSeparatorColor=@Variant(\0\0\0\x43\x1\xff\xff\x44\x44\x36\x36))\0\0)
backup_install=true backup_install=true
[PluginPersistance]
Python%20Proxy\tryInit=false
[Settings] [Settings]
profile_local_inis=false
profile_local_saves=false
profile_archive_invalidation=true
log_level=1
language=en
compact_downloads=true
meta_downloads=false
autohide_downloads=false
check_for_updates=true
use_prereleases=false
center_dialogs=false
show_change_game_confirmation=true
show_menubar_on_alt=true
double_click_previews=true
style=Dark Bronze.qss style=Dark Bronze.qss
overwrittenLooseFilesColor=@Variant(\0\0\0\x43\x1@@\0\0\xff\xff\0\0\0\0)
overwritingLooseFilesColor=@Variant(\0\0\0\x43\x1@@\xff\xff\0\0\0\0\0\0)
overwrittenArchiveFilesColor=@Variant(\0\0\0\x43\x1@@\0\0\xff\xff\xff\xff\0\0)
overwritingArchiveFilesColor=@Variant(\0\0\0\x43\x1@@\xff\xff\0\0\xff\xff\0\0)
containsPluginColor=@Variant(\0\0\0\x43\x1@@\0\0\0\0\xff\xff\0\0)
containedColor=@Variant(\0\0\0\x43\x1@@\0\0\0\0\xff\xff\0\0)
colorSeparatorScrollbars=true
display_foreign=true
collapsible_separators_asc=true
collapsible_separators_dsc=true
collapsible_separators_conflicts_from=true
collapsible_separators_conflicts_to=true
collapsible_separators_per_profile=false
save_filters=false
auto_collapse_on_hover=false
autocheck_update_install=true
collapsible_separators_icons_1=true
collapsible_separators_icons_2=true
collapsible_separators_icons_3=true
collapsible_separators_icons_7=true
crash_dumps_type=1
crash_dumps_max=5
loot_log_level=2
endorsement_integration=true
tracked_integration=true
category_mappings=true
hide_api_counter=false
force_enable_core_files=true
lock_gui=true
archive_parsing_experimental=false
offline_mode=false
use_proxy=false
use_custom_browser=false
custom_browser=
executable_blacklist="Chrome.exe;Firefox.exe;TSVNCache.exe;TGitCache.exe;Steam.exe;GameOverlayUI.exe;Discord.exe;GalaxyClient.exe;Spotify.exe;Brave.exe"
skip_file_suffixes=.mohidden
skip_directories=.git
filter_regex=false
regex_case_sensitive=false
regex_extended=false
filter_scroll_to_selection=false
[customExecutables] [customExecutables]
size=1 size=6
1\arguments= 1\arguments=
1\binary=replace_me/SPT.Launcher.exe 1\binary=replace_me/SPT.Launcher.exe
1\hide=false 1\hide=false
@@ -20,3 +78,102 @@ size=1
1\title=Multiplayer 1\title=Multiplayer
1\toolbar=false 1\toolbar=false
1\workingDirectory=replace_me 1\workingDirectory=replace_me
2\arguments=
2\binary=replace_me/sptvfsbridge.bat
2\hide=false
2\ownicon=true
2\steamAppID=
2\title=Singleplayer
2\toolbar=false
2\workingDirectory=replace_me
3\arguments=
3\binary=D:/Modding/Modlists/Fika Tarkov/mods/Load Order Editor/LoEDD/LoEDD.exe
3\hide=false
3\ownicon=true
3\steamAppID=
3\title=Load Order Editor
3\toolbar=true
3\workingDirectory=D:\\Modding\\Modlists\\Fika Tarkov\\mods\\Load Order Editor\\LoEDD
4\arguments=
4\binary=D:/Modding/Modlists/Fika Tarkov/mods/Server Value Modifier/user/mods/[SVM] Server Value Modifier/Greed.exe
4\hide=false
4\ownicon=false
4\steamAppID=
4\title=Greed
4\toolbar=true
4\workingDirectory=D:\\Modding\\Modlists\\Fika Tarkov\\mods\\Server Value Modifier\\user\\mods\\[SVM] Server Value Modifier
5\arguments=\"D:\\Games\\Singleplayer Tarkov\"
5\binary=D:/Modding/Modlists/Fika Tarkov/explorer++/Explorer++.exe
5\hide=false
5\ownicon=true
5\steamAppID=
5\title=Explore Virtual Folder
5\toolbar=false
5\workingDirectory=D:\\Modding\\Modlists\\Fika Tarkov\\explorer++
[Widgets]
SettingsDialog_tabWidget_index=0
MainWindow_executablesListBox_index=1
MainWindow_tabWidget_index=2
MainWindow_dataTabShowOnlyConflicts_checked=false
MainWindow_dataTabShowFromArchives_checked=false
MainWindow_groupCombo_index=0
MainWindow_modList_index=SWAG + DONUTS_backup, Fika, Essentials, Bug Fixes & Optimizations, Interface & HUD, SFX & Music, New Items & Keys, Gameplay Tweaks, New Traders & Tweaks, New Weapons & Gear, AI & Combat Tweaks, VFX & Atmosphere, Modlist Addons, Backburner, Version 1.32.0, Unsorted, Overwrite
MainWindow_filters_index=0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
MainWindow_filtersAnd_checked=true
MainWindow_filtersOr_checked=false
MainWindow_filtersSeparators_index=0
ModInfoTabOrder=tabFiles tabText tabIni tabImages tabESPs tabConflicts tabCategories tabNexus tabNotes
ModInfoDialog_tabWidget_index=0
ModInfoDialog_imagesShowDDS_checked=false
ModInfoDialog_tabConflictsTabs_index=0
ModInfoDialog_conflictsAdvancedShowNoConflict_checked=true
ModInfoDialog_conflictsAdvancedShowAll_checked=true
ModInfoDialog_conflictsAdvancedShowNearest_checked=false
[Geometry]
SettingsDialog_geometry=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\x2\xe3\0\0\x1\x30\0\0\x6\x16\0\0\x3\x9d\0\0\x2\xe3\0\0\x1N\0\0\x6\x16\0\0\x3\x9d\0\0\0\0\0\0\0\0\t\xe\0\0\x2\xe3\0\0\x1N\0\0\x6\x16\0\0\x3\x9d)
MainWindow_state=@ByteArray(\0\0\0\xff\0\0\0\0\xfd\0\0\0\x1\0\0\0\x3\0\0\t\xe\0\0\0\xd7\xfc\x1\0\0\0\x1\xfb\0\0\0\xe\0l\0o\0g\0\x44\0o\0\x63\0k\0\0\0\0\0\0\0\t\xe\0\0\0R\0\xff\xff\xff\0\0\t\xe\0\0\x4T\0\0\0\x4\0\0\0\x4\0\0\0\b\0\0\0\b\xfc\0\0\0\x1\0\0\0\x2\0\0\0\x1\0\0\0\xe\0t\0o\0o\0l\0\x42\0\x61\0r\x1\0\0\0\0\xff\xff\xff\xff\0\0\0\0\0\0\0\0)
MainWindow_geometry=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\0\0\xff\xff\xff\xf9\0\0\t\r\0\0\x4\xe8\0\0\0\v\0\0\0\x1f\0\0\az\0\0\x4w\0\0\0\0\x2\0\0\0\t\xe\0\0\0\0\0\0\0\x17\0\0\t\r\0\0\x4\xe8)
MainWindow_docks_logDock_size=215
MainWindow_menuBar_visibility=true
MainWindow_statusBar_visibility=true
MainWindow_toolBar_visibility=true
toolbar_size=@Size(42 36)
toolbar_button_style=0
MainWindow_splitter_state=@ByteArray(\0\0\0\xff\0\0\0\x1\0\0\0\x2\0\0\x3\xf9\0\0\x2\xb0\x1\xff\xff\xff\xff\x1\0\0\0\x1\0)
MainWindow_categoriesSplitter_state=@ByteArray(\0\0\0\xff\0\0\0\x1\0\0\0\x2\0\0\x1\b\0\0\x3\x16\0\xff\xff\xff\xff\x1\0\0\0\x1\0)
MainWindow_monitor=0
MainWindow_categoriesGroup_visibility=false
MainWindow_espList_state=@ByteArray(\0\0\0\xff\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\x2\x1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x2n\0\0\0\x4\x1\x1\0\x1\0\0\0\0\0\0\0\0\x1\0\0\0\x64\xff\xff\xff\xff\0\0\0\x81\0\0\0\0\0\0\0\x4\0\0\x1\xce\0\0\0\x1\0\0\0\0\0\0\0%\0\0\0\x1\0\0\0\0\0\0\0\x33\0\0\0\x1\0\0\0\0\0\0\0H\0\0\0\x1\0\0\0\0\0\0\x3\xe8\0\0\0\0\x46\0\0\0\0)
MainWindow_downloadView_state=@ByteArray(\0\0\0\xff\0\0\0\0\0\0\0\x1\0\0\0\x1\0\0\0\x3\x1\0\0\0\0\0\0\0\0\0\0\0\b\xf0\0\0\0\x4\0\0\0\x4\0\0\0\x64\0\0\0\a\0\0\0\x64\0\0\0\x6\0\0\0\x64\0\0\0\x5\0\0\0\x64\0\0\x3\x80\0\0\0\b\x1\x1\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x64\xff\xff\xff\xff\0\0\0\x81\0\0\0\0\0\0\0\b\0\0\x2\x62\0\0\0\x1\0\0\0\0\0\0\0V\0\0\0\x1\0\0\0\0\0\0\0\x64\0\0\0\x1\0\0\0\0\0\0\0\x64\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\x3\xe8\x1\0\0\0\0\0\0\0\0)
MainWindow_savegameList_state=@ByteArray(\0\0\0\xff\0\0\0\0\0\0\0\x1\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x2n\0\0\0\x2\x1\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\0\x64\xff\xff\xff\xff\0\0\0\x81\0\0\0\0\0\0\0\x2\0\0\x1\xa1\0\0\0\x1\0\0\0\0\0\0\0\xcd\0\0\0\x1\0\0\0\0\0\0\x3\xe8\0\0\0\0\x64\0\0\0\0)
MainWindow_dataTree_state=@ByteArray(\0\0\0\xff\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x3\x80\0\0\0\x5\x1\x1\0\x1\0\0\0\0\0\0\0\0\0\0\0\0\x64\xff\xff\xff\xff\0\0\0\x81\0\0\0\0\0\0\0\x5\0\0\x1s\0\0\0\x1\0\0\0\0\0\0\0\x81\0\0\0\x1\0\0\0\0\0\0\0\xb2\0\0\0\x1\0\0\0\0\0\0\0\x64\0\0\0\x1\0\0\0\0\0\0\0v\0\0\0\x1\0\0\0\0\0\0\x3\xe8\0\0\0\0\x64\0\0\0\0)
MainWindow_modList_state=@ByteArray(\0\0\0\xff\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\t\x1\0\0\0\v\0\0\0\0\0\0\0\x2\0\0\0\x3\0\0\0\x6\0\0\0\x5\0\0\0\a\0\0\0\b\0\0\0\t\0\0\0\x4\0\0\0\n\0\0\0\x1\0\0\0\v\0\0\0\0\0\0\0\n\0\0\0\x1\0\0\0\x2\0\0\0\b\0\0\0\x4\0\0\0\x3\0\0\0\x5\0\0\0\x6\0\0\0\a\0\0\0\t\0\0\0\v\xc2\x3\0\0\0\x5\0\0\0\a\0\0\0Y\0\0\0\x3\0\0\0 \0\0\0\x6\0\0\0 \0\0\0\n\0\0\x1\xb3\0\0\0\x5\0\0\0 \0\0\x5\x42\0\0\0\v\x1\x1\0\x1\0\0\0\0\0\0\0\0\x1\0\0\0'\xff\xff\xff\xff\0\0\0\x81\0\0\0\0\0\0\0\v\0\0\x3\n\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\x64\0\0\0\x1\0\0\0\0\0\0\0H\0\0\0\x1\0\0\0\0\0\0\0\xac\0\0\0\x1\0\0\0\0\0\0\0|\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\x64\0\0\0\x1\0\0\0\0\0\0\x3\xe8\x1\0\0\0U\0\0\0\0)
EditExecutablesDialog_geometry=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\x2\xa7\0\0\x1\x8d\0\0\a2\0\0\x3\xbb\0\0\x2\xa7\0\0\x1\xab\0\0\a2\0\0\x3\xbb\0\0\0\0\0\0\0\0\t\xe\0\0\x2\xa7\0\0\x1\xab\0\0\a2\0\0\x3\xbb)
ModInfoDialog_tabTextSplitter_state=@ByteArray(\0\0\0\xff\0\0\0\x1\0\0\0\x2\0\0\x1\xc8\0\0\x3\x62\0\xff\xff\xff\xff\x1\0\0\0\x1\0)
ModInfoDialog_tabIniSplitter_state=@ByteArray(\0\0\0\xff\0\0\0\x1\0\0\0\x2\0\0\0\xc8\0\0\0\xed\x1\xff\xff\xff\xff\x1\0\0\0\x1\0)
ModInfoDialog_tabImagesSplitter_state=@ByteArray(\0\0\0\xff\0\0\0\x1\0\0\0\x2\0\0\0\x80\0\0\0\x83\0\xff\xff\xff\xff\x1\0\0\0\x1\0)
ModInfoDialog_ESPsSplitter_state=@ByteArray(\0\0\0\xff\0\0\0\x1\0\0\0\x2\0\0\0|\0\0\0\xab\x1\xff\xff\xff\xff\x1\0\0\0\x1\0)
ModInfoDialog_overwriteExpander_state=@ByteArray(\x1)
ModInfoDialog_overwrittenExpander_state=@ByteArray(\x1)
ModInfoDialog_noConflictExpander_state=@ByteArray(\0)
ModInfoDialog_overwriteTree_state=@ByteArray(\0\0\0\xff\0\0\0\0\0\0\0\x1\0\0\0\x1\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x5(\0\0\0\x2\x1\x1\0\x1\0\0\0\0\0\0\0\0\0\0\0\0\x64\xff\xff\xff\xff\0\0\0\x81\0\0\0\0\0\0\0\x2\0\0\x2\x88\0\0\0\x1\0\0\0\0\0\0\x2\xa0\0\0\0\x1\0\0\0\0\0\0\x3\xe8\0\0\0\0\x64\0\0\0\0)
ModInfoDialog_noConflictTree_state=@ByteArray(\0\0\0\xff\0\0\0\0\0\0\0\x1\0\0\0\x1\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x64\0\0\0\x1\x1\x1\0\x1\0\0\0\0\0\0\0\0\0\0\0\0\x64\xff\xff\xff\xff\0\0\0\x81\0\0\0\0\0\0\0\x1\0\0\0\x64\0\0\0\x1\0\0\0\0\0\0\x3\xe8\0\0\0\0\x64\0\0\0\0)
ModInfoDialog_overwrittenTree_state=@ByteArray(\0\0\0\xff\0\0\0\0\0\0\0\x1\0\0\0\x1\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x2\xdd\0\0\0\x2\x1\x1\0\x1\0\0\0\0\0\0\0\0\0\0\0\0\x64\xff\xff\xff\xff\0\0\0\x81\0\0\0\0\0\0\0\x2\0\0\x2y\0\0\0\x1\0\0\0\0\0\0\0\x64\0\0\0\x1\0\0\0\0\0\0\x3\xe8\0\0\0\0\x64\0\0\0\0)
ModInfoDialog_conflictsAdvancedList_state="@ByteArray(\0\0\0\xff\0\0\0\0\0\0\0\x1\0\0\0\x1\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x1,\0\0\0\x3\x1\x1\0\x1\0\0\0\0\0\0\0\0\0\0\0\0\x64\xff\xff\xff\xff\0\0\0\x81\0\0\0\0\0\0\0\x3\0\0\0\x64\0\0\0\x1\0\0\0\0\0\0\0\x64\0\0\0\x1\0\0\0\0\0\0\0\x64\0\0\0\x1\0\0\0\0\0\0\x3\xe8\0\0\0\0\x64\0\0\0\0)"
ModInfoDialog_filetree_state=@ByteArray(\0\0\0\xff\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x5\x30\0\0\0\x4\x1\x1\0\x1\0\0\0\0\0\0\0\0\0\0\0\0\x64\xff\xff\xff\xff\0\0\0\x81\0\0\0\0\0\0\0\x4\0\0\x1\xbf\0\0\0\x1\0\0\0\0\0\0\0\x64\0\0\0\x1\0\0\0\0\0\0\0\x64\0\0\0\x1\0\0\0\0\0\0\x2\xa9\0\0\0\x1\0\0\0\0\0\0\x3\xe8\0\0\0\0\x64\0\0\0\0)
ModInfoDialog_geometry=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\x1\xca\0\0\x1\x1b\0\0\a\x17\0\0\x4\x1e\0\0\x1\xca\0\0\x1\x39\0\0\a\x17\0\0\x4\x1e\0\0\0\0\0\0\0\0\t\xe\0\0\x1\xca\0\0\x1\x39\0\0\a\x17\0\0\x4\x1e)
PreviewDialog_geometry=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\x3\r\0\0\x1\x35\0\0\x5\xec\0\0\x3\x99\0\0\x3\r\0\0\x1S\0\0\x5\xec\0\0\x3\x99\0\0\0\0\0\0\0\0\t\xe\0\0\x3\r\0\0\x1S\0\0\x5\xec\0\0\x3\x99)
ProfilesDialog_geometry=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\x3\x8c\0\0\x1\xb2\0\0\x5m\0\0\x3\x1b\0\0\x3\x8c\0\0\x1\xd0\0\0\x5m\0\0\x3\x1b\0\0\0\0\0\0\0\0\t\xe\0\0\x3\x8c\0\0\x1\xd0\0\0\x5m\0\0\x3\x1b)
__overwriteDialog_geometry=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\x2\x82\0\0\x1\x8c\0\0\a\xa9\0\0\x4\xa8\0\0\x2\x82\0\0\x1\xaa\0\0\a\xa9\0\0\x4\xa8\0\0\0\0\0\0\0\0\t\xe\0\0\x2\x82\0\0\x1\xaa\0\0\a\xa9\0\0\x4\xa8)
__overwriteDialog_filesView_state=@ByteArray(\0\0\0\xff\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x4\xfe\0\0\0\x4\x1\x1\0\x1\0\0\0\0\0\0\0\0\0\0\0\0\x64\xff\xff\xff\xff\0\0\0\x81\0\0\0\0\0\0\0\x4\0\0\x1\xd7\0\0\0\x1\0\0\0\0\0\0\0\x64\0\0\0\x1\0\0\0\0\0\0\0\x64\0\0\0\x1\0\0\0\0\0\0\x2_\0\0\0\x1\0\0\0\0\0\0\x3\xe8\0\0\0\0\x64\0\0\0\0)
ProblemsDialog_geometry=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\x3^\0\0\x1\x9c\0\0\x5\x9b\0\0\x3\x31\0\0\x3^\0\0\x1\xba\0\0\x5\x9b\0\0\x3\x31\0\0\0\0\0\0\0\0\t\xe\0\0\x3^\0\0\x1\xba\0\0\x5\x9b\0\0\x3\x31)
CategoriesDialog_geometry=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\x1\xd3\0\0\x1T\0\0\x4\x99\0\0\x3#\0\0\x1\xd3\0\0\x1r\0\0\x4\x99\0\0\x3#\0\0\0\0\0\0\0\0\t\xe\0\0\x1\xd3\0\0\x1r\0\0\x4\x99\0\0\x3#)
ListDialog_geometry=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\x3\xfa\0\0\0\xfe\0\0\x4\xff\0\0\x3^\0\0\x3\xfa\0\0\x1\x1c\0\0\x4\xff\0\0\x3^\0\0\0\0\0\0\0\0\t\xe\0\0\x3\xfa\0\0\x1\x1c\0\0\x4\xff\0\0\x3^)
[Servers]
size=0
[pluginBlacklist]
size=0
@@ -1,11 +1,11 @@
[General] [General]
gameName=spt gameName=spt
modid=0 modid=0
version=d2025.1.1.0 version=d2025.1.15.0
newestVersion= newestVersion=
category="1,2" category="1,"
nexusFileStatus=1 nexusFileStatus=1
installationFile=Default Epic.zip installationFile=MoxoPixel-BlackCore.zip
repository=Nexus repository=Nexus
ignoredVersion= ignoredVersion=
comments= comments=
@@ -15,7 +15,7 @@ url=
hasCustomURL=true hasCustomURL=true
lastNexusQuery= lastNexusQuery=
lastNexusUpdate= lastNexusUpdate=
nexusLastModified=2025-01-01T06:47:45Z nexusLastModified=2025-01-16T01:49:42Z
nexusCategory=0 nexusCategory=0
converted=false converted=false
validated=false validated=false
@@ -0,0 +1,556 @@
{
"manifest": [
{
"key":"tactical_all_insight_wmx200_retex.bundle",
"dependencyKeys":[]
},
{
"key":"mag_stanag_hk_polymer_mag_556x45_30_retex.bundle",
"dependencyKeys":[]
},
{
"key":"handguard_ar15_dd_ris_ii_fsp_9,5_retex.bundle",
"dependencyKeys":[]
},
{
"key":"scope_all_eotech_exps3_retex.bundle",
"dependencyKeys":[
"scope_all_eotech_exps3_gloss_nrm_retex.bundle",
"scope_all_eotech_exps3_mesh_retex.bundle",
"scope_all_eotech_exps3_tan_textures_retex.bundle",
"scope_all_eotech_xps3_textures_retex.bundle"
]
},
{
"key":"scope_all_eotech_exps3_gloss_nrm_retex.bundle",
"dependencyKeys":[]
},
{
"key":"scope_all_eotech_exps3_tan_textures_retex.bundle",
"dependencyKeys":[]
},
{
"key":"scope_all_eotech_xps3_textures_retex.bundle",
"dependencyKeys":[]
},
{
"key":"scope_all_eotech_exps3_mesh_retex.bundle",
"dependencyKeys":[
"scope_all_eotech_exps3_gloss_nrm_retex.bundle",
"scope_all_eotech_exps3_tan_textures_retex.bundle",
"scope_all_eotech_xps3_textures_retex.bundle"
]
},
{
"key":"tactical_all_holosun_ls321_retex.bundle",
"dependencyKeys":[
"assets/commonassets/physics/physicsmaterials.bundle",
"assets/content/textures/holemanager/glow_particle_bright.bundle",
"assets/standard assets/effects/lightcookies/textures/flashlightcookie.bundle",
"assets/systems/effects/collimator.bundle",
"assets/systems/effects/laserbeam/laser.bundle",
"assets/systems/effects/multiflare/multiflare.bundle",
"assets/systems/effects/nightvision.bundle",
"cubemaps",
"shaders"
]
},
{
"key":"m4a1_black_lines/textures/client_assets.bundle",
"dependencyKeys":[
]
},
{
"key":"m4a1_black_lines/client_assets.bundle",
"dependencyKeys":[
"m4a1_black_lines/textures/client_assets.bundle",
"cubemaps",
"shaders"
]
},
{
"key":"m4a1_black_lines/weapon_colt_m4a1_556x45_container.bundle",
"dependencyKeys":[
"assets/commonassets/physics/physicsmaterials.bundle",
"assets/content/audio/banks/m4a1.bundle",
"assets/content/audio/blendoptions/assets.bundle",
"assets/content/audio/weapons/ak74.bundle",
"assets/content/audio/weapons/generic",
"assets/content/audio/weapons/m4a1.bundle",
"assets/content/weapons/additional_hands/client_assets.bundle",
"assets/content/weapons/animations/simple_animations.bundle",
"assets/content/weapons/animations/spirit_animations.bundle",
"m4a1_black_lines/client_assets.bundle",
"m4a1_black_lines/textures/client_assets.bundle",
"assets/content/weapons/tx15/client_assets.bundle",
"assets/content/weapons/tx15/textures/client_assets.bundle",
"assets/content/weapons/tx15/weapon_lone_star_tx15_designated_marksman_556x45_container.bundle",
"assets/content/weapons/weapon_root_anim_fix.bundle",
"assets/content/weapons/wip/kibas tuning prefabs/muzzlejets_templates/default_assets.bundle",
"assets/systems/effects/heathaze/defaultheathaze.bundle",
"assets/systems/effects/muzzleflash/muzzleflash.bundle",
"assets/systems/effects/smoke.bundle",
"cubemaps",
"shaders"
]
},
{
"key":"ak103_black_lines/textures/client_assets.bundle",
"dependencyKeys":[
]
},
{
"key":"ak103_black_lines/client_assets.bundle",
"dependencyKeys":[
"ak103_black_lines/textures/client_assets.bundle",
"cubemaps",
"shaders"
]
},
{
"key":"ak103_black_lines/weapon_izhmash_ak103_762x39_container.bundle",
"dependencyKeys":[
"assets/commonassets/physics/physicsmaterials.bundle",
"assets/content/audio/banks/ak74.bundle",
"assets/content/audio/banks/akm.bundle",
"assets/content/audio/blendoptions/assets.bundle",
"assets/content/audio/weapons/ak74.bundle",
"assets/content/audio/weapons/akm.bundle",
"assets/content/audio/weapons/generic",
"assets/content/audio/weapons/saiga12.bundle",
"assets/content/items/mods/handguards/handguard_pp-19-01_izhmash_vityaz_std_plastic_textures.bundle",
"assets/content/weapons/additional_hands/client_assets.bundle",
"ak103_black_lines/client_assets.bundle",
"ak103_black_lines/textures/client_assets.bundle",
"assets/content/weapons/ak100/weapon_izhmash_ak104_762x39_container.bundle",
"assets/content/weapons/ak100/weapon_izhmash_ak105_545x39_container.bundle",
"assets/content/weapons/ak74m/textures/client_assets.bundle",
"assets/content/weapons/animations/simple_animations.bundle",
"assets/content/weapons/animations/spirit_animations.bundle",
"assets/content/weapons/pp-19-01/textures/client_assets.bundle",
"assets/content/weapons/weapon_root_anim_fix.bundle",
"assets/content/weapons/wip/kibas tuning prefabs/muzzlejets_templates/default_assets.bundle",
"assets/systems/effects/heathaze/defaultheathaze.bundle",
"assets/systems/effects/muzzleflash/muzzleflash.bundle",
"assets/systems/effects/smoke.bundle",
"cubemaps",
"shaders"
]
},
{
"key":"reciever_ak_akademia_bastion_retex.bundle",
"dependencyKeys":[
"assets/commonassets/physics/physicsmaterials.bundle",
"cubemaps",
"shaders"
]
},
{
"key":"rsass_black/weapon_remington_r11_rsass_762x51_container.bundle",
"dependencyKeys":[
"assets/commonassets/physics/physicsmaterials.bundle",
"assets/content/audio/banks/rsass.bundle",
"assets/content/audio/blendoptions/assets.bundle",
"assets/content/audio/weapons/ak74.bundle",
"assets/content/audio/weapons/generic",
"assets/content/audio/weapons/mpx.bundle",
"assets/content/weapons/additional_hands/client_assets.bundle",
"assets/content/weapons/animations/simple_animations.bundle",
"assets/content/weapons/animations/spirit_animations.bundle",
"rsass_black/client_assets.bundle",
"rsass_black/textures/client_assets.bundle",
"assets/content/weapons/weapon_root_anim_fix.bundle",
"assets/content/weapons/wip/kibas tuning prefabs/muzzlejets_templates/default_assets.bundle",
"assets/systems/effects/heathaze/defaultheathaze.bundle",
"assets/systems/effects/muzzleflash/muzzleflash.bundle",
"assets/systems/effects/smoke.bundle",
"cubemaps",
"shaders"
]
},
{
"key":"rsass_black/client_assets.bundle",
"dependencyKeys":[
"rsass_black/textures/client_assets.bundle",
"cubemaps",
"shaders"
]
},
{
"key":"rsass_black/textures/client_assets.bundle",
"dependencyKeys":[
]
},
{
"key":"mk47_black_lines/textures/client_assets.bundle",
"dependencyKeys":[
]
},
{
"key":"mk47_black_lines/client_assets.bundle",
"dependencyKeys":[
"mk47_black_lines/textures/client_assets.bundle",
"cubemaps",
"shaders"
]
},
{
"key":"mk47_black_lines/weapon_cmmg_mk47_762x39_container.bundle",
"dependencyKeys":[
"assets/commonassets/physics/physicsmaterials.bundle",
"assets/content/audio/banks/mp5.bundle",
"assets/content/audio/blendoptions/assets.bundle",
"assets/content/audio/weapons/ak74.bundle",
"assets/content/audio/weapons/akm/instrumental.bundle",
"assets/content/audio/weapons/generic",
"assets/content/audio/weapons/mp5.bundle",
"assets/content/audio/weapons/mpx.bundle",
"assets/content/weapons/additional_hands/client_assets.bundle",
"assets/content/weapons/animations/simple_animations.bundle",
"assets/content/weapons/animations/spirit_animations.bundle",
"assets/content/weapons/m4a1/client_assets.bundle",
"assets/content/weapons/m4a1/textures/client_assets.bundle",
"mk47_black_lines/client_assets.bundle",
"mk47_black_lines/textures/client_assets.bundle",
"assets/content/weapons/weapon_root_anim_fix.bundle",
"assets/content/weapons/wip/kibas tuning prefabs/muzzlejets_templates/default_assets.bundle",
"assets/systems/effects/heathaze/defaultheathaze.bundle",
"assets/systems/effects/muzzleflash/muzzleflash.bundle",
"assets/systems/effects/smoke.bundle",
"cubemaps",
"shaders"
]
},
{
"key":"reciever_mk47_cmmg_mk47_std_retex.bundle",
"dependencyKeys":[
]
},
{
"key":"tactical_all_wilcox_raptar_es_retex.bundle",
"dependencyKeys":[
"assets/commonassets/physics/physicsmaterials.bundle",
"assets/content/textures/holemanager/glow_particle_bright.bundle",
"assets/standard assets/effects/lightcookies/textures/flashlightcookie.bundle",
"assets/systems/effects/collimator.bundle",
"assets/systems/effects/laserbeam/laser.bundle",
"assets/systems/effects/multiflare/multiflare.bundle",
"assets/systems/effects/nightvision.bundle",
"cubemaps",
"shaders"
]
},
{
"key":"scope_30mm_razor_hd_gen_2_1_6x24_retex.bundle",
"dependencyKeys":[
"assets/commonassets/physics/physicsmaterials.bundle",
"assets/content/textures/holemanager/round_spec_mask.bundle",
"assets/systems/effects/opticsight/opticsightsmasks.bundle",
"cubemaps",
"shaders"
]
},
{
"key":"reciever_ar15_noveske_gen3_retex.bundle",
"dependencyKeys":[
]
},
{
"key":"stock_vepr_molot_vpo-101_std_wood_retex.bundle",
"dependencyKeys":[
]
},
{
"key":"stock_m14_troy_sass_chassis_retex.bundle",
"dependencyKeys":[
]
},
{
"key":"silencer_mount_silencerco_hybrid_46_multi_retex.bundle",
"dependencyKeys":[]
},
{
"key":"mag_aug_steyr_std_556x45_30_retex.bundle",
"dependencyKeys":[]
},
{
"key":"stock_ak_zenit_pt_1_retex.bundle",
"dependencyKeys":[]
},
{
"key":"pistolgrip_ak_magpul_moe_ak_retex.bundle",
"dependencyKeys":[]
},
{
"key":"gas_block_akp_slr_ak_railed_gas_tube_retex.bundle",
"dependencyKeys":[]
},
{
"key":"reciever_ak_texas_weapon_systems_dog_leg_rail_gen_3_retex.bundle",
"dependencyKeys":[]
},
{
"key":"handguard_ar15_precision_reflex_carbon_fiber_delta_gen_3_retex.bundle",
"dependencyKeys":[]
},
{
"key":"helmet_armor_slaap.bundle",
"dependencyKeys":[]
},
{
"key":"reciever_glock_glock_17_std_retex.bundle",
"dependencyKeys":[]
},
{
"key":"reciever_glock_gspc_viper_slide_cut_retex.bundle",
"dependencyKeys":[]
},
{
"key":"m4a1_flame/textures/client_assets.bundle",
"dependencyKeys":[
]
},
{
"key":"m4a1_flame/client_assets.bundle",
"dependencyKeys":[
"m4a1_flame/textures/client_assets.bundle",
"cubemaps",
"shaders"
]
},
{
"key":"m4a1_flame/weapon_colt_m4a1_556x45_container.bundle",
"dependencyKeys":[
"assets/commonassets/physics/physicsmaterials.bundle",
"assets/content/audio/banks/m4a1.bundle",
"assets/content/audio/blendoptions/assets.bundle",
"assets/content/audio/weapons/ak74.bundle",
"assets/content/audio/weapons/generic",
"assets/content/audio/weapons/m4a1.bundle",
"assets/content/weapons/additional_hands/client_assets.bundle",
"assets/content/weapons/animations/simple_animations.bundle",
"assets/content/weapons/animations/spirit_animations.bundle",
"m4a1_flame/client_assets.bundle",
"m4a1_flame/textures/client_assets.bundle",
"assets/content/weapons/tx15/client_assets.bundle",
"assets/content/weapons/tx15/textures/client_assets.bundle",
"assets/content/weapons/tx15/weapon_lone_star_tx15_designated_marksman_556x45_container.bundle",
"assets/content/weapons/weapon_root_anim_fix.bundle",
"assets/content/weapons/wip/kibas tuning prefabs/muzzlejets_templates/default_assets.bundle",
"assets/systems/effects/heathaze/defaultheathaze.bundle",
"assets/systems/effects/muzzleflash/muzzleflash.bundle",
"assets/systems/effects/smoke.bundle",
"cubemaps",
"shaders"
]
},
{
"key":"foregrip_all_bcm_mod_3_new.bundle",
"dependencyKeys":[]
},
{
"key":"mag_ak74_izhmash_6l23_545x39_30_retex.bundle",
"dependencyKeys":[]
},
{
"key":"m4a1_new/textures/client_assets.bundle",
"dependencyKeys":[
]
},
{
"key":"m4a1_new/client_assets.bundle",
"dependencyKeys":[
"m4a1_new/textures/client_assets.bundle",
"cubemaps",
"shaders"
]
},
{
"key":"m4a1_new/weapon_colt_m4a1_556x45_container.bundle",
"dependencyKeys":[
"assets/commonassets/physics/physicsmaterials.bundle",
"assets/content/audio/banks/m4a1.bundle",
"assets/content/audio/blendoptions/assets.bundle",
"assets/content/audio/weapons/ak74.bundle",
"assets/content/audio/weapons/generic",
"assets/content/audio/weapons/m4a1.bundle",
"assets/content/weapons/additional_hands/client_assets.bundle",
"assets/content/weapons/animations/simple_animations.bundle",
"assets/content/weapons/animations/spirit_animations.bundle",
"m4a1_new/client_assets.bundle",
"m4a1_new/textures/client_assets.bundle",
"assets/content/weapons/tx15/client_assets.bundle",
"assets/content/weapons/tx15/textures/client_assets.bundle",
"assets/content/weapons/tx15/weapon_lone_star_tx15_designated_marksman_556x45_container.bundle",
"assets/content/weapons/weapon_root_anim_fix.bundle",
"assets/content/weapons/wip/kibas tuning prefabs/muzzlejets_templates/default_assets.bundle",
"assets/systems/effects/heathaze/defaultheathaze.bundle",
"assets/systems/effects/muzzleflash/muzzleflash.bundle",
"assets/systems/effects/smoke.bundle",
"cubemaps",
"shaders"
]
},
{
"key":"reciever_ar15_vltor_mur-1s_retex.bundle",
"dependencyKeys":[
]
},
{
"key":"mag_ar10_lancer_l7_awm_762x51_20.bundle",
"dependencyKeys":[
]
},
{
"key":"mag_ar10_lancer_l7_awm_762x51_25.bundle",
"dependencyKeys":[
]
},
{
"key":"spear_black/textures/client_assets.bundle",
"dependencyKeys":[
]
},
{
"key":"spear_black/client_assets.bundle",
"dependencyKeys":[
"spear_black/textures/client_assets.bundle",
"cubemaps",
"shaders"
]
},
{
"key":"spear_black/weapon_sig_mcx_spear_68x51_container.bundle",
"dependencyKeys":[
"assets/commonassets/physics/physicsmaterials.bundle",
"assets/content/audio/blendoptions/assets.bundle",
"assets/content/audio/weapons/ak74.bundle",
"assets/content/audio/weapons/generic",
"assets/content/weapons/additional_hands/client_assets.bundle",
"assets/content/weapons/animations/simple_animations.bundle",
"assets/content/weapons/animations/spirit_animations.bundle",
"spear_black/client_assets.bundle",
"spear_black/textures/client_assets.bundle",
"assets/content/weapons/weapon_root_anim_fix.bundle",
"assets/content/weapons/wip/kibas tuning prefabs/muzzlejets_templates/default_assets.bundle",
"assets/systems/effects/heathaze/defaultheathaze.bundle",
"assets/systems/effects/muzzleflash/muzzleflash.bundle",
"assets/systems/effects/smoke.bundle",
"cubemaps",
"shaders"
]
},
{
"key":"spear_black/reciever_mcx_sig_spear_upper.bundle",
"dependencyKeys":[
"assets/commonassets/physics/physicsmaterials.bundle",
"spear_black/client_assets.bundle",
"spear_black/textures/client_assets.bundle",
"cubemaps",
"shaders"
]
},
{
"key":"pistolgrip_ar15_sig_reduced_angle_pistol_grip_ct_retex.bundle",
"dependencyKeys":[
]
},
{
"key":"handguard_mcx_sig_spear_m_lok_retex.bundle",
"dependencyKeys":[]
},
{
"key":"silencer_clutchlok_sig_slx68_mg_qd_suppressor_68x51_retex.bundle",
"dependencyKeys":[]
},
{
"key":"charge_spear_sig_spear_std_retex.bundle",
"dependencyKeys":[]
},
{
"key":"stock_ar15_magpul_moe_sl_k_carbine_ct_retex.bundle",
"dependencyKeys":[]
},
{
"key":"stock_base_sig_low_profile_tube_ct_retex.bundle",
"dependencyKeys":[]
},
{
"key":"balaclava/item_equipment_facecover_balaclava_black.bundle",
"dependencyKeys":[
"balaclava/wildman01head_textures_black.bundle"
]
},
{
"key":"balaclava/wildman01head_textures_black.bundle",
"dependencyKeys":[]
},
{
"key":"glasses/item_equipment_glasses_npp_retex.bundle",
"dependencyKeys":[]
},
{
"key":"rigs/cr_arscpc_retex.bundle",
"dependencyKeys":[]
},
{
"key":"rigs/item_equipment_rig_carriertactec_retex.bundle",
"dependencyKeys":[]
},
{
"key":"rigs/item_equipment_rig_tv110_retex.bundle",
"dependencyKeys":[]
},
{
"key":"rigs/item_equipment_rig_cryeavs_retex.bundle",
"dependencyKeys":[]
},
{
"key":"scope_all_vortex_razor_amg_uh-1_retex.bundle",
"dependencyKeys":[
"assets/commonassets/physics/physicsmaterials.bundle",
"assets/content/textures/holemanager/eotech_spec_mask.bundle",
"cubemaps",
"shaders"
]
},
{
"key":"tactical_all_insight_anpeq15_retex.bundle",
"dependencyKeys":[
"assets/commonassets/physics/physicsmaterials.bundle",
"assets/content/textures/holemanager/glow_particle_bright.bundle",
"assets/standard assets/effects/lightcookies/textures/flashlightcookie.bundle",
"assets/systems/effects/collimator.bundle",
"assets/systems/effects/laserbeam/laser.bundle",
"assets/systems/effects/multiflare/multiflare.bundle",
"assets/systems/effects/nightvision.bundle",
"cubemaps",
"shaders"
]
},
{
"key":"stock_ar15_fab_defense_gl_core_retex.bundle",
"dependencyKeys":[
]
},
{
"key":"scope_30mm_sig_tango6t_1_6x24_retex.bundle",
"dependencyKeys":[
"assets/commonassets/physics/physicsmaterials.bundle",
"assets/content/textures/holemanager/round_spec_mask.bundle",
"assets/systems/effects/opticsight/opticsightsmasks.bundle",
"cubemaps",
"shaders"
]
},
{
"key":"nvg_l3_gpnvg-18_anvis_retex.bundle",
"dependencyKeys":[
"assets/commonassets/physics/physicsmaterials.bundle",
"assets/content/items/equipment/glasses_6b34/glasses_6b34_glass_textures",
"cubemaps",
"shaders"
]
}
]
}
@@ -0,0 +1,603 @@
{
"ItemPresets": {
"6783f24f861dfacffe36b138": {
"_changeWeaponName": false,
"_encyclopedia": "672e37d19f1683101780773b",
"_id": "6783f24f861dfacffe36b138",
"_items": [
{
"_id": "6783f25b69d649d493cda1fd",
"_tpl": "672e37d19f1683101780773b",
"upd": {
"Repairable": {
"Durability": 100,
"MaxDurability": 100
}
}
},
{
"_id": "6783f26abcf5805ba9248ad7",
"_tpl": "55d4b9964bdc2d1d4e8b456e",
"parentId": "6783f25b69d649d493cda1fd",
"slotId": "mod_pistol_grip"
},
{
"_id": "6783f26d3b2ca6db3f36b858",
"_tpl": "55d4887d4bdc2d962f8b4570",
"parentId": "6783f25b69d649d493cda1fd",
"slotId": "mod_magazine"
},
{
"_id": "6783f2723a07e8c6a8006e9f",
"_tpl": "672e37d1249244ae3a50bb2f",
"parentId": "6783f25b69d649d493cda1fd",
"slotId": "mod_reciever"
},
{
"_id": "6783f29a304ff60a67653ddb",
"_tpl": "55d3632e4bdc2d972f8b4569",
"parentId": "6783f2723a07e8c6a8006e9f",
"slotId": "mod_barrel"
},
{
"_id": "6783f29f017667af4aeda8df",
"_tpl": "544a38634bdc2d58388b4568",
"parentId": "6783f29a304ff60a67653ddb",
"slotId": "mod_muzzle"
},
{
"_id": "6783f2a148624b6f5fe0a317",
"_tpl": "5ae30e795acfc408fb139a0b",
"parentId": "6783f29a304ff60a67653ddb",
"slotId": "mod_gas_block"
},
{
"_id": "6783f2a88b7b6cd3c9225511",
"_tpl": "5ae30db85acfc408fb139a05",
"parentId": "6783f2723a07e8c6a8006e9f",
"slotId": "mod_handguard"
},
{
"_id": "6783f2ad374903cfc652f22f",
"_tpl": "637f57a68d137b27f70c4968",
"parentId": "6783f2a88b7b6cd3c9225511",
"slotId": "mod_handguard"
},
{
"_id": "6783f2aeb598721f40ef1263",
"_tpl": "5ae30bad5acfc400185c2dc4",
"parentId": "6783f2723a07e8c6a8006e9f",
"slotId": "mod_sight_rear"
},
{
"_id": "6783f2af7cf3b743d3d8c1e2",
"_tpl": "5649be884bdc2d79388b4577",
"parentId": "6783f25b69d649d493cda1fd",
"slotId": "mod_stock"
},
{
"_id": "6783f2b54115cf68d3ffa632",
"_tpl": "55d4ae6c4bdc2d8b2f8b456e",
"parentId": "6783f2af7cf3b743d3d8c1e2",
"slotId": "mod_stock_000"
},
{
"_id": "6783f2b66dc7254a0401b1ca",
"_tpl": "55d44fd14bdc2d962f8b456e",
"parentId": "6783f25b69d649d493cda1fd",
"slotId": "mod_charge"
}
],
"_name": "M4A1 Std Painter Edition",
"_parent": "6783f25b69d649d493cda1fd",
"_type": "Preset"
},
"6783f192c8a5270c18aad6b6": {
"_changeWeaponName": false,
"_encyclopedia": "672e37d1ddaf7c656e3a634c",
"_id": "6783f192c8a5270c18aad6b6",
"_items": [
{
"_id": "6783f1a47ef435b43580168c",
"_tpl": "672e37d1ddaf7c656e3a634c",
"upd": {
"Repairable": {
"Durability": 100,
"MaxDurability": 100
}
}
},
{
"_id": "6783f1b85be1b42bf29e4a61",
"_tpl": "55d4b9964bdc2d1d4e8b456e",
"parentId": "6783f1a47ef435b43580168c",
"slotId": "mod_pistol_grip"
},
{
"_id": "6783f1bb8ce2bb9545fae1d8",
"_tpl": "55d4887d4bdc2d962f8b4570",
"parentId": "6783f1a47ef435b43580168c",
"slotId": "mod_magazine"
},
{
"_id": "6783f1c160f9c16d7f779a4d",
"_tpl": "55d355e64bdc2d962f8b4569",
"parentId": "6783f1a47ef435b43580168c",
"slotId": "mod_reciever"
},
{
"_id": "6783f1d493fa264e4493ac2e",
"_tpl": "55d3632e4bdc2d972f8b4569",
"parentId": "6783f1c160f9c16d7f779a4d",
"slotId": "mod_barrel"
},
{
"_id": "6783f1d9be58dbc9b2a069ba",
"_tpl": "544a38634bdc2d58388b4568",
"parentId": "6783f1d493fa264e4493ac2e",
"slotId": "mod_muzzle"
},
{
"_id": "6783f1daae07965124acac83",
"_tpl": "5ae30e795acfc408fb139a0b",
"parentId": "6783f1d493fa264e4493ac2e",
"slotId": "mod_gas_block"
},
{
"_id": "6783f1ddde94724c8bd6ca16",
"_tpl": "5ae30db85acfc408fb139a05",
"parentId": "6783f1c160f9c16d7f779a4d",
"slotId": "mod_handguard"
},
{
"_id": "6783f1e275d0b1ed88572ad0",
"_tpl": "637f57a68d137b27f70c4968",
"parentId": "6783f1ddde94724c8bd6ca16",
"slotId": "mod_handguard"
},
{
"_id": "6783f1e3fbc6c6dbf0aadc86",
"_tpl": "5ae30bad5acfc400185c2dc4",
"parentId": "6783f1c160f9c16d7f779a4d",
"slotId": "mod_sight_rear"
},
{
"_id": "6783f1ec39e6076911b5df9c",
"_tpl": "5649be884bdc2d79388b4577",
"parentId": "6783f1a47ef435b43580168c",
"slotId": "mod_stock"
},
{
"_id": "6783f1f09bad1af82a378d05",
"_tpl": "55d4ae6c4bdc2d8b2f8b456e",
"parentId": "6783f1ec39e6076911b5df9c",
"slotId": "mod_stock_000"
},
{
"_id": "6783f1f235ede9255929f2d4",
"_tpl": "55d44fd14bdc2d962f8b456e",
"parentId": "6783f1a47ef435b43580168c",
"slotId": "mod_charge"
}
],
"_name": "M4A1 Std Flames",
"_parent": "6783f1a47ef435b43580168c",
"_type": "Preset"
},
"6783f0fbb5c5bfbb971871e1": {
"_changeWeaponName": false,
"_encyclopedia": "672e37d1179b7b969b7577cb",
"_id": "6783f0fbb5c5bfbb971871e1",
"_items": [
{
"_id": "6783f10174bf20e471c5c055",
"_tpl": "672e37d1179b7b969b7577cb",
"upd": {
"Repairable": {
"Durability": 100,
"MaxDurability": 100
}
}
},
{
"_id": "6783f11512857c267b254af7",
"_tpl": "55d4b9964bdc2d1d4e8b456e",
"parentId": "6783f10174bf20e471c5c055",
"slotId": "mod_pistol_grip"
},
{
"_id": "6783f11aec8108543017f1e3",
"_tpl": "55d4887d4bdc2d962f8b4570",
"parentId": "6783f10174bf20e471c5c055",
"slotId": "mod_magazine"
},
{
"_id": "6783f1205747a3ea48865e73",
"_tpl": "55d355e64bdc2d962f8b4569",
"parentId": "6783f10174bf20e471c5c055",
"slotId": "mod_reciever"
},
{
"_id": "6783f1350fbe98026207e7ea",
"_tpl": "55d3632e4bdc2d972f8b4569",
"parentId": "6783f1205747a3ea48865e73",
"slotId": "mod_barrel"
},
{
"_id": "6783f13b8484c0c25a66be35",
"_tpl": "544a38634bdc2d58388b4568",
"parentId": "6783f1350fbe98026207e7ea",
"slotId": "mod_muzzle"
},
{
"_id": "6783f13dc1acd3ecae24270f",
"_tpl": "5ae30e795acfc408fb139a0b",
"parentId": "6783f1350fbe98026207e7ea",
"slotId": "mod_gas_block"
},
{
"_id": "6783f1488a3d2dc4157c8758",
"_tpl": "5ae30db85acfc408fb139a05",
"parentId": "6783f1205747a3ea48865e73",
"slotId": "mod_handguard"
},
{
"_id": "6783f151960a80ad5f9745ae",
"_tpl": "637f57a68d137b27f70c4968",
"parentId": "6783f1488a3d2dc4157c8758",
"slotId": "mod_handguard"
},
{
"_id": "6783f154906b450be0b3182f",
"_tpl": "5ae30bad5acfc400185c2dc4",
"parentId": "6783f1205747a3ea48865e73",
"slotId": "mod_sight_rear"
},
{
"_id": "6783f15600d12159f91920f6",
"_tpl": "5649be884bdc2d79388b4577",
"parentId": "6783f10174bf20e471c5c055",
"slotId": "mod_stock"
},
{
"_id": "6783f15bc0fe63d6d241fb9b",
"_tpl": "55d4ae6c4bdc2d8b2f8b456e",
"parentId": "6783f15600d12159f91920f6",
"slotId": "mod_stock_000"
},
{
"_id": "6783f1f861bc1198d4d14f7c",
"_tpl": "55d44fd14bdc2d962f8b456e",
"parentId": "6783f10174bf20e471c5c055",
"slotId": "mod_charge"
}
],
"_name": "M4A1 Std Topo",
"_parent": "6783f10174bf20e471c5c055",
"_type": "Preset"
},
"6783f026a570e11e98538c25": {
"_changeWeaponName": false,
"_encyclopedia": "672e37d1e35a6ec6e6997492",
"_id": "6783f026a570e11e98538c25",
"_items": [
{
"_id": "6783f04c9ff3e61038c7a73b",
"_tpl": "672e37d1e35a6ec6e6997492"
},
{
"_id": "6783f05f37f27dd00e59aa24",
"_tpl": "59c6633186f7740cf0493bb9",
"parentId": "6783f04c9ff3e61038c7a73b",
"slotId": "mod_gas_block"
},
{
"_id": "6783f07124277c3fd1890147",
"_tpl": "5648b1504bdc2d9d488b4584",
"parentId": "6783f05f37f27dd00e59aa24",
"slotId": "mod_handguard"
},
{
"_id": "6783f0741ec1081b46650491",
"_tpl": "5ac72e7d5acfc40016339a02",
"parentId": "6783f04c9ff3e61038c7a73b",
"slotId": "mod_muzzle"
},
{
"_id": "6783f0764bac8452114f4a95",
"_tpl": "5649ade84bdc2d1b2b8b4587",
"parentId": "6783f04c9ff3e61038c7a73b",
"slotId": "mod_pistol_grip"
},
{
"_id": "6783f0770459d79d0f33b9da",
"_tpl": "672e37d10c5f88d8ed0d056a",
"parentId": "6783f04c9ff3e61038c7a73b",
"slotId": "mod_reciever"
},
{
"_id": "6783f07a137b256bffe1cfb1",
"_tpl": "5ac50c185acfc400163398d4",
"parentId": "6783f04c9ff3e61038c7a73b",
"slotId": "mod_stock"
},
{
"_id": "6783f07c8853c5e4efc96806",
"_tpl": "5ac66bea5acfc43b321d4aec",
"parentId": "6783f04c9ff3e61038c7a73b",
"slotId": "mod_magazine"
}
],
"_name": "AK-103 Default Topo",
"_parent": "6783f04c9ff3e61038c7a73b",
"_type": "Preset"
},
"6783ec2851c792b686291cb9": {
"_changeWeaponName": false,
"_encyclopedia": "672e37d17f433cdb29072bc8",
"_id": "6783ec2851c792b686291cb9",
"_items": [
{
"_id": "6783ec33c8d50fdb6b63d3e9",
"_tpl": "672e37d17f433cdb29072bc8",
"upd": {
"FireMode": {
"FireMode": "single"
},
"Repairable": {
"Durability": 100,
"MaxDurability": 100
}
}
},
{
"_id": "657eb3773271d8578610fe2a",
"_tpl": "672e37d1861c12c7e1d94089",
"parentId": "6783ec33c8d50fdb6b63d3e9",
"slotId": "mod_pistol_grip"
},
{
"_id": "657eb3773271d8578610fe2b",
"_tpl": "672e37d19811257c1de39e6d",
"parentId": "6783ec33c8d50fdb6b63d3e9",
"slotId": "mod_magazine"
},
{
"_id": "6783ec4cf0b00cd50d9c2a87",
"_tpl": "672e37d133cc1fb4424ddb4c",
"parentId": "6783ec33c8d50fdb6b63d3e9",
"slotId": "mod_reciever"
},
{
"_id": "6783ec6e1a49dfd7571ae44e",
"_tpl": "5b2389515acfc4771e1be0c0",
"parentId": "6783ec4cf0b00cd50d9c2a87",
"slotId": "mod_scope"
},
{
"_id": "6783ec7588341583da153886",
"_tpl": "67617ec9ea1e82ea5e103054",
"parentId": "6783ec6e1a49dfd7571ae44e",
"slotId": "mod_scope_000"
},
{
"_id": "6783ec85d0fd3275f2ab164a",
"_tpl": "652910565ae2ae97b80fdf35",
"parentId": "6783ec4cf0b00cd50d9c2a87",
"slotId": "mod_barrel"
},
{
"_id": "6783ec955c4560dd83a3c26f",
"_tpl": "6529113b5ae2ae97b80fdf39",
"parentId": "6783ec85d0fd3275f2ab164a",
"slotId": "mod_muzzle"
},
{
"_id": "6783ec9892098902e42933bd",
"_tpl": "672e37d143ba463a1cdcbd7b",
"parentId": "6783ec955c4560dd83a3c26f",
"slotId": "mod_muzzle"
},
{
"_id": "6783ec9ddf30430fd30d48ef",
"_tpl": "652910bc24cbe3c74a05e5b9",
"parentId": "6783ec85d0fd3275f2ab164a",
"slotId": "mod_gas_block"
},
{
"_id": "6783ec9fb358c9d737de5800",
"_tpl": "672e37d1984bc9a10241a9c7",
"parentId": "6783ec4cf0b00cd50d9c2a87",
"slotId": "mod_handguard"
},
{
"_id": "6783eea29163d870c845e6b9",
"_tpl": "6529348224cbe3c74a05e5c4",
"parentId": "6783ec33c8d50fdb6b63d3e9",
"slotId": "mod_stock_000"
},
{
"_id": "6783eea6b0158f1b5bf6ba4e",
"_tpl": "672e37d151b832f3fb8ccbb0",
"parentId": "6783eea29163d870c845e6b9",
"slotId": "mod_stock"
},
{
"_id": "6783eeaa698962dfeeda79a3",
"_tpl": "672e37d1d9a55146e49287d6",
"parentId": "6783eea6b0158f1b5bf6ba4e",
"slotId": "mod_stock_000"
},
{
"_id": "6783eca92713d47b3f369d0b",
"_tpl": "672e37d1906226680c4e28d5",
"parentId": "6783ec33c8d50fdb6b63d3e9",
"slotId": "mod_charge"
}
],
"_name": "SIG SPEAR default black",
"_parent": "6783ec33c8d50fdb6b63d3e9",
"_type": "Preset"
},
"6783e5da52977a05d959ac2f": {
"_changeWeaponName": false,
"_encyclopedia": "672e37d1dd890afba20c10e7",
"_id": "6783e5da52977a05d959ac2f",
"_items": [
{
"_id": "6783e5f4c23d0a4830e3d069",
"_tpl": "672e37d1dd890afba20c10e7",
"upd": {
"Repairable": {
"Durability": 100,
"MaxDurability": 100
}
}
},
{
"_id": "6783e603e6cebbfe9babfb73",
"_tpl": "5cc9bcaed7f00c011c04e179",
"parentId": "6783e5f4c23d0a4830e3d069",
"slotId": "mod_pistol_grip"
},
{
"_id": "6783e60517f08a8301bbd2c5",
"_tpl": "5a3501acc4a282000d72293a",
"parentId": "6783e5f4c23d0a4830e3d069",
"slotId": "mod_magazine"
},
{
"_id": "6783e607810d48f18bc7e606",
"_tpl": "5a33ca0fc4a282000d72292f",
"parentId": "6783e5f4c23d0a4830e3d069",
"slotId": "mod_stock"
},
{
"_id": "6783e60ba048490f25da323e",
"_tpl": "5d44069ca4b9361ebd26fc37",
"parentId": "6783e607810d48f18bc7e606",
"slotId": "mod_stock"
},
{
"_id": "6783e60d0f11531e764dd864",
"_tpl": "5d00ef6dd7ad1a0940739b16",
"parentId": "6783e5f4c23d0a4830e3d069",
"slotId": "mod_handguard"
},
{
"_id": "6783e61457c31046a3d9466b",
"_tpl": "5a34fae7c4a2826c6e06d760",
"parentId": "6783e5f4c23d0a4830e3d069",
"slotId": "mod_barrel"
},
{
"_id": "6783e618cc78902eec1f2c0b",
"_tpl": "5a34fd2bc4a282329a73b4c5",
"parentId": "6783e61457c31046a3d9466b",
"slotId": "mod_muzzle"
},
{
"_id": "6783e61a7bfb5f73bdcef867",
"_tpl": "5a34fbadc4a28200741e230a",
"parentId": "6783e61457c31046a3d9466b",
"slotId": "mod_gas_block"
}
],
"_name": "RSASS Black",
"_parent": "6783e5f4c23d0a4830e3d069",
"_type": "Preset"
},
"6783eb2892780aded22f44d6": {
"_changeWeaponName": false,
"_encyclopedia": "672e37d10b7a12e6a7a50b77",
"_id": "6783eb2892780aded22f44d6",
"_items": [
{
"_id": "6783eb3a05c979d9171196e2",
"_tpl": "672e37d10b7a12e6a7a50b77",
"upd": {
"FireMode": {
"FireMode": "single"
}
}
},
{
"_id": "6783eb482a3ac74d07710776",
"_tpl": "55802f5d4bdc2dac148b458f",
"parentId": "6783eb3a05c979d9171196e2",
"slotId": "mod_pistol_grip"
},
{
"_id": "6783eb4de2e02a031c2d2eb9",
"_tpl": "59d6272486f77466146386ff",
"parentId": "6783eb3a05c979d9171196e2",
"slotId": "mod_magazine"
},
{
"_id": "6783eb54e77a16ac4853c726",
"_tpl": "672e37d1a98e0628807ba29a",
"parentId": "6783eb3a05c979d9171196e2",
"slotId": "mod_reciever"
},
{
"_id": "6783eb6f7e0a5b57278b5d8f",
"_tpl": "60658776f2cb2e02a42ace2b",
"parentId": "6783eb54e77a16ac4853c726",
"slotId": "mod_barrel"
},
{
"_id": "6783eb76f0ceaeb9063cdbf2",
"_tpl": "6065c6e7132d4d12c81fd8e1",
"parentId": "6783eb6f7e0a5b57278b5d8f",
"slotId": "mod_muzzle"
},
{
"_id": "6783eb7901da578da4b2230c",
"_tpl": "6065dc8a132d4d12c81fd8e3",
"parentId": "6783eb6f7e0a5b57278b5d8f",
"slotId": "mod_gas_block"
},
{
"_id": "6783eb7b04cdf6ff2fb14809",
"_tpl": "6065880c132d4d12c81fd8da",
"parentId": "6783eb54e77a16ac4853c726",
"slotId": "mod_handguard"
},
{
"_id": "6783eb7e73028d0ad6ba25a7",
"_tpl": "5bc09a30d4351e00367fb7c8",
"parentId": "6783eb7b04cdf6ff2fb14809",
"slotId": "mod_sight_front"
},
{
"_id": "6783eb801f0133eec60418fd",
"_tpl": "5bc09a18d4351e003562b68e",
"parentId": "6783eb54e77a16ac4853c726",
"slotId": "mod_sight_rear"
},
{
"_id": "6783eb82d4bfe4734f1968e8",
"_tpl": "606587e18900dc2d9a55b65f",
"parentId": "6783eb3a05c979d9171196e2",
"slotId": "mod_stock_001"
},
{
"_id": "6783eb85ede00f4e10fe95fa",
"_tpl": "606587d11246154cad35d635",
"parentId": "6783eb82d4bfe4734f1968e8",
"slotId": "mod_stock_000"
},
{
"_id": "6783eb8781c4dad6d094d7d5",
"_tpl": "606587bd6d0bd7580617bacc",
"parentId": "6783eb3a05c979d9171196e2",
"slotId": "mod_charge"
}
],
"_name": "CMMG MK47 short default black",
"_parent": "6783eb3a05c979d9171196e2",
"_type": "Preset"
}
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,26 @@
{
"name": "Black Core",
"version": "1.1.6",
"main": "src/mod.js",
"license": "University of Illinois/NCSA Open Source License",
"author": "MoxoPixel",
"sptVersion": "3.10.X",
"isBundleMod": true,
"scripts": {
"setup": "npm i",
"build": "node ./build.mjs",
"buildinfo": "node ./build.mjs --verbose"
},
"devDependencies": {
"@types/node": "20.11",
"@typescript-eslint/eslint-plugin": "7.2",
"@typescript-eslint/parser": "7.2",
"archiver": "^6.0",
"eslint": "8.57",
"fs-extra": "11.2",
"ignore": "^5.2",
"tsyringe": "4.8.0",
"typescript": "5.4",
"winston": "3.12"
}
}
@@ -0,0 +1,236 @@
import { DependencyContainer } from "tsyringe";
import { IPostDBLoadMod } from "@spt/models/external/IPostDBLoadMod";
import { DatabaseServer } from "@spt/servers/DatabaseServer";
import { ImporterUtil } from "@spt/utils/ImporterUtil";
import { ILogger } from "@spt/models/spt/utils/ILogger";
import { PreSptModLoader } from "@spt/loaders/PreSptModLoader";
import { IDatabaseTables } from "@spt/models/spt/server/IDatabaseTables";
import { JsonUtil } from "@spt/utils/JsonUtil"
interface IHandbookEntry {
Id: string;
ParentId: string;
Price: number;
}
class BlackCore implements IPostDBLoadMod {
private db: IDatabaseTables;
private mydb: any;
private logger: ILogger;
private jsonUtil: JsonUtil;
public postDBLoad(container: DependencyContainer): void {
try {
this.logger = container.resolve<ILogger>("WinstonLogger");
this.jsonUtil = container.resolve<JsonUtil>("JsonUtil");
const databaseServer = container.resolve<DatabaseServer>("DatabaseServer");
const databaseImporter = container.resolve<ImporterUtil>("ImporterUtil");
const modLoader = container.resolve<PreSptModLoader>("PreSptModLoader");
this.db = databaseServer.getTables();
this.mydb = databaseImporter.loadRecursive(`${modLoader.getModPath("MoxoPixel-BlackCore")}database/`);
if (!this.db || !this.mydb) {
throw new Error("Failed to load required databases");
}
const modFolderName = "MoxoPixel-BlackCore";
const traders = {
"painter": "668aaff35fd574b6dcc4a686"
};
for (const newItem in this.mydb.items) {
this.cloneItem(this.mydb.items[newItem].clone, newItem);
this.addCompatibilitiesAndConflicts(this.mydb.items[newItem].clone, newItem);
const newItemLocales = this.mydb.items[newItem].locales;
for (const lang in this.db.locales.global) {
this.db.locales.global[lang][`${newItem} Name`] = newItemLocales.Name;
this.db.locales.global[lang][`${newItem} ShortName`] = newItemLocales.Shortname;
this.db.locales.global[lang][`${newItem} Description`] = newItemLocales.Description;
}
}
for (const trader in traders) this.addTraderAssort(traders[trader]);
for (const preset in this.mydb.globals.ItemPresets) {
this.db.globals.ItemPresets[preset] = this.mydb.globals.ItemPresets[preset];
}
const dbMastering = this.db.globals.config.Mastering;
for (const weapon in dbMastering) {
if (dbMastering[weapon].Name == "M4") dbMastering[weapon].Templates.push("672e37d1179b7b969b7577cb", "672e37d1ddaf7c656e3a634c", "672e37d19f1683101780773b");
if (dbMastering[weapon].Name == "AK74") dbMastering[weapon].Templates.push("672e37d1e35a6ec6e6997492");
if (dbMastering[weapon].Name == "R11SRASS") dbMastering[weapon].Templates.push("672e37d1dd890afba20c10e7");
if (dbMastering[weapon].Name == "MK47") dbMastering[weapon].Templates.push("672e37d10b7a12e6a7a50b77");
if (dbMastering[weapon].Name == "SPEAR") dbMastering[weapon].Templates.push("672e37d17f433cdb29072bc8");
}
const dbQuests = this.db.templates.quests;
for (const M4Quest in dbQuests) {
if (
dbQuests[M4Quest]._id === "5a27bb8386f7741c770d2d0a" ||
dbQuests[M4Quest]._id === "5c0d4c12d09282029f539173" ||
dbQuests[M4Quest]._id === "63a9b229813bba58a50c9ee5" ||
dbQuests[M4Quest]._id === "64e7b9bffd30422ed03dad38" ||
dbQuests[M4Quest]._id === "666314b4d7f171c4c20226c3"
) {
const availableForFinish = dbQuests[M4Quest].conditions.AvailableForFinish;
for (const condition of availableForFinish) {
if (condition.counter && condition.counter.conditions) {
for (const counterCondition of condition.counter.conditions) {
if (counterCondition.weapon) {
counterCondition.weapon.push(
"672e37d1179b7b969b7577cb",
"672e37d1ddaf7c656e3a634c",
"672e37d19f1683101780773b"
);
}
}
}
}
}
}
for (const AKQuest in dbQuests) {
if (
dbQuests[AKQuest]._id === "59c50a9e86f7745fef66f4ff" ||
dbQuests[AKQuest]._id === "61e6e60223374d168a4576a6" ||
dbQuests[AKQuest]._id === "64e7b9bffd30422ed03dad38"
) {
const availableForFinish = dbQuests[AKQuest].conditions.AvailableForFinish;
for (const condition of availableForFinish) {
if (condition.counter && condition.counter.conditions) {
for (const counterCondition of condition.counter.conditions) {
if (counterCondition.weapon) {
counterCondition.weapon.push(
"672e37d1e35a6ec6e6997492"
);
}
}
}
}
}
}
for (const MK47Quest in dbQuests) {
if (
dbQuests[MK47Quest]._id === "64e7b9bffd30422ed03dad38"
) {
const availableForFinish = dbQuests[MK47Quest].conditions.AvailableForFinish;
for (const condition of availableForFinish) {
if (condition.counter && condition.counter.conditions) {
for (const counterCondition of condition.counter.conditions) {
if (counterCondition.weapon) {
counterCondition.weapon.push(
"672e37d10b7a12e6a7a50b77",
"672e37d17f433cdb29072bc8"
);
}
}
}
}
}
}
this.logger.info("------------------------");
this.logger.info("Black Core Loaded");
} catch (error) {
this.logger.error(`Error loading BlackCore mod: ${error.message}`);
}
}
private cloneItem(itemToClone: string, blackCoreID: string): void {
if (!itemToClone || !blackCoreID) {
this.logger.error("Invalid parameters passed to cloneItem");
return;
}
if (!this.mydb.items[blackCoreID]?.enable) {
return;
}
if (!this.db.templates.items[itemToClone]) {
this.logger.error(`Template item ${itemToClone} not found`);
return;
}
if (this.mydb.items[blackCoreID].enable == true) {
let blackCoreItemOut = this.jsonUtil.clone(this.db.templates.items[itemToClone]);
blackCoreItemOut._id = blackCoreID;
blackCoreItemOut = this.compareAndReplace(blackCoreItemOut, this.mydb.items[blackCoreID]["items"]);
const bcCompatibilities: object = (typeof this.mydb.items[blackCoreID].bcCompatibilities == "undefined") ? {} : this.mydb.items[blackCoreID].bcCompatibilities;
const bcConflicts: Array<string> = (typeof this.mydb.items[blackCoreID].bcConflicts == "undefined") ? [] : this.mydb.items[blackCoreID].bcConflicts;
for (const modSlotName in bcCompatibilities) {
for (const slot of blackCoreItemOut._props.Slots) {
if (slot._name === modSlotName) for (const id of bcCompatibilities[modSlotName]) slot._props.filters[0].Filter.push(id);
}
}
blackCoreItemOut._props.ConflictingItems = blackCoreItemOut._props.ConflictingItems.concat(bcConflicts);
this.db.templates.items[blackCoreID] = blackCoreItemOut;
const handbookEntry: IHandbookEntry = {
"Id": blackCoreID,
"ParentId": this.mydb.items[blackCoreID]["handbook"]["ParentId"],
"Price": this.mydb.items[blackCoreID]["handbook"]["Price"]
};
this.db.templates.handbook.Items.push(handbookEntry);
}
}
private compareAndReplace(originalItem: any, attributesToChange: any): any {
for (const key in attributesToChange) {
if ((["boolean", "string", "number"].includes(typeof attributesToChange[key])) || Array.isArray(attributesToChange[key])) {
if (key in originalItem) originalItem[key] = attributesToChange[key];
else this.logger.error("Error finding the attribute: \"" + key + "\", default value is used instead.");
}
else originalItem[key] = this.compareAndReplace(originalItem[key], attributesToChange[key]);
}
return originalItem;
}
private addCompatibilitiesAndConflicts(itemClone: string, blackCoreID: string): void {
for (const item in this.db.templates.items) {
if (item in this.mydb.items) continue;
const slots = (typeof this.db.templates.items[item]._props.Slots === "undefined") ? [] : this.db.templates.items[item]._props.Slots;
const chambers = (typeof this.db.templates.items[item]._props.Chambers === "undefined") ? [] : this.db.templates.items[item]._props.Chambers;
const cartridges = (typeof this.db.templates.items[item]._props.Cartridges === "undefined") ? [] : this.db.templates.items[item]._props.Cartridges;
const combined = slots.concat(chambers, cartridges)
for (const entry of combined) {
for (const id of entry._props.filters[0].Filter) {
if (id === itemClone) entry._props.filters[0].Filter.push(blackCoreID);
}
}
const conflictingItems = (typeof this.db.templates.items[item]._props.ConflictingItems === "undefined") ? [] : this.db.templates.items[item]._props.ConflictingItems;
for (const conflictID of conflictingItems) if (conflictID === itemClone) conflictingItems.push(blackCoreID);
}
}
private addTraderAssort(trader: string): void {
if (!this.db.traders[trader]?.assort || !this.mydb.traders[trader]?.assort) {
this.logger.error(`Invalid trader assort data for trader: ${trader}`);
return;
}
for (const item in this.mydb.traders[trader].assort.items) {
this.db.traders[trader].assort.items.push(this.mydb.traders[trader].assort.items[item]);
}
for (const item in this.mydb.traders[trader].assort.barter_scheme) {
this.db.traders[trader].assort.barter_scheme[item] = this.mydb.traders[trader].assort.barter_scheme[item];
}
for (const item in this.mydb.traders[trader].assort.loyal_level_items) {
this.db.traders[trader].assort.loyal_level_items[item] = this.mydb.traders[trader].assort.loyal_level_items[item];
}
}
}
module.exports = { mod: new BlackCore() }
@@ -130,9 +130,9 @@ scavMaxGroupSize = 4
## Max pmc group size ## Max pmc group size
# Setting type: Int32 # Setting type: Int32
# Default value: 5 # Default value: 4
# Acceptable value range: From 0 to 10 # Acceptable value range: From 0 to 10
pmcMaxGroupSize = 5 pmcMaxGroupSize = 4
## Increases chances of pmc groups spawning, doesn't dramatically increase quantity. ## Increases chances of pmc groups spawning, doesn't dramatically increase quantity.
# Setting type: Boolean # Setting type: Boolean
@@ -158,9 +158,9 @@ MaxBotCap = 25
## This controls the health of zombies ## This controls the health of zombies
# Setting type: Double # Setting type: Double
# Default value: 0.5 # Default value: 1
# Acceptable value range: From 0 to 3 # Acceptable value range: From 0 to 3
ZombieHealth = 0.5 ZombieHealth = 1
## Multiplies wave counts seen in the server's mapConfig.json by this number ## Multiplies wave counts seen in the server's mapConfig.json by this number
# Setting type: Double # Setting type: Double
@@ -170,14 +170,14 @@ ZombieWaveQuantity = 1
## Determines the weighting of spawns at the beginning (1) spread evenly throughout (0.5) or at the end(0) of the raid ## Determines the weighting of spawns at the beginning (1) spread evenly throughout (0.5) or at the end(0) of the raid
# Setting type: Double # Setting type: Double
# Default value: 0.2 # Default value: 0.5
# Acceptable value range: From 0 to 1 # Acceptable value range: From 0 to 1
ZombieWaveDistribution = 0.2 ZombieWaveDistribution = 0.5
## Enables zombies to spawn ## Enables zombies to spawn
# Setting type: Boolean # Setting type: Boolean
# Default value: true # Default value: false
zombiesEnabled On/Off = true zombiesEnabled On/Off = false
## Determines the weighting of spawns at the beginning (1) spread evenly throughout (0.5) or at the end(0) of the raid ## Determines the weighting of spawns at the beginning (1) spread evenly throughout (0.5) or at the end(0) of the raid
# Setting type: Double # Setting type: Double
@@ -187,21 +187,21 @@ ScavWaveDistribution = 0.5
## Determines the weighting of spawns at the beginning (1) spread evenly throughout (0.5) or at the end(0) of the raid ## Determines the weighting of spawns at the beginning (1) spread evenly throughout (0.5) or at the end(0) of the raid
# Setting type: Double # Setting type: Double
# Default value: 0.8 # Default value: 0.7
# Acceptable value range: From 0 to 1 # Acceptable value range: From 0 to 1
PmcWaveDistribution = 0.8 PmcWaveDistribution = 0.7
## Multiplies wave counts seen in the server's mapConfig.json by this number ## Multiplies wave counts seen in the server's mapConfig.json by this number
# Setting type: Double # Setting type: Double
# Default value: 1.5 # Default value: 1
# Acceptable value range: From 0 to 10 # Acceptable value range: From 0 to 10
ScavWaveQuantity = 1.5 ScavWaveQuantity = 1
## Multiplies wave counts seen in the server's mapConfig.json by this number ## Multiplies wave counts seen in the server's mapConfig.json by this number
# Setting type: Double # Setting type: Double
# Default value: 1.5 # Default value: 1
# Acceptable value range: From 0 to 10 # Acceptable value range: From 0 to 10
PmcWaveQuantity = 1.5 PmcWaveQuantity = 1
[3.Debug] [3.Debug]
@@ -51,7 +51,7 @@ Gating level = 0
## Will reset when the game opens. You are supposed to use the gating increase/decrease keys to change the gating level, but you are free to change it manually if you want to make sure you are at a specific gating level. ## Will reset when the game opens. You are supposed to use the gating increase/decrease keys to change the gating level, but you are free to change it manually if you want to make sure you are at a specific gating level.
# Setting type: Int32 # Setting type: Int32
# Default value: 0 # Default value: 0
Gating level = 0 Gating level = -2
1.Manual gating increase = KeypadPlus 1.Manual gating increase = KeypadPlus
+11 -8
View File
@@ -7,6 +7,7 @@
"tyfon-uifixes", "tyfon-uifixes",
"MoreCheckmarksBackend", "MoreCheckmarksBackend",
"ExpandedTaskText", "ExpandedTaskText",
"aMoxoPixel-Painter",
"acidphantasm-bosseshavelegamedals", "acidphantasm-bosseshavelegamedals",
"acidphantasm-defaultfiremode", "acidphantasm-defaultfiremode",
"acidphantasm-refsptfriendlyquests", "acidphantasm-refsptfriendlyquests",
@@ -17,6 +18,9 @@
"choccy-striker-1.0.5", "choccy-striker-1.0.5",
"flir-betterkeysng", "flir-betterkeysng",
"redlaser42-Increase Climb Height", "redlaser42-Increase Climb Height",
"MoxoPixel-BlackCore",
"Additional Clothing USEC",
"Additional Clothing BEAR",
"WTT-LittleDrummerBoy", "WTT-LittleDrummerBoy",
"WTTArmoryAk5C", "WTTArmoryAk5C",
"WTTArmoryHK417", "WTTArmoryHK417",
@@ -24,21 +28,20 @@
"WTTArmorySVD", "WTTArmorySVD",
"choccy-rpg7-1.1.4", "choccy-rpg7-1.1.4",
"choccy-saa-1.0.7", "choccy-saa-1.0.7",
"raid_review__0.3.0", "BRNVG_N-15Adapter",
"z_hacker228-makevalvssgreatagain",
"OpticRework-310",
"tyfon-weaponcustomizer",
"ArenaLockboxes-Delod-1.0.0",
"lacyway-mergeconsumables", "lacyway-mergeconsumables",
"acidphantasm-brightlasers", "acidphantasm-brightlasers",
"AUG_AttachmentPack", "AUG_AttachmentPack",
"shibdib-shibsexpandedcrafts", "shibdib-shibsexpandedcrafts",
"zSolarint-SAIN-ServerMod", "zSolarint-SAIN-ServerMod",
"Skwizzy-LootingBots-ServerMod", "Skwizzy-LootingBots-ServerMod",
"acidphantasm-progressivebotsystem",
"DewardianDev-MOAR", "DewardianDev-MOAR",
"inory-dynamicgoons", "inory-dynamicgoons",
"acidphantasm-progressivebotsystem", "raid_review__0.3.0"
"ArenaLockboxes-Delod-1.0.0",
"tyfon-weaponcustomizer",
"Additional Clothing BEAR",
"Additional Clothing USEC",
"BRNVG_N-15Adapter",
"OpticRework-310"
] ]
} }
+1 -1
View File
@@ -6,7 +6,7 @@ newestVersion=
category="1," category="1,"
nexusFileStatus=1 nexusFileStatus=1
installationFile=DewardianDev-MOAR-2.6.7.zip installationFile=DewardianDev-MOAR-2.6.7.zip
repository=Nexus repository=
ignoredVersion= ignoredVersion=
comments= comments=
notes= notes=
@@ -5,7 +5,7 @@
"scavDifficulty": 0.4, "scavDifficulty": 0.4,
"scavWaveDistribution": 0.5, "scavWaveDistribution": 0.5,
"scavWaveQuantity": 1.5, "scavWaveQuantity": 1,
"startingPmcs": false, "startingPmcs": false,
@@ -13,20 +13,20 @@
"pmcOpenZones": true, "pmcOpenZones": true,
"allOpenZones": false, "allOpenZones": false,
"pmcWaveDistribution": 0.8, "pmcWaveDistribution": 0.7,
"pmcWaveQuantity": 1.5, "pmcWaveQuantity": 1,
"zombiesEnabled": true, "zombiesEnabled": false,
"zombieWaveDistribution": 0.2, "zombieWaveDistribution": 0.5,
"zombieWaveQuantity": 1, "zombieWaveQuantity": 1,
"zombieHealth": 0.5, "zombieHealth": 1,
"maxBotCap": 25, "maxBotCap": 25,
"maxBotPerZone": 5, "maxBotPerZone": 5,
"moreScavGroups": false, "moreScavGroups": false,
"morePmcGroups": false, "morePmcGroups": false,
"pmcMaxGroupSize": 5, "pmcMaxGroupSize": 4,
"scavMaxGroupSize": 4, "scavMaxGroupSize": 4,
"snipersHaveFriends": false, "snipersHaveFriends": false,
@@ -1,11 +1,11 @@
[General] [General]
gameName=spt gameName=spt
modid=0 modid=0
version=d2025.1.14.0 version=d2025.1.13.0
newestVersion= newestVersion=
category="1," category="1,"
nexusFileStatus=1 nexusFileStatus=1
installationFile=SWAG-Donuts-v4.0.0RC4-SPT310x.7z installationFile=DewardianDev-MOAR-2.6.7.zip
repository=Nexus repository=Nexus
ignoredVersion= ignoredVersion=
comments= comments=
@@ -15,7 +15,7 @@ url=
hasCustomURL=false hasCustomURL=false
lastNexusQuery= lastNexusQuery=
lastNexusUpdate= lastNexusUpdate=
nexusLastModified=2024-12-18T07:07:11Z nexusLastModified=2024-12-16T06:46:30Z
nexusCategory=0 nexusCategory=0
converted=false converted=false
validated=false validated=false
@@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2023 Kevin Copyright (c) 2023 Dushaoan
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@@ -0,0 +1,12 @@
{
"live-like": 25,
"more-scavs": 8,
"more-pmcs": 8,
"more-scavs-and-pmcs": 5,
"main-boss-roaming": 5,
"sniper-buddies": 4,
"boss-invasion": 2,
"rogue-invasion": 0,
"raider-invasion": 0,
"insanity": 0
}
@@ -0,0 +1,64 @@
{
"live-like": {},
"more-scavs": {
"moreScavGroups": true,
"scavMaxGroupSize": 5,
"scavWaveQuantity": 1.2
},
"more-pmcs": {
"scavWaveDistribution": 0.4,
"morePmcGroups": true,
"pmcMaxGroupSize": 5,
"pmcWaveQuantity": 1.2
},
"more-scavs-and-pmcs": {
"scavWaveDistribution": 0.4,
"moreScavGroups": true,
"scavMaxGroupSize": 5,
"morePmcGroups": true,
"pmcMaxGroupSize": 5,
"scavWaveQuantity": 1.2,
"pmcWaveQuantity": 1.2,
"mainBossChanceBuff": 25
},
"boss-invasion": {
"bossOpenZones": true,
"bossInvasion": true,
"bossInvasionSpawnChance": 10,
"mainBossChanceBuff": 25,
"gradualBossInvasion": true
},
"rogue-invasion": {
"randomRaiderGroup": true,
"randomRaiderGroupChance": 50
},
"raider-invasion": {
"randomRaiderGroup": true,
"randomRaiderGroupChance": 50
},
"insanity": {
"scavWaveDistribution": 0.4,
"scavWaveQuantity": 1.3,
"pmcWaveQuantity": 1.3,
"moreScavGroups": true,
"morePmcGroups": true,
"pmcMaxGroupSize": 6,
"scavMaxGroupSize": 6,
"snipersHaveFriends": true,
"bossOpenZones": true,
"randomRaiderGroup": true,
"randomRaiderGroupChance": 50,
"randomRogueGroup": true,
"randomRogueGroupChance": 50,
"mainBossChanceBuff": 50,
"bossInvasion": true,
"bossInvasionSpawnChance": 10
},
"main-boss-roaming": {
"bossOpenZones": true,
"mainBossChanceBuff": 35
},
"sniper-buddies": {
"snipersHaveFriends": true
}
}
@@ -0,0 +1,63 @@
{
"ADD_THESE_TO_A_MAP_TO_OVERRIDE_OR_ADD_A_BOSS_TO_A_MAP": {
"BOSS_NAME_EXAMPLE": "CHANCE_OF_SPAWNING_PERCENT",
"sectantPriest": 0,
"arenaFighterEvent": 0,
"bossBoarSniper": 0,
"pmcBot": 0,
"bossZryachiy": 0,
"exUsec": 0,
"crazyAssaultEvent": 0,
"peacemaker": 0,
"bossKojaniy": 0,
"bossGluhar": 0,
"bossSanitar": 0,
"bossKilla": 0,
"bossTagilla": 0,
"bossKnight": 0,
"bossBoar": 0,
"bossKolontay": 0,
"bossPartisan": 0,
"bossBully": 0
},
"customs": {
"bossKnight": 30,
"bossPartisan": 30,
"bossBully": 30
},
"factoryDay": {
"bossTagilla": 30
},
"factoryNight": {
"bossTagilla": 30
},
"interchange": {
"bossKilla": 30
},
"laboratory": {},
"lighthouse": {
"bossKnight": 30,
"bossPartisan": 30
},
"rezervbase": {
"bossGluhar": 30
},
"shoreline": {
"bossKnight": 30,
"bossPartisan": 30,
"bossSanitar": 30
},
"tarkovstreets": {
"bossBoar": 30,
"bossKolontay": 30
},
"woods": {
"bossKojaniy": 30,
"bossKnight": 30,
"bossPartisan": 30
},
"gzLow": {},
"gzHigh": {
"bossKolontay": 30
}
}
@@ -0,0 +1,50 @@
{
"enableBotSpawning": true,
"pmcDifficulty": 0.6,
"scavDifficulty": 0.4,
"scavWaveDistribution": 0.5,
"scavWaveQuantity": 1.0,
"startingPmcs": false,
"playerOpenZones": false,
"pmcOpenZones": true,
"allOpenZones": false,
"pmcWaveDistribution": 0.8,
"pmcWaveQuantity": 1.0,
"zombiesEnabled": true,
"zombieWaveDistribution": 0.2,
"zombieWaveQuantity": 1,
"zombieHealth": 0.5,
"maxBotCap": 25,
"maxBotPerZone": 5,
"moreScavGroups": false,
"morePmcGroups": false,
"pmcMaxGroupSize": 5,
"scavMaxGroupSize": 4,
"snipersHaveFriends": false,
"bossOpenZones": false,
"randomRaiderGroup": false,
"randomRaiderGroupChance": 10,
"randomRogueGroup": false,
"randomRogueGroupChance": 10,
"disableBosses": false,
"mainBossChanceBuff": 0,
"bossInvasion": false,
"bossInvasionSpawnChance": 5,
"gradualBossInvasion": true,
"debug": false
}
@@ -0,0 +1,110 @@
{
"customs": {
"spawnMinDistance": 30,
"pmcWaveCount": 14,
"scavWaveCount": 21,
"zombieWaveCount": 9,
"scavHotZones": [
"ZoneDormitory"
],
"pmcHotZones": [
"ZoneDormitory"
]
},
"factoryDay": {
"spawnMinDistance": 20,
"maxBotCapOverride": 12,
"maxBotPerZoneOverride": 10,
"pmcWaveCount": 10,
"scavWaveCount": 10,
"zombieWaveCount": 6
},
"factoryNight": {
"spawnMinDistance": 20,
"maxBotCapOverride": 12,
"maxBotPerZoneOverride": 10,
"pmcWaveCount": 10,
"scavWaveCount": 10,
"zombieWaveCount": 6
},
"interchange": {
"spawnMinDistance": 40,
"pmcWaveCount": 16,
"scavWaveCount": 32,
"zombieWaveCount": 12,
"scavHotZones": [
"ZoneCenterBot",
"ZoneCenter"
]
},
"laboratory": {
"spawnMinDistance": 20,
"pmcWaveCount": 12,
"scavWaveCount": 0,
"zombieWaveCount": 12
},
"lighthouse": {
"spawnMinDistance": 40,
"pmcWaveCount": 14,
"scavWaveCount": 22,
"zombieWaveCount": 10,
"scavHotZones": [
"Zone_LongRoad",
"Zone_LongRoad"
]
},
"rezervbase": {
"spawnMinDistance": 40,
"pmcWaveCount": 14,
"scavWaveCount": 26,
"zombieWaveCount": 9,
"scavHotZones": [
"ZoneRailStrorage"
],
"pmcHotZones": [
"ZoneBarrack"
]
},
"shoreline": {
"spawnMinDistance": 40,
"pmcWaveCount": 16,
"scavWaveCount": 32,
"zombieWaveCount": 12,
"scavHotZones": [
"ZoneSanatorium1"
],
"pmcHotZones": [
"ZoneSanatorium2"
]
},
"tarkovstreets": {
"spawnMinDistance": 40,
"pmcWaveCount": 16,
"scavWaveCount": 28,
"zombieWaveCount": 13
},
"woods": {
"spawnMinDistance": 40,
"pmcWaveCount": 16,
"scavWaveCount": 28,
"zombieWaveCount": 10,
"scavHotZones": [
"ZoneWoodCutter"
],
"pmcHotZones": [
"ZoneWoodCutter"
]
},
"gzLow": {
"spawnMinDistance": 30,
"pmcWaveCount": 12,
"scavWaveCount": 18,
"zombieWaveCount": 9
},
"gzHigh": {
"spawnMinDistance": 30,
"pmcWaveCount": 12,
"scavWaveCount": 18,
"zombieWaveCount": 9
}
}
@@ -0,0 +1,25 @@
{
"name": "MOAR",
"version": "2.6.7",
"main": "src/mod.js",
"license": "MIT",
"author": "DewardianDev",
"sptVersion": "^3.10.x",
"scripts": {
"setup": "npm i",
"build": "node ./packageBuild.ts"
},
"devDependencies": {
"@semantic-release/git": "^10.0.1",
"@types/node": "16.18.10",
"@typescript-eslint/eslint-plugin": "5.46.1",
"@typescript-eslint/parser": "5.46.1",
"bestzip": "2.2.1",
"eslint": "8.30.0",
"fs-extra": "11.1.0",
"glob": "8.0.3",
"semantic-release": "^24.2.0",
"tsyringe": "4.7.0",
"typescript": "4.9.4"
}
}
@@ -0,0 +1,11 @@
import config from "../config/config.json";
import { ILocationBase } from "@spt/models/eft/common/ILocationBase";
export class globalValues {
public static baseConfig: typeof config = undefined;
public static overrideConfig: Partial<typeof config> = undefined;
public static locationsBase: ILocationBase[] = undefined;
public static currentPreset: string = "";
public static forcedPreset: string = "custom";
public static addedMapZones: Record<string, string[]> = {};
}
@@ -0,0 +1,168 @@
import { DependencyContainer } from "tsyringe";
import { buildWaves } from "../Spawning/Spawning";
import { StaticRouterModService } from "@spt/services/mod/staticRouter/StaticRouterModService";
// import { DynamicRouterModService } from "@spt/services/mod/dynamicRouter/DynamicRouterModService";
import { globalValues } from "../GlobalValues";
import { kebabToTitle } from "../utils";
import PresetWeightingsConfig from "../../config/PresetWeightings.json";
export const setupRoutes = (container: DependencyContainer) => {
const staticRouterModService = container.resolve<StaticRouterModService>(
"StaticRouterModService"
);
// const dynamicRouterModService = container.resolve<DynamicRouterModService>(
// "DynamicRouterModService"
// );
// Make buildwaves run on game end
staticRouterModService.registerStaticRouter(
`moarUpdater`,
[
{
url: "/client/match/local/end",
action: async (_url, info, sessionId, output) => {
buildWaves(container);
return output;
},
},
],
"moarUpdater"
);
staticRouterModService.registerStaticRouter(
`moarGetCurrentPreset`,
[
{
url: "/moar/currentPreset",
action: async () => {
return globalValues.forcedPreset || "random";
},
},
],
"moarGetCurrentPreset"
);
staticRouterModService.registerStaticRouter(
`moarGetAnnouncePreset`,
[
{
url: "/moar/announcePreset",
action: async () => {
if (globalValues.forcedPreset?.toLowerCase() === "random") {
return globalValues.currentPreset;
}
return globalValues.forcedPreset || globalValues.currentPreset;
},
},
],
"moarGetAnnouncePreset"
);
staticRouterModService.registerStaticRouter(
`getDefaultConfig`,
[
{
url: "/moar/getDefaultConfig",
action: async () => {
return JSON.stringify(globalValues.baseConfig);
},
},
],
"getDefaultConfig"
);
staticRouterModService.registerStaticRouter(
`getServerConfigWithOverrides`,
[
{
url: "/moar/getServerConfigWithOverrides",
action: async () => {
return JSON.stringify({
...(globalValues.baseConfig || {}),
...(globalValues.overrideConfig || {}),
});
},
},
],
"getServerConfigWithOverrides"
);
staticRouterModService.registerStaticRouter(
`getServerConfigWithOverrides`,
[
{
url: "/moar/getServerConfigWithOverrides",
action: async () => {
return JSON.stringify({
...globalValues.baseConfig,
...globalValues.overrideConfig,
});
},
},
],
"getServerConfigWithOverrides"
);
staticRouterModService.registerStaticRouter(
`moarGetPresetsList`,
[
{
url: "/moar/getPresets",
action: async () => {
let result = [
...Object.keys(PresetWeightingsConfig).map((preset) => ({
Name: kebabToTitle(preset),
Label: preset,
})),
{ Name: "Random", Label: "random" },
{ Name: "Custom", Label: "custom" },
];
return JSON.stringify({ data: result });
},
},
],
"moarGetPresetsList"
);
staticRouterModService.registerStaticRouter(
"setOverrideConfig",
[
{
url: "/moar/setOverrideConfig",
action: async (
url: string,
overrideConfig: typeof globalValues.overrideConfig = {},
sessionID,
output
) => {
globalValues.overrideConfig = overrideConfig;
buildWaves(container);
return "Success";
},
},
],
"setOverrideConfig"
);
staticRouterModService.registerStaticRouter(
"moarSetPreset",
[
{
url: "/moar/setPreset",
action: async (url: string, { Preset }, sessionID, output) => {
globalValues.forcedPreset = Preset;
buildWaves(container);
return `Current Preset: ${kebabToTitle(
globalValues.forcedPreset || "Random"
)}`;
},
},
],
"moarSetPreset"
);
};
@@ -0,0 +1,158 @@
import { IBotConfig } from "@spt/models/spt/config/IBotConfig.d";
import { IPmcConfig } from "@spt/models/spt/config/IPmcConfig.d";
import { DatabaseServer } from "@spt/servers/DatabaseServer";
import _config from "../../config/config.json";
import _mapConfig from "../../config/mapConfig.json";
import { ConfigServer } from "@spt/servers/ConfigServer";
import { ConfigTypes } from "@spt/models/enums/ConfigTypes";
import { DependencyContainer } from "tsyringe";
import { globalValues } from "../GlobalValues";
import {
cloneDeep,
getRandomPresetOrCurrentlySelectedPreset,
saveToFile,
} from "../utils";
import { ILocationConfig } from "@spt/models/spt/config/ILocationConfig.d";
import { originalMapList } from "./constants";
import { buildBossWaves } from "./buildBossWaves";
import buildZombieWaves from "./buildZombieWaves";
import buildScavMarksmanWaves from "./buildScavMarksmanWaves";
import buildPmcs from "./buildPmcs";
import { setEscapeTimeOverrides } from "./utils";
import { ILogger } from "@spt/models/spt/utils/ILogger";
import updateSpawnLocations from "./updateSpawnLocations";
export const buildWaves = (container: DependencyContainer) => {
const configServer = container.resolve<ConfigServer>("ConfigServer");
const Logger = container.resolve<ILogger>("WinstonLogger");
const pmcConfig = configServer.getConfig<IPmcConfig>(ConfigTypes.PMC);
const botConfig = configServer.getConfig<IBotConfig>(ConfigTypes.BOT);
const locationConfig = configServer.getConfig<ILocationConfig>(
ConfigTypes.LOCATION
);
locationConfig.rogueLighthouseSpawnTimeSettings.waitTimeSeconds = 60;
locationConfig.enableBotTypeLimits = false;
locationConfig.fitLootIntoContainerAttempts = 1; // Move to ALP
locationConfig.addCustomBotWavesToMaps = false;
locationConfig.customWaves = { boss: {}, normal: {} };
const databaseServer = container.resolve<DatabaseServer>("DatabaseServer");
const { locations, bots, globals } = databaseServer.getTables();
let config = cloneDeep(globalValues.baseConfig) as typeof _config;
const preset = getRandomPresetOrCurrentlySelectedPreset();
Object.keys(globalValues.overrideConfig).forEach((key) => {
if (config[key] !== globalValues.overrideConfig[key]) {
config.debug &&
console.log(
`[MOAR] overrideConfig ${key} changed from ${config[key]} to ${globalValues.overrideConfig[key]}`
);
config[key] = globalValues.overrideConfig[key];
}
});
// Set from preset if preset above is not empty
Object.keys(preset).forEach((key) => {
if (config[key] !== preset[key]) {
config.debug &&
console.log(
`[MOAR] preset ${globalValues.currentPreset}: ${key} changed from ${config[key]} to ${preset[key]}`
);
config[key] = preset[key];
}
});
// config.debug &&
console.log(
globalValues.forcedPreset === "custom"
? "custom"
: globalValues.currentPreset
);
const {
bigmap: customs,
factory4_day: factoryDay,
factory4_night: factoryNight,
interchange,
laboratory,
lighthouse,
rezervbase,
shoreline,
tarkovstreets,
woods,
sandbox: gzLow,
sandbox_high: gzHigh,
} = locations;
let locationList = [
customs,
factoryDay,
factoryNight,
interchange,
laboratory,
lighthouse,
rezervbase,
shoreline,
tarkovstreets,
woods,
gzLow,
gzHigh,
];
// This resets all locations to original state
if (!globalValues.locationsBase) {
globalValues.locationsBase = locationList.map(({ base }) =>
cloneDeep(base)
);
} else {
locationList = locationList.map((item, key) => ({
...item,
base: cloneDeep(globalValues.locationsBase[key]),
}));
}
pmcConfig.convertIntoPmcChance = {
default: {
assault: { min: 0, max: 0 },
cursedassault: { min: 0, max: 0 },
pmcbot: { min: 0, max: 0 },
exusec: { min: 0, max: 0 },
arenafighter: { min: 0, max: 0 },
arenafighterevent: { min: 0, max: 0 },
crazyassaultevent: { min: 0, max: 0 },
},
factory4_day: { assault: { min: 0, max: 0 } },
laboratory: { pmcbot: { min: 0, max: 0 } },
rezervbase: { pmcbot: { min: 0, max: 0 } },
};
updateSpawnLocations(locationList, config);
setEscapeTimeOverrides(locationList, _mapConfig, Logger, config);
// Make main waves
buildScavMarksmanWaves(config, locationList, botConfig);
// BOSS RELATED STUFF!
buildBossWaves(config, locationList);
//Zombies
if (config.zombiesEnabled) {
buildZombieWaves(config, locationList, bots);
}
buildPmcs(config, locationList);
originalMapList.forEach((name, index) => {
if (!locations[name]) {
console.log("[MOAR] OH CRAP we have a problem!", name);
} else {
locations[name] = locationList[index];
}
});
};
@@ -0,0 +1,277 @@
import { ILocation } from "@spt/models/eft/common/ILocation";
import _config from "../../config/config.json";
import bossConfig from "../../config/bossConfig.json";
import mapConfig from "../../config/mapConfig.json";
import {
bossesToRemoveFromPool,
configLocations,
mainBossNameList,
originalMapList,
} from "./constants";
import { buildBossBasedWave, shuffle } from "./utils";
import { IBossLocationSpawn } from "@spt/models/eft/common/ILocationBase";
import { cloneDeep } from "../utils";
export function buildBossWaves(
config: typeof _config,
locationList: ILocation[]
) {
let {
randomRaiderGroup,
randomRaiderGroupChance,
randomRogueGroup,
randomRogueGroupChance,
mainBossChanceBuff,
bossInvasion,
bossInvasionSpawnChance,
disableBosses,
bossOpenZones,
gradualBossInvasion,
} = config;
const bossList = mainBossNameList.filter(
(bossName) => !["bossKnight"].includes(bossName)
);
const allBosses: Record<string, IBossLocationSpawn> = {};
for (const key in locationList) {
locationList[key].base.BossLocationSpawn.forEach((boss) => {
if (!allBosses[boss.BossName]) {
allBosses[boss.BossName] = boss;
}
});
}
// CreateBossList
const bosses: Record<string, IBossLocationSpawn> = {};
for (let indx = 0; indx < locationList.length; indx++) {
// Disable Bosses
if (disableBosses && !!locationList[indx].base?.BossLocationSpawn) {
locationList[indx].base.BossLocationSpawn = [];
} else {
//Remove all other spawns from pool now that we have the spawns zone list
locationList[indx].base.BossLocationSpawn = locationList[
indx
].base.BossLocationSpawn.filter(
(boss) => !bossesToRemoveFromPool.has(boss.BossName)
);
const location = locationList[indx];
const defaultBossSettings =
mapConfig?.[configLocations[indx]]?.defaultBossSettings;
// Sets bosses spawn chance from settings
if (
location?.base?.BossLocationSpawn &&
defaultBossSettings &&
Object.keys(defaultBossSettings)?.length
) {
const filteredBossList = Object.keys(defaultBossSettings).filter(
(name) => defaultBossSettings[name]?.BossChance !== undefined
);
if (filteredBossList?.length) {
filteredBossList.forEach((bossName) => {
location.base.BossLocationSpawn =
location.base.BossLocationSpawn.map((boss) => ({
...boss,
...(boss.BossName === bossName
? { BossChance: defaultBossSettings[bossName].BossChance }
: {}),
}));
});
}
}
if (randomRaiderGroup) {
const raiderWave = buildBossBasedWave(
randomRaiderGroupChance,
"1,2,2,2,3",
"pmcBot",
"pmcBot",
"",
locationList[indx].base.EscapeTimeLimit
);
location.base.BossLocationSpawn.push(raiderWave);
}
if (randomRogueGroup) {
const rogueWave = buildBossBasedWave(
randomRogueGroupChance,
"1,2,2,2,3",
"exUsec",
"exUsec",
"",
locationList[indx].base.EscapeTimeLimit
);
location.base.BossLocationSpawn.push(rogueWave);
}
//Add each boss from each map to bosses object
const filteredBosses = location.base.BossLocationSpawn?.filter(
({ BossName }) => mainBossNameList.includes(BossName)
);
if (filteredBosses.length) {
for (let index = 0; index < filteredBosses.length; index++) {
const boss = filteredBosses[index];
if (
!bosses[boss.BossName] ||
(bosses[boss.BossName] &&
bosses[boss.BossName].BossChance < boss.BossChance)
) {
bosses[boss.BossName] = { ...boss };
}
}
}
}
}
if (!disableBosses) {
// Make boss Invasion
if (bossInvasion) {
if (bossInvasionSpawnChance) {
bossList.forEach((bossName) => {
if (bosses[bossName])
bosses[bossName].BossChance = bossInvasionSpawnChance;
});
}
for (let key = 0; key < locationList.length; key++) {
//Gather bosses to avoid duplicating.
const duplicateBosses = [
...locationList[key].base.BossLocationSpawn.filter(
({ BossName, BossZone }) => bossList.includes(BossName)
).map(({ BossName }) => BossName),
"bossKnight", // So knight doesn't invade
];
//Build bosses to add
const bossesToAdd = shuffle<IBossLocationSpawn[]>(Object.values(bosses))
.filter(({ BossName }) => !duplicateBosses.includes(BossName))
.map((boss, j) => ({
...boss,
BossZone: "",
BossEscortAmount:
boss.BossEscortAmount === "0" ? boss.BossEscortAmount : "1",
...(gradualBossInvasion ? { Time: j * 20 + 1 } : {}),
}));
// UpdateBosses
locationList[key].base.BossLocationSpawn = [
...locationList[key].base.BossLocationSpawn,
...bossesToAdd,
];
}
}
let hasChangedBossSpawns = false;
// console.log(Object.keys(allBosses));
configLocations.forEach((mapName, index) => {
const bossLocationSpawn = locationList[index].base.BossLocationSpawn;
const mapBossConfig: Record<string, number> = cloneDeep(
bossConfig[mapName] || {}
);
// if (Object.keys(mapBossConfig).length === 0) console.log(name, "empty");
const adjusted = new Set<string>([]);
bossLocationSpawn.forEach(({ BossName, BossChance }, bossIndex) => {
if (typeof mapBossConfig[BossName] === "number") {
if (BossChance !== mapBossConfig[BossName]) {
if (!hasChangedBossSpawns) {
console.log(
`\n[MOAR]: --- Adjusting default boss spawn rates --- `
);
hasChangedBossSpawns = true;
}
console.log(
`[MOAR]: ${mapName} ${BossName}: ${locationList[index].base.BossLocationSpawn[bossIndex].BossChance} => ${mapBossConfig[BossName]}`
);
locationList[index].base.BossLocationSpawn[bossIndex].BossChance =
mapBossConfig[BossName];
}
adjusted.add(BossName);
}
});
const bossesToAdd = Object.keys(mapBossConfig)
.filter(
(adjustName) => !adjusted.has(adjustName) && !!allBosses[adjustName]
)
.map((bossName) => {
`[MOAR]: Adding non-default boss ${bossName} to ${originalMapList[index]}`;
const newBoss: IBossLocationSpawn = cloneDeep(
allBosses[bossName] || {}
);
newBoss.BossChance = mapBossConfig[bossName];
// console.log(
// "Adding boss",
// bossName,
// "to ",
// originalMapList[index],
// "spawn chance =>",
// mapBossConfig[bossName]
// );
return newBoss;
});
// console.log(bossesToAdd);
if (bossOpenZones || mainBossChanceBuff) {
locationList[index].base?.BossLocationSpawn?.forEach((boss, key) => {
if (bossList.includes(boss.BossName)) {
if (bossOpenZones) {
locationList[index].base.BossLocationSpawn[key] = {
...locationList[index].base.BossLocationSpawn[key],
BossZone: "",
};
}
if (!!boss.BossChance && mainBossChanceBuff > 0) {
locationList[index].base.BossLocationSpawn[key] = {
...locationList[index].base.BossLocationSpawn[key],
BossChance:
boss.BossChance + mainBossChanceBuff > 100
? 100
: Math.round(boss.BossChance + mainBossChanceBuff),
};
}
}
});
}
locationList[index].base.BossLocationSpawn = [
...locationList[index].base.BossLocationSpawn,
...bossesToAdd,
];
bossesToAdd.length &&
console.log(
`[MOAR] Adding the following bosses to map ${
configLocations[index]
}: ${bossesToAdd.map(({ BossName }) => BossName)}`
);
// console.log(locationList[index].base.BossLocationSpawn.length);
// Apply the percentages on all bosses, cull those that won't spawn, make all bosses 100 chance that remain.
locationList[index].base.BossLocationSpawn = locationList[
index
].base.BossLocationSpawn.filter(({ BossChance, BossName }, bossIndex) => {
if (BossChance < 100 && BossChance / 100 < Math.random()) {
return false;
}
return true;
}).map((boss) => ({ ...boss, ...{ BossChance: 100 } }));
// if (mapName === "customs")
// console.log(mapName, locationList[index].base.BossLocationSpawn);
});
if (hasChangedBossSpawns) {
console.log(
`[MOAR]: --- Adjusting default boss spawn rates complete --- \n`
);
}
}
}
@@ -0,0 +1,88 @@
import { ILocation } from "@spt/models/eft/common/ILocation";
import _config from "../../config/config.json";
import mapConfig from "../../config/mapConfig.json";
import {
bossesToRemoveFromPool,
defaultEscapeTimes,
defaultHostility,
} from "./constants";
import { buildPmcWaves, MapSettings, shuffle } from "./utils";
import { saveToFile } from "../utils";
export default function buildPmcs(
config: typeof _config,
locationList: ILocation[]
) {
for (let index = 0; index < locationList.length; index++) {
const mapSettingsList = Object.keys(mapConfig) as Array<
keyof typeof mapConfig
>;
const map = mapSettingsList[index];
locationList[index].base.BotLocationModifier.AdditionalHostilitySettings =
defaultHostility;
const { pmcHotZones = [] } = (mapConfig?.[map] as MapSettings) || {};
let pmcZones = shuffle<string[]>([
...new Set(
[...locationList[index].base.SpawnPointParams]
.filter(
({ Categories, BotZoneName }) =>
!!BotZoneName &&
!BotZoneName.includes("snipe") &&
(Categories.includes("Player") || Categories.includes("All")) &&
!BotZoneName.includes("BotZoneGate")
)
.map(({ BotZoneName, ...rest }) => {
return BotZoneName;
})
),
]);
// Make labs have only named zones
if (map === "laboratory") {
pmcZones = new Array(10).fill(pmcZones).flat(1);
}
const { pmcWaveCount } = mapConfig[map];
const escapeTimeLimitRatio = Math.round(
locationList[index].base.EscapeTimeLimit / defaultEscapeTimes[map]
);
const totalWaves = Math.round(
pmcWaveCount * config.pmcWaveQuantity * escapeTimeLimitRatio
);
const numberOfZoneless = totalWaves - pmcZones.length;
if (numberOfZoneless > 0) {
const addEmpty = new Array(numberOfZoneless).fill("");
pmcZones = shuffle<string[]>([...pmcZones, ...addEmpty]);
}
if (config.debug) {
console.log(`${map} PMC count ${totalWaves} \n`);
escapeTimeLimitRatio !== 1 &&
console.log(
`${map} PMC wave count changed from ${pmcWaveCount} to ${totalWaves} due to escapeTimeLimit adjustment`
);
}
const timeLimit = locationList[index].base.EscapeTimeLimit * 60;
const waves = buildPmcWaves(
totalWaves,
timeLimit,
config,
pmcZones,
pmcHotZones
);
locationList[index].base.BossLocationSpawn = [
...waves,
...locationList[index].base.BossLocationSpawn,
];
}
}
@@ -0,0 +1,218 @@
import { ILocation } from "@spt/models/eft/common/ILocation";
import _config from "../../config/config.json";
import mapConfig from "../../config/mapConfig.json";
import {
configLocations,
defaultEscapeTimes,
defaultHostility,
originalMapList,
} from "./constants";
import { MapSettings, shuffle, waveBuilder } from "./utils";
import { IWave, WildSpawnType } from "@spt/models/eft/common/ILocationBase";
import { IBotConfig } from "@spt/models/spt/config/IBotConfig";
import { saveToFile } from "../utils";
export default function buildScavMarksmanWaves(
config: typeof _config,
locationList: ILocation[],
botConfig: IBotConfig
) {
let {
debug,
maxBotCap,
scavWaveQuantity,
scavWaveDistribution,
snipersHaveFriends,
maxBotPerZone,
scavMaxGroupSize,
scavDifficulty,
moreScavGroups,
} = config;
for (let index = 0; index < locationList.length; index++) {
const mapSettingsList = Object.keys(mapConfig) as Array<
keyof typeof mapConfig
>;
const map = mapSettingsList[index];
locationList[index].base = {
...locationList[index].base,
...{
NewSpawn: false,
OcculsionCullingEnabled: true,
OfflineNewSpawn: false,
OfflineOldSpawn: true,
OldSpawn: true,
BotSpawnCountStep: 0,
},
};
locationList[index].base.NonWaveGroupScenario.Enabled = false;
locationList[index].base["BotStartPlayer"] = 0;
if (
locationList[index].base.BotStop <
locationList[index].base.EscapeTimeLimit * 60
) {
locationList[index].base.BotStop =
locationList[index].base.EscapeTimeLimit * 60;
}
const {
maxBotPerZoneOverride,
maxBotCapOverride,
EscapeTimeLimit,
scavHotZones,
} = (mapConfig?.[map] as MapSettings) || {};
// Set per map EscapeTimeLimit
if (EscapeTimeLimit) {
locationList[index].base.EscapeTimeLimit = EscapeTimeLimit;
locationList[index].base.exit_access_time = EscapeTimeLimit + 1;
}
// Set default or per map maxBotCap
if (maxBotCapOverride || maxBotCap) {
const capToSet = maxBotCapOverride || maxBotCap;
// console.log(map, capToSet, maxBotCapOverride, maxBotCap);
locationList[index].base.BotMax = capToSet;
locationList[index].base.BotMaxPvE = capToSet;
botConfig.maxBotCap[originalMapList[index]] = capToSet;
}
// Adjust botZone quantity
if (maxBotPerZoneOverride || maxBotPerZone) {
const BotPerZone = maxBotPerZoneOverride || maxBotPerZone;
// console.log(map, BotPerZone, maxBotPerZoneOverride, maxBotPerZone);
locationList[index].base.MaxBotPerZone = BotPerZone;
}
const sniperLocations = new Set(
[...locationList[index].base.SpawnPointParams]
.filter(
({ Categories, DelayToCanSpawnSec, BotZoneName, Sides }) =>
!Categories.includes("Boss") &&
Sides[0] === "Savage" &&
(BotZoneName?.toLowerCase().includes("snipe") ||
DelayToCanSpawnSec > 40)
)
.map(({ BotZoneName }) => BotZoneName || "")
);
if (sniperLocations.size) {
locationList[index].base.MinMaxBots = [
{
WildSpawnType: "marksman",
max: sniperLocations.size * 5,
min: sniperLocations.size,
},
];
}
let scavZones = shuffle<string[]>([
...new Set(
[...locationList[index].base.SpawnPointParams]
.filter(
({ Categories, Sides, BotZoneName }) =>
!!BotZoneName &&
Categories.includes("Bot") &&
(Sides.includes("Savage") || Sides.includes("All"))
)
.map(({ BotZoneName }) => BotZoneName)
.filter((name) => !sniperLocations.has(name))
),
]);
const { scavWaveCount } = mapConfig[map];
const escapeTimeLimitRatio = Math.round(
locationList[index].base.EscapeTimeLimit / defaultEscapeTimes[map]
);
// Scavs
const scavTotalWaveCount = Math.round(
scavWaveCount * scavWaveQuantity * escapeTimeLimitRatio
);
const numberOfZoneless = scavTotalWaveCount - scavZones.length;
// console.log(numberOfZoneless);
if (numberOfZoneless > 0) {
const addEmpty = new Array(numberOfZoneless).fill("");
scavZones = shuffle<string[]>([...scavZones, ...addEmpty]);
}
// console.log(scavZones);
config.debug &&
escapeTimeLimitRatio !== 1 &&
console.log(
`${map} Scav wave count changed from ${scavWaveCount} to ${scavTotalWaveCount} due to escapeTimeLimit adjustment`
);
const timeLimit = locationList[index].base.EscapeTimeLimit * 60;
let snipers = waveBuilder(
sniperLocations.size,
Math.round(timeLimit / 4),
0.5,
WildSpawnType.MARKSMAN,
0.7,
false,
2,
[],
shuffle([...sniperLocations]),
80,
true,
true
);
if (snipersHaveFriends)
snipers = snipers.map((wave) => ({
...wave,
...(snipersHaveFriends && wave.slots_max < 2
? { slots_min: 1, slots_max: 2 }
: {}),
}));
const scavWaves = waveBuilder(
scavTotalWaveCount,
timeLimit,
scavWaveDistribution,
WildSpawnType.ASSAULT,
scavDifficulty,
false,
scavMaxGroupSize,
map === "gzHigh" ? [] : scavZones,
scavHotZones,
0,
false,
!!moreScavGroups
);
if (debug) {
let totalscav = 0;
scavWaves.forEach(({ slots_max }) => (totalscav += slots_max));
console.log(configLocations[index]);
console.log(
"Scavs:",
totalscav,
"configVal",
Math.round((totalscav / scavWaveCount) * 100) / 100,
"configWaveCount",
scavWaveCount,
"waveCount",
scavWaves.length,
"\n"
);
}
// const finalSniperWaves = snipers?.map(({ ...rest }, snipKey) => ({
// ...rest,
// number: snipKey,
// time_min: snipKey * 120,
// time_max: snipKey * 120 + 120,
// }));
// if (map === "customs") saveToFile({ scavWaves }, "scavWaves.json");
locationList[index].base.waves = [...snipers, ...scavWaves]
.sort(({ time_min: a }, { time_min: b }) => a - b)
.map((wave, i) => ({ ...wave, number: i + 1 }));
}
}

Some files were not shown because too many files have changed in this diff Show More