From fe9aa4e952bcd3924cd74d63fb13954e38b6085a Mon Sep 17 00:00:00 2001 From: AmVoidGuy Date: Mon, 22 May 2023 18:57:09 -0400 Subject: [PATCH 1/6] Fixed typo in EquipmentDetail.ts, Added core functionality for Enhancing --- src/MooLite/core/Game.ts | 6 + src/MooLite/core/enhancing/Enhancing.ts | 138 ++++++++++++++++++ src/MooLite/core/equipment/EquipmentDetail.ts | 4 +- .../core/server/messages/InitClientInfo.ts | 4 +- src/main.ts | 2 + 5 files changed, 150 insertions(+), 4 deletions(-) create mode 100644 src/MooLite/core/enhancing/Enhancing.ts diff --git a/src/MooLite/core/Game.ts b/src/MooLite/core/Game.ts index aee20d7..d4e8c01 100644 --- a/src/MooLite/core/Game.ts +++ b/src/MooLite/core/Game.ts @@ -9,6 +9,7 @@ import { Combat } from "src/MooLite/core/combat/Combat"; import { Leaderboard } from "src/MooLite/core/leaderboard/Leaderboard"; import { Equipment } from "src/MooLite/core/equipment/Equipment"; import { LootBoxes } from "src/MooLite/core/lootboxes/LootBoxes"; +import { Enhancing } from "src/MooLite/core/enhancing/Enhancing"; export class Game { gameVersion: string; @@ -23,6 +24,7 @@ export class Game { chat: Chat; actionQueue: ActionQueue; inventory: Inventory; + enhancing: Enhancing; notifier: Notifier; @@ -58,6 +60,10 @@ export class Game { clientInfo.itemCategoryDetailMap, clientInfo.itemLocationDetailMap ); + this.enhancing = new Enhancing( + clientInfo.enhancementLevelSuccessRateTable, + clientInfo.enhancementLevelTotalBonusMultiplierTable + ); this.notifier = new Notifier(); } diff --git a/src/MooLite/core/enhancing/Enhancing.ts b/src/MooLite/core/enhancing/Enhancing.ts new file mode 100644 index 0000000..dfbbe6e --- /dev/null +++ b/src/MooLite/core/enhancing/Enhancing.ts @@ -0,0 +1,138 @@ +import { ItemDetail } from "src/MooLite/core/inventory/items/ItemDetail"; + +export class Enhancing { + public readonly enhancementLevelSuccessRateTable: number[]; + public readonly enhancementLevelTotalBonusMultiplierTable: number[]; + + constructor(enhancementLevelSuccessRateTable: number[], enhancementLevelTotalBonusMultiplierTable: number[]) { + this.enhancementLevelSuccessRateTable = enhancementLevelSuccessRateTable; + this.enhancementLevelTotalBonusMultiplierTable = enhancementLevelTotalBonusMultiplierTable; + } + + getSuccessChanceTable(currentEnhancingLevel: number, currentItemLevel: number, toolBonus: number): number[] { + let successChanceTable: number[] = [0]; + for (let i = 0; i < this.enhancementLevelSuccessRateTable.length; i++) { + let baseChance = this.enhancementLevelSuccessRateTable.at(i); + const levelBuff = 0.0005 * Math.max(currentEnhancingLevel - currentItemLevel, 0); + const levelDebuff = Math.min((currentEnhancingLevel / currentItemLevel + 1) / 2, 1); + if (baseChance != undefined) { + const actualChance = baseChance * (toolBonus + levelBuff + levelDebuff); + successChanceTable.push(actualChance); + } + } + successChanceTable.push(successChanceTable[successChanceTable.length - 1]); + return successChanceTable; + } + + getZScoreTable(successChanceTable: number[]): number[] { + let zScoreTable = []; + for (let i = 0; i < successChanceTable.length - 1; i++) { + const zScore = (1 - successChanceTable[i + 1]) * this.multiply(successChanceTable.slice(1, i + 1)); + zScoreTable.push(zScore); + } + return zScoreTable; + } + + getSTable(successChanceTable: number[]): number[] { + let sTable = [1 - successChanceTable[1]]; + for (let i = 1; i < successChanceTable.length - 1; i++) { + const sValue = this.multiply(successChanceTable.slice(1, i + 1)); + sTable.push(sValue); + } + return sTable; + } + + getCostTable(zScoreTable: number[], sTable: number[], materialCost: number): number[] { + let costs = [0]; + let multArray = []; + let sumTable = []; + for (let i = 0; i < zScoreTable.length; i++) { + multArray[i] = zScoreTable[i] * (i + 1); + sumTable.push(multArray.slice(0, i + 1).reduce((a, b) => a + b, 0)); + } + for (let i = 1; i < sTable.length; i++) { + const cost = ((sumTable[i - 1] + sTable[i] * i) / sTable[i]) * materialCost; + costs.push(cost); + } + return costs; + } + + getActionsRequiredTable( + costTable: number[], + successChanceTable: number[], + protectLevel: number, + enhancementCost: number + ): number[] { + let actions = [0]; + for (let i = 1; i < successChanceTable.length; i++) { + let currentActionAmount = 0; + if (protectLevel >= i) { + currentActionAmount = costTable[i] / enhancementCost; + } else { + currentActionAmount = + (actions[i - 1] + 1 - (1 - successChanceTable[i]) * actions[i - 2]) / successChanceTable[i]; + } + actions.push(currentActionAmount); + } + return actions; + } + + getProtectsRequiredTable( + costTable: number[], + actionAmountTable: number[], + protectCost: number, + enhanceCost: number + ): number[] { + let protects = []; + for (let i = 0; i < costTable.length; i++) { + protects.push((costTable[i] - actionAmountTable[i] * enhanceCost) / protectCost); + } + return protects; + } + + getCostWithProtects( + costTable: number[], + successChanceTable: number[], + protectCost: number, + materialCost: number + ): number[] { + let costsWithProtects = [costTable[0], costTable[1]]; + for (let i = 2; i < successChanceTable.length; i++) { + const cost = Math.min( + costTable[i], + (costsWithProtects[i - 1] + + (protectCost * (1 - successChanceTable[i]) + materialCost) - + (1 - successChanceTable[i]) * costsWithProtects[i - 2]) / + successChanceTable[i] + ); + costsWithProtects.push(cost); + } + return costsWithProtects; + } + + recommendedProtectLevel(costTable: number[], costWithProtectTable: number[]): number { + for (let i = 2; i < costTable.length; i++) { + if (costTable[i] > costWithProtectTable[i]) { + return i - 1; + } + } + return 20; + } + + private multiply(numbers: number[]): number { + let result = 1; + for (let num in numbers) { + result = result * numbers[num]; + } + return result; + } + + getEnhancingToolBonus(enhancementLevel: number, itemDetails: ItemDetail): number { + const enhancementLevelMulti = this.enhancementLevelTotalBonusMultiplierTable; + const baseBonus = itemDetails.equipmentDetail.noncombatStats.enhancingSuccess; + const enhancementBonus = + itemDetails.equipmentDetail.noncombatEnhancementBonuses.enhancingSuccess * + enhancementLevelMulti[enhancementLevel]; + return baseBonus + enhancementBonus; + } +} diff --git a/src/MooLite/core/equipment/EquipmentDetail.ts b/src/MooLite/core/equipment/EquipmentDetail.ts index d3de2ca..df38c69 100644 --- a/src/MooLite/core/equipment/EquipmentDetail.ts +++ b/src/MooLite/core/equipment/EquipmentDetail.ts @@ -7,7 +7,7 @@ export interface EquipmentDetail { combatEnhancementBonuses: CombatStats; combatStats: CombatStats; levelRequirements: LevelRequirement[] | null; - nonCombatEnhancementBonuses: NonCombatStats; - nonCombatStats: NonCombatStats; + noncombatEnhancementBonuses: NonCombatStats; + noncombatStats: NonCombatStats; type: EquipmentTypeHrid; } diff --git a/src/MooLite/core/server/messages/InitClientInfo.ts b/src/MooLite/core/server/messages/InitClientInfo.ts index 9f08218..2ff957d 100644 --- a/src/MooLite/core/server/messages/InitClientInfo.ts +++ b/src/MooLite/core/server/messages/InitClientInfo.ts @@ -51,8 +51,8 @@ export interface InitClientInfoMessage extends ServerMessage { // cowbellBundleDetailMap: Record; // currentTimestamp: string; // damageTypeDetailMap: Record; - // enhancementLevelSuccessRateTable: number; - // enhancementLevelTotalBonusMultiplierTable: number; + enhancementLevelSuccessRateTable: number[]; + enhancementLevelTotalBonusMultiplierTable: number[]; equipmentTypeDetailMap: Record; gameVersion: string; itemCategoryDetailMap: Record; diff --git a/src/main.ts b/src/main.ts index 10203f9..b5142c8 100644 --- a/src/main.ts +++ b/src/main.ts @@ -17,6 +17,7 @@ import { LeaderboardPlugin } from "src/MooLite/plugins/Leaderboard/LeaderboardPl import { LootNotifierPlugin } from "src/MooLite/plugins/LootNotifier/LootNotifierPlugin"; import { ConsumableNotifierPlugin } from "./MooLite/plugins/ConsumableNotifier/ConsumableNotifierPlugin"; import { EquipmentExporterPlugin } from "src/MooLite/plugins/EquipmentExporter/EquipmentExporterPlugin"; +import { EnhancerHelperPlugin } from "src/MooLite/plugins/EnhancerHelper/EnhancerHelperPlugin"; declare global { interface Window { @@ -57,6 +58,7 @@ const launchMooLite = () => { new LeaderboardPlugin(), new ConsumableNotifierPlugin(), new EquipmentExporterPlugin(), + new EnhancerHelperPlugin(), ]) as unknown as MooLitePlugin[]; const pluginManager = reactive(new PluginManager(game, plugins)) as PluginManager; From 203726b1536ceead7b92d21d41f370f0781189c2 Mon Sep 17 00:00:00 2001 From: AmVoidGuy Date: Mon, 22 May 2023 18:58:04 -0400 Subject: [PATCH 2/6] Enhancement Plugin Display and logic --- .../EnhancerHelper/EnhancerHelperPlugin.ts | 167 ++++++++++++++ .../EnhancerHelperPluginDisplay.vue | 214 ++++++++++++++++++ 2 files changed, 381 insertions(+) create mode 100644 src/MooLite/plugins/EnhancerHelper/EnhancerHelperPlugin.ts create mode 100644 src/MooLite/plugins/EnhancerHelper/EnhancerHelperPluginDisplay.vue diff --git a/src/MooLite/plugins/EnhancerHelper/EnhancerHelperPlugin.ts b/src/MooLite/plugins/EnhancerHelper/EnhancerHelperPlugin.ts new file mode 100644 index 0000000..388912f --- /dev/null +++ b/src/MooLite/plugins/EnhancerHelper/EnhancerHelperPlugin.ts @@ -0,0 +1,167 @@ +import { MooLitePlugin } from "src/MooLite/core/plugins/MooLitePlugin"; +import { MooLiteTab } from "src/MooLite/core/plugins/MooLiteTab"; +import { markRaw } from "vue"; +import EnhancerHelperPluginDisplay from "src/MooLite/plugins/EnhancerHelper/EnhancerHelperPluginDisplay.vue"; +import { ItemDetail } from "src/MooLite/core/inventory/items/ItemDetail"; +import { ItemAmount } from "src/MooLite/core/inventory/items/ItemAmount"; +import { ItemHrid } from "src/MooLite/core/inventory/ItemHrid"; +import { CharacterItem } from "src/MooLite/core/inventory/CharacterItem"; + +export class EnhancerHelperPlugin extends MooLitePlugin { + name: string = "Enhancer Helper"; + key = "enhancer-helper"; + description: string = "Various enhancing tools - By Void"; + + tab: MooLiteTab = { + icon: "💎", + pluginName: this.name, + componentName: "EnhancerHelperPluginDisplay", + component: markRaw(EnhancerHelperPluginDisplay), + }; + + getEnhanceableItems(): ItemDetail[] { + return this._game.inventory.sortedAlphabeticalItems.filter((item) => item.enhancementCosts != null); + } + + getEnhancementMaterials(itemHrid: ItemHrid): ItemAmount[] | undefined | null { + return this._game.inventory.sortedAlphabeticalItems.find((item) => item.hrid === itemHrid)?.enhancementCosts; + } + + getItemName(itemHrid: ItemHrid): String | null { + return this._game.inventory.itemDetailMap[itemHrid].name; + } + + getEnhancingLevel(): number { + return this._game.skills.getLevel("/skills/enhancing"); + } + + getEnhancementSuccessTable(enhancingLevel: number, itemLevel: number, toolBonus: number): number[] { + let enhancementLevelBonus = 0; + const enhancingTea = document.getElementById("enhancingTea"); + const superEnhancingTea = document.getElementById("superEnhancingTea"); + if (superEnhancingTea.checked) { + enhancementLevelBonus = 6; + } else if (enhancingTea.checked) { + enhancementLevelBonus = 3; + } + return this._game.enhancing.getSuccessChanceTable(enhancingLevel + enhancementLevelBonus, itemLevel, toolBonus); + } + + getEnhancementSTable(successTable: number[]): number[] { + return this._game.enhancing.getSTable(successTable); + } + + getEnhancementZTable(successTable: number[]): number[] { + return this._game.enhancing.getZScoreTable(successTable); + } + + getEnhancementCostTable(zTable: number[], sTable: number[], materialCost: number): number[] { + return this._game.enhancing.getCostTable(zTable, sTable, materialCost); + } + + getEnhancementCostTableWithProtects( + costTable: number[], + successTable: number[], + protectCost: number, + materialCost: number + ): number[] { + return this._game.enhancing.getCostWithProtects(costTable, successTable, protectCost, materialCost); + } + + getEnhancementActionsRequiredTable( + costTable: number[], + successTable: number[], + protectLevel: number, + materialCost: number + ): number[] { + return this._game.enhancing.getActionsRequiredTable(costTable, successTable, protectLevel, materialCost); + } + + getEnhancementProtectionsRequiredTable( + costTable: number[], + actionsTable: number[], + protectCost: number, + enhancementCost: number + ): number[] { + return this._game.enhancing.getProtectsRequiredTable(costTable, actionsTable, protectCost, enhancementCost); + } + + getTotalMaterialCost(table: HTMLTableElement | null): number { + let totalCost = 0; + if (table) { + for (let i = 1; i < table.rows.length; i++) { + const amount = Number(table.rows[i].cells[1].innerHTML); + const value = Object(table.rows[i].cells[2].firstChild).value; + totalCost += amount * value; + } + } + return totalCost; + } + + getItemLevel(itemHrid: ItemHrid): number { + return this._game.inventory.itemDetailMap[itemHrid].itemLevel; + } + + getProtectLevel(costTable: number[], protectTable: number[]): number { + return this._game.enhancing.recommendedProtectLevel(costTable, protectTable); + } + + getEnhancingTool(): CharacterItem | null { + const allItems = this._game.inventory._characterItems; + let index = allItems.findIndex( + (item: CharacterItem) => item.itemLocationHrid.toString() === "/item_locations/enhancing_tool" + ); + if (index != -1) { + return allItems[index]; + } + return null; + } + + getEnhancingToolBonus(item: CharacterItem | null): number { + if (item == null) { + return 0; + } else { + const enhancementLevel = item.enhancementLevel; + const itemDetails = this._game.inventory.itemDetailMap[item.itemHrid]; + return this._game.enhancing.getEnhancingToolBonus(enhancementLevel, itemDetails); + } + } + + getProtectionAmount( + protectionAmountTable: number[], + targetItemLevel: number, + currentEnhancementLevel: number + ): number { + const useProtection = document.getElementById("useProtect"); + if (useProtection.checked) { + return protectionAmountTable[targetItemLevel] - protectionAmountTable[currentEnhancementLevel]; + } + return 0; + } + + getActionAmount( + actionAmountTable: number[], + enhancementCostTable: number[], + targetItemLevel: number, + currentEnhancementLevel: number, + totalMaterialCost: number + ): number { + const useProtection = document.getElementById("useProtect"); + if (useProtection.checked) { + return actionAmountTable[targetItemLevel] - actionAmountTable[currentEnhancementLevel]; + } + return ( + (enhancementCostTable[targetItemLevel] - enhancementCostTable[currentEnhancementLevel]) / totalMaterialCost + ); + } + + getExperience(): number { + const wisdomTea = document.getElementById("wisdomTea"); + //TODO Big maths for experience + let experience = 0; + if (wisdomTea.checked) { + experience *= 1.15; + } + return experience; + } +} diff --git a/src/MooLite/plugins/EnhancerHelper/EnhancerHelperPluginDisplay.vue b/src/MooLite/plugins/EnhancerHelper/EnhancerHelperPluginDisplay.vue new file mode 100644 index 0000000..afcf5f4 --- /dev/null +++ b/src/MooLite/plugins/EnhancerHelper/EnhancerHelperPluginDisplay.vue @@ -0,0 +1,214 @@ + + + From 1d4aecacb8baf54f526760cbe62de3a17cf6a9e8 Mon Sep 17 00:00:00 2001 From: AmVoidGuy Date: Sat, 27 May 2023 17:26:50 -0400 Subject: [PATCH 3/6] Blessed Tea and Wisdom Tea buffs. Experience and Action time logic. Added some more requested fields --- src/MooLite/core/enhancing/Enhancing.ts | 13 +++++ .../EnhancerHelper/EnhancerHelperPlugin.ts | 58 +++++++++++++++++-- .../EnhancerHelperPluginDisplay.vue | 39 ++++++++++--- 3 files changed, 96 insertions(+), 14 deletions(-) diff --git a/src/MooLite/core/enhancing/Enhancing.ts b/src/MooLite/core/enhancing/Enhancing.ts index dfbbe6e..faa89a6 100644 --- a/src/MooLite/core/enhancing/Enhancing.ts +++ b/src/MooLite/core/enhancing/Enhancing.ts @@ -90,6 +90,19 @@ export class Enhancing { return protects; } + getBlessedTeaTable(successTable: number[], blessedTeaBoost: number): number[] { + let blessedTeaTable = [1, 1]; + for (let i = 2; i < successTable.length; i++) { + blessedTeaTable.push( + ((1 - blessedTeaBoost) ** 2 + + blessedTeaBoost * (1 - blessedTeaBoost) * (1 - successTable[i]) + + blessedTeaBoost / successTable[i - 1]) * + blessedTeaTable[i - 1] + ); + } + return blessedTeaTable; + } + getCostWithProtects( costTable: number[], successChanceTable: number[], diff --git a/src/MooLite/plugins/EnhancerHelper/EnhancerHelperPlugin.ts b/src/MooLite/plugins/EnhancerHelper/EnhancerHelperPlugin.ts index 388912f..bc96649 100644 --- a/src/MooLite/plugins/EnhancerHelper/EnhancerHelperPlugin.ts +++ b/src/MooLite/plugins/EnhancerHelper/EnhancerHelperPlugin.ts @@ -86,6 +86,10 @@ export class EnhancerHelperPlugin extends MooLitePlugin { return this._game.enhancing.getProtectsRequiredTable(costTable, actionsTable, protectCost, enhancementCost); } + getBlessedTeaTable(successTable: number[]): number[] { + return this._game.enhancing.getBlessedTeaTable(successTable, 0.01); + } + getTotalMaterialCost(table: HTMLTableElement | null): number { let totalCost = 0; if (table) { @@ -142,26 +146,68 @@ export class EnhancerHelperPlugin extends MooLitePlugin { getActionAmount( actionAmountTable: number[], enhancementCostTable: number[], + blessedTeaTable: number[], targetItemLevel: number, currentEnhancementLevel: number, totalMaterialCost: number ): number { const useProtection = document.getElementById("useProtect"); + const useBlessedTea = document.getElementById("blessedTea"); + let actionAmount = 0; if (useProtection.checked) { - return actionAmountTable[targetItemLevel] - actionAmountTable[currentEnhancementLevel]; + actionAmount = actionAmountTable[targetItemLevel] - actionAmountTable[currentEnhancementLevel]; + } else { + actionAmount = + (enhancementCostTable[targetItemLevel] - enhancementCostTable[currentEnhancementLevel]) / + totalMaterialCost; } - return ( - (enhancementCostTable[targetItemLevel] - enhancementCostTable[currentEnhancementLevel]) / totalMaterialCost - ); + if (useBlessedTea.checked) { + return actionAmount / blessedTeaTable[targetItemLevel]; + } + return actionAmount; } - getExperience(): number { + getExperience( + sTable: number[], + actionAmount: number, + itemLevel: number, + currentLevel: number, + targetLevel: number + ): number { const wisdomTea = document.getElementById("wisdomTea"); - //TODO Big maths for experience let experience = 0; + const baseExpRate = 1.4 * itemLevel + 14; + let remainingActionAmount = actionAmount; + for (let i = currentLevel + 1; i < targetLevel; i++) { + experience += + baseExpRate * i * actionAmount * sTable[i] + + baseExpRate * i * (remainingActionAmount - actionAmount * sTable[i]) * (1 - sTable[i]) * 0.1; + remainingActionAmount = actionAmount * sTable[i]; + } + experience += baseExpRate * targetLevel; + if (remainingActionAmount - 1 > 0) { + experience += baseExpRate * targetLevel * (remainingActionAmount - 1) * 0.1; + } if (wisdomTea.checked) { experience *= 1.15; } return experience; } + + getTimeTaken(actionAmount: number, enhancingLevel: number, itemLevel: number): number { + let actionSpeedBonus = 1; + if (enhancingLevel - itemLevel >= 0) { + actionSpeedBonus = 1 + (enhancingLevel - itemLevel) / 100; + } + const baseTime = 12; + return (baseTime / actionSpeedBonus) * actionAmount; + } + + getTimeTakenString(totalSeconds: number): String { + const totalMinutes = Math.floor(totalSeconds / 60); + const seconds = Math.floor(totalSeconds % 60); + const hours = Math.floor(totalMinutes / 60); + const minutes = Math.floor(totalMinutes % 60); + return hours + "h " + minutes + "m " + seconds + "s"; + } } diff --git a/src/MooLite/plugins/EnhancerHelper/EnhancerHelperPluginDisplay.vue b/src/MooLite/plugins/EnhancerHelper/EnhancerHelperPluginDisplay.vue index afcf5f4..394c097 100644 --- a/src/MooLite/plugins/EnhancerHelper/EnhancerHelperPluginDisplay.vue +++ b/src/MooLite/plugins/EnhancerHelper/EnhancerHelperPluginDisplay.vue @@ -32,15 +32,16 @@ const currentToolBonus = ref(props.plugin.getEnhancingToolBonus(props.plugin.get const currentEnhancementLevel = ref(0); const targetItemLevel = ref(1); const protectCost = ref(1); +const baseItemCost = ref(1); const selectedHrid = ref(options.value[0].value); const protectLevel = ref(); const actionAmount = ref(); const protectionAmount = ref(); const estimatedTotalCost = ref(); const estimatedTotalExperience = ref(); +const timeTaken = ref(); const simulate = () => { - //TODO BlessedTea Approximation and Experience Calculations let enhancementLevelBonus = 0; let totalMaterialCost = props.plugin.getTotalMaterialCost( document.getElementById("materialTable") @@ -73,6 +74,7 @@ const simulate = () => { protectCost.value, totalMaterialCost ); + let blessedTeaTable = props.plugin.getBlessedTeaTable(successTable); protectionAmount.value = props.plugin.getProtectionAmount( protectionAmountTable, targetItemLevel.value, @@ -81,12 +83,21 @@ const simulate = () => { actionAmount.value = props.plugin.getActionAmount( actionAmountTable, enhancementCostTable, + blessedTeaTable, targetItemLevel.value, currentEnhancementLevel.value, totalMaterialCost ); - estimatedTotalCost.value = totalMaterialCost * actionAmount.value + protectCost.value * protectionAmount.value; - estimatedTotalExperience.value = props.plugin.getExperience(); + timeTaken.value = props.plugin.getTimeTaken(actionAmount.value, currentEnhancingLevel.value, itemLevel); + estimatedTotalCost.value = + totalMaterialCost * actionAmount.value + protectCost.value * protectionAmount.value + baseItemCost.value; + estimatedTotalExperience.value = props.plugin.getExperience( + sTable, + actionAmount.value, + itemLevel, + currentEnhancementLevel.value, + targetItemLevel.value + ); }; @@ -149,6 +160,15 @@ const simulate = () => {
+ Base Item Cost: + + Protect Item Cost: { > @@ -205,10 +225,13 @@ const simulate = () => {
- Average Actions: {{ Math.round(actionAmount).toLocaleString() }} - Total Cost: {{ Math.round(estimatedTotalCost).toLocaleString() }} Best Protection Level: {{ protectLevel }} - + Total Cost: {{ Math.round(estimatedTotalCost).toLocaleString() }} + Average Actions: {{ Math.round(actionAmount).toLocaleString() }} + Time Taken: {{ props.plugin.getTimeTakenString(timeTaken) }} + Experience: {{ Math.round(estimatedTotalExperience).toLocaleString() }} + Xp/Hr: {{ Math.round((estimatedTotalExperience * 3600) / timeTaken).toLocaleString() }} + Gp/Xp: {{ Math.round((estimatedTotalCost / estimatedTotalExperience) * 100) / 100 }} From c0dc05c163073b3c65270392af4be4fc10104ae5 Mon Sep 17 00:00:00 2001 From: AmVoidGuy Date: Sun, 28 May 2023 21:58:22 -0400 Subject: [PATCH 4/6] Removed querying for html elements, methods now pass in vue input bindings. Added Buffs.ts so that the ConsumableDetail can now grab item buffs from the init client info. Moved some methods to Util helper classes --- src/MooLite/core/enhancing/Enhancing.ts | 16 +--- src/MooLite/core/inventory/Inventory.ts | 11 +++ src/MooLite/core/inventory/items/Buffs.ts | 13 +++ .../core/inventory/items/ConsumableDetail.ts | 4 +- src/MooLite/core/skills/Skills.ts | 4 + .../EnhancerHelper/EnhancerHelperPlugin.ts | 87 ++++++++++--------- .../EnhancerHelperPluginDisplay.vue | 45 +++++++--- src/MooLite/util/DateFormatter.ts | 8 ++ src/MooLite/util/Math.ts | 16 ++++ 9 files changed, 135 insertions(+), 69 deletions(-) create mode 100644 src/MooLite/core/inventory/items/Buffs.ts create mode 100644 src/MooLite/util/Math.ts diff --git a/src/MooLite/core/enhancing/Enhancing.ts b/src/MooLite/core/enhancing/Enhancing.ts index faa89a6..44c399d 100644 --- a/src/MooLite/core/enhancing/Enhancing.ts +++ b/src/MooLite/core/enhancing/Enhancing.ts @@ -1,4 +1,5 @@ import { ItemDetail } from "src/MooLite/core/inventory/items/ItemDetail"; +import { Math as MathUtil } from "src/MooLite/util/Math"; export class Enhancing { public readonly enhancementLevelSuccessRateTable: number[]; @@ -27,7 +28,7 @@ export class Enhancing { getZScoreTable(successChanceTable: number[]): number[] { let zScoreTable = []; for (let i = 0; i < successChanceTable.length - 1; i++) { - const zScore = (1 - successChanceTable[i + 1]) * this.multiply(successChanceTable.slice(1, i + 1)); + const zScore = (1 - successChanceTable[i + 1]) * MathUtil.multiplyArray(successChanceTable.slice(1, i + 1)); zScoreTable.push(zScore); } return zScoreTable; @@ -36,7 +37,7 @@ export class Enhancing { getSTable(successChanceTable: number[]): number[] { let sTable = [1 - successChanceTable[1]]; for (let i = 1; i < successChanceTable.length - 1; i++) { - const sValue = this.multiply(successChanceTable.slice(1, i + 1)); + const sValue = MathUtil.multiplyArray(successChanceTable.slice(1, i + 1)); sTable.push(sValue); } return sTable; @@ -45,11 +46,10 @@ export class Enhancing { getCostTable(zScoreTable: number[], sTable: number[], materialCost: number): number[] { let costs = [0]; let multArray = []; - let sumTable = []; for (let i = 0; i < zScoreTable.length; i++) { multArray[i] = zScoreTable[i] * (i + 1); - sumTable.push(multArray.slice(0, i + 1).reduce((a, b) => a + b, 0)); } + let sumTable = MathUtil.sumArray(multArray); for (let i = 1; i < sTable.length; i++) { const cost = ((sumTable[i - 1] + sTable[i] * i) / sTable[i]) * materialCost; costs.push(cost); @@ -132,14 +132,6 @@ export class Enhancing { return 20; } - private multiply(numbers: number[]): number { - let result = 1; - for (let num in numbers) { - result = result * numbers[num]; - } - return result; - } - getEnhancingToolBonus(enhancementLevel: number, itemDetails: ItemDetail): number { const enhancementLevelMulti = this.enhancementLevelTotalBonusMultiplierTable; const baseBonus = itemDetails.equipmentDetail.noncombatStats.enhancingSuccess; diff --git a/src/MooLite/core/inventory/Inventory.ts b/src/MooLite/core/inventory/Inventory.ts index 4488d3c..d1521dd 100644 --- a/src/MooLite/core/inventory/Inventory.ts +++ b/src/MooLite/core/inventory/Inventory.ts @@ -160,4 +160,15 @@ export class Inventory { public getEquippedDrinks(): Record { return this._characterDrinks; } + + public getEnhancingTool(): CharacterItem | null { + const allItems = this._characterItems; + let index = allItems.findIndex( + (item: CharacterItem) => item.itemLocationHrid.toString() === "/item_locations/enhancing_tool" + ); + if (index != -1) { + return allItems[index]; + } + return null; + } } diff --git a/src/MooLite/core/inventory/items/Buffs.ts b/src/MooLite/core/inventory/items/Buffs.ts new file mode 100644 index 0000000..789e83f --- /dev/null +++ b/src/MooLite/core/inventory/items/Buffs.ts @@ -0,0 +1,13 @@ +import { BuffTypeHrid } from "src/MooLite/core/combat/buffs/BuffTypeHrid"; +import { BuffUniqueHrid } from "src/MooLite/core/combat/buffs/BuffUniqueHrid"; + +export interface Buffs { + duration: number; + flatBoost: number; + flatBoostLevelBonus: number; + ratioBoost: number; + ratioBoostLevelBonus: number; + startTime: Date; + typeHrid: BuffTypeHrid; + uniqueHrid: BuffUniqueHrid; +} diff --git a/src/MooLite/core/inventory/items/ConsumableDetail.ts b/src/MooLite/core/inventory/items/ConsumableDetail.ts index f8991a6..a4c661a 100644 --- a/src/MooLite/core/inventory/items/ConsumableDetail.ts +++ b/src/MooLite/core/inventory/items/ConsumableDetail.ts @@ -1,8 +1,8 @@ import { CombatTrigger } from "src/MooLite/core/combat/triggers/CombatTrigger"; +import { Buffs } from "src/MooLite/core/inventory/items/Buffs"; export interface ConsumableDetail { - // TODO(@Isha): Or what? - buffs: null; + buffs: Buffs[]; cooldownDuration: number; defaultCombatTriggers: CombatTrigger[] | null; hitpointsRestore: number; diff --git a/src/MooLite/core/skills/Skills.ts b/src/MooLite/core/skills/Skills.ts index 07407e6..9e76630 100644 --- a/src/MooLite/core/skills/Skills.ts +++ b/src/MooLite/core/skills/Skills.ts @@ -89,4 +89,8 @@ export class Skills { public getLevel(skillHrid: SkillHrid) { return this._characterSkills[skillHrid].level; } + + public getEnhancingLevel() { + return this._characterSkills["/skills/enhancing"].level; + } } diff --git a/src/MooLite/plugins/EnhancerHelper/EnhancerHelperPlugin.ts b/src/MooLite/plugins/EnhancerHelper/EnhancerHelperPlugin.ts index bc96649..4924a6f 100644 --- a/src/MooLite/plugins/EnhancerHelper/EnhancerHelperPlugin.ts +++ b/src/MooLite/plugins/EnhancerHelper/EnhancerHelperPlugin.ts @@ -6,6 +6,7 @@ import { ItemDetail } from "src/MooLite/core/inventory/items/ItemDetail"; import { ItemAmount } from "src/MooLite/core/inventory/items/ItemAmount"; import { ItemHrid } from "src/MooLite/core/inventory/ItemHrid"; import { CharacterItem } from "src/MooLite/core/inventory/CharacterItem"; +import { DateFormatter } from "src/MooLite/util/DateFormatter"; export class EnhancerHelperPlugin extends MooLitePlugin { name: string = "Enhancer Helper"; @@ -13,7 +14,7 @@ export class EnhancerHelperPlugin extends MooLitePlugin { description: string = "Various enhancing tools - By Void"; tab: MooLiteTab = { - icon: "💎", + icon: "📡", pluginName: this.name, componentName: "EnhancerHelperPluginDisplay", component: markRaw(EnhancerHelperPluginDisplay), @@ -32,17 +33,27 @@ export class EnhancerHelperPlugin extends MooLitePlugin { } getEnhancingLevel(): number { - return this._game.skills.getLevel("/skills/enhancing"); + return this._game.skills.getEnhancingLevel(); } - getEnhancementSuccessTable(enhancingLevel: number, itemLevel: number, toolBonus: number): number[] { + getEnhancementSuccessTable( + enhancingLevel: number, + itemLevel: number, + toolBonus: number, + useEnhancingTea: boolean, + useSuperEnhancingTea: boolean + ): number[] { let enhancementLevelBonus = 0; - const enhancingTea = document.getElementById("enhancingTea"); - const superEnhancingTea = document.getElementById("superEnhancingTea"); - if (superEnhancingTea.checked) { - enhancementLevelBonus = 6; - } else if (enhancingTea.checked) { - enhancementLevelBonus = 3; + const enhancingTeaBuff = + this._game.inventory.itemDetailMap[("/items/enhancing_tea")].consumableDetail.buffs[0] + .flatBoost; + const superEnhancingTeaBuff = + this._game.inventory.itemDetailMap[("/items/super_enhancing_tea")].consumableDetail + .buffs[0].flatBoost; + if (useSuperEnhancingTea) { + enhancementLevelBonus = superEnhancingTeaBuff; + } else if (useEnhancingTea) { + enhancementLevelBonus = enhancingTeaBuff; } return this._game.enhancing.getSuccessChanceTable(enhancingLevel + enhancementLevelBonus, itemLevel, toolBonus); } @@ -87,16 +98,17 @@ export class EnhancerHelperPlugin extends MooLitePlugin { } getBlessedTeaTable(successTable: number[]): number[] { - return this._game.enhancing.getBlessedTeaTable(successTable, 0.01); + const blessedTeaBoost = + this._game.inventory.itemDetailMap[("/items/blessed_tea")].consumableDetail.buffs[0] + .flatBoost; + return this._game.enhancing.getBlessedTeaTable(successTable, blessedTeaBoost); } - getTotalMaterialCost(table: HTMLTableElement | null): number { + getTotalMaterialCost(materials: { name: String | null; amount: number; value: number }[] | undefined): number { let totalCost = 0; - if (table) { - for (let i = 1; i < table.rows.length; i++) { - const amount = Number(table.rows[i].cells[1].innerHTML); - const value = Object(table.rows[i].cells[2].firstChild).value; - totalCost += amount * value; + if (materials) { + for (let i = 0; i < materials.length; i++) { + totalCost += materials[i].value * materials[i].amount; } } return totalCost; @@ -111,14 +123,7 @@ export class EnhancerHelperPlugin extends MooLitePlugin { } getEnhancingTool(): CharacterItem | null { - const allItems = this._game.inventory._characterItems; - let index = allItems.findIndex( - (item: CharacterItem) => item.itemLocationHrid.toString() === "/item_locations/enhancing_tool" - ); - if (index != -1) { - return allItems[index]; - } - return null; + return this._game.inventory.getEnhancingTool(); } getEnhancingToolBonus(item: CharacterItem | null): number { @@ -134,10 +139,10 @@ export class EnhancerHelperPlugin extends MooLitePlugin { getProtectionAmount( protectionAmountTable: number[], targetItemLevel: number, - currentEnhancementLevel: number + currentEnhancementLevel: number, + useProtection: boolean ): number { - const useProtection = document.getElementById("useProtect"); - if (useProtection.checked) { + if (useProtection) { return protectionAmountTable[targetItemLevel] - protectionAmountTable[currentEnhancementLevel]; } return 0; @@ -149,19 +154,19 @@ export class EnhancerHelperPlugin extends MooLitePlugin { blessedTeaTable: number[], targetItemLevel: number, currentEnhancementLevel: number, - totalMaterialCost: number + totalMaterialCost: number, + useProtection: boolean, + useBlessedTea: boolean ): number { - const useProtection = document.getElementById("useProtect"); - const useBlessedTea = document.getElementById("blessedTea"); let actionAmount = 0; - if (useProtection.checked) { + if (useProtection) { actionAmount = actionAmountTable[targetItemLevel] - actionAmountTable[currentEnhancementLevel]; } else { actionAmount = (enhancementCostTable[targetItemLevel] - enhancementCostTable[currentEnhancementLevel]) / totalMaterialCost; } - if (useBlessedTea.checked) { + if (useBlessedTea) { return actionAmount / blessedTeaTable[targetItemLevel]; } return actionAmount; @@ -172,9 +177,13 @@ export class EnhancerHelperPlugin extends MooLitePlugin { actionAmount: number, itemLevel: number, currentLevel: number, - targetLevel: number + targetLevel: number, + useWisdomTea: boolean ): number { - const wisdomTea = document.getElementById("wisdomTea"); + const wisdomTeaBuff = + 1 + + this._game.inventory.itemDetailMap[("/items/wisdom_tea")].consumableDetail.buffs[0] + .flatBoost; let experience = 0; const baseExpRate = 1.4 * itemLevel + 14; let remainingActionAmount = actionAmount; @@ -188,8 +197,8 @@ export class EnhancerHelperPlugin extends MooLitePlugin { if (remainingActionAmount - 1 > 0) { experience += baseExpRate * targetLevel * (remainingActionAmount - 1) * 0.1; } - if (wisdomTea.checked) { - experience *= 1.15; + if (useWisdomTea) { + experience *= wisdomTeaBuff; } return experience; } @@ -204,10 +213,6 @@ export class EnhancerHelperPlugin extends MooLitePlugin { } getTimeTakenString(totalSeconds: number): String { - const totalMinutes = Math.floor(totalSeconds / 60); - const seconds = Math.floor(totalSeconds % 60); - const hours = Math.floor(totalMinutes / 60); - const minutes = Math.floor(totalMinutes % 60); - return hours + "h " + minutes + "m " + seconds + "s"; + return DateFormatter.secondsToHHMMSS(totalSeconds); } } diff --git a/src/MooLite/plugins/EnhancerHelper/EnhancerHelperPluginDisplay.vue b/src/MooLite/plugins/EnhancerHelper/EnhancerHelperPluginDisplay.vue index 394c097..0fef8fc 100644 --- a/src/MooLite/plugins/EnhancerHelper/EnhancerHelperPluginDisplay.vue +++ b/src/MooLite/plugins/EnhancerHelper/EnhancerHelperPluginDisplay.vue @@ -23,6 +23,7 @@ const materials = computed(() => { return { name: props.plugin.getItemName(item.itemHrid), amount: item.count, + value: 1, }; }); }); @@ -40,17 +41,22 @@ const protectionAmount = ref(); const estimatedTotalCost = ref(); const estimatedTotalExperience = ref(); const timeTaken = ref(); +const enhancingTea = ref(); +const superEnhancingTea = ref(); +const blessedTea = ref(); +const wisdomTea = ref(); +const useProtect = ref(); const simulate = () => { let enhancementLevelBonus = 0; - let totalMaterialCost = props.plugin.getTotalMaterialCost( - document.getElementById("materialTable") - ); + let totalMaterialCost = props.plugin.getTotalMaterialCost(materials.value); let itemLevel = props.plugin.getItemLevel(selectedHrid.value); let successTable = props.plugin.getEnhancementSuccessTable( currentEnhancingLevel.value + enhancementLevelBonus, itemLevel, - currentToolBonus.value + currentToolBonus.value, + enhancingTea.value, + superEnhancingTea.value ); let sTable = props.plugin.getEnhancementSTable(successTable); let zTable = props.plugin.getEnhancementZTable(successTable); @@ -78,7 +84,8 @@ const simulate = () => { protectionAmount.value = props.plugin.getProtectionAmount( protectionAmountTable, targetItemLevel.value, - currentEnhancementLevel.value + currentEnhancementLevel.value, + useProtect.value ); actionAmount.value = props.plugin.getActionAmount( actionAmountTable, @@ -86,7 +93,9 @@ const simulate = () => { blessedTeaTable, targetItemLevel.value, currentEnhancementLevel.value, - totalMaterialCost + totalMaterialCost, + useProtect.value, + blessedTea.value ); timeTaken.value = props.plugin.getTimeTaken(actionAmount.value, currentEnhancingLevel.value, itemLevel); estimatedTotalCost.value = @@ -96,7 +105,8 @@ const simulate = () => { actionAmount.value, itemLevel, currentEnhancementLevel.value, - targetItemLevel.value + targetItemLevel.value, + wisdomTea.value ); }; @@ -156,7 +166,9 @@ const simulate = () => { {{ entry.name }} {{ entry.amount.toLocaleString() }} - + + +
@@ -183,23 +195,28 @@ const simulate = () => { Options:
@@ -231,7 +248,7 @@ const simulate = () => { Time Taken: {{ props.plugin.getTimeTakenString(timeTaken) }} Experience: {{ Math.round(estimatedTotalExperience).toLocaleString() }} Xp/Hr: {{ Math.round((estimatedTotalExperience * 3600) / timeTaken).toLocaleString() }} - Gp/Xp: {{ Math.round((estimatedTotalCost / estimatedTotalExperience) * 100) / 100 }} + Gp/Xp: {{ Math.round(((estimatedTotalCost - baseItemCost) / estimatedTotalExperience) * 100) / 100 }} diff --git a/src/MooLite/util/DateFormatter.ts b/src/MooLite/util/DateFormatter.ts index c3447a2..5f3130c 100644 --- a/src/MooLite/util/DateFormatter.ts +++ b/src/MooLite/util/DateFormatter.ts @@ -2,4 +2,12 @@ export class DateFormatter { public static toHHMM(date: Date): string { return `${date.getHours().toString().padStart(2, "0")}:${date.getMinutes().toString().padStart(2, "0")}`; } + + public static secondsToHHMMSS(totalSeconds: number): String { + const totalMinutes = Math.floor(totalSeconds / 60); + const seconds = Math.floor(totalSeconds % 60); + const hours = Math.floor(totalMinutes / 60); + const minutes = Math.floor(totalMinutes % 60); + return hours + "h " + minutes + "m " + seconds + "s"; + } } diff --git a/src/MooLite/util/Math.ts b/src/MooLite/util/Math.ts new file mode 100644 index 0000000..406bdce --- /dev/null +++ b/src/MooLite/util/Math.ts @@ -0,0 +1,16 @@ +export class Math { + public static multiplyArray(numbers: number[]): number { + let result = 1; + for (let num in numbers) { + result = result * numbers[num]; + } + return result; + } + public static sumArray(numbers: number[]): number[] { + let sumTable = []; + for (let i = 0; i < numbers.length; i++) { + sumTable.push(numbers.slice(0, i + 1).reduce((a, b) => a + b, 0)); + } + return sumTable; + } +} From 8120f842233d1c424623c18050a3e82948582506 Mon Sep 17 00:00:00 2001 From: AmVoidGuy Date: Sun, 28 May 2023 22:04:56 -0400 Subject: [PATCH 5/6] Ran prettier because git was angry --- .../plugins/EnhancerHelper/EnhancerHelperPluginDisplay.vue | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/MooLite/plugins/EnhancerHelper/EnhancerHelperPluginDisplay.vue b/src/MooLite/plugins/EnhancerHelper/EnhancerHelperPluginDisplay.vue index 0fef8fc..1cda0b2 100644 --- a/src/MooLite/plugins/EnhancerHelper/EnhancerHelperPluginDisplay.vue +++ b/src/MooLite/plugins/EnhancerHelper/EnhancerHelperPluginDisplay.vue @@ -248,7 +248,10 @@ const simulate = () => { Time Taken: {{ props.plugin.getTimeTakenString(timeTaken) }} Experience: {{ Math.round(estimatedTotalExperience).toLocaleString() }} Xp/Hr: {{ Math.round((estimatedTotalExperience * 3600) / timeTaken).toLocaleString() }} - Gp/Xp: {{ Math.round(((estimatedTotalCost - baseItemCost) / estimatedTotalExperience) * 100) / 100 }} + Gp/Xp: + {{ Math.round(((estimatedTotalCost - baseItemCost) / estimatedTotalExperience) * 100) / 100 }} From ba9206208d2ee349c628c09dcdfe05c5e92b294e Mon Sep 17 00:00:00 2001 From: AmVoidGuy Date: Thu, 1 Jun 2023 01:26:15 -0400 Subject: [PATCH 6/6] Moved any server-sided values into a Constants file. Also moved method for efficiency to Skills as it can be used for any skill, not just enhancing. --- src/MooLite/core/enhancing/Enhancing.ts | 4 +++- .../core/enhancing/EnhancingConstants.ts | 7 +++++++ src/MooLite/core/skills/Skills.ts | 7 +++++++ .../EnhancerHelper/EnhancerHelperPlugin.ts | 19 +++++++++++-------- 4 files changed, 28 insertions(+), 9 deletions(-) create mode 100644 src/MooLite/core/enhancing/EnhancingConstants.ts diff --git a/src/MooLite/core/enhancing/Enhancing.ts b/src/MooLite/core/enhancing/Enhancing.ts index 44c399d..ad4a227 100644 --- a/src/MooLite/core/enhancing/Enhancing.ts +++ b/src/MooLite/core/enhancing/Enhancing.ts @@ -1,5 +1,6 @@ import { ItemDetail } from "src/MooLite/core/inventory/items/ItemDetail"; import { Math as MathUtil } from "src/MooLite/util/Math"; +import { EnhancingConstants } from "src/MooLite/core/enhancing/EnhancingConstants"; export class Enhancing { public readonly enhancementLevelSuccessRateTable: number[]; @@ -14,7 +15,8 @@ export class Enhancing { let successChanceTable: number[] = [0]; for (let i = 0; i < this.enhancementLevelSuccessRateTable.length; i++) { let baseChance = this.enhancementLevelSuccessRateTable.at(i); - const levelBuff = 0.0005 * Math.max(currentEnhancingLevel - currentItemLevel, 0); + const levelBuff = + EnhancingConstants.levelBuffMultiplier * Math.max(currentEnhancingLevel - currentItemLevel, 0); const levelDebuff = Math.min((currentEnhancingLevel / currentItemLevel + 1) / 2, 1); if (baseChance != undefined) { const actualChance = baseChance * (toolBonus + levelBuff + levelDebuff); diff --git a/src/MooLite/core/enhancing/EnhancingConstants.ts b/src/MooLite/core/enhancing/EnhancingConstants.ts new file mode 100644 index 0000000..97f0262 --- /dev/null +++ b/src/MooLite/core/enhancing/EnhancingConstants.ts @@ -0,0 +1,7 @@ +export class EnhancingConstants { + static readonly actionSpeed = 12; + static readonly experienceBonus = 14; + static readonly experiencePerLevel = 1.4; + static readonly failureExperienceRate = 0.1; + static readonly levelBuffMultiplier = 0.0005; +} diff --git a/src/MooLite/core/skills/Skills.ts b/src/MooLite/core/skills/Skills.ts index 9e76630..f660e8b 100644 --- a/src/MooLite/core/skills/Skills.ts +++ b/src/MooLite/core/skills/Skills.ts @@ -93,4 +93,11 @@ export class Skills { public getEnhancingLevel() { return this._characterSkills["/skills/enhancing"].level; } + + public getSkillEfficiencyBonusRatio(requiredLevel: number, currentLevel: number): number { + if (requiredLevel >= currentLevel) { + return 0; + } + return (currentLevel - requiredLevel) / 100; + } } diff --git a/src/MooLite/plugins/EnhancerHelper/EnhancerHelperPlugin.ts b/src/MooLite/plugins/EnhancerHelper/EnhancerHelperPlugin.ts index 4924a6f..233f34d 100644 --- a/src/MooLite/plugins/EnhancerHelper/EnhancerHelperPlugin.ts +++ b/src/MooLite/plugins/EnhancerHelper/EnhancerHelperPlugin.ts @@ -7,6 +7,7 @@ import { ItemAmount } from "src/MooLite/core/inventory/items/ItemAmount"; import { ItemHrid } from "src/MooLite/core/inventory/ItemHrid"; import { CharacterItem } from "src/MooLite/core/inventory/CharacterItem"; import { DateFormatter } from "src/MooLite/util/DateFormatter"; +import { EnhancingConstants } from "src/MooLite/core/enhancing/EnhancingConstants"; export class EnhancerHelperPlugin extends MooLitePlugin { name: string = "Enhancer Helper"; @@ -185,17 +186,22 @@ export class EnhancerHelperPlugin extends MooLitePlugin { this._game.inventory.itemDetailMap[("/items/wisdom_tea")].consumableDetail.buffs[0] .flatBoost; let experience = 0; - const baseExpRate = 1.4 * itemLevel + 14; + const baseExpRate = EnhancingConstants.experiencePerLevel * itemLevel + EnhancingConstants.experienceBonus; let remainingActionAmount = actionAmount; for (let i = currentLevel + 1; i < targetLevel; i++) { experience += baseExpRate * i * actionAmount * sTable[i] + - baseExpRate * i * (remainingActionAmount - actionAmount * sTable[i]) * (1 - sTable[i]) * 0.1; + baseExpRate * + i * + (remainingActionAmount - actionAmount * sTable[i]) * + (1 - sTable[i]) * + EnhancingConstants.failureExperienceRate; remainingActionAmount = actionAmount * sTable[i]; } experience += baseExpRate * targetLevel; if (remainingActionAmount - 1 > 0) { - experience += baseExpRate * targetLevel * (remainingActionAmount - 1) * 0.1; + experience += + baseExpRate * targetLevel * (remainingActionAmount - 1) * EnhancingConstants.failureExperienceRate; } if (useWisdomTea) { experience *= wisdomTeaBuff; @@ -204,11 +210,8 @@ export class EnhancerHelperPlugin extends MooLitePlugin { } getTimeTaken(actionAmount: number, enhancingLevel: number, itemLevel: number): number { - let actionSpeedBonus = 1; - if (enhancingLevel - itemLevel >= 0) { - actionSpeedBonus = 1 + (enhancingLevel - itemLevel) / 100; - } - const baseTime = 12; + let actionSpeedBonus = 1 + this._game.skills.getSkillEfficiencyBonusRatio(itemLevel, enhancingLevel); + const baseTime = EnhancingConstants.actionSpeed; return (baseTime / actionSpeedBonus) * actionAmount; }