Merge tag '4.0.4'
This commit is contained in:
+1
-1
@@ -1,7 +1,7 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<!-- SPT specific -->
|
||||
<SptVersion Condition="'$(SptVersion)' == ''">4.0.2</SptVersion>
|
||||
<SptVersion Condition="'$(SptVersion)' == ''">4.0.3</SptVersion>
|
||||
<SptCommit Condition="'$(SptCommit)' == ''">a12b34</SptCommit>
|
||||
<SptBuildTime Condition="'$(SptBuildTime)' == ''">0000000000</SptBuildTime>
|
||||
<SptBuildType Condition="'$(SptBuildType)' == ''">LOCAL</SptBuildType>
|
||||
|
||||
@@ -3,6 +3,7 @@ namespace SPTarkov.Reflection.Patching;
|
||||
/// <summary>
|
||||
/// Cache of active patches for mod developers to use for compatibility reasons
|
||||
/// </summary>
|
||||
[Obsolete("Patches will be injectable through IEnumerable<IRuntimePatch> in SPT 4.1, making this redundant")]
|
||||
public static class ModPatchCache
|
||||
{
|
||||
private static readonly List<AbstractPatch> _activePatches = [];
|
||||
@@ -22,6 +23,7 @@ public static class ModPatchCache
|
||||
/// <remarks>
|
||||
/// This should never be called before PreSptLoad is completed, otherwise could be empty.
|
||||
/// </remarks>
|
||||
[Obsolete("Patches will be injectable through IEnumerable<IRuntimePatch> in SPT 4.1, making this redundant")]
|
||||
public static IReadOnlyList<AbstractPatch> GetActivePatches()
|
||||
{
|
||||
// We're not exposing _activePatches so it cant be altered outside of this class. Do NOT implement this as a property.
|
||||
@@ -38,6 +40,7 @@ public static class ModPatchCache
|
||||
/// <remarks>
|
||||
/// This should never be called before PreSptLoad is completed, otherwise could be empty.
|
||||
/// </remarks>
|
||||
[Obsolete("Patches will be injectable through IEnumerable<IRuntimePatch> in SPT 4.1, making this redundant")]
|
||||
public static List<string> GetActivePatchedMethodNames()
|
||||
{
|
||||
var result = new List<string>();
|
||||
|
||||
@@ -2895,10 +2895,19 @@
|
||||
"bossKilla",
|
||||
"bossKojaniy",
|
||||
"bossSanitar",
|
||||
"bossKolontay",
|
||||
"bossKnight"
|
||||
"bossKolontay"
|
||||
],
|
||||
"resetDay": "Monday"
|
||||
},
|
||||
"goonSpawnSystem": {
|
||||
"enabled": true,
|
||||
"locationPool": [
|
||||
"bigmap",
|
||||
"woods",
|
||||
"shoreline",
|
||||
"lighthouse"
|
||||
],
|
||||
"spawnChance": 35
|
||||
},
|
||||
"replaceScavWith": "assault"
|
||||
}
|
||||
|
||||
@@ -61,7 +61,8 @@
|
||||
"679baa2c61f588ae2b062a24",
|
||||
"679baa4f59b8961f370dd683",
|
||||
"679baa5a59b8961f370dd685",
|
||||
"679baa9091966fe40408f149"
|
||||
"679baa9091966fe40408f149",
|
||||
"67ab3d4b83869afd170fdd3f"
|
||||
],
|
||||
"bossItems": [
|
||||
"6275303a9f372d6ea97f9ec7",
|
||||
@@ -475,6 +476,74 @@
|
||||
"_name": "FN SCAR-H X-17 762x51 default",
|
||||
"_parent": "679f5f42ca975ceee4001927",
|
||||
"_type": "Preset"
|
||||
},
|
||||
{
|
||||
"_changeWeaponName": false,
|
||||
"_encyclopedia": "67d0576f29f580ebc10efd08",
|
||||
"_id": "690a065b64b2a3bab0a986da",
|
||||
"_items": [
|
||||
{
|
||||
"_id": "690a06bc6c65be6d001b4cd1",
|
||||
"_tpl": "67d0576f29f580ebc10efd08",
|
||||
"upd": {
|
||||
"Repairable": {
|
||||
"Durability": 100,
|
||||
"MaxDurability": 100
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"_id": "690a06bc6c65be6d001b4d0a",
|
||||
"_tpl": "67d4178bffb910d21f04720a",
|
||||
"parentId": "690a06bc6c65be6d001b4cd1",
|
||||
"slotId": "mod_barrel"
|
||||
},
|
||||
{
|
||||
"_id": "690a06bc6c65be6d001b4d18",
|
||||
"_tpl": "67d417c023ec241bb70d4896",
|
||||
"parentId": "690a06bc6c65be6d001b4d0a",
|
||||
"slotId": "mod_gas_block"
|
||||
},
|
||||
{
|
||||
"_id": "690a06bc6c65be6d001b4d32",
|
||||
"_tpl": "67d41883f378a36c4706eeb7",
|
||||
"parentId": "690a06bc6c65be6d001b4d0a",
|
||||
"slotId": "mod_muzzle"
|
||||
},
|
||||
{
|
||||
"_id": "690a06bc6c65be6d001b4d3b",
|
||||
"_tpl": "67d416e19bd76ef20f0e743b",
|
||||
"parentId": "690a06bc6c65be6d001b4cd1",
|
||||
"slotId": "mod_reciever"
|
||||
},
|
||||
{
|
||||
"_id": "690a06bc6c65be6d001b4d43",
|
||||
"_tpl": "5aa66a9be5b5b0214e506e89",
|
||||
"parentId": "690a06bc6c65be6d001b4d3b",
|
||||
"slotId": "mod_scope"
|
||||
},
|
||||
{
|
||||
"_id": "690a06bc6c65be6d001b4d4b",
|
||||
"_tpl": "5aa66be6e5b5b0214e506e97",
|
||||
"parentId": "690a06bc6c65be6d001b4d43",
|
||||
"slotId": "mod_scope"
|
||||
},
|
||||
{
|
||||
"_id": "690a06bc6c65be6d001b4d5c",
|
||||
"_tpl": "6087e663132d4d12c81fd96b",
|
||||
"parentId": "690a06bc6c65be6d001b4cd1",
|
||||
"slotId": "mod_pistol_grip"
|
||||
},
|
||||
{
|
||||
"_id": "690a06bc6c65be6d001b4d65",
|
||||
"_tpl": "67d418d0ffb910d21f04720e",
|
||||
"parentId": "690a06bc6c65be6d001b4cd1",
|
||||
"slotId": "mod_magazine"
|
||||
}
|
||||
],
|
||||
"_name": "AK-50 .50 BMG sniper rifle default",
|
||||
"_parent": "690a06bc6c65be6d001b4cd1",
|
||||
"_type": "Preset"
|
||||
}
|
||||
],
|
||||
"handbookPriceOverride": {
|
||||
|
||||
@@ -194,14 +194,14 @@
|
||||
},
|
||||
"5d650c3e815116009f6201d2": {
|
||||
"_name": "FUEL",
|
||||
"conditionChance": 0.12,
|
||||
"conditionChance": 0.23,
|
||||
"current": {
|
||||
"max": 1,
|
||||
"min": 1
|
||||
},
|
||||
"max": {
|
||||
"max": 1,
|
||||
"min": 0.7
|
||||
"min": 0.1
|
||||
}
|
||||
},
|
||||
"644120aa86ffbe10ee032b6f": {
|
||||
@@ -323,7 +323,8 @@
|
||||
"57bef4c42459772e8d35a53b",
|
||||
"55802f4a4bdc2ddb688b4569",
|
||||
"616eb7aea207f41933308f46",
|
||||
"543be5cb4bdc2deb348b4568"
|
||||
"543be5cb4bdc2deb348b4568",
|
||||
"5d650c3e815116009f6201d2"
|
||||
],
|
||||
"showDefaultPresetsOnly": true,
|
||||
"stackablePercent": {
|
||||
|
||||
@@ -1264,7 +1264,8 @@
|
||||
"BossName": "infectedAssault",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -1284,7 +1285,8 @@
|
||||
"BossName": "infectedAssault",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -1304,7 +1306,8 @@
|
||||
"BossName": "infectedAssault",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [],
|
||||
"Supports": null,
|
||||
@@ -1321,7 +1324,8 @@
|
||||
"BossName": "infectedAssault",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [],
|
||||
"Supports": null,
|
||||
@@ -1338,7 +1342,8 @@
|
||||
"BossName": "infectedPmc",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [],
|
||||
"Supports": null,
|
||||
@@ -1355,7 +1360,8 @@
|
||||
"BossName": "infectedPmc",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -1375,7 +1381,8 @@
|
||||
"BossName": "infectedAssault",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -1395,7 +1402,8 @@
|
||||
"BossName": "infectedPmc",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -1415,7 +1423,8 @@
|
||||
"BossName": "infectedAssault",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -1450,7 +1459,8 @@
|
||||
"BossName": "infectedAssault",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -1485,7 +1495,8 @@
|
||||
"BossName": "infectedAssault",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -1513,7 +1524,8 @@
|
||||
"BossName": "infectedAssault",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -1541,7 +1553,8 @@
|
||||
"BossName": "infectedPmc",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -1569,7 +1582,8 @@
|
||||
"BossName": "infectedPmc",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -1597,7 +1611,8 @@
|
||||
"BossName": "infectedPmc",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -1625,7 +1640,8 @@
|
||||
"BossName": "infectedPmc",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -1653,7 +1669,8 @@
|
||||
"BossName": "infectedPmc",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -1902,7 +1919,8 @@
|
||||
"BossName": "infectedAssault",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
"pve"
|
||||
@@ -1921,7 +1939,8 @@
|
||||
"BossName": "infectedAssault",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
"pve"
|
||||
@@ -1940,7 +1959,8 @@
|
||||
"BossName": "infectedAssault",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"SpawnMode": [],
|
||||
"Supports": null,
|
||||
"Time": 9999,
|
||||
@@ -1956,7 +1976,8 @@
|
||||
"BossName": "infectedAssault",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"SpawnMode": [],
|
||||
"Supports": null,
|
||||
"Time": 9999,
|
||||
@@ -1972,7 +1993,8 @@
|
||||
"BossName": "infectedPmc",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"SpawnMode": [],
|
||||
"Supports": null,
|
||||
"Time": 9999,
|
||||
@@ -1988,7 +2010,8 @@
|
||||
"BossName": "infectedPmc",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
"pve"
|
||||
@@ -2007,7 +2030,8 @@
|
||||
"BossName": "infectedAssault",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
"pve"
|
||||
@@ -2026,7 +2050,8 @@
|
||||
"BossName": "infectedPmc",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
"pve"
|
||||
@@ -2045,7 +2070,8 @@
|
||||
"BossName": "infectedAssault",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
"pve"
|
||||
@@ -2079,7 +2105,8 @@
|
||||
"BossName": "infectedAssault",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
"pve"
|
||||
@@ -2113,7 +2140,8 @@
|
||||
"BossName": "infectedAssault",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
"pve"
|
||||
@@ -2140,7 +2168,8 @@
|
||||
"BossName": "infectedAssault",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
"pve"
|
||||
@@ -2167,7 +2196,8 @@
|
||||
"BossName": "infectedPmc",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
"pve"
|
||||
@@ -2194,7 +2224,8 @@
|
||||
"BossName": "infectedPmc",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
"pve"
|
||||
@@ -2221,7 +2252,8 @@
|
||||
"BossName": "infectedPmc",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
"pve"
|
||||
@@ -2248,7 +2280,8 @@
|
||||
"BossName": "infectedPmc",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
"pve"
|
||||
@@ -2275,7 +2308,8 @@
|
||||
"BossName": "infectedPmc",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
"pve"
|
||||
@@ -3262,7 +3296,8 @@
|
||||
"BossPlayer": false,
|
||||
"BossZone": "BotZoneFloor1,BotZoneFloor2,BotZoneBasement",
|
||||
"Delay": 0,
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -3283,7 +3318,8 @@
|
||||
"BossPlayer": false,
|
||||
"BossZone": "BotZoneFloor1,BotZoneFloor2,BotZoneBasement",
|
||||
"Delay": 0,
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -3304,7 +3340,8 @@
|
||||
"BossPlayer": false,
|
||||
"BossZone": "BotZoneFloor1,BotZoneFloor2,BotZoneBasement",
|
||||
"Delay": 0,
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [],
|
||||
"Supports": null,
|
||||
@@ -3322,7 +3359,8 @@
|
||||
"BossPlayer": false,
|
||||
"BossZone": "BotZoneFloor1,BotZoneFloor2,BotZoneBasement",
|
||||
"Delay": 0,
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -3343,7 +3381,8 @@
|
||||
"BossPlayer": false,
|
||||
"BossZone": "BotZoneFloor1,BotZoneFloor2,BotZoneBasement",
|
||||
"Delay": 0,
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [],
|
||||
"Supports": null,
|
||||
@@ -3361,7 +3400,8 @@
|
||||
"BossPlayer": false,
|
||||
"BossZone": "BotZoneFloor1,BotZoneFloor2,BotZoneBasement",
|
||||
"Delay": 0,
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [],
|
||||
"Supports": null,
|
||||
@@ -3379,7 +3419,8 @@
|
||||
"BossPlayer": false,
|
||||
"BossZone": "BotZoneFloor1,BotZoneFloor2,BotZoneBasement",
|
||||
"Delay": 0,
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -3400,7 +3441,8 @@
|
||||
"BossPlayer": false,
|
||||
"BossZone": "BotZoneFloor1,BotZoneFloor2,BotZoneBasement",
|
||||
"Delay": 0,
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -3421,7 +3463,8 @@
|
||||
"BossPlayer": false,
|
||||
"BossZone": "BotZoneFloor1,BotZoneFloor2,BotZoneBasement",
|
||||
"Delay": 0,
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -3457,7 +3500,8 @@
|
||||
"BossPlayer": false,
|
||||
"BossZone": "BotZoneFloor1,BotZoneFloor2,BotZoneBasement",
|
||||
"Delay": 0,
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -3500,7 +3544,8 @@
|
||||
"BossPlayer": false,
|
||||
"BossZone": "BotZoneFloor1,BotZoneFloor2,BotZoneBasement",
|
||||
"Delay": 0,
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -3529,7 +3574,8 @@
|
||||
"BossPlayer": false,
|
||||
"BossZone": "BotZoneFloor1,BotZoneFloor2,BotZoneBasement",
|
||||
"Delay": 0,
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -3558,7 +3604,8 @@
|
||||
"BossPlayer": false,
|
||||
"BossZone": "BotZoneFloor1,BotZoneFloor2,BotZoneBasement",
|
||||
"Delay": 0,
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -3587,7 +3634,8 @@
|
||||
"BossPlayer": false,
|
||||
"BossZone": "BotZoneFloor1,BotZoneFloor2,BotZoneBasement",
|
||||
"Delay": 0,
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -3616,7 +3664,8 @@
|
||||
"BossPlayer": false,
|
||||
"BossZone": "BotZoneFloor1,BotZoneFloor2,BotZoneBasement",
|
||||
"Delay": 0,
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -3645,7 +3694,8 @@
|
||||
"BossPlayer": false,
|
||||
"BossZone": "BotZoneFloor1,BotZoneFloor2,BotZoneBasement",
|
||||
"Delay": 0,
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -3674,7 +3724,8 @@
|
||||
"BossPlayer": false,
|
||||
"BossZone": "BotZoneFloor1,BotZoneFloor2,BotZoneBasement",
|
||||
"Delay": 0,
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -5590,7 +5641,8 @@
|
||||
"BossName": "infectedCivil",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -5610,7 +5662,8 @@
|
||||
"BossName": "infectedCivil",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -5630,7 +5683,8 @@
|
||||
"BossName": "infectedCivil",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -5650,7 +5704,8 @@
|
||||
"BossName": "infectedCivil",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -5670,7 +5725,8 @@
|
||||
"BossName": "infectedCivil",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -5690,7 +5746,8 @@
|
||||
"BossName": "infectedCivil",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -5710,7 +5767,8 @@
|
||||
"BossName": "infectedCivil",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -5730,7 +5788,8 @@
|
||||
"BossName": "infectedCivil",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -5750,7 +5809,8 @@
|
||||
"BossName": "infectedCivil",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -5792,7 +5852,8 @@
|
||||
"BossName": "infectedPmc",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -5834,7 +5895,8 @@
|
||||
"BossName": "infectedPmc",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -5869,7 +5931,8 @@
|
||||
"BossName": "infectedPmc",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -5904,7 +5967,8 @@
|
||||
"BossName": "infectedPmc",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -5939,7 +6003,8 @@
|
||||
"BossName": "infectedPmc",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -5974,7 +6039,8 @@
|
||||
"BossName": "infectedPmc",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -6009,7 +6075,8 @@
|
||||
"BossName": "infectedPmc",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -6044,7 +6111,8 @@
|
||||
"BossName": "infectedPmc",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -6281,7 +6349,8 @@
|
||||
"BossName": "infectedCivil",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -6301,7 +6370,8 @@
|
||||
"BossName": "infectedCivil",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -6321,7 +6391,8 @@
|
||||
"BossName": "infectedCivil",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -6341,7 +6412,8 @@
|
||||
"BossName": "infectedCivil",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -6361,7 +6433,8 @@
|
||||
"BossName": "infectedCivil",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -6381,7 +6454,8 @@
|
||||
"BossName": "infectedCivil",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -6401,7 +6475,8 @@
|
||||
"BossName": "infectedCivil",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -6421,7 +6496,8 @@
|
||||
"BossName": "infectedCivil",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -6441,7 +6517,8 @@
|
||||
"BossName": "infectedCivil",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -6483,7 +6560,8 @@
|
||||
"BossName": "infectedPmc",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -6525,7 +6603,8 @@
|
||||
"BossName": "infectedPmc",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -6560,7 +6639,8 @@
|
||||
"BossName": "infectedPmc",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -6595,7 +6675,8 @@
|
||||
"BossName": "infectedPmc",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -6630,7 +6711,8 @@
|
||||
"BossName": "infectedPmc",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -6665,7 +6747,8 @@
|
||||
"BossName": "infectedPmc",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -6700,7 +6783,8 @@
|
||||
"BossName": "infectedPmc",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -6735,7 +6819,8 @@
|
||||
"BossName": "infectedPmc",
|
||||
"BossPlayer": false,
|
||||
"BossZone": "",
|
||||
"IgnoreMaxBots": false,
|
||||
"ForceSpawn": true,
|
||||
"IgnoreMaxBots": true,
|
||||
"RandomTimeSpawn": false,
|
||||
"SpawnMode": [
|
||||
"regular",
|
||||
@@ -9807,7 +9892,7 @@
|
||||
"endMonth": "11",
|
||||
"name": "halloween",
|
||||
"settings": {
|
||||
"enableSummoning": false,
|
||||
"enableSummoning": true,
|
||||
"removeEntryRequirement": [
|
||||
"laboratory"
|
||||
],
|
||||
@@ -9817,7 +9902,7 @@
|
||||
"laboratory"
|
||||
],
|
||||
"disableWaves": [],
|
||||
"enabled": true,
|
||||
"enabled": false,
|
||||
"mapInfectionAmount": {
|
||||
"Sandbox": 25,
|
||||
"factory4": 50,
|
||||
@@ -13894,6 +13979,22 @@
|
||||
"UsecPlayerBehaviour": "AlwaysEnemies"
|
||||
}
|
||||
]
|
||||
},
|
||||
"summon": {
|
||||
"default": [
|
||||
{
|
||||
"AlwaysEnemies": [],
|
||||
"AlwaysFriends": [],
|
||||
"BearPlayerBehaviour": "AlwaysFriends",
|
||||
"BotRole": "peacefullZryachiyEvent",
|
||||
"ChancedEnemies": [],
|
||||
"SavageEnemyChance": 0,
|
||||
"BearEnemyChance": 0,
|
||||
"UsecEnemyChance": 0,
|
||||
"SavagePlayerBehaviour": "AlwaysFriends",
|
||||
"UsecPlayerBehaviour": "AlwaysFriends"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -475,7 +475,7 @@
|
||||
"visibilityConditions": [],
|
||||
"globalQuestCounterId": "",
|
||||
"parentId": "",
|
||||
"target": "66058cc208308761cf390993",
|
||||
"target": "68341f6fe2e7ef70a3060a0a",
|
||||
"status": [
|
||||
4
|
||||
],
|
||||
|
||||
@@ -623,6 +623,7 @@
|
||||
"ragfair-invalid_player_offer_request": "Unable to place offer, request is invalid",
|
||||
"ragfair-item_not_in_db_unable_to_generate_dynamic_stack_count": "Item with tpl: %s not found in db. Unable to generate a dynamic stack count",
|
||||
"ragfair-missing_barter_scheme": "generateFleaOffersForTrader() Failed to find barterScheme for item id: {{itemId}} tpl: {{tpl}} on {{name}}",
|
||||
"ragfair-missing_loyal_level_item": "generateFleaOffersForTrader() Failed to find LoyalLevelItem for item id: {{itemId}} tpl: {{tpl}} on {{name}}",
|
||||
"ragfair-no_trader_assorts_cant_generate_flea_offers": "Unable to generate flea offers for trader %s, no assort found",
|
||||
"ragfair-offer_no_longer_exists": "Offer no longer exists",
|
||||
"ragfair-offer_not_found_in_profile": "Could not find offer with id: {{offerId}} in profile: {{profileId}} to remove",
|
||||
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"barter_scheme": {},
|
||||
"items": [],
|
||||
"loyal_level_items": {}
|
||||
}
|
||||
@@ -953,7 +953,7 @@ public class HideoutController(
|
||||
|
||||
// Continuous crafts have special handling in EventOutputHolder.updateOutputProperties()
|
||||
hideoutProduction.SptIsComplete = true;
|
||||
hideoutProduction.SptIsContinuous = recipe.Continuous;
|
||||
hideoutProduction.SptIsContinuous = recipe.Continuous ?? false;
|
||||
|
||||
// Continuous recipes need the craft time refreshed as it gets created once on initial craft and stays the same regardless of what
|
||||
// production.json is set to
|
||||
|
||||
@@ -772,23 +772,33 @@ public class RagfairController(
|
||||
var offerRootItem = offer.Items.FirstOrDefault(x => x.Id == offerRequest.Items[0]);
|
||||
|
||||
// Get average of items quality+children
|
||||
var qualityMultiplier = itemHelper.GetItemQualityModifierForItems(offer.Items, true);
|
||||
var qualityMiltiplierForPlayerOffer = itemHelper.GetItemQualityModifierForItems(offer.Items, true);
|
||||
|
||||
// Check for and apply item price modifer if it exists in config
|
||||
if (RagfairConfig.Dynamic.ItemPriceMultiplier.TryGetValue(offerRootItem.Template, out var itemPriceModifer))
|
||||
// Player may be listing a custom weapon with non-standard mods, calculate the average price of the listed weapons' mods
|
||||
if (itemHelper.IsOfBaseclass(offerRootItem.Template, BaseClasses.WEAPON))
|
||||
{
|
||||
averageOfferPriceSingleItem *= itemPriceModifer;
|
||||
averageOfferPriceSingleItem = ragfairPriceService.GetPresetPriceByChildren(offer.Items);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check for and apply item price modifer if it exists in config
|
||||
if (RagfairConfig.Dynamic.ItemPriceMultiplier.TryGetValue(offerRootItem.Template, out var itemPriceModifer))
|
||||
{
|
||||
averageOfferPriceSingleItem *= itemPriceModifer;
|
||||
}
|
||||
}
|
||||
|
||||
// Multiply single item price by quality
|
||||
averageOfferPriceSingleItem *= qualityMultiplier;
|
||||
// Target price is adjusted to match quality of player item to create better comparison
|
||||
averageOfferPriceSingleItem *= qualityMiltiplierForPlayerOffer;
|
||||
|
||||
// Packs are reduced to the average price of a single item in the pack vs the averaged single price of an item
|
||||
var sellChancePercent = ragfairSellHelper.CalculateSellChance(
|
||||
averageOfferPriceSingleItem.Value,
|
||||
playerListedPriceInRub,
|
||||
qualityMultiplier
|
||||
qualityMiltiplierForPlayerOffer
|
||||
);
|
||||
|
||||
offer.SellResults = ragfairSellHelper.RollForSale(sellChancePercent, (int)stackCountTotal);
|
||||
|
||||
// Subtract flea market fee from stash
|
||||
|
||||
@@ -6,8 +6,10 @@
|
||||
///
|
||||
/// This should not be used at all when having direct access to DI.
|
||||
/// </summary>
|
||||
[Obsolete("This will be removed in the next version of SPT in favor of DI injecting patches")]
|
||||
public static class ServiceLocator
|
||||
{
|
||||
[Obsolete("This will be removed in the next version of SPT in favor of DI injecting patches")]
|
||||
public static IServiceProvider ServiceProvider { get; private set; }
|
||||
|
||||
internal static void SetServiceProvider(IServiceProvider provider)
|
||||
|
||||
@@ -588,7 +588,21 @@ public class RagfairOfferGenerator(
|
||||
}
|
||||
|
||||
var barterSchemeItems = barterScheme[0];
|
||||
var loyalLevel = assortsClone.LoyalLevelItems[item.Id];
|
||||
if (!assortsClone.LoyalLevelItems.TryGetValue(item.Id, out var loyalLevel))
|
||||
{
|
||||
logger.Warning(
|
||||
localisationService.GetText(
|
||||
"ragfair-missing_loyal_level_item",
|
||||
new
|
||||
{
|
||||
itemId = item.Id,
|
||||
tpl = item.Template,
|
||||
name = trader.Base.Nickname,
|
||||
}
|
||||
)
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
var createOfferDetails = new CreateFleaOfferDetails
|
||||
{
|
||||
@@ -742,7 +756,10 @@ public class RagfairOfferGenerator(
|
||||
if (itemHelper.IsOfBaseclass(itemDetails.Id, BaseClasses.FUEL))
|
||||
{
|
||||
var totalCapacity = itemDetails.Properties.MaxResource;
|
||||
var remainingFuel = Math.Round((double)totalCapacity * maxMultiplier);
|
||||
|
||||
// Randomise multi between value in config and 1 (100%)
|
||||
var randomisedMulti = randomUtil.GetDouble(maxMultiplier, 1);
|
||||
var remainingFuel = Math.Round((double)totalCapacity * randomisedMulti);
|
||||
rootItem.Upd.Resource = new UpdResource { UnitsConsumed = totalCapacity - remainingFuel, Value = remainingFuel };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -537,6 +537,7 @@ public class ItemHelper(
|
||||
{
|
||||
if (IsOfBaseclass(itemWithChildren.First().Template, BaseClasses.WEAPON))
|
||||
{
|
||||
// Only root of weapon has durability
|
||||
return Math.Round(GetItemQualityModifier(itemWithChildren.First()), 5);
|
||||
}
|
||||
|
||||
@@ -594,42 +595,44 @@ public class ItemHelper(
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (item.Upd is not null)
|
||||
if (item.Upd is null)
|
||||
{
|
||||
if (item.Upd.MedKit is not null)
|
||||
{
|
||||
// Meds
|
||||
result = (item.Upd.MedKit.HpResource ?? 0) / (itemDetails.Properties?.MaxHpResource ?? 0);
|
||||
}
|
||||
else if (item.Upd.Repairable is not null)
|
||||
{
|
||||
result = GetRepairableItemQualityValue(itemDetails, item.Upd.Repairable, item);
|
||||
}
|
||||
else if (item.Upd.FoodDrink is not null)
|
||||
{
|
||||
result = (item.Upd.FoodDrink.HpPercent ?? 0) / (itemDetails.Properties?.MaxResource ?? 0);
|
||||
}
|
||||
else if (item.Upd.Key?.NumberOfUsages > 0 && itemDetails.Properties?.MaximumNumberOfUsage > 0)
|
||||
{
|
||||
// keys - keys count upwards, not down like everything else
|
||||
var maxNumOfUsages = itemDetails.Properties.MaximumNumberOfUsage;
|
||||
result = (maxNumOfUsages ?? 0 - item.Upd.Key.NumberOfUsages) / maxNumOfUsages ?? 0;
|
||||
}
|
||||
else if (item.Upd.Resource?.UnitsConsumed > 0)
|
||||
{
|
||||
// E.g. fuel tank
|
||||
result = (item.Upd.Resource.Value ?? 0) / (itemDetails.Properties?.MaxResource ?? 0);
|
||||
}
|
||||
else if (item.Upd.RepairKit is not null)
|
||||
{
|
||||
result = (item.Upd.RepairKit.Resource ?? 0) / (itemDetails.Properties?.MaxRepairResource ?? 0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
if (result == 0)
|
||||
// make item non-zero but still very low
|
||||
{
|
||||
result = 0.01;
|
||||
}
|
||||
if (item.Upd.MedKit is not null)
|
||||
{
|
||||
// Meds
|
||||
result = (item.Upd.MedKit.HpResource ?? 0) / (itemDetails.Properties?.MaxHpResource ?? 0);
|
||||
}
|
||||
else if (item.Upd.Repairable is not null)
|
||||
{
|
||||
result = GetRepairableItemQualityValue(itemDetails, item.Upd.Repairable, item);
|
||||
}
|
||||
else if (item.Upd.FoodDrink is not null)
|
||||
{
|
||||
result = (item.Upd.FoodDrink.HpPercent ?? 0) / (itemDetails.Properties?.MaxResource ?? 0);
|
||||
}
|
||||
else if (item.Upd.Key?.NumberOfUsages > 0 && itemDetails.Properties?.MaximumNumberOfUsage > 0)
|
||||
{
|
||||
// keys - keys count upwards, not down like everything else
|
||||
var maxNumOfUsages = itemDetails.Properties.MaximumNumberOfUsage;
|
||||
result = (maxNumOfUsages ?? 0 - item.Upd.Key.NumberOfUsages) / maxNumOfUsages ?? 0;
|
||||
}
|
||||
else if (item.Upd.Resource?.UnitsConsumed > 0) // Item is less than 100% usage
|
||||
{
|
||||
// E.g. fuel tank
|
||||
result = (item.Upd.Resource.Value ?? 0) / (itemDetails.Properties?.MaxResource ?? 0);
|
||||
}
|
||||
else if (item.Upd.RepairKit is not null)
|
||||
{
|
||||
result = (item.Upd.RepairKit.Resource ?? 0) / (itemDetails.Properties?.MaxRepairResource ?? 0);
|
||||
}
|
||||
|
||||
if (result == 0)
|
||||
// make item non-zero but still very low
|
||||
{
|
||||
result = 0.01;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -37,7 +37,7 @@ public class RagfairSellHelper(
|
||||
|
||||
// Modifier gets applied twice to either penalize or incentivize over/under pricing (Probably a cleaner way to do this)
|
||||
var sellModifier = averageOfferPriceRub / playerListedPriceRub * sellConfig.SellMultiplier;
|
||||
var sellChance = Math.Round(baseSellChancePercent * sellModifier * Math.Pow(sellModifier, 3) + 10); // Power of 3
|
||||
var sellChance = Math.Round(baseSellChancePercent * sellModifier * (Math.Pow(sellModifier, 3) + 10)); // Power of 3
|
||||
|
||||
// Adjust sell chance if below config value
|
||||
if (sellChance < sellConfig.MinSellChancePercent)
|
||||
|
||||
@@ -229,18 +229,7 @@ public class RewardHelper(
|
||||
// "TraderId" holds area ID that will be used to craft unlocked item
|
||||
var desiredHideoutAreaType = (HideoutAreas)int.Parse(craftUnlockReward.TraderId.ToString());
|
||||
|
||||
var matchingProductions = GetMatchingProductions(desiredHideoutAreaType, questId, craftUnlockReward);
|
||||
|
||||
// More/less than single match, above filtering wasn't strict enough
|
||||
if (matchingProductions.Count != 1)
|
||||
// Multiple matches were found, last ditch attempt to match by questid (value we add manually to production.json via `gen:productionquests` command)
|
||||
{
|
||||
matchingProductions = matchingProductions
|
||||
.Where(prod => prod.Requirements.Any(requirement => requirement.QuestId == questId))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
return matchingProductions;
|
||||
return GetMatchingProductions(desiredHideoutAreaType, questId, craftUnlockReward);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -252,20 +241,35 @@ public class RewardHelper(
|
||||
/// <returns>Hideout crafts that match input parameters</returns>
|
||||
protected List<HideoutProduction> GetMatchingProductions(HideoutAreas desiredHideoutAreaType, MongoId questId, Reward craftUnlockReward)
|
||||
{
|
||||
var rewardItemTpl = craftUnlockReward.Items.FirstOrDefault()?.Template;
|
||||
var rewardItemTpl = craftUnlockReward.Items?.FirstOrDefault()?.Template;
|
||||
if (rewardItemTpl is null)
|
||||
{
|
||||
logger.Warning("Unable to get matching hideout craft as reward item tpl is missing");
|
||||
|
||||
var craftingRecipes = databaseService.GetHideout().Production.Recipes;
|
||||
return craftingRecipes
|
||||
return [];
|
||||
}
|
||||
|
||||
var craftingRecipesDb = databaseService.GetHideout().Production.Recipes;
|
||||
var result = craftingRecipesDb
|
||||
.Where(production =>
|
||||
// Some crafts have the questId, easy match
|
||||
// Attempt to match by questId (value we add manually to production.json via `gen:productionquests` command)
|
||||
production.Requirements.Any(req => req.QuestId == questId)
|
||||
||
|
||||
// Couldn't get craft by questId, get the closest match based on information we know
|
||||
)
|
||||
.ToList();
|
||||
if (result.Count == 1)
|
||||
{
|
||||
// One result, good match
|
||||
return result;
|
||||
}
|
||||
|
||||
// Found more than or less than 1 craft by questId, try to get closest match based on information we know
|
||||
return craftingRecipesDb
|
||||
.Where(production =>
|
||||
(
|
||||
rewardItemTpl is not null
|
||||
&& production.AreaType == desiredHideoutAreaType
|
||||
production.AreaType == desiredHideoutAreaType
|
||||
&& production.EndProduct == rewardItemTpl.Value
|
||||
&& production.Requirements.Any(req => req.Type is "QuestComplete")
|
||||
&& production.Locked.GetValueOrDefault(false) // Craft would be locked if we're unlocking it
|
||||
&& production.Requirements.Any(req => req.RequiredLevel == craftUnlockReward.LoyaltyLevel)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -137,6 +137,21 @@ public record BotConfig : BaseConfig
|
||||
/// </summary>
|
||||
[JsonPropertyName("replaceScavWith")]
|
||||
public required WildSpawnType ReplaceScavWith { get; set; }
|
||||
|
||||
[JsonPropertyName("goonSpawnSystem")]
|
||||
public required GoonSpawnSystem GoonSpawnSystem { get; set; }
|
||||
}
|
||||
|
||||
public record GoonSpawnSystem
|
||||
{
|
||||
[JsonPropertyName("enabled")]
|
||||
public bool Enabled { get; set; }
|
||||
|
||||
[JsonPropertyName("locationPool")]
|
||||
public IEnumerable<string> LocationPool { get; set; }
|
||||
|
||||
[JsonPropertyName("spawnChance")]
|
||||
public double SpawnChance { get; set; }
|
||||
}
|
||||
|
||||
public record WeeklyBossSettings
|
||||
|
||||
@@ -31,6 +31,7 @@ public class SaveServer(
|
||||
protected const string profileFilepath = "user/profiles/";
|
||||
|
||||
// onLoad = require("../bindings/SaveLoad");
|
||||
[Obsolete("This will be removed in the next version of SPT")]
|
||||
protected readonly Dictionary<string, Func<SptProfile, SptProfile>> onBeforeSaveCallbacks = new();
|
||||
|
||||
protected readonly ConcurrentDictionary<MongoId, SptProfile> profiles = new();
|
||||
@@ -42,6 +43,7 @@ public class SaveServer(
|
||||
/// </summary>
|
||||
/// <param name="id"> ID for the save callback </param>
|
||||
/// <param name="callback"> Callback to execute prior to running SaveServer.saveProfile() </param>
|
||||
[Obsolete("This will be removed in the next version of SPT")]
|
||||
public void AddBeforeSaveCallback(string id, Func<SptProfile, SptProfile> callback)
|
||||
{
|
||||
onBeforeSaveCallbacks[id] = callback;
|
||||
@@ -51,6 +53,7 @@ public class SaveServer(
|
||||
/// Remove a callback from being executed prior to saving profile in SaveServer.saveProfile()
|
||||
/// </summary>
|
||||
/// <param name="id"> ID of Callback to remove </param>
|
||||
[Obsolete("This will be removed in the next version of SPT")]
|
||||
public void RemoveBeforeSaveCallback(string id)
|
||||
{
|
||||
onBeforeSaveCallbacks.Remove(id);
|
||||
|
||||
@@ -56,6 +56,7 @@ public class LocationLifecycleService(
|
||||
protected readonly RagfairConfig RagfairConfig = configServer.GetConfig<RagfairConfig>();
|
||||
protected readonly HideoutConfig HideoutConfig = configServer.GetConfig<HideoutConfig>();
|
||||
protected readonly PmcConfig PMCConfig = configServer.GetConfig<PmcConfig>();
|
||||
protected readonly BotConfig BotConfig = configServer.GetConfig<BotConfig>();
|
||||
protected readonly LostOnDeathConfig LostOnDeathConfig = configServer.GetConfig<LostOnDeathConfig>();
|
||||
|
||||
protected const string Pmc = "pmc";
|
||||
@@ -320,6 +321,11 @@ public class LocationLifecycleService(
|
||||
return locationBaseClone;
|
||||
}
|
||||
|
||||
if (BotConfig.GoonSpawnSystem.Enabled)
|
||||
{
|
||||
AdjustGoonMapSpawns();
|
||||
}
|
||||
|
||||
// Add custom PMCs to map every time its run
|
||||
pmcWaveGenerator.ApplyWaveChangesToMap(locationBaseClone);
|
||||
|
||||
@@ -348,6 +354,63 @@ public class LocationLifecycleService(
|
||||
return locationBaseClone;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Goons will spawn on one map each hour, changing randomly based on a consistent seed made from current utc year + utc hour
|
||||
/// </summary>
|
||||
/// <param name="locationBlacklist">LocationIds to always ignore when choosing a spawn</param>
|
||||
protected void AdjustGoonMapSpawns(HashSet<string>? locationBlacklist = null)
|
||||
{
|
||||
locationBlacklist ??= ["hideout", "develop"];
|
||||
|
||||
// Reset all maps with goons to 0% spawn, ignore blacklisted locations
|
||||
var allLocations = databaseService.GetLocations().GetDictionary();
|
||||
foreach (var (locationId, location) in allLocations)
|
||||
{
|
||||
if (!locationBlacklist.Contains(locationId) && location?.Base?.BossLocationSpawn is not null)
|
||||
{
|
||||
foreach (var goonSpawn in location.Base.BossLocationSpawn.Where(x => x.BossName == "bossKnight"))
|
||||
{
|
||||
goonSpawn.BossChance = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var now = DateTime.UtcNow;
|
||||
|
||||
// Create consistent seed for hour (use prime)
|
||||
var seed = (now.Year * 1009) + now.Hour;
|
||||
|
||||
// Init Random class with unique seed
|
||||
var random = new Random(seed);
|
||||
|
||||
// Filter locations pool
|
||||
var validLocationIds = BotConfig
|
||||
.GoonSpawnSystem.LocationPool.Where(locationId =>
|
||||
!locationBlacklist.Contains(locationId)
|
||||
&& allLocations.TryGetValue(locationId, out var location)
|
||||
&& location?.Base?.BossLocationSpawn is not null
|
||||
)
|
||||
.ToList();
|
||||
|
||||
if (validLocationIds.Count == 0)
|
||||
{
|
||||
logger.Error("Unable to adjust goon spawn chance, no valid locations found");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Choose a spawn location for goons
|
||||
var chosenMapId = validLocationIds[random.Next(0, validLocationIds.Count)];
|
||||
var chosenMap = allLocations[chosenMapId];
|
||||
|
||||
// "Where" just incase there's multiple knight spawns for some reason
|
||||
var goonSpawns = chosenMap.Base.BossLocationSpawn.Where(x => x.BossName == "bossKnight");
|
||||
foreach (var goonSpawn in goonSpawns)
|
||||
{
|
||||
goonSpawn.BossChance = BotConfig.GoonSpawnSystem.SpawnChance;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle client/match/local/end
|
||||
/// </summary>
|
||||
|
||||
@@ -216,7 +216,7 @@ public class PostDbLoadService(
|
||||
|
||||
// Create a consistent seed for the week using the year and the day of the year of above monday chosen
|
||||
// This results in seed being identical for the week
|
||||
var seed = startOfWeek.Year * 1000 + startOfWeek.DayOfYear;
|
||||
var seed = startOfWeek.Year * 1009 + startOfWeek.DayOfYear;
|
||||
|
||||
// Init Random class with unique seed
|
||||
var random = new Random(seed);
|
||||
@@ -717,6 +717,11 @@ public class PostDbLoadService(
|
||||
continue;
|
||||
}
|
||||
|
||||
if (traderData.QuestAssort is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Merge started/success/fail quest assorts into one dictionary
|
||||
var mergedQuestAssorts = new Dictionary<MongoId, MongoId>();
|
||||
mergedQuestAssorts = mergedQuestAssorts
|
||||
|
||||
@@ -531,15 +531,17 @@ public class RagfairPriceService(
|
||||
/// </summary>
|
||||
/// <param name="weaponWithChildren">weapon plus mods</param>
|
||||
/// <returns>price of weapon in roubles</returns>
|
||||
protected double GetPresetPriceByChildren(IEnumerable<Item> weaponWithChildren)
|
||||
public double GetPresetPriceByChildren(IEnumerable<Item> weaponWithChildren)
|
||||
{
|
||||
var priceTotal = 0d;
|
||||
foreach (var item in weaponWithChildren)
|
||||
{
|
||||
// Root item uses static price
|
||||
if (item.ParentId == null)
|
||||
if (item.ParentId == null || string.Equals(item.ParentId, "hideout", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
priceTotal += GetStaticPriceForItem(item.Template) ?? 0;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
priceTotal += GetFleaPriceForItem(item.Template);
|
||||
|
||||
@@ -29,6 +29,7 @@ public class RepairService(
|
||||
PaymentService paymentService,
|
||||
ProfileHelper profileHelper,
|
||||
RepairHelper repairHelper,
|
||||
InventoryHelper inventoryHelper,
|
||||
ServerLocalisationService serverLocalisationService,
|
||||
ConfigServer configServer,
|
||||
WeightedRandomHelper weightedRandomHelper
|
||||
@@ -49,14 +50,16 @@ public class RepairService(
|
||||
var itemToRepair = pmcData.Inventory.Items.FirstOrDefault(item => item.Id == repairItemDetails.Id);
|
||||
if (itemToRepair is null)
|
||||
{
|
||||
logger.Error(serverLocalisationService.GetText("repair-unable_to_find_item_in_inventory_cant_repair", repairItemDetails.Id));
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText("repair-unable_to_find_item_in_inventory_cant_repair", repairItemDetails.Id.ToString())
|
||||
);
|
||||
}
|
||||
|
||||
var priceCoef = traderHelper.GetLoyaltyLevel(traderId, pmcData).RepairPriceCoefficient;
|
||||
var traderRepairDetails = traderHelper.GetTrader(traderId, sessionID)?.Repair;
|
||||
if (traderRepairDetails is null)
|
||||
{
|
||||
logger.Error(serverLocalisationService.GetText("repair-unable_to_find_trader_details_by_id", traderId));
|
||||
logger.Error(serverLocalisationService.GetText("repair-unable_to_find_trader_details_by_id", traderId.ToString()));
|
||||
}
|
||||
|
||||
var repairQualityMultiplier = traderRepairDetails.Quality;
|
||||
@@ -80,7 +83,7 @@ public class RepairService(
|
||||
var itemRepairCost = items[itemToRepair.Template].Properties.RepairCost;
|
||||
if (itemRepairCost is null)
|
||||
{
|
||||
logger.Error(serverLocalisationService.GetText("repair-unable_to_find_item_repair_cost", itemToRepair.Template));
|
||||
logger.Error(serverLocalisationService.GetText("repair-unable_to_find_item_repair_cost", itemToRepair.Template.ToString()));
|
||||
}
|
||||
|
||||
var repairCost = Math.Round(itemRepairCost.Value * repairItemDetails.Count.Value * repairRate.Value * RepairConfig.PriceMultiplier);
|
||||
@@ -166,7 +169,9 @@ public class RepairService(
|
||||
if (!itemDetails.Key)
|
||||
{
|
||||
// No item found
|
||||
logger.Error(serverLocalisationService.GetText("repair-unable_to_find_item_in_db", repairDetails.RepairedItem.Template));
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText("repair-unable_to_find_item_in_db", repairDetails.RepairedItem.Template.ToString())
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -175,7 +180,9 @@ public class RepairService(
|
||||
var vestSkillToLevel = isHeavyArmor ? SkillTypes.HeavyVests : SkillTypes.LightVests;
|
||||
if (repairDetails.RepairPoints is null)
|
||||
{
|
||||
logger.Error(serverLocalisationService.GetText("repair-item_has_no_repair_points", repairDetails.RepairedItem.Template));
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText("repair-item_has_no_repair_points", repairDetails.RepairedItem.Template.ToString())
|
||||
);
|
||||
}
|
||||
|
||||
var pointsToAddToVestSkill = repairDetails.RepairPoints * RepairConfig.ArmorKitSkillPointGainPerRepairPointMultiplier;
|
||||
@@ -205,7 +212,9 @@ public class RepairService(
|
||||
// Limit gain to a max value defined in config.maxIntellectGainPerRepair
|
||||
if (repairDetails.RepairPoints is null)
|
||||
{
|
||||
logger.Error(serverLocalisationService.GetText("repair-item_has_no_repair_points", repairDetails.RepairedItem.Template));
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText("repair-item_has_no_repair_points", repairDetails.RepairedItem.Template.ToString())
|
||||
);
|
||||
}
|
||||
|
||||
return Math.Min(repairDetails.RepairPoints.Value * intRepairMultiplier, RepairConfig.MaxIntellectGainPerRepair.Kit);
|
||||
@@ -272,43 +281,61 @@ public class RepairService(
|
||||
var itemToRepair = pmcData.Inventory.Items.FirstOrDefault(x => x.Id == itemToRepairId);
|
||||
if (itemToRepair is null)
|
||||
{
|
||||
logger.Error(serverLocalisationService.GetText("repair-item_not_found_unable_to_repair", itemToRepairId));
|
||||
logger.Error(serverLocalisationService.GetText("repair-item_not_found_unable_to_repair", itemToRepairId.ToString()));
|
||||
}
|
||||
|
||||
var itemsDb = databaseService.GetItems();
|
||||
var itemToRepairDetails = itemsDb[itemToRepair.Template];
|
||||
var repairItemIsArmor = itemToRepairDetails.Properties.ArmorMaterial is not null;
|
||||
var repairAmount = repairKits[0].Count / GetKitDivisor(itemToRepairDetails, repairItemIsArmor, pmcData);
|
||||
var shouldApplyDurabilityLoss = ShouldRepairKitApplyDurabilityLoss(pmcData, RepairConfig.ApplyRandomizeDurabilityLoss);
|
||||
|
||||
// Amount to add to gun as durability
|
||||
var repairAmountTotal = repairKits[0].Count / GetKitDivisor(itemToRepairDetails, repairItemIsArmor, pmcData);
|
||||
|
||||
repairHelper.UpdateItemDurability(
|
||||
itemToRepair,
|
||||
itemToRepairDetails,
|
||||
repairItemIsArmor,
|
||||
repairAmount.Value,
|
||||
repairAmountTotal.Value,
|
||||
true,
|
||||
1,
|
||||
shouldApplyDurabilityLoss
|
||||
ShouldRepairKitApplyDurabilityLoss(pmcData, RepairConfig.ApplyRandomizeDurabilityLoss)
|
||||
);
|
||||
|
||||
// Find and use repair kit defined in body
|
||||
List<MongoId> kitIdsToDelete = [];
|
||||
foreach (var repairKit in repairKits)
|
||||
{
|
||||
var repairKitInInventory = pmcData.Inventory.Items.FirstOrDefault(item => item.Id == repairKit.Id);
|
||||
if (repairKitInInventory is null)
|
||||
{
|
||||
logger.Error(serverLocalisationService.GetText("repair-repair_kit_not_found_in_inventory", repairKit.Id));
|
||||
logger.Error(serverLocalisationService.GetText("repair-repair_kit_not_found_in_inventory", repairKit.Id.ToString()));
|
||||
}
|
||||
|
||||
var repairKitDetails = itemsDb[repairKitInInventory.Template];
|
||||
var repairKitReductionAmount = repairKit.Count;
|
||||
var repairKitDbDetails = itemsDb[repairKitInInventory.Template];
|
||||
AddMaxResourceToKitIfMissing(repairKitDbDetails, repairKitInInventory);
|
||||
|
||||
AddMaxResourceToKitIfMissing(repairKitDetails, repairKitInInventory);
|
||||
if (repairKitInInventory.Upd.RepairKit.Resource <= repairKit.Count)
|
||||
{
|
||||
// Repair kit will be fully used up
|
||||
// Flag kit for deletion
|
||||
kitIdsToDelete.Add(repairKit.Id);
|
||||
|
||||
// reduce usages on repairkit used
|
||||
repairKitInInventory.Upd.RepairKit.Resource -= repairKitReductionAmount;
|
||||
// Move on to next repair kit
|
||||
continue;
|
||||
}
|
||||
|
||||
// Repair kit had enough resources to repair in one go
|
||||
// Update server item resource value
|
||||
repairKitInInventory.Upd.RepairKit.Resource -= repairKit.Count;
|
||||
|
||||
output.ProfileChanges[sessionId].Items.ChangedItems.Add(repairKitInInventory);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
foreach (var kitId in kitIdsToDelete)
|
||||
{
|
||||
inventoryHelper.RemoveItem(pmcData, kitId, sessionId, output);
|
||||
}
|
||||
|
||||
return new RepairDetails
|
||||
@@ -316,7 +343,7 @@ public class RepairService(
|
||||
RepairPoints = repairKits[0].Count,
|
||||
RepairedItem = itemToRepair,
|
||||
RepairedItemIsArmor = repairItemIsArmor,
|
||||
RepairAmount = repairAmount,
|
||||
RepairAmount = repairAmountTotal,
|
||||
RepairedByKit = true,
|
||||
};
|
||||
}
|
||||
@@ -348,7 +375,7 @@ public class RepairService(
|
||||
var destructability = 1 + armorMaterial.Destructibility;
|
||||
var armorClass = itemToRepairDetails.Properties.ArmorClass.Value;
|
||||
var armorClassDivisor = globals.Configuration.RepairSettings.ArmorClassDivisor;
|
||||
var armorClassMultiplier = 1.0 + armorClass / armorClassDivisor;
|
||||
var armorClassMultiplier = 1.0 + (armorClass / armorClassDivisor);
|
||||
|
||||
return durabilityPointCostArmor * armorBonus * destructability * armorClassMultiplier;
|
||||
}
|
||||
@@ -414,7 +441,7 @@ public class RepairService(
|
||||
{
|
||||
if (logger.IsLogEnabled(LogLevel.Debug))
|
||||
{
|
||||
logger.Debug($"Repair kit: {repairKitInInventory.Id} in inventory lacks upd object, adding");
|
||||
logger.Debug($"Repair kit: {repairKitInInventory.Id.ToString()} in inventory lacks upd object, adding");
|
||||
}
|
||||
|
||||
repairKitInInventory.Upd = new Upd { RepairKit = new UpdRepairKit { Resource = maxRepairAmount } };
|
||||
@@ -550,7 +577,9 @@ public class RepairService(
|
||||
|
||||
if (repairDetails.RepairPoints is null)
|
||||
{
|
||||
logger.Error(serverLocalisationService.GetText("repair-item_has_no_repair_points", repairDetails.RepairedItem.Template));
|
||||
logger.Error(
|
||||
serverLocalisationService.GetText("repair-item_has_no_repair_points", repairDetails.RepairedItem.Template.ToString())
|
||||
);
|
||||
}
|
||||
|
||||
var durabilityToRestorePercent = repairDetails.RepairPoints / template.Properties.MaxDurability;
|
||||
|
||||
@@ -651,6 +651,9 @@ public class SeasonalEventService(
|
||||
);
|
||||
if (matchingBaseSettings is null)
|
||||
{
|
||||
// Doesn't exist, add it
|
||||
locationBase.Base.BotLocationModifier.AdditionalHostilitySettings.Append(settings);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -769,6 +772,11 @@ public class SeasonalEventService(
|
||||
protected void EnableHalloweenSummonEvent()
|
||||
{
|
||||
databaseService.GetGlobals().Configuration.EventSettings.EventActive = true;
|
||||
|
||||
if (SeasonalEventConfig.HostilitySettingsForEvent.TryGetValue("summon", out var botData))
|
||||
{
|
||||
ReplaceBotHostility(botData);
|
||||
}
|
||||
}
|
||||
|
||||
protected void ConfigureZombies(ZombieSettings zombieSettings)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Runtime;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Authentication;
|
||||
using System.Text;
|
||||
@@ -44,7 +43,9 @@ public static class Program
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine("=========================================================================================================");
|
||||
Console.WriteLine("The server has unexpectedly stopped, please check your log files and reach out to #spt-support in discord");
|
||||
Console.WriteLine(
|
||||
"The server has unexpectedly stopped, reach out to #spt-support in discord, create a support thread by following the instructions found in #support-guidelines. Also include a screenshot of this message + the below error"
|
||||
);
|
||||
Console.WriteLine(e);
|
||||
Console.WriteLine("=========================================================================================================");
|
||||
Console.WriteLine("Press any key to exit...");
|
||||
|
||||
Reference in New Issue
Block a user