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
This commit is contained in:
Dev 2024-02-09 17:13:19 +00:00
parent 8b6de1a7ea
commit 1cfc7f2a16
2 changed files with 28 additions and 30 deletions

View File

@ -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}`);
}
}
}

View File

@ -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,
);
}