Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/MooLite/core/Game.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -23,6 +24,7 @@ export class Game {
chat: Chat;
actionQueue: ActionQueue;
inventory: Inventory;
enhancing: Enhancing;

notifier: Notifier;

Expand Down Expand Up @@ -58,6 +60,10 @@ export class Game {
clientInfo.itemCategoryDetailMap,
clientInfo.itemLocationDetailMap
);
this.enhancing = new Enhancing(
clientInfo.enhancementLevelSuccessRateTable,
clientInfo.enhancementLevelTotalBonusMultiplierTable
);

this.notifier = new Notifier();
}
Expand Down
145 changes: 145 additions & 0 deletions src/MooLite/core/enhancing/Enhancing.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
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[];
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 =
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);
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]) * MathUtil.multiplyArray(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 = MathUtil.multiplyArray(successChanceTable.slice(1, i + 1));
sTable.push(sValue);
}
return sTable;
}

getCostTable(zScoreTable: number[], sTable: number[], materialCost: number): number[] {
let costs = [0];
let multArray = [];
for (let i = 0; i < zScoreTable.length; i++) {
multArray[i] = zScoreTable[i] * (i + 1);
}
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);
}
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;
}

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[],
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;
}

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;
}
}
7 changes: 7 additions & 0 deletions src/MooLite/core/enhancing/EnhancingConstants.ts
Original file line number Diff line number Diff line change
@@ -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;
}
4 changes: 2 additions & 2 deletions src/MooLite/core/equipment/EquipmentDetail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export interface EquipmentDetail {
combatEnhancementBonuses: CombatStats;
combatStats: CombatStats;
levelRequirements: LevelRequirement[] | null;
nonCombatEnhancementBonuses: NonCombatStats;
nonCombatStats: NonCombatStats;
noncombatEnhancementBonuses: NonCombatStats;
noncombatStats: NonCombatStats;
type: EquipmentTypeHrid;
}
11 changes: 11 additions & 0 deletions src/MooLite/core/inventory/Inventory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,4 +160,15 @@ export class Inventory {
public getEquippedDrinks(): Record<ActionTypeHrid, (CharacterConsumable | null)[]> {
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;
}
}
13 changes: 13 additions & 0 deletions src/MooLite/core/inventory/items/Buffs.ts
Original file line number Diff line number Diff line change
@@ -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;
}
4 changes: 2 additions & 2 deletions src/MooLite/core/inventory/items/ConsumableDetail.ts
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
4 changes: 2 additions & 2 deletions src/MooLite/core/server/messages/InitClientInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ export interface InitClientInfoMessage extends ServerMessage {
// cowbellBundleDetailMap: Record<string, CowbellBundleDetail>;
// currentTimestamp: string;
// damageTypeDetailMap: Record<DamageTypeHrid, DamageTypeDetail>;
// enhancementLevelSuccessRateTable: number;
// enhancementLevelTotalBonusMultiplierTable: number;
enhancementLevelSuccessRateTable: number[];
enhancementLevelTotalBonusMultiplierTable: number[];
equipmentTypeDetailMap: Record<EquipmentTypeHrid, EquipmentTypeDetail>;
gameVersion: string;
itemCategoryDetailMap: Record<ItemCategoryHrid, ItemCategoryDetail>;
Expand Down
11 changes: 11 additions & 0 deletions src/MooLite/core/skills/Skills.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,15 @@ export class Skills {
public getLevel(skillHrid: SkillHrid) {
return this._characterSkills[skillHrid].level;
}

public getEnhancingLevel() {
return this._characterSkills["/skills/enhancing"].level;
}

public getSkillEfficiencyBonusRatio(requiredLevel: number, currentLevel: number): number {
if (requiredLevel >= currentLevel) {
return 0;
}
return (currentLevel - requiredLevel) / 100;
}
}
Loading