diff --git a/d2bs/kolbot/libs/core/Misc.js b/d2bs/kolbot/libs/core/Misc.js index eb190274..097c01a2 100644 --- a/d2bs/kolbot/libs/core/Misc.js +++ b/d2bs/kolbot/libs/core/Misc.js @@ -644,7 +644,8 @@ const Misc = (function () { case sdk.shrines.Gem: // for now we ignore if we are gem hunting later on // TODO: add gem hunting logic, get gem from stash if we have one - return !Scripts.GemHunter; + console.debug("shriner: gem shrine. try my best."); + return Town.prepareForGemShrine(); } return false; }; @@ -703,6 +704,7 @@ const Misc = (function () { } } this.getShrine(shrine); + Pickit.pickItems(); } } } @@ -794,6 +796,11 @@ const Misc = (function () { shrine.objtype === Config.ScanShrines[i] || (Config.ScanShrines[i] === "well" && shrine.name.toLowerCase().includes("well") && needWell()) ) && (Pather.useTeleport() || !checkCollision(me, shrine, sdk.collision.WallOrRanged))) { + // Gem shrine - prepare and pick anyways + if (Config.ScanShrines[i] === sdk.shrines.Gem) { + console.debug("scanshrines: gem shine. try my best."); + Town.prepareForGemShrine(); + } this.getShrine(shrine); // Gem shrine - pick gem diff --git a/d2bs/kolbot/libs/core/Town.js b/d2bs/kolbot/libs/core/Town.js index d5b67d67..d469d12d 100644 --- a/d2bs/kolbot/libs/core/Town.js +++ b/d2bs/kolbot/libs/core/Town.js @@ -1425,8 +1425,7 @@ const Town = { */ canStash: function (item) { if (Town.ignoreType(item.itemType) - || [sdk.items.quest.HoradricStaff, sdk.items.quest.KhalimsWill].includes(item.classid) - || !Town.canStashGem(item)) { + || [sdk.items.quest.HoradricStaff, sdk.items.quest.KhalimsWill].includes(item.classid)) { return false; } /** @@ -1435,68 +1434,6 @@ const Town = { return Storage.Stash.CanFit(item); }, - /** - * get ordered list of gems in inventory to use with Gem Hunter Script - * @returns {ItemUnit[]} ordered list of relevant gems - */ - getGemsInInv: function () { - let GemList = Config.GemHunter.GemList; - return me.getItemsEx() - .filter((p) => p.isInInventory && GemList.includes(p.classid)) - .sort((a, b) => GemList.indexOf(a.classid) - GemList.indexOf(b.classid)); - }, - - /** - * get ordered list of gems in stash to use with Gem Hunter Script - * @returns {ItemUnit[]} ordered list of relevant gems - */ - getGemsInStash: function () { - let GemList = Config.GemHunter.GemList; - return me.getItemsEx() - .filter((p) => p.isInStash && GemList.includes(p.classid)) - .sort((a, b) => GemList.indexOf(a.classid) - GemList.indexOf(b.classid)); - }, - - /** - * gem check for use with Gem Hunter Script - * @param {ItemUnit} item - * @returns {boolean} if we should stash this gem - */ - canStashGem: function (item) { - // we aren't using the gem hunter script or we aren't scanning for the gem shrines while moving - // for now we are only going to keep a gem in our invo while the script is active - if (Loader.scriptName() !== "GemHunter") return true; - // not in our list - if (Config.GemHunter.GemList.indexOf(item.classid) === -1) return true; - - let GemList = Config.GemHunter.GemList; - let gemsInStash = Town.getGemsInStash(); - let bestGeminStash = gemsInStash.length > 0 ? gemsInStash.first().classid : -1; - let gemsInInvo = Town.getGemsInInv(); - let bestGeminInv = gemsInInvo.length > 0 ? gemsInInvo.first().classid : -1; - - return ( - (GemList.indexOf(bestGeminStash) < GemList.indexOf(bestGeminInv)) // better one in stash - || (GemList.indexOf(bestGeminInv) < GemList.indexOf(item.classid)) // better one in inv - || (gemsInInvo.filter((p) => p.classid === item.classid).length > 1)); // another one in inv - }, - - /** - * move best gem from stash to inventory, if none in inventrory - * to use with Gem Hunter Script - * @returns {boolean} if any gem has been moved - */ - getGem: function () { - if (Loader.scriptName() === "GemHunter") { - if (Town.getGemsInInv().length === 0 && Town.getGemsInStash().length > 0) { - let gem = Town.getGemsInStash().first(); - Storage.Inventory.MoveTo(gem) && Item.logger("Inventoried", gem); - return true; - } - } - return false; - }, - /** * @param {boolean} [stashGold=true] * @returns {boolean} @@ -2218,5 +2155,117 @@ const Town = { console.info(false, "CurrentArea: " + getAreaName(me.area)); return true; + }, + + /** + * @description get a gem worthy upgrading to inventory. go town if needed + * @returns {boolean} If a gem to upgrade is in inventory + */ + prepareForGemShrine: function () { + + function isUpgradePossible(unit) { + return ( + unit.itemType >= sdk.items.type.Amethyst + && unit.itemType <= sdk.items.type.Skull + && !Object.values(sdk.items.gems.Perfect).includes(unit.classid) + ); + } + + function pickitWantsUpgrade(unit) { + // Stub Object to let Pickit Check + function GemUnit(gem) { + this.itemType = gem.itemType; + this.classid = gem.classid; + this.type = gem.type; + this.mode = gem.mode; + this.gid = gem.gid; + } + // eslint-disable-next-line no-unused-vars + GemUnit.prototype.getFlag = function (flag) { + return true; + }; + + let gem = new GemUnit(unit); + // lets upgrade the gem + gem.classid += 1; + return [ + Pickit.Result.WANTED, Pickit.Result.CUBING, + Pickit.Result.RUNEWORD, Pickit.Result.CRAFTING + ].includes(Pickit.checkItem(gem).result); + } + + // do i have any gem worth upgrading + const haveUpGems = me.getItemsEx() + .filter(function (p) { + return isUpgradePossible(p) && pickitWantsUpgrade(p); + }) + .length > 0; + + if (!haveUpGems) { + console.debug("I dont have any gems worth upgrading"); + return false; + } + // we have gems that must not be upgraded in inventory + const isInventoryClean = me.getItemsEx() + .filter(function (p) { + return p.isInInventory && isUpgradePossible(p) && !pickitWantsUpgrade(p); + }) + .length === 0; + + // we have gems that can be upgraded in inventory + const isInventoryValid = me.getItemsEx() + .filter(function (p) { + return p.isInInventory && isUpgradePossible(p) && pickitWantsUpgrade(p); + }) + .length > 0; + + // we already got good gems in inv and no bad games -> take shrine + if (isInventoryClean && isInventoryValid) { + console.debug("Inventory looks good. lets take the shrine."); + return true; + } + // go to town + const preArea = me.area; + const preAct = me.act; + if (!me.inTown) { + // not an essential function -> handle thrown errors + try { + Town.goToTown(); + } catch (e) { + return false; + } + } + + // stash the bad gems first + !isInventoryClean && Town.stash(); + + // get any good gem. flawless first (by lvlreq) + let goodGems = me.getItemsEx() + .filter(function (p) { + return isUpgradePossible(p) && pickitWantsUpgrade(p); + }) + .sort (function(a, b) { + return b.lvlreq - a.lvlreq; + }); + if (goodGems.length) { + console.debug("get Gem: " + goodGems[0].fname); + Town.openStash(); + Storage.Inventory.MoveTo(goodGems.first()) && Item.logger("Inventoried", goodGems[0]); + } + + // leave town + me.act !== preAct && Town.goToTown(preAct); + Town.move("portalspot"); + + if (!Pather.usePortal(null, me.name)) { + try { + Pather.usePortal(preArea, me.name); + } catch (e) { + throw new Error("Town.visitTown: Failed to go back from town"); + } + } + + Config.PublicMode && Pather.makePortal(); + return (goodGems.length); } }; diff --git a/d2bs/kolbot/libs/scripts/GemHunter.js b/d2bs/kolbot/libs/scripts/GemHunter.js index 7bdaf09b..850b415a 100644 --- a/d2bs/kolbot/libs/scripts/GemHunter.js +++ b/d2bs/kolbot/libs/scripts/GemHunter.js @@ -15,25 +15,21 @@ const GemHunter = new Runnable( function GemHunter () { Town.doChores(); - Town.getGem(); - if (Town.getGemsInInv().length === 0) { + if (!Town.prepareForGemShrine()) { console.log("ÿc4GemHunterÿc0: no gems in inventory - aborting."); return false; } for (let area of Config.GemHunter.AreaList) { - if (Town.getGemsInInv().length > 0) { - console.log("ÿc4GemHunterÿc0: Moving to " + getAreaName(area)); - Pather.journeyTo(area); - if (i % 2 === 0) Precast.doPrecast(true); - if (Misc.getShrinesInArea(area, sdk.shrines.Gem, true)) { - Pickit.pickItems(); - console.log("ÿc4GemHunterÿc0: found a gem Shrine"); - if ((Town.getGemsInInv().length === 0) && (Town.getGemsInStash().length > 0)) { - console.log("ÿc4GemHunterÿc0: Getting a new Gem in Town."); - Town.visitTown(); // Go to Town and do chores. Will throw an error if it fails to return from Town. - Town.getGem(); - } + console.log("ÿc4GemHunterÿc0: Moving to " + getAreaName(area)); + Pather.journeyTo(area); + Precast.doPrecast(false); + if (Misc.getShrinesInArea(area, sdk.shrines.Gem, true)) { + Pickit.pickItems(); + console.log("ÿc4GemHunterÿc0: found a gem Shrine"); + if (!Town.prepareForGemShrine()) { + console.log("ÿc4GemHunterÿc0: more gems in inventory - aborting."); + return false; } } } diff --git a/d2bs/kolbot/sdk/types/Town.d.ts b/d2bs/kolbot/sdk/types/Town.d.ts index 3bb0508e..62dd9243 100644 --- a/d2bs/kolbot/sdk/types/Town.d.ts +++ b/d2bs/kolbot/sdk/types/Town.d.ts @@ -74,6 +74,7 @@ declare global { function moveToSpot(spot?: string, allowTK?: boolean): boolean; function goToTown(act?: 2 | 1 | 4 | 3 | 5, wpmenu?: boolean): boolean; function visitTown(repair?: boolean): boolean; + function prepareForGemShrine(): boolean; } } export {};