I'm having trouble figuring out how to spawn more than one item in to a container with a weight limit. What I'm having trouble with is the understanding, rather than what statements to write;
My items are composed of weight
, type
and foundIn
, among other things. My containers are items, with some minor changes. foundIn
is an array of strings which match "container" items, and should be either "world", "container-name", or empty ([]
). "container" items follow a similar structure, with slight deviance.
Whenever I want to drop an item, I get a pool of items in a foundIn
location, make a Math.random
check against the commonRate
, and if that item is a type = "container"
, I try to fill the container.
Here is where I have my problem; I can not figure out how to decide if multiple items of the same type
should be dropped inside the container, and if so, how many. If I can figure this out, I can have monsters carry their own drops, instead of having to write a whole monster drop-table with levels and oddities.
The following is my code. The last method, dropItem
, glues the displayed methods together.
placeExists(place) {
return this._itemPlaces.indexOf(place) > -1;
}
getItemsOfType(arrayOfTypes, inList) {
if (!Array.isArray(arrayOfTypes)) throw new Error('Index must be string');
let pool = this.list;
if (inList) pool = inList;
return pool.map((item => {
if (arrayOfTypes.indexOf(item.type) > -1) {
return item;
}
}));
}
populateContainer(container, pool) {
let chance = Math.random();
pool = pool.map(item => {
let canBeFound = item.foundIn.indexOf(container.name) > -1
|| item.foundIn.indexOf('world') > -1;
if (item.commonRate >= chance && canBeFound) return item;
});
this.getItemsOfType(container.availableTypePool, pool).some(item => {
if (container.capacity.freeSpace <= 0) return true;
if (item.commonRate >= Math.random()
&& item.weight <= container.capacity.freeSpace) {
container.addItem(item);
}
});
return container;
}
getItemsOfPlace(place) {
return this._LIST.map(item => {
if (item.isFoundIn(place)) {
return item;
}
})
}
dropItem(fromPlace) {
if (this.placeExists(fromPlace)) return [];
let foundItem = [];
let pool = this.getItemsOfPlace(fromPlace);
pool.some(item => {
let chance = Math.random();
if (chance > item.commonRate) {
if (item.type == 'container')
foundItem.push(this.populateContainer(item, pool));
else
foundItem.push(item);
return true;
}
});
return foundItem;
}
// container abstracted method of adding an item
container.addItem = (item = new Item()) {
if (item instanceof Item === false) throw Error('item needs to be of type Item');
if (item.type == 'container') throw Error('Yo dawg, I heard you like containers...');
this._contained.push(item.code);
this.carryingWeight = +item.weight;
}
How do I decide if I should drop multiple items, and how do I randomly select that amount?
Note that this.list
and this._LIST
are the same list. For some reason, WebStorm seems to lose track of one or the other when inside certain callbacks, so I switch to avoid losing autocomplete. For reference, this.list
is get list() { return this._LIST }
, and is obtained from extending a custom List
class.