From 01eadd8812733f1c44f2b55054d93cc3e00462ce Mon Sep 17 00:00:00 2001 From: Ben Carter Date: Mon, 22 Jul 2024 00:10:17 -0400 Subject: [PATCH] Added updates to mythic panel for changing how state works and fixing bug with shared state across users --- modules/UI/mythicplus/mythicplus.client.ts | 49 ++++++----- modules/UI/mythicplus/mythicplus.server.ts | 97 ++++++++++++++++------ modules/classes/logger.ts | 6 ++ modules/commands/set-xp-rate.ts | 6 +- modules/items/bonus-enchantment.ts | 3 + 5 files changed, 111 insertions(+), 50 deletions(-) diff --git a/modules/UI/mythicplus/mythicplus.client.ts b/modules/UI/mythicplus/mythicplus.client.ts index 8505d4d..e85bb63 100644 --- a/modules/UI/mythicplus/mythicplus.client.ts +++ b/modules/UI/mythicplus/mythicplus.client.ts @@ -1,5 +1,8 @@ /** @ts-expect-error */ -let aio: AIO = {}; +let aio: AIO = {}; + +import { MythicPlusState } from "./mythicplus.state"; + if(!aio.AddAddon()) { const mythicPlusHandlers = aio.AddHandlers('MythicPlus', {}); @@ -13,11 +16,6 @@ const selectImages = [ "Interface/MythicPlus/ascendant-selected" ]; -type SelectionState = { - difficulty: number; - selected: number; -} - const Difficulty = { Mythic: 2, Legendary: 3, @@ -51,9 +49,12 @@ const MPanelSounds = { }; let MythicUIPanel: WoWAPI.Frame; -const MythicClientState: SelectionState = { +let MythicClientState: MythicPlusState = { difficulty: 0, - selected: 0 + groupId: -1, + groupLeader: -1, + inGroup: false, + isLeader: false, }; let Text = { @@ -63,7 +64,7 @@ let Text = { MYTHIC_DESC3: `Potential Affixes: 0`, MYTHIC_DESC4: `Party Deaths: |cff1eff00 Unlimited`, MYTHIC_REWARD1: `Drops: |cff9F3FFF Epic up to 320`, - MYTHIC_REWARD2: `Bonus Stats: 1 High Stat`, + MYTHIC_REWARD2: `Bonus Stats: Mid Tier`, LEGENDARY_TITLE: `LEGENDARY DUNGEON`, LEGENDARY_DESC1: `Enemy Strength: x3`, @@ -71,7 +72,7 @@ let Text = { LEGENDARY_DESC3: `Potential Affixes: 1`, LEGENDARY_DESC4: `Party Deaths: |cff1eff00 Unlimited`, LEGENDARY_REWARD1: `Drops: |cff9F3FFF Epic up to 340`, - LEGENDARY_REWARD2: `Bonus Stats: 1 High Stat / 1 Low Stat`, + LEGENDARY_REWARD2: `Bonus Stats: High Tier`, ASCENDANT_TITLE: `ASCENDANT DUNGEON`, ASCENDANT_DESC1: `Enemy Strength: x5`, @@ -79,23 +80,24 @@ let Text = { ASCENDANT_DESC3: `Potential Affixes: 2`, ASCENDANT_DESC4: `Party Deaths:|cffff0000 15 (Instance Reset at 0 lives)`, ASCENDANT_REWARD1: `Drops:|cffFF8400 Legendary up to 360 `, - ASCENDANT_REWARD2: `Bonus Stats: 2 High Stats`, + ASCENDANT_REWARD2: `Bonus Stats: Epic Tier`, DEFAULT_DESC1: `Harder difficulty dungeon not set.`, DEFAULT_DESC2: `Select a dungeon difficulty to view information.` } - +// These are used to store the textures and fonts for the Mythic+ UI panel so they can +// be referenced in different functions const MPTextures: Record = {}; const MPFonts: Record = {}; - function refreshUIState() { updateInfoText(MythicClientState.selected); updateSkulls(MythicClientState.selected); } -function updateSkulls(selected: number) { +// Updates the skull images based on the selected difficulty passed in +function updateSkulls(selected: number): void { switch(selected) { case Difficulty.Mythic: { MPTextures[`SkullImg2`].SetTexture(selectImages[1]); @@ -138,6 +140,7 @@ function updateSkulls(selected: number) { } } +// Updates the information text based on the selected difficulty passed in function updateInfoText(difficulty: Difficulty) { const titleFont = MPFonts[`InfoTitle`]; const descFont1 = MPFonts[`InfoDesc1`]; @@ -202,6 +205,7 @@ function updateInfoText(difficulty: Difficulty) { } +// Creates the information text for the Mythic+ UI panel function CreateInfoText(parent: WoWAPI.Frame, difficulty: Difficulty = null): void { const infoFrame = CreateFrame("Frame", `MPInfoFrame`, parent); @@ -251,10 +255,10 @@ function CreateInfoText(parent: WoWAPI.Frame, difficulty: Difficulty = null): vo MPFonts[`Reward2`] = reward2; } +// Creates the skull frames UI elements and artwork for the Mythic+ UI panel function CreateSkullFrame(difficulty: Difficulty, title: string, imageIndex: number): void { const parent = _G["MythicPlusPanel"]; - const MythicFrame = CreateFrame("Frame", `SkullFrame${difficulty}`, parent, null, difficulty); MythicFrame.SetSize(MPanelStyles.skullWidth, MPanelStyles.skullHeight); @@ -287,8 +291,11 @@ function CreateSkullFrame(difficulty: Difficulty, title: string, imageIndex: num if(MythicClientState.selected == f.GetID()) { MythicClientState.selected = 0; + SetDungeonDifficulty(2); + refreshUIState(); } else { MythicClientState.selected = f.GetID(); + SetDungeonDifficulty(2); } aio.Handle("MythicPlus", "SetDifficulty", MythicClientState.selected); @@ -350,17 +357,15 @@ function ShowUIPanel(): void { mainFrame.Show(); } -mythicPlusHandlers.ShowUI = (state) : void => { - MythicClientState.difficulty = state.difficulty; - MythicClientState.selected = state.difficulty; +mythicPlusHandlers.ShowUI = (state: MythicPlusState) : void => { + MythicClientState = state; ShowUIPanel(); - refreshUIState(); }; -mythicPlusHandlers.SetDifficulty = (difficulty: number): void => { - MythicClientState.difficulty = difficulty; - updateInfoText(difficulty); +mythicPlusHandlers.UpdateState = (state: MythicPlusState) : void => { + MythicClientState = state; + refreshUIState(); } // Shows the button that opens the Mythic+ UI diff --git a/modules/UI/mythicplus/mythicplus.server.ts b/modules/UI/mythicplus/mythicplus.server.ts index 615408a..b818855 100644 --- a/modules/UI/mythicplus/mythicplus.server.ts +++ b/modules/UI/mythicplus/mythicplus.server.ts @@ -1,7 +1,14 @@ /** @ts-expect-error */ let aio: AIO = {}; -function getPlayerGroupId(player: Player): number { +import { Logger } from "../../classes/logger"; +import type { MythicPlusState } from "./mythicplus.state"; + +const logger = new Logger("MythicPlusMod"); +const StateStorage: Map = new Map(); + +// This looks up the current group id for the player -1 indicates no group +function getPlayerGroupId(player: Player): number { const result = CharDBQuery(`SELECT m.guid FROM acore_characters.characters c left join acore_characters.group_member m on c.guid = m.memberGuid where c.guid = ${player.GetGUID()}`); if(!result) { @@ -11,28 +18,25 @@ function getPlayerGroupId(player: Player): number { return result.GetUInt32(0); } - // Get the difficulty alread set for the player or group function _getDifficulty(player: Player): number { const difficulty = player.GetDifficulty(); - const group = player.GetGroup(); - if(!group) { + const groupId = getPlayerGroupId(player); + + + logger.debug(`MythicPlusMod: Getting difficulty for ${player.GetName()} with difficulty ${difficulty} and group ${groupId}`); + + if(groupId == -1) { aio.Handle(player, "MythicPlus", "SetDifficulty", difficulty); } - const result = CharDBQuery(`SELECT difficulty FROM group_difficulty WHERE guid = ${group.GetGUID()}`); + const result = CharDBQuery(`SELECT difficulty FROM group_difficulty WHERE guid = ${groupId}`); if(result) { - print(`MythicPlusMod: Setting difficulty for ${player.GetName()} to ${result.GetUInt32(0)}`); - aio.Handle(player, 'MythicPlus', 'SetDifficulty', result.GetUInt32(0)); - return; + logger.debug(`MythicPlusMod: Setting difficulty for ${player.GetName()} to ${result.GetUInt32(0)}`); + return result.GetUInt32(0); } } -// Server API for Client -function GetDifficulty(this:void, player: Player): void { - aio.Handle(player, 'MythicPlus', 'SetDifficulty', _getDifficulty(player)); -} - // Set the difficulty for the encounter function _setDifficulty(player: Player, difficulty: number): void { const groupId = getPlayerGroupId(player); @@ -41,19 +45,24 @@ function _setDifficulty(player: Player, difficulty: number): void { player.SendNotification('You must be in a group to set a mythic+ difficulty'); return; } - PrintInfo("Group ID: " + groupId); + logger.debug(`Setting difficulty for ${player.GetName()} to ${difficulty}`); if(! group.IsLeader(player.GetGUID())) { return; } + const map = player.GetMap(); + if(map.IsDungeon() != false) { + player.SendNotification('You can not change the difficulty in a dungeon'); + return; + } + if(difficulty > 4) { - PrintError(`MythicPlusMod: Invalid difficulty set: ${difficulty}`); + logger.error(`Invalid difficulty set: ${difficulty}`); } if(difficulty == 0) { - CharDBExecute(`DELETE FROM group_difficulty WHERE guid = ${groupId}`); - GetDifficulty(player); + CharDBExecute(`DELETE FROM group_difficulty WHERE guid = ${groupId}`); return; } @@ -62,22 +71,56 @@ function _setDifficulty(player: Player, difficulty: number): void { function SetDifficulty(this:void, player: Player, difficulty: number): void { _setDifficulty(player, difficulty); + aio.Handle(player, 'MythicPlus', 'UpdateState', StateStorage.get(player.GetGUIDLow())); } -const ShowIt: player_event_on_command = (event: number,player: Player, command: string): boolean => { - if(command == 'mythicplus') { - const difficulty = player.GetDifficulty(); - PrintInfo(`MythicPlusMod: Showing UI for ${player.GetName()} with difficulty ${difficulty}`); - aio.Handle(player, 'MythicPlus', 'ShowUI', {difficulty: difficulty}); +function _refreshState(player: Player) { + if(player.IsInGroup()) { + const groupId = getPlayerGroupId(player); + const groupLeader = player.GetGroup().GetLeaderGUID(); + const isLeader = player.GetGUID() == groupLeader; + const difficulty = _getDifficulty(player); + StateStorage.set(player.GetGUIDLow(), {difficulty, inGroup: true, groupId, groupLeader, isLeader}); + return; + } else { + StateStorage.set(player.GetGUIDLow(), {difficulty: _getDifficulty(player), inGroup: false, groupId: -1, groupLeader: -1, isLeader: false}); + } +} + +// Update the state from what is on the server and send it back to the client. +function GetState(this:void, player: Player): void { + _refreshState(player); + const state = StateStorage.get(player.GetGUIDLow()); + aio.Handle(player, 'MythicPlus', 'UpdateState', state); +} + +const OpenUI: player_event_on_command = (event: number,player: Player, command: string): boolean => { + if(command == 'mythicplus') { + const state = StateStorage.get(player.GetGUIDLow()); + logger.debug(`OpenUI command + player: ${player.GetName()}, + difficulty ${state.difficulty}, + groupId: ${state.groupId}, + groupLeader: ${state.groupLeader}, + isLeader: ${state.isLeader}` + ); + aio.Handle(player, 'MythicPlus', 'ShowUI', StateStorage.get(player.GetGUIDLow())); return false; } return true; }; +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_COMMAND, (...args) => OpenUI(...args)); +const MPStartState: player_event_on_login = (_event: number, player: Player): void => { + _refreshState(player); +}; + +// On login set up the mythic panel mod state for the player +RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOGIN, (...args) => MPStartState(...args)); + +// API Handlers available to the client const MPHandlers = aio.AddHandlers("MythicPlus", { - GetDifficulty, - SetDifficulty -}); - -RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_COMMAND, (...args) => ShowIt(...args)); + SetDifficulty, + GetState, +}); \ No newline at end of file diff --git a/modules/classes/logger.ts b/modules/classes/logger.ts index 67e93b7..fe54636 100644 --- a/modules/classes/logger.ts +++ b/modules/classes/logger.ts @@ -13,6 +13,12 @@ export class Logger { print(`[${this.logname}][Log]: ${message} was printed from ${info.short_src}:${info.currentline}`); } + debug(message: string) { + const info = debug.getinfo(2, "Sl"); + PrintDebug(`[${this.logname}][Debug]: ${message} was printed from ${info.short_src}:${info.currentline}`); + } + + info(message: string) { const info = debug.getinfo(2, "Sl"); PrintInfo(`[${this.logname}][Info]: ${message} was printed from ${info.short_src}:${info.currentline}`); diff --git a/modules/commands/set-xp-rate.ts b/modules/commands/set-xp-rate.ts index a0cb862..f1e9aa6 100644 --- a/modules/commands/set-xp-rate.ts +++ b/modules/commands/set-xp-rate.ts @@ -79,7 +79,11 @@ const XPBonus: player_event_on_give_xp = (event: number, player: Player, amount: const xpRate = xpRateCache.get(player.GetGUIDLow()); if(xpRate && xpRate > 1) { - // player.GiveXP(amount * xpRate); + + if(player.GetLevel() < 80) { + player.GiveXP(amount * xpRate); + } + } } diff --git a/modules/items/bonus-enchantment.ts b/modules/items/bonus-enchantment.ts index c10e50c..8754c04 100644 --- a/modules/items/bonus-enchantment.ts +++ b/modules/items/bonus-enchantment.ts @@ -215,5 +215,8 @@ RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOOT_ITEM, (event, player, item if(ids[1]) { item.SetEnchantment(ids[1], 5); } + + + PrintInfo("BonusEnchantment/OnLootItem - Enchanting item: " + item.GetEntry() + " with enchants: " + ids[0] + " and " + ids[1]); }); \ No newline at end of file