From 1cfc7f2a162073e1c72aa35b1cc9bcd6d66ba5e1 Mon Sep 17 00:00:00 2001 From: Dev Date: Fri, 9 Feb 2024 17:13:19 +0000 Subject: [PATCH] Fixed issue with server not properly handling item rotations when trying to fit an item into a container Added small optimisations to skip full rows when looking for a free slot to put item in Added small optimisation to skip looking for a free slot when entire container is full Fixed error messages not properly being passed back up chain --- project/src/helpers/ContainerHelper.ts | 27 ++++++++++++++-------- project/src/helpers/InventoryHelper.ts | 31 +++++++++----------------- 2 files changed, 28 insertions(+), 30 deletions(-) diff --git a/project/src/helpers/ContainerHelper.ts b/project/src/helpers/ContainerHelper.ts index 763c537f..cb32052b 100644 --- a/project/src/helpers/ContainerHelper.ts +++ b/project/src/helpers/ContainerHelper.ts @@ -34,24 +34,31 @@ export class ContainerHelper const limitY = containerY - minVolume; const limitX = containerX - minVolume; - // Every slot taken up, exit + // Every x+y slot taken up in container, exit if (container2D.every((x) => x.every((y) => y === 1))) { return new FindSlotResult(false); } + // Down for (let y = 0; y < limitY; y++) { + // Across + if (container2D[y].every((x) => x === 1)) + { + // Every item in row is full, skip row + continue; + } + for (let x = 0; x < limitX; x++) { let foundSlot = this.locateSlot(container2D, containerX, containerY, x, y, itemWidth, itemHeight); - /** - * Failed to find slot, rotate item and try again - */ + // Failed to find slot, rotate item and try again if (!foundSlot && itemWidth * itemHeight > 1) - { // bigger than 1x1 - foundSlot = this.locateSlot(container2D, containerX, containerY, x, y, itemHeight, itemWidth); + { + // Bigger than 1x1 + foundSlot = this.locateSlot(container2D, containerX, containerY, x, y, itemHeight, itemWidth); // Height/Width swapped if (foundSlot) { // Found a slot for it when rotated @@ -104,7 +111,7 @@ export class ContainerHelper break; } - // Does item fit x-ways + // Does item fit x-ways across for (let itemX = 0; itemX < itemW; itemX++) { if (foundSlot && x + itemW - 1 > containerX - 1) @@ -131,7 +138,7 @@ export class ContainerHelper /** * Find a free slot for an item to be placed at - * @param container2D Container to palce item in + * @param container2D Container to place item in * @param x Container x size * @param y Container y size * @param itemW Items width @@ -147,6 +154,7 @@ export class ContainerHelper rotate: boolean, ): void { + // Swap height/width if we want to fit it in rotated const itemWidth = rotate ? itemH : itemW; const itemHeight = rotate ? itemW : itemH; @@ -156,11 +164,12 @@ export class ContainerHelper { if (container2D[tmpY][tmpX] === 0) { + // Flag slot as used container2D[tmpY][tmpX] = 1; } else { - throw new Error(`Slot at (${x}, ${y}) is already filled`); + throw new Error(`Slot at (${x}, ${y}) is already filled. Cannot fit a ${itemW} by ${itemH}`); } } } diff --git a/project/src/helpers/InventoryHelper.ts b/project/src/helpers/InventoryHelper.ts index 9e9ebb45..01257be4 100644 --- a/project/src/helpers/InventoryHelper.ts +++ b/project/src/helpers/InventoryHelper.ts @@ -236,7 +236,7 @@ export class InventoryHelper { const pmcData = this.profileHelper.getPmcProfile(sessionId); - const stashFS2D = this.getStashSlotMap(pmcData, sessionId); + const stashFS2D = this.jsonUtil.clone(this.getStashSlotMap(pmcData, sessionId)); for (const itemWithChildren of itemsWithChildren) { if (this.canPlaceItemInInventory(stashFS2D, itemWithChildren)) @@ -258,25 +258,20 @@ export class InventoryHelper const findSlotResult = this.containerHelper.findSlotForItem(stashFS2D, itemSize[0], itemSize[1]); if (findSlotResult.success) { - /* Fill in the StashFS_2D with an imaginary item, to simulate it already being added - * so the next item to search for a free slot won't find the same one */ - const itemSizeX = findSlotResult.rotation ? itemSize[1] : itemSize[0]; - const itemSizeY = findSlotResult.rotation ? itemSize[0] : itemSize[1]; - try { this.containerHelper.fillContainerMapWithItem( stashFS2D, findSlotResult.x, findSlotResult.y, - itemSizeX, - itemSizeY, + itemSize[0], + itemSize[1], findSlotResult.rotation, ); } catch (err) { - const errorText = (typeof err === "string") ? ` -> ${err}` : ""; + const errorText = (typeof err === "string") ? ` -> ${err}` : err.message; this.logger.error(`Unable to fit item into inventory: ${errorText}`); return false; @@ -315,25 +310,20 @@ export class InventoryHelper const findSlotResult = this.containerHelper.findSlotForItem(stashFS2D, itemSize[0], itemSize[1]); if (findSlotResult.success) { - /* Fill in the StashFS_2D with an imaginary item, to simulate it already being added - * so the next item to search for a free slot won't find the same one */ - const itemSizeX = findSlotResult.rotation ? itemSize[1] : itemSize[0]; - const itemSizeY = findSlotResult.rotation ? itemSize[0] : itemSize[1]; - try { this.containerHelper.fillContainerMapWithItem( stashFS2D, findSlotResult.x, findSlotResult.y, - itemSizeX, - itemSizeY, + itemSize[0], + itemSize[1], findSlotResult.rotation, ); } catch (err) { - const errorText = (typeof err === "string") ? ` -> ${err}` : ""; + const errorText = (typeof err === "string") ? ` -> ${err}` : err.message; this.logger.error(this.localisationService.getText("inventory-fill_container_failed", errorText)); this.httpResponse.appendErrorToOutput( @@ -365,16 +355,15 @@ export class InventoryHelper itemSize[0], itemSize[1], ); - const itemSizeX = findSortingSlotResult.rotation ? itemSize[1] : itemSize[0]; - const itemSizeY = findSortingSlotResult.rotation ? itemSize[0] : itemSize[1]; + try { this.containerHelper.fillContainerMapWithItem( sortingTableFS2D, findSortingSlotResult.x, findSortingSlotResult.y, - itemSizeX, - itemSizeY, + itemSize[0], + itemSize[1], findSortingSlotResult.rotation, ); }