bdo-shopping-cart-package
Version:
For use with my bdo-crafting-profit projects
183 lines • 8.52 kB
JavaScript
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __spreadArrays = (this && this.__spreadArrays) || function () {
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
for (var r = Array(s), k = 0, i = 0; i < il; i++)
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
r[k] = a[j];
return r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PPSOptimizer = void 0;
var OptimizerInterface_1 = require("./OptimizerInterface");
var Action_1 = require("./Action");
var ShoppingCartCore_1 = require("../shoppingCart/ShoppingCartCore");
var PPSOptimizer = /** @class */ (function (_super) {
__extends(PPSOptimizer, _super);
function PPSOptimizer() {
return _super !== null && _super.apply(this, arguments) || this;
}
/**
* Find the most optimal actions
*/
PPSOptimizer.prototype.findOptimalActionSets = function () {
if (this.rootItemName == null ||
this.items == null ||
!(this.rootItemName in this.items))
return {};
var bestRecipeActions = {};
var rootItem = this.items[this.rootItemName];
for (var _i = 0, _a = Object.entries(rootItem.recipes); _i < _a.length; _i++) {
var _b = _a[_i], recipeId = _b[0], recipe = _b[1];
this.startCalculatingOptimalActions(this.rootItemName, recipeId);
bestRecipeActions[recipeId] = {
recipe: recipe,
optimalActions: this.optimalActions,
};
}
return bestRecipeActions;
};
PPSOptimizer.prototype.startCalculatingOptimalActions = function (itemName, startingRecipeId) {
this.resetOptimalActions();
// starting recipe id == null is the 'Buy' action
if (itemName == "" ||
itemName == null ||
this.items == null ||
this.items == {}) {
return {};
}
this.optimalActions = this.calculateOptimalActions(itemName, startingRecipeId, null);
return this.optimalActions || {};
};
/**
*
* @param item
* @param recipeRestriction Must choose this recipe
* @param optimalActions
*/
PPSOptimizer.prototype.calculateOptimalActions = function (itemName, recipeRestriction, optimalActions) {
var _a;
if (recipeRestriction == "")
recipeRestriction = null;
// Initialize dictionary
if (optimalActions == null)
optimalActions = {};
// Double check itemName
if (itemName == null)
return optimalActions;
var item = this.items[itemName];
// If the calculations were already performed, just return those.
if (optimalActions[itemName] != null)
return optimalActions;
// What is the cost to buy this item?
var itemMarketPrice = ShoppingCartCore_1.getMarketPriceForItem(item);
if (optimalActions[itemName] == null) {
optimalActions[itemName] = (_a = {},
_a[Action_1.ActionTaken.Buy] = item.marketData && item.marketData["Market Price"]
? new Action_1.Action(itemMarketPrice, 0, null, null, null)
: null,
_a[Action_1.ActionTaken.Craft] = null,
_a);
}
// For every possible recipe that can be crafted...
var possibleCraftOptions = [];
for (var _i = 0, _b = Object.entries(item.recipes); _i < _b.length; _i++) {
var _c = _b[_i], recipe_id = _c[0], possibleRecipe = _c[1];
// If there is a recipe restriction, skip all other recipes
if (recipeRestriction != null && recipe_id !== recipeRestriction)
continue;
// Skip to next recipe if there is no crafting option
var recipeIngredients = possibleRecipe.ingredients;
if (recipeIngredients == null)
continue;
// Generate all possible sequences of 'Buy' or 'Craft' for the list of ingredients
var arr = [];
for (var i = 0; i < recipeIngredients.length; i++) {
arr.push("Buy");
}
var gen = this.sequenceGenerator(arr.length, arr, 0); // Sample sequence: ['Buy', 'Sell', 'Buy']
var generatorResult = gen.next();
while (generatorResult.done === false) {
var sequence = generatorResult.value;
var action = this.calculateRecipeCostUsingSequence(sequence, possibleRecipe, recipe_id, optimalActions);
if (action != null)
possibleCraftOptions.push(action);
// Pick next sequence to test...
generatorResult = gen.next();
}
}
if (possibleCraftOptions.length > 0) {
optimalActions[item.name]["Craft"] = this.pickBestCraftingAction(possibleCraftOptions, itemMarketPrice);
}
return optimalActions;
};
PPSOptimizer.prototype.pickBestCraftingAction = function (possibleCraftOptions, itemMarketPrice) {
return possibleCraftOptions.reduce(function (bestAction, action) {
var bestActionProfit = bestAction.calculateProfit(itemMarketPrice);
var profit = action.calculateProfit(itemMarketPrice);
// This if statement handles symbolic recipes
if (!Number.isFinite(profit)) {
profit = -action.monetaryCost;
}
if (!Number.isFinite(bestActionProfit)) {
bestActionProfit = -bestAction.monetaryCost;
}
// We found a better crafting recipe!
if (profit > bestActionProfit)
return action;
else
return bestAction;
});
};
PPSOptimizer.prototype.calculateRecipeCostUsingSequence = function (sequence, recipe, recipe_id, optimalActions) {
var recipeIngredients = recipe.ingredients;
var totalCost = 0;
var totalTime = 0;
var sequenceImpossible = false;
for (var i = 0; i < sequence.length; i++) {
// Buy or craft the ingredient?
var buyOrCraft = sequence[i];
var ingredient = recipeIngredients[i]; // The string
var result = this.calculateOptimalActions(ingredient["Item Name"], null, optimalActions);
var action = result[ingredient["Item Name"]][buyOrCraft];
// The provided sequence is impossible. (Cannot craft the ingredient!)
if (action == null) {
sequenceImpossible = true;
break;
}
// For this 'possible recipe' what is the cost to craft it?
// (using optimal action)
if (buyOrCraft === "Buy") {
totalCost += ingredient["Amount"] * action.monetaryCost;
}
else {
// Some items used to produce this ingredent may have been bought while others were crafted
totalTime += ingredient["Amount"] * action.time;
totalCost += ingredient["Amount"] * action.monetaryCost;
}
}
totalTime += recipe.timeToProduce;
// console.log('PPSOptimizer.jsx | ', item.name, generatorResult.value, totalCost / recipe.quantityProduced, recipe)
if (!sequenceImpossible) {
// The sequence was valid!
return new Action_1.Action(totalCost / recipe.quantityProduced, totalTime / recipe.quantityProduced, recipe, recipe_id, __spreadArrays(sequence));
}
else
return null;
};
return PPSOptimizer;
}(OptimizerInterface_1.Optimizer));
exports.PPSOptimizer = PPSOptimizer;
//# sourceMappingURL=PPSOptimizer.js.map