Correctly pass item rotation when calling fillContainerMapWithItem()

Removed unused legacy function `placeItemInInventoryLegacy()`
Dont return stash layout as result in `fillContainerMapWithItem()`

Added small optimisation to `fillContainerMapWithItem()`, check if all slots of failled before trying to fit item
This commit is contained in:
Dev 2024-02-09 15:13:49 +00:00
parent 791ebd4693
commit 5a8317b8a1
3 changed files with 28 additions and 140 deletions

View File

@ -412,9 +412,9 @@ export class LocationGenerator
const containerLootPool = this.getPossibleLootItemsForContainer(containerTpl, staticLootDist);
// Some containers need to have items forced into it (quest keys etc)
const tplsForced = staticForced.filter((x) => x.containerId === containerClone.template.Id).map((x) =>
x.itemTpl
);
const tplsForced = staticForced.filter((forcedStaticProp) =>
forcedStaticProp.containerId === containerClone.template.Id
).map((x) => x.itemTpl);
// Draw random loot
// Money spawn more than once in container
@ -427,7 +427,7 @@ export class LocationGenerator
itemCountToAdd,
this.locationConfig.allowDuplicateItemsInStaticContainers,
locklist,
).filter((x) => !tplsForced.includes(x));
).filter((tpl) => !tplsForced.includes(tpl));
// Add forced loot to chosen item pool
const tplsToAddToContainer = tplsForced.concat(chosenTpls);
@ -442,9 +442,9 @@ export class LocationGenerator
const result = this.containerHelper.findSlotForItem(containerMap, width, height);
if (!result.success)
{
// 2 attempts to fit an item, container is probably full, stop trying to add more
if (failedToFitCount >= this.locationConfig.fitLootIntoContainerAttempts)
{
// x attempts to fit an item, container is probably full, stop trying to add more
break;
}
@ -454,7 +454,7 @@ export class LocationGenerator
continue;
}
containerMap = this.containerHelper.fillContainerMapWithItem(
this.containerHelper.fillContainerMapWithItem(
containerMap,
result.x,
result.y,

View File

@ -34,6 +34,12 @@ export class ContainerHelper
const limitY = containerY - minVolume;
const limitX = containerX - minVolume;
// Every slot taken up, exit
if (container2D.every((x) => x.every((y) => y === 1)))
{
return new FindSlotResult(false);
}
for (let y = 0; y < limitY; y++)
{
for (let x = 0; x < limitX; x++)
@ -41,21 +47,21 @@ export class ContainerHelper
let foundSlot = this.locateSlot(container2D, containerX, containerY, x, y, itemWidth, itemHeight);
/**
* Try to rotate if there is enough room for the item
* Only occupies one grid of items, no rotation required
* 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);
if (foundSlot)
{
// Found a slot for it when rotated
rotation = true;
}
}
if (!foundSlot)
{
// Didn't fit this hole, try again
continue;
}
@ -63,7 +69,8 @@ export class ContainerHelper
}
}
return new FindSlotResult();
// Tried all possible holes, nothing big enough for the item
return new FindSlotResult(false);
}
/**
@ -130,7 +137,6 @@ export class ContainerHelper
* @param itemW Items width
* @param itemH Items height
* @param rotate is item rotated
* @returns Location to place item
*/
public fillContainerMapWithItem(
container2D: number[][],
@ -139,7 +145,7 @@ export class ContainerHelper
itemW: number,
itemH: number,
rotate: boolean,
): number[][]
): void
{
const itemWidth = rotate ? itemH : itemW;
const itemHeight = rotate ? itemW : itemH;
@ -158,7 +164,5 @@ export class ContainerHelper
}
}
}
return container2D;
}
}

View File

@ -265,14 +265,14 @@ export class InventoryHelper
try
{
stashFS2D = this.containerHelper.fillContainerMapWithItem(
this.containerHelper.fillContainerMapWithItem(
stashFS2D,
findSlotResult.x,
findSlotResult.y,
itemSizeX,
itemSizeY,
false,
); // TODO: rotation not passed in, bad?
findSlotResult.rotation,
);
}
catch (err)
{
@ -311,14 +311,14 @@ export class InventoryHelper
try
{
stashFS2D = this.containerHelper.fillContainerMapWithItem(
this.containerHelper.fillContainerMapWithItem(
stashFS2D,
findSlotResult.x,
findSlotResult.y,
itemSizeX,
itemSizeY,
false,
); // TODO: rotation not passed in, bad?
findSlotResult.rotation,
);
}
catch (err)
{
@ -358,14 +358,14 @@ export class InventoryHelper
const itemSizeY = findSortingSlotResult.rotation ? itemSize[0] : itemSize[1];
try
{
sortingTableFS2D = this.containerHelper.fillContainerMapWithItem(
this.containerHelper.fillContainerMapWithItem(
sortingTableFS2D,
findSortingSlotResult.x,
findSortingSlotResult.y,
itemSizeX,
itemSizeY,
false,
); // TODO: rotation not passed in, bad?
findSortingSlotResult.rotation,
);
}
catch (err)
{
@ -397,122 +397,6 @@ export class InventoryHelper
}
}
/**
* Take the given item, find a free slot in passed in inventory and place it there
* If no space in inventory, place in sorting table
* @param itemToAdd Item to add to inventory
* @param stashFS2D Two dimentional stash map
* @param sortingTableFS2D Two dimentional sorting table stash map
* @param itemLib
* @param pmcData Player profile
* @param useSortingTable Should sorting table be used for overflow items when no inventory space for item
* @param output Client output object
* @returns Client error output if placing item failed
*/
protected placeItemInInventoryLegacy(
itemToAdd: IAddItemTempObject,
stashFS2D: number[][],
sortingTableFS2D: number[][],
itemLib: Item[],
playerInventory: Inventory,
useSortingTable: boolean,
output: IItemEventRouterResponse,
): IItemEventRouterResponse
{
const itemSize = this.getItemSize(itemToAdd.itemRef._tpl, itemToAdd.itemRef._id, itemLib);
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
{
stashFS2D = this.containerHelper.fillContainerMapWithItem(
stashFS2D,
findSlotResult.x,
findSlotResult.y,
itemSizeX,
itemSizeY,
false,
); // TODO: rotation not passed in, bad?
}
catch (err)
{
const errorText = typeof err === "string" ? ` -> ${err}` : "";
this.logger.error(this.localisationService.getText("inventory-fill_container_failed", errorText));
return this.httpResponse.appendErrorToOutput(
output,
this.localisationService.getText("inventory-no_stash_space"),
);
}
// Store details for object, incuding container item will be placed in
itemToAdd.containerId = playerInventory.stash;
itemToAdd.location = {
x: findSlotResult.x,
y: findSlotResult.y,
r: findSlotResult.rotation ? 1 : 0,
rotation: findSlotResult.rotation,
};
// Success! exit
return;
}
// Space not found in main stash, use sorting table
if (useSortingTable)
{
const findSortingSlotResult = this.containerHelper.findSlotForItem(
sortingTableFS2D,
itemSize[0],
itemSize[1],
);
const itemSizeX = findSortingSlotResult.rotation ? itemSize[1] : itemSize[0];
const itemSizeY = findSortingSlotResult.rotation ? itemSize[0] : itemSize[1];
try
{
sortingTableFS2D = this.containerHelper.fillContainerMapWithItem(
sortingTableFS2D,
findSortingSlotResult.x,
findSortingSlotResult.y,
itemSizeX,
itemSizeY,
false,
); // TODO: rotation not passed in, bad?
}
catch (err)
{
const errorText = typeof err === "string" ? ` -> ${err}` : "";
this.logger.error(this.localisationService.getText("inventory-fill_container_failed", errorText));
return this.httpResponse.appendErrorToOutput(
output,
this.localisationService.getText("inventory-no_stash_space"),
);
}
// Store details for object, incuding container item will be placed in
itemToAdd.containerId = playerInventory.sortingTable;
itemToAdd.location = {
x: findSortingSlotResult.x,
y: findSortingSlotResult.y,
r: findSortingSlotResult.rotation ? 1 : 0,
rotation: findSortingSlotResult.rotation,
};
}
else
{
return this.httpResponse.appendErrorToOutput(
output,
this.localisationService.getText("inventory-no_stash_space"),
);
}
}
/**
* Add ammo to ammo boxes
* @param itemToAdd Item to check is ammo box