|
|
|
@@ -1,53 +1,29 @@
|
|
|
|
|
import type { DependencyContainer } from "tsyringe";
|
|
|
|
|
|
|
|
|
|
import type { InventoryController } from "@spt-aki/controllers/InventoryController";
|
|
|
|
|
import type { HideoutHelper } from "@spt-aki/helpers/HideoutHelper";
|
|
|
|
|
import type { InRaidHelper } from "@spt-aki/helpers/InRaidHelper";
|
|
|
|
|
import type { InventoryHelper } from "@spt-aki/helpers/InventoryHelper";
|
|
|
|
|
import type { ItemHelper } from "@spt-aki/helpers/ItemHelper";
|
|
|
|
|
import type { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
|
|
|
|
|
import type { RagfairSortHelper } from "@spt-aki/helpers/RagfairSortHelper";
|
|
|
|
|
import type { IHideoutSingleProductionStartRequestData } from "@spt-aki/models/eft/hideout/IHideoutSingleProductionStartRequestData";
|
|
|
|
|
import type { IRagfairOffer } from "@spt-aki/models/eft/ragfair/IRagfairOffer";
|
|
|
|
|
import { Money } from "@spt-aki/models/enums/Money";
|
|
|
|
|
import type { IPreAkiLoadMod } from "@spt-aki/models/external/IPreAkiLoadMod";
|
|
|
|
|
import type { ILogger } from "@spt-aki/models/spt/utils/ILogger";
|
|
|
|
|
import type { DatabaseServer } from "@spt-aki/servers/DatabaseServer";
|
|
|
|
|
import type { StaticRouterModService } from "@spt-aki/services/mod/staticRouter/StaticRouterModService";
|
|
|
|
|
import type { JsonUtil } from "@spt-aki/utils/JsonUtil";
|
|
|
|
|
import type { HideoutHelper } from "@spt/helpers/HideoutHelper";
|
|
|
|
|
import type { InRaidHelper } from "@spt/helpers/InRaidHelper";
|
|
|
|
|
import type { InventoryHelper } from "@spt/helpers/InventoryHelper";
|
|
|
|
|
import type { ItemHelper } from "@spt/helpers/ItemHelper";
|
|
|
|
|
import type { IHideoutSingleProductionStartRequestData } from "@spt/models/eft/hideout/IHideoutSingleProductionStartRequestData";
|
|
|
|
|
import type { IPreSptLoadMod } from "@spt/models/external/IPreSptLoadMod";
|
|
|
|
|
import type { ILogger } from "@spt/models/spt/utils/ILogger";
|
|
|
|
|
import type { DatabaseService } from "@spt/services/DatabaseService";
|
|
|
|
|
import type { StaticRouterModService } from "@spt/services/mod/staticRouter/StaticRouterModService";
|
|
|
|
|
import type { ICloner } from "@spt/utils/cloners/ICloner";
|
|
|
|
|
|
|
|
|
|
import config from "../config/config.json";
|
|
|
|
|
|
|
|
|
|
class UIFixes implements IPreAkiLoadMod {
|
|
|
|
|
private databaseServer: DatabaseServer;
|
|
|
|
|
class UIFixes implements IPreSptLoadMod {
|
|
|
|
|
private databaseService: DatabaseService;
|
|
|
|
|
private logger: ILogger;
|
|
|
|
|
|
|
|
|
|
public preAkiLoad(container: DependencyContainer): void {
|
|
|
|
|
this.databaseServer = container.resolve<DatabaseServer>("DatabaseServer");
|
|
|
|
|
this.logger = container.resolve<ILogger>("WinstonLogger");
|
|
|
|
|
public preSptLoad(container: DependencyContainer): void {
|
|
|
|
|
this.databaseService = container.resolve<DatabaseService>("DatabaseService");
|
|
|
|
|
this.logger = container.resolve<ILogger>("PrimaryLogger");
|
|
|
|
|
|
|
|
|
|
const profileHelper = container.resolve<ProfileHelper>("ProfileHelper");
|
|
|
|
|
const itemHelper = container.resolve<ItemHelper>("ItemHelper");
|
|
|
|
|
const staticRouterModService = container.resolve<StaticRouterModService>("StaticRouterModService");
|
|
|
|
|
const jsonUtil = container.resolve<JsonUtil>("JsonUtil");
|
|
|
|
|
|
|
|
|
|
// Handle scav profile for post-raid scav transfer swaps (fixed in 3.9.0)
|
|
|
|
|
container.afterResolution(
|
|
|
|
|
"InventoryController",
|
|
|
|
|
(_, inventoryController: InventoryController) => {
|
|
|
|
|
const original = inventoryController.swapItem;
|
|
|
|
|
|
|
|
|
|
inventoryController.swapItem = (pmcData, request, sessionID) => {
|
|
|
|
|
let playerData = pmcData;
|
|
|
|
|
if (request.fromOwner?.type === "Profile" && request.fromOwner.id !== playerData._id) {
|
|
|
|
|
playerData = profileHelper.getScavProfile(sessionID);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return original.call(inventoryController, playerData, request, sessionID);
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
{ frequency: "Always" }
|
|
|
|
|
);
|
|
|
|
|
const cloner = container.resolve<ICloner>("RecursiveCloner");
|
|
|
|
|
|
|
|
|
|
// Keep quickbinds for items that aren't actually lost on death
|
|
|
|
|
container.afterResolution(
|
|
|
|
@@ -57,7 +33,7 @@ class UIFixes implements IPreAkiLoadMod {
|
|
|
|
|
|
|
|
|
|
inRaidHelper.deleteInventory = (pmcData, sessionId) => {
|
|
|
|
|
// Copy the existing quickbinds
|
|
|
|
|
const fastPanel = jsonUtil.clone(pmcData.Inventory.fastPanel);
|
|
|
|
|
const fastPanel = cloner.clone(pmcData.Inventory.fastPanel);
|
|
|
|
|
|
|
|
|
|
// Nukes the inventory and the fastpanel
|
|
|
|
|
original.call(inRaidHelper, pmcData, sessionId);
|
|
|
|
@@ -73,23 +49,6 @@ class UIFixes implements IPreAkiLoadMod {
|
|
|
|
|
{ frequency: "Always" }
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Handle barter sort type (fixed in 3.9.0)
|
|
|
|
|
container.afterResolution(
|
|
|
|
|
"RagfairSortHelper",
|
|
|
|
|
(_, ragfairSortHelper: RagfairSortHelper) => {
|
|
|
|
|
const original = ragfairSortHelper.sortOffers;
|
|
|
|
|
|
|
|
|
|
ragfairSortHelper.sortOffers = (offers, type, direction) => {
|
|
|
|
|
if (+type == 2) {
|
|
|
|
|
offers.sort(this.sortOffersByBarter);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return original.call(ragfairSortHelper, offers, type, direction);
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
{ frequency: "Always" }
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Better tool return - starting production
|
|
|
|
|
if (config.putToolsBack) {
|
|
|
|
|
container.afterResolution(
|
|
|
|
@@ -124,7 +83,7 @@ class UIFixes implements IPreAkiLoadMod {
|
|
|
|
|
const original = inventoryHelper.addItemToStash;
|
|
|
|
|
|
|
|
|
|
inventoryHelper.addItemToStash = (sessionId, request, pmcData, output) => {
|
|
|
|
|
const itemWithModsToAddClone = jsonUtil.clone(request.itemWithModsToAdd);
|
|
|
|
|
const itemWithModsToAddClone = cloner.clone(request.itemWithModsToAdd);
|
|
|
|
|
|
|
|
|
|
// If a tool marked with uifixes is there, try to return it to its original container
|
|
|
|
|
const tool = itemWithModsToAddClone[0];
|
|
|
|
@@ -141,13 +100,13 @@ class UIFixes implements IPreAkiLoadMod {
|
|
|
|
|
containerId
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const canPlaceResult = inventoryHelper.canPlaceItemInContainer(
|
|
|
|
|
jsonUtil.clone(containerFS2D), // will change the array so clone it
|
|
|
|
|
itemWithModsToAddClone
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// In 3.8.3 canPlaceItemInContainer is wonky and returns undefined when the answer is yes
|
|
|
|
|
if (canPlaceResult === undefined) {
|
|
|
|
|
// will change the array so clone it
|
|
|
|
|
if (
|
|
|
|
|
inventoryHelper.canPlaceItemInContainer(
|
|
|
|
|
cloner.clone(containerFS2D),
|
|
|
|
|
itemWithModsToAddClone
|
|
|
|
|
)
|
|
|
|
|
) {
|
|
|
|
|
// At this point everything should succeed
|
|
|
|
|
inventoryHelper.placeItemInContainer(
|
|
|
|
|
containerFS2D,
|
|
|
|
@@ -189,7 +148,7 @@ class UIFixes implements IPreAkiLoadMod {
|
|
|
|
|
[
|
|
|
|
|
{
|
|
|
|
|
url: "/uifixes/assortUnlocks",
|
|
|
|
|
action: (url, info, sessionId, output) => {
|
|
|
|
|
action: async (url, info, sessionId, output) => {
|
|
|
|
|
return JSON.stringify(this.loadAssortmentUnlocks());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@@ -199,8 +158,8 @@ class UIFixes implements IPreAkiLoadMod {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private loadAssortmentUnlocks() {
|
|
|
|
|
const traders = this.databaseServer.getTables().traders;
|
|
|
|
|
const quests = this.databaseServer.getTables().templates.quests;
|
|
|
|
|
const traders = this.databaseService.getTraders();
|
|
|
|
|
const quests = this.databaseService.getQuests();
|
|
|
|
|
|
|
|
|
|
const result: Record<string, string> = {};
|
|
|
|
|
|
|
|
|
@@ -231,13 +190,6 @@ class UIFixes implements IPreAkiLoadMod {
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private sortOffersByBarter(a: IRagfairOffer, b: IRagfairOffer): number {
|
|
|
|
|
const moneyTpls = Object.values<string>(Money);
|
|
|
|
|
const aIsOnlyMoney = a.requirements.length == 1 && moneyTpls.includes(a.requirements[0]._tpl) ? 1 : 0;
|
|
|
|
|
const bIsOnlyMoney = b.requirements.length == 1 && moneyTpls.includes(b.requirements[0]._tpl) ? 1 : 0;
|
|
|
|
|
return aIsOnlyMoney - bIsOnlyMoney;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
module.exports = { mod: new UIFixes() };
|
|
|
|
|