All the latest and greatest changes

This commit is contained in:
2025-03-18 13:22:12 -04:00
parent 88bbbf0885
commit 5c1e3ef667
31 changed files with 6547 additions and 886 deletions

2
.gitignore vendored
View File

@@ -3,5 +3,5 @@ node_modules
node_modules/* node_modules/*
dist dist
wow-wotlk-declarations wow-wotlk-declarations
.DS_Store

1832
.vscode/eluna.code-snippets vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,27 +0,0 @@
const onUtPlayerEnter: map_event_on_player_enter = (event: number, map: EMap, player: Player) => {
// Implementation
print(`Player ${player.GetName()} entered map ${map.GetName()}`);
print(map.GetInstanceId());
if(map.GetMapId() == MapIdType.Utgarde_Keep) {
print("Utgarde Keep");
// AddAuraToCreatures(player);
const creatures = player.GetCreaturesInRange(1000);
for(let i=0; i<creatures.length; i++) {
const creature = creatures[i];
creature.AddAura(45078, creature);
creature.AddAura(48162, creature);
// creature.SetMaxHealth(creature.GetMaxHealth() * 3);
creature.SetScale(1);
}
}
};
// Register Map Event on Player Enter
RegisterServerEvent(ServerEvents.MAP_EVENT_ON_PLAYER_ENTER, (...args) => onUtPlayerEnter(...args));

View File

@@ -0,0 +1,132 @@
const groupInstance = {};
const onPlayerEnter : map_event_on_player_enter = (event: number, map: EMap, player: Player) => {
// Implementation
};
// Register Map Event on Player Enter
RegisterServerEvent(ServerEvents.MAP_EVENT_ON_PLAYER_ENTER, (event: number, map: EMap, player: Player) => {
// Implementation
print(`Player ${player.GetName()} entered map ${map.GetName()}`);
print(map.GetInstanceId());
let group = player.GetGroup();
if(!group) {
return;
}
if(!groupInstance[group.GetGUID()]) {
groupInstance[group.GetGUID()] = [];
}
if(groupInstance[group.GetGUID()].includes(map.GetInstanceId())) {
return;
}
if(!groupInstance[map.GetInstanceId()]) {
groupInstance[map.GetInstanceId()] = [];
player.
const group = player.GetGroup();
const members = group.GetMembers();
for(let i=0; i<members.length; i++) {
const member = members[i];
print(member.GetName());
}
}
if(map.GetMapId() == MapIdType.Utgarde_Keep) {
print("Utgarde Keep");
// AddAuraToCreatures(player);
const creatures = player.GetCreaturesInRange(1000);
for(let i=0; i<creatures.length; i++) {
const creature = creatures[i];
creature.AddAura(45078, creature);
creature.AddAura(48162, creature);
creature.AddAura(48161, creature);
// creature.SetMaxHealth(creature.GetMaxHealth() * 3);
creature.SetScale(1);
}
}
};
RegisterServerEvent(ServerEvents.MAP_EVENT_ON_PLAYER_ENTER, (...args) => onPlayerEnter(...args));
// // Register Map Event on Player Enter
// RegisterServerEvent(ServerEvents.MAP_EVENT_ON_PLAYER_ENTER, (...args) => onUtPlayerEnter(...args));
// const onCreatureCreate: instance_event_on_creature_create = (event: number, instance_data: number[], map: EMap, creature: Creature) => {
// print('Creature Create');
// }
// const onInstanceInitialize: instance_event_on_initialize = (event: number, instance_data: number[], map: EMap) => {
// print('Instance Initialize');
// }
// const onPlayerEnter: instance_event_on_player_enter = (event: number, instance_data: number[], map: EMap, player: Player) => {
// print('Player Enter');
// print(map.GetName());
// print(map.GetInstanceId());
// print(player.GetName());
// print(player.GetGUID());
// print(player.GetMapId());
// }
// const onMapPlayerEnter: map_event_on_player_enter = (event: number, map: EMap, player: Player) => {
// print('Player Enter');
// print(map.GetName());
// print(map.GetInstanceId());
// print(player.GetName());
// print(player.GetGUID());
// print(player.GetMapId());
// }
// const onMapCreate: map_event_on_create = (event: number, map: EMap) => {
// print('Map Create');
// print(map.GetName());
// print(map.GetInstanceId());
// if(!map.IsDungeon()) {
// return;
// }
// }
// const onMapLoad: instance_event_on_load = (event: number, instance_data: number[], map: EMap) => {
// print('Map Load');
// }
// RegisterMapEvent(MapIdType.ZulFarrak, InstanceEvents.INSTANCE_EVENT_ON_INITIALIZE, (...args) => onInstanceInitialize(...args));
// RegisterMapEvent(MapIdType.ZulFarrak, InstanceEvents.INSTANCE_EVENT_ON_CREATURE_CREATE, (...args) => onCreatureCreate(...args));
// RegisterMapEvent(MapIdType.ZulFarrak, InstanceEvents.INSTANCE_EVENT_ON_PLAYER_ENTER, (...args) => onPlayerEnter(...args));
// RegisterMapEvent(MapIdType.Kalimdor, InstanceEvents.INSTANCE_EVENT_ON_INITIALIZE, (...args) => onInstanceInitialize(...args));
// RegisterMapEvent(MapIdType.Kalimdor, InstanceEvents.INSTANCE_EVENT_ON_CREATURE_CREATE, (...args) => onCreatureCreate(...args));
// RegisterMapEvent(MapIdType.Kalimdor, InstanceEvents.INSTANCE_EVENT_ON_PLAYER_ENTER, (...args) => onPlayerEnter(...args));
// RegisterMapEvent(MapIdType.Kalimdor, InstanceEvents.INSTANCE_EVENT_ON_LOAD, (...args) => onMapLoad(...args));
// RegisterInstanceEvent(6, InstanceEvents.INSTANCE_EVENT_ON_PLAYER_ENTER, (...args) => onPlayerEnter(...args));
// RegisterServerEvent(ServerEvents.MAP_EVENT_ON_PLAYER_ENTER, (...args) => onMapPlayerEnter(...args));
// RegisterServerEvent(ServerEvents.MAP_EVENT_ON_CREATE, (...args) => onMapCreate(...args));
// // RegisterCreatureEvent(CreatureEvents.CREATURE_EVENT_ON_ADD, (...args) => onCreatureCreate(...args));
// print ('Dungeon Elites Loaded');
// // RegisterInstanceEvent(InstanceEvents.INSTANCE_EVENT_ON_CREATURE_CREATE, (...args) => onCreatureCreate(...args));

View File

@@ -0,0 +1,71 @@
const dungeonGo: player_event_on_map_change = (event: number, player: Player) => {
const map = player.GetMap();
if (! map.IsDungeon() && ! map.IsRaid()) {
return;
}
if (player.GetMapId() !== 0) {
return;
}
const group = player.GetGroup();
if (!group) {
return;
}
if(player.GetRace() != 9) {
print("was not a goblin you get no chaos items")
} // Goblins only
player.SendChatMessageToPlayer(ChatMsg.CHAT_MSG_RAID_BOSS_EMOTE,Language.LANG_COMMON,`YOU HAVE ENTERED GOBLIN CHAOS!`, player);
};
RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_MAP_CHANGE, (...args) => dungeonGo(...args));
RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOOT_ITEM, (event, player, item) => {
const itemCls = item.GetClass();
const subClass = item.GetSubClass();
if (item.GetQuality() < 2) {
return;
}
if (itemCls !== 2 && itemCls !== 4) {
return;
}
const weaponList = [0,1,2,3,4,5,6,7,8,10,13,15,16,17,18,19];
const armorList = [0,1,2,3,4,6]
// not a weapon
if ( itemCls === 2 && !weaponList.includes(subClass)) {
return;
}
// not armor
if ( itemCls === 4 && !armorList.includes(subClass)) {
return;
}
const ids = rollEnchant(item, true);
if(ids.length !== 2) {
PrintError("BonusEnchantment/OnLootITem - Failed to get enchant ids");
return;
}
if(ids[0]) {
item.SetEnchantment(ids[0], 4);
}
if(ids[1]) {
item.SetEnchantment(ids[1], 5);
}
PrintInfo("BonusEnchantment/OnLootItem - Enchanting item: " + item.GetEntry() + " with enchants: " + ids[0] + " and " + ids[1]);
});

View File

@@ -0,0 +1,28 @@
class Command {
onCommand : player_event_on_command = (
event: number,
player: Player,
command: string
) => {
if(command == "doit") {
const message = "A Command from the script has been entered" + command;
print(message);
SendWorldMessage(message);
}
print("debug: " + command);
return true;
}
}
const commandHander = new Command();
RegisterPlayerEvent(
PlayerEvents.PLAYER_EVENT_ON_COMMAND,
(...args) => commandHander.onCommand(...args)
)

View File

@@ -1,168 +0,0 @@
local ____lualib = require("lualib_bundle")
local __TS__New = ____lualib.__TS__New
local __TS__ArrayIncludes = ____lualib.__TS__ArrayIncludes
local __TS__StringIncludes = ____lualib.__TS__StringIncludes
local ____exports = {}
local ____money = require("classes.money")
local ToCopper = ____money.ToCopper
local GetPlayerTax = ____money.GetPlayerTax
local ____account = require("classes.account")
local AccountInfo = ____account.AccountInfo
local spawned = {}
local NPCS = {
GOTHUK = 9000003,
BERNIE = 9000004,
EDWARD = 9000005,
LUNA = 9000006,
BOB_B = 9000007,
SHIVA = 9000008
}
local selectedItem = {}
local function GossipHello(____, event, player, creature)
local accountId = player:GetAccountId()
local bernieCost = ToCopper(nil, 1000) + GetPlayerTax(nil, player, 5)
player:GossipClearMenu()
do
local i = 23
while i <= 38 do
local item = player:GetItemByPos(255, i)
if item ~= nil then
print(item:GetItemLink())
if item:IsSoulBound() then
local quality = item:GetQuality()
if quality > 2 then
player:GossipMenuAddItem(
1,
"Item: " .. item:GetItemLink(),
1,
item:GetGUIDLow(),
nil,
nil
)
end
end
end
i = i + 1
end
end
player:GossipSendMenu(NPCS.GOTHUK, creature, 10000)
return true
end
local function GossipSelect(____, event, player, creature, selection, action, code, menuId)
PrintInfo("selection: " .. tostring(selection))
print("action " .. tostring(action))
local account = __TS__New(
AccountInfo,
player:GetAccountId()
)
local characters = account:GetCharacters()
if action > 15 then
do
local numC = 0
while numC < #characters do
local name = characters[numC + 1].name
if name ~= player:GetName() then
player:GossipMenuAddItem(
2,
"Send to: " .. name,
2,
numC + 1,
nil
)
end
numC = numC + 1
end
end
selectedItem[player:GetName()] = action
player:GossipSendMenu(NPCS.GOTHUK, creature, 10000)
end
if action <= 15 then
local itemToChange = selectedItem[player:GetName()]
local itemGuid = GetItemGUID(itemToChange)
local PlayerItem = player:GetItemByGUID(itemGuid)
print((("Item Info: " .. PlayerItem:GetOwner():GetName()) .. " owns ") .. PlayerItem:GetName())
print("To Name is " .. characters[action].name)
local newItemGuid = SendMail(
"Item Soulswap " .. PlayerItem:GetName(),
"Soulbinder has sent you a gift " .. PlayerItem:GetName(),
characters[action].guid,
player:GetGUIDLow(),
41,
100,
0,
0,
PlayerItem:GetEntry(),
1
)
print((("send new item " .. tostring(newItemGuid)) .. " to ") .. characters[action].name)
player:GossipComplete()
end
return true
end
--- This will load NPCs that shoud be loaded based on purchased guild benefits
-- and if system is enabled.
local function LoadNpcOnStart(____, event)
local npcs = {
9000003,
9000004,
9000005,
9000006,
9000007,
9000008
}
local result = WorldDBQuery("SELECT * from guild_elite_benefits")
do
local i = 0
while i < result:GetRowCount() do
local benefit = result:GetRow()
local entry = benefit.creature_entry
if benefit.purchased == 1 and not __TS__ArrayIncludes(spawned, entry) then
PerformIngameSpawn(
1,
entry,
1,
0,
benefit.x,
benefit.y,
benefit.z,
benefit.o,
false
)
PrintInfo("benefit.benefit,'was purchased!")
else
PrintInfo("benefit.benefit,'was NOT purchased!'")
end
result:NextRow()
i = i + 1
end
end
end
RegisterCreatureGossipEvent(
9000003,
1,
function(...) return GossipHello(nil, ...) end
)
RegisterCreatureGossipEvent(
9000003,
2,
function(...) return GossipSelect(nil, ...) end
)
local function seeItems(____, event, player, command)
if __TS__StringIncludes(command, "backpack") then
do
local i = 23
while i <= 38 do
local item = player:GetItemByPos(255, i)
print(item:GetName())
print(item:GetItemLink())
i = i + 1
end
end
end
return true
end
RegisterPlayerEvent(
42,
function(...) return seeItems(nil, ...) end
)
return ____exports

View File

@@ -1,245 +0,0 @@
import { ToGold, ToCopper, GetPlayerTax } from "../modules/classes/money";
import { AccountInfo } from "../modules/classes/account";
const spawned:Array<number> = [];
const NPCS = {
GOTHUK: 9000003,
BERNIE: 9000004,
EDWARD: 9000005,
LUNA: 9000006,
BOB_B: 9000007,
SHIVA: 9000008
};
const selectedItem: Record<string, number> = {};
const GossipHello : gossip_event_on_hello = (event: number, player: Player, creature: EObject) => {
const accountId = player.GetAccountId();
// NPC Hire Costs
const bernieCost = ToCopper(1000) + GetPlayerTax(player,5);
player.GossipClearMenu();
let items = 0;
for(let i=23; i <= 38; i++ ) {
let item = player.GetItemByPos(255, i);
if(item != undefined) {
print(item.GetItemLink());
if(item.IsSoulBound() ) {
const quality = item.GetQuality();
if(quality > 2) {
items += 1;
player.GossipMenuAddItem(1,`Item: ${item.GetItemLink()}`,1,item.GetGUIDLow(), undefined, undefined);
}
}
}
// print(item.GetName());
// print(item.GetItemLink());
}
if(items === 0) {
player.SendNotification("You have no soulbound items in your backback to send to your other characters.");
}
player.GossipMenuAddItem(1,`Stop using the device`,1,50500);
// player.GossipMenuAddItem(1,`Hire Grandmaster Smith - (Reset Timers) 200g`,1,10,undefined,undefined,10000*200);
// player.GossipMenuAddItem(1,`Hire Grandmaster Tailor - (Reset Timers) 200g`,1,20,undefined,undefined,10000*200);
// // // player.GossipMenuAddItem(1,`Hire Grandmaster Leatherworker - (Reset Timers) 200g`, 1,30, undefined, undefined, 10000*200);
// // player.GossipMenuAddItem(1,`Hire Grandmaster Jewelcrafter - (Reset Timers) 200g`, 1,40, undefined, undefined, 10000*200);
// player.GossipMenuAddItem(1,`Hire Bernie, Leather Trader - ${ToGold(bernieCost)}g`, NPCS.BERNIE,50, undefined, undefined, bernieCost);
// // player.GossipMenuAddItem(1,`Epic Tradeskill Vendor - 650g`, 1,60, undefined, undefined, 10000*650);
// // player.GossipMenuAddItem(1,`Secret Goods Vendor 1300g`, 1,80, undefined, undefined, 10000*1300);
// player.GossipMenuAddItem(0, `I will leave you alone`,1,2);
player.GossipSendMenu(NPCS.GOTHUK, creature, 10000);
return true;
}
const GossipSelect: gossip_event_on_select = (event: number, player: Player, creature: any, selection, action, code, menuId) => {
PrintInfo(`selection: ${selection}`);
print(`action ${action}`);
// const cost = 100000;
// const inGold = cost / 10000;
const account = new AccountInfo(player.GetAccountId());
const characters = account.GetCharacters();
if(action === 50500) {
player.GossipClearMenu();
player.GossipComplete();
return true;
}
// player.GossipClearMenu();
if(action > 15) {
for(let numC = 0; numC < characters.length; numC++) {
let name = characters[numC].name;
if(name != player.GetName()) {
// player.GossipMenuAddItem(2, `Send to: ${name}`, 2, numC+1, undefined, `Are you sure you will to rebind this item to ${name}?`, 10000);
player.GossipMenuAddItem(2, `Send to: ${name}`, 2, numC+1, undefined);
}
}
selectedItem[player.GetName()] = action;
player.GossipSendMenu(NPCS.GOTHUK, creature, 10000);
}
if(action <= 15) {
let itemToChange = selectedItem[player.GetName()];
let itemGuid = GetItemGUID(itemToChange);
const PlayerItem = player.GetItemByGUID(itemGuid);
print(`Item Info: ${PlayerItem.GetOwner().GetName()} owns ${PlayerItem.GetName()}`);
let newItemGuid = SendMail(
`Item Rebound ${PlayerItem.GetName()}`,
`Soulbinder has sent you a gift ${PlayerItem.GetName()}`,
characters[action-1].guid,
player.GetGUIDLow(),
MailStationery.MAIL_STATIONERY_DEFAULT,
0,
0,
0,
PlayerItem.GetEntry(),
1
);
print(`To Name is ${characters[action-1].name}`);
player.RemoveItem(PlayerItem, PlayerItem.GetEntry(), 1);
print(`send new item ${newItemGuid} to ${characters[action-1].name}`);
player.GossipClearMenu();
player.GossipComplete();
}
return true;
}
// const MapLog: map_event_on_player_enter = (event: number, map: EMap, player:Player) => {
// PrintInfo(map.GetName());
// PrintInfo(`${map.GetInstanceId()}`);
// PrintInfo(`${player.GetZoneId()}`);
// PrintInfo(`${GetGameTime()}`);
// if(player.GetZoneId() == 876) {
// WorldDBExecute(`insert into guild_house_log VALUES(null,'${player.GetGUID()}','${player.GetName()} entered the guild house', CURTIME())`);
// }
// return true;
// }
/**
* This will load NPCs that shoud be loaded based on purchased guild benefits
* and if system is enabled.
*/
const LoadNpcOnStart: eluna_event_on_lua_state_open = (event: number) => {
const npcs = [
9000003, // Gothuk
9000004, // Bernie
9000005, // Edward
9000006, // Luna
9000007, // Bob B
9000008 // Shiva
];
const result = WorldDBQuery("SELECT * from guild_elite_benefits");
for(let i =0; i < result.GetRowCount(); i++ ) {
let benefit = result.GetRow();
let entry = benefit.creature_entry as number;
if(benefit.purchased === 1 && !spawned.includes(entry)) {
PerformIngameSpawn(1,entry,1,0,
// location data
benefit.x as number,
benefit.y as number,
benefit.z as number,
benefit.o as number,
false);
PrintInfo(`benefit.benefit,'was purchased!`);
} else {
PrintInfo(`benefit.benefit,'was NOT purchased!'`);
}
result.NextRow();
}
// for(const npcId of npcs) {
// Get
// }
}
// RegisterServerEvent(
// ServerEvents.ELUNA_EVENT_ON_LUA_STATE_OPEN,
// (...args) => {
// let spawned = [];
// LoadNpcOnStart(...args)
// }
// );
// PerformIngameSpawn(1,9000003,1,0,16221.8,16278,20.9032,4.70345,false);
// const object = GetObjectGUID(3110516,9000003);
RegisterCreatureGossipEvent(
9000003,
GossipEvents.GOSSIP_EVENT_ON_HELLO,
(...args) => GossipHello(...args)
);
RegisterCreatureGossipEvent(
9000003,
GossipEvents.GOSSIP_EVENT_ON_SELECT,
(...args) => GossipSelect(...args)
);
RegisterGameObjectGossipEvent(
750000,
GossipEvents.GOSSIP_EVENT_ON_HELLO,
(...args) => GossipHello(...args)
);
RegisterGameObjectGossipEvent(
750000,
GossipEvents.GOSSIP_EVENT_ON_SELECT,
(...args) => GossipSelect(...args)
);
// RegisterServerEvent(
// ServerEvents.MAP_EVENT_ON_PLAYER_ENTER,
// (...args) => MapLog(...args)
// )
const seeItems: player_event_on_command = (event: number, player: Player, command: string): boolean => {
if(command.includes('backpack')) {
for(let i=23; i <= 38; i++ ) {
let item = player.GetItemByPos(255, i);
print(item.GetName());
print(item.GetItemLink());
}
}
return true;
}
RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_COMMAND, (...args) => seeItems(...args));

View File

@@ -0,0 +1,206 @@
/** @ts-expect-error */
let aio: AIO = {};
const id = (name: string) => `UpgradeUI_${name}`;
import { colors } from "../../classes/ui-utils";
if (!aio.AddAddon()) {
const upgradeUIHandlers = aio.AddHandlers("UpgradeUI", {});
const UpgradeUIFrames: Map<number, WoWAPI.Frame> = new Map();
const itemSlots: Map<number, string> = new Map();
let selectedDice: WoWAPI.Button | null = null;
let rolling: boolean = false;
const mainWidth = 768;
const mainHeight = 512;
const centerOffset = mainWidth / 2;
const usedTextures = {
"bgFrame": "Interface/Modules/MythicPlus/Textures/mythic-adv-frame",
"bgFrameHq": "Interface/Modules/MythicPlus/Textures/mythic-adv-frame-hq",
"bgFrameHq2": "Interface/Modules/MythicPlus/Textures/mythic-upgrade-frame-hq-2",
"darkBg": "Interface/DialogFrame/UI-DialogBox-Background-Dark",
"diceFrame": "Interface/Modules/MythicPlus/Textures/advancement_frame",
}
function GetTexture(name: string): string {
return usedTextures[name] || "";
}
function CreateUpgradeWindow() {
const frame = CreateFrame("Frame", id("main"), UIParent);
frame.SetSize(mainWidth, mainHeight);
frame.SetPoint("CENTER");
frame.SetMovable(true);
frame.EnableMouse(true);
frame.RegisterForDrag("LeftButton");
frame.SetScript("OnDragStart", frame.StartMoving);
frame.SetScript("OnDragStop", frame.StopMovingOrSizing);
const bgTexture = frame.CreateTexture(id("background"), "BACKGROUND");
bgTexture.SetPoint('TOPLEFT');
bgTexture.SetWidth(mainWidth);
bgTexture.SetHeight(mainHeight);
bgTexture.SetTexture(GetTexture("bgFrameHq"));
bgTexture.SetTexCoord(0, 768/1024, 0, 1); // Show 75% of width (768/1024) and full height
frame.Show();
// Add title background
const titleBg = frame.CreateTexture(id("TitleBg"), "ARTWORK");
// titleBg.SetTexture("Interface/DialogFrame/UI-DialogBox-Header");
// titleBg.SetWidth(300);
// titleBg.SetHeight(64);
// titleBg.SetDrawLayer("OVERLAY", 10)
// titleBg.SetPoint("TOP", 0, 14);
// Add title text
const titleBar = frame.CreateFontString(id("TitleBar"), "OVERLAY");
titleBar.SetPoint("TOP", -150, -40);
titleBar.SetTextColor(1, 0.84, 0, 1) // Golden yellow
titleBar.SetFont("Interface/Modules/MythicPlus/Fonts/NOTO.TTF", 16)
titleBar.SetText(`Mythic Upgrades`);
// Remove the template's close button
const templateCloseButton = frame.GetChildren()[0] as WoWAPI.Frame;
if (templateCloseButton) {
templateCloseButton.Hide();
}
// // Add our custom close button
// const closeButton = CreateFrame("Button", id("CloseButton"), frame, "UIPanelCloseButton");
// closeButton.SetPoint("TOPRIGHT", -5, -5);
// closeButton.SetScript("OnClick", () => {
// frame.Hide();
// });
// Header Row: Skill Icons & Ranks
for (let i = 0; i < 3; i++) {
const skillFrame = CreateFrame("Frame", id(`Skill_${i}`), frame);
skillFrame.SetSize(64, 64);
skillFrame.SetPoint("TOP", -125 + i * 125, -55);
const skillIcon = skillFrame.CreateTexture(id(`SkillIcon_${i}`), "ARTWORK");
skillIcon.SetTexture("Interface\\Icons\\INV_Misc_QuestionMark");
skillIcon.SetAllPoints();
const skillName = skillFrame.CreateFontString(id(`SkillName_${i}`), "OVERLAY", "GameFontNormalLarge");
skillName.SetPoint("TOP", skillFrame, "BOTTOM", 0, -5);
skillName.SetText(`Skill ${i + 1}`);
const skillRank = skillFrame.CreateFontString(id(`SkillRank_${i}`), "OVERLAY", "GameFontHighlightLarge");
skillRank.SetPoint("TOP", skillName, "BOTTOM", 0, -2);
skillRank.SetText("0 / 50");
}
// Add a new texture in the middle of the frame that is 512x512 and the middle layer
const centerTexture = frame.CreateTexture(id("DiceTextureBack"), "ARTWORK");
centerTexture.SetDrawLayer("ARTWORK", 3);
centerTexture.SetSize(128, 128);
centerTexture.SetPoint("CENTER", frame, "CENTER", 0, -20);
centerTexture.SetTexture("Interface\\MythicPlus\\adv-dice-light.blp");
const circleTexture = frame.CreateTexture(id("DiceTextureBack"), "BACKGROUND");
circleTexture.SetDrawLayer("ARTWORK", 5);
circleTexture.SetSize(512, 512);
circleTexture.SetAlpha(0.20);
circleTexture.SetPoint("CENTER", frame, "CENTER", 0, -20);
circleTexture.SetTexture("Interface\\MythicPlus\\gold-circle.blp");
// Add a glowing effect behind the dice
const glowTexture = frame.CreateTexture(id("DiceGlow"), "ARTWORK");
glowTexture.SetDrawLayer("ARTWORK", -2);
glowTexture.SetSize(300, 300);
glowTexture.SetPoint("CENTER", centerTexture, "CENTER", 0, 0);
glowTexture.SetTexture("Interface\\GLUES\\MODELS\\UI_MainMenu_Legion\\UI_MainMenu_Legion3");
glowTexture.SetAlpha(0.3);
// Roll Display with better font handling
const rollDisplay = frame.CreateFontString(id("RollDisplay"),"ARTWORK");
rollDisplay.SetFont("Interface\\MythicPlus\\NOTO.TTF", 256, "THICKOUTLINE");
rollDisplay.SetPoint("CENTER", frame, "CENTER", 0, -80);
rollDisplay.SetTextColor(1, 0.84, 0, 1); // More golden yellow color
rollDisplay.SetText("-");
// Dice Multipliers with Selection Logic
const diceMultipliers = ["1x", "2x", "3x"];
for (let k = 0; k < diceMultipliers.length; k++) {
const diceButton = CreateFrame("Button", id(`Dice_${k}`), frame);
diceButton.SetSize(24, 24);
diceButton.SetPoint("TOPLEFT", 150 + (k * 30), -450);
const diceText = diceButton.CreateFontString(id(`DiceText_${k}`), "OVERLAY", "GameFontHighlight");
diceText.SetPoint("CENTER", diceButton, "CENTER", 0, 0);
diceText.SetText(diceMultipliers[k]);
diceButton.SetScript("OnClick", function() {
if (selectedDice) {
selectedDice.SetAlpha(1.0); // Reset previous selection
}
selectedDice = diceButton;
selectedDice.SetAlpha(1.5); // Glow effect
});
}
// Roll Button with animation logic
const rollButton = CreateFrame("Button", id("RollButton"), frame, "UIPanelButtonTemplate");
rollButton.SetSize(100, 30);
rollButton.SetPoint("BOTTOM", frame, "BOTTOM", 0, 50);
rollButton.SetText("Roll");
function rollDice(min: number, max: number, duration: number = 5000) {
if (rolling) return;
rolling = true;
let elapsed = 0;
let lastUpdate = 0;
frame.SetScript("OnUpdate", function(_, deltaTime) {
elapsed = elapsed + deltaTime * 5000;
lastUpdate += deltaTime * 1000;
// Only update every 200ms to slow down the rolling animation
if (lastUpdate >= 100) {
lastUpdate = 0;
rollDisplay.SetText(`${Math.floor(Math.random() * (max - min + 1)) + min}`);
}
if (elapsed >= duration) {
frame.SetScript("OnUpdate", null);
rolling = false;
// Set final roll
rollDisplay.SetText(`${Math.floor(Math.random() * (max - min + 1)) + min}`);
}
});
}
rollButton.SetScript("OnClick", function() {
rollDice(2, 23); // Default to 2-23 range for backward compatibility
});
// Roll History
const historyFrame = CreateFrame("Frame", id("HistoryFrame"), frame);
historyFrame.SetSize(380, 80);
historyFrame.SetPoint("BOTTOM", frame, "BOTTOM", 0, 10);
const historyText = historyFrame.CreateFontString(id("HistoryText"), "OVERLAY", "GameFontHighlight");
historyText.SetPoint("TOPLEFT", historyFrame, "TOPLEFT", 10, -10);
historyText.SetText("Roll History:");
UpgradeUIFrames.set(1, frame);
}
CreateUpgradeWindow();
UpgradeUIFrames.get(1).Show();
upgradeUIHandlers.ShowUpgradeWindow = () => {
if (!UpgradeUIFrames.has(1)) {
CreateUpgradeWindow();
}
UpgradeUIFrames.get(1).Show();
};
}

View File

@@ -0,0 +1,24 @@
/** @ts-expect-error */
let aio: AIO = {};
const SCRIPT_NAME = 'UpgradeUI';
import { Logger } from "../../classes/logger";
const log = new Logger(SCRIPT_NAME);
/**
* Handles the logic for showing the upgrade UI when a player types .advanceme
*/
const ShowUpgradeUI: player_event_on_command = (event: number, player: Player, command: string): boolean => {
if (command === "advanceme") {
log.info(`Showing Upgrade UI for player: ${player.GetName()}`);
aio.Handle(player, 'UpgradeUI', 'ShowUpgradeWindow');
return false;
}
return true;
};
/**
* Register the command event to listen for ".advanceme"
*/
RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_COMMAND, (...args) => ShowUpgradeUI(...args));

View File

@@ -1,35 +0,0 @@
const bonusAuraId = 600000;
const bonusAreaId = 3817;
const teleportData = {
map: 571,
x: 5496.157227,
y: 4725.473633,
z: -194.177444,
o: 2.009775,
};
function exitPlayer(player): boolean {
if (player.GetAreaId() === bonusAreaId && !player.HasAura(bonusAuraId)) {
player.Teleport(teleportData.map, teleportData.x, teleportData.y, teleportData.z, teleportData.o);
return true;
}
return false;
}
const checkAura = (eventId: number, delay: number, repeats: number, player: Player): void => {
if(exitPlayer(player)){
player.RemoveEventById(eventId);
}
}
const openRift: player_event_on_update_zone = (event: number, player: Player) => {
// Exit player should not be here
if(!exitPlayer(player)){
player.RegisterEvent(checkAura, 60000, 11);
}
}
RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_UPDATE_ZONE, (...args) => openRift(...args));

View File

@@ -1,56 +0,0 @@
/** @ts-expect-error */
let aio: AIO = {};
if(!aio.AddAddon()) {
const myHandlers = aio.AddHandlers('AIOTest', {});
const FrameTest = CreateFrame("Frame", "FrameTest2", UIParent, "UIPanelDialogTemplate");
let frame = FrameTest;
frame.SetSize(400,300);
frame.SetMovable(true);
frame.RegisterForDrag("LeftButton");
frame.SetPoint("CENTER");
frame.EnableMouse(true);
frame.Hide();
frame.SetHyperlinksEnabled(true);
frame.SetScript("OnHyperlinkClick")
frame.SetScript("OnDragStart", frame.StartMoving);
frame.SetScript("OnHide", frame.StopMovingOrSizing);
frame.SetScript("OnDragStop", frame.StopMovingOrSizing);
let increment = -40;
frame.SetScript("OnEnter", (frame: WoWAPI.Frame) => {
if(CursorHasItem()) {
let [objectType, objectId, link] = GetCursorInfo();
const text = frame.CreateFontString('itemdragged', "OVERLAY", "GameFontHighlight");
text.SetPoint("TOPLEFT", 10,increment);
text.SetText(link);
increment = increment - 15;
}
// if(CursorHasItem()) {
// print(type);
// print(GetCursorInfo());
// print(details);
// }
// print(CursorHasItem());
});
myHandlers.ShowFrame = (player: Player) => {
frame.Show();
}
frame.Show();
}

View File

@@ -1,21 +0,0 @@
/** @ts-expect-error */
let aio: AIO = {};
const myHandlers = aio.AddHandlers('AIOTest', {});
myHandlers.print = (...args) => {
print(args);
}
const ShowWindow: player_event_on_command = (event: number,player: Player, command: string): boolean => {
if(command == 'testwin') {
aio.Handle(player, 'AIOTest', 'ShowFrame');
return false;
}
return true;
};
RegisterPlayerEvent(
PlayerEvents.PLAYER_EVENT_ON_COMMAND,
(...args) => ShowWindow(...args)
);

View File

@@ -1,31 +0,0 @@
/** @ts-expect-error */
let aio: AIO = {};
// Helper functions to create unique ids for frames and components
// const id = (name: string, entry: number = null) => `Transmog${name}` + (entry ? entry : '');
// const compId = (pageId: number, name: string) => `${botId}:BotMgr${name}`;
if(!aio.AddAddon()) {
const transmogHandlers = aio.AddHandlers('Transmog', {});
let transmogFrame: WoWAPI.Frame;
function mainFrame(player: Player) {
// Build the main frame
if(!transmogFrame) {
transmogFrame = CreateFrame("Frame", "TransmogMainFrame", UIParent, null, 1 );
transmogFrame.SetSize(550, 265);
transmogFrame.SetPoint("CENTER", UIParent, "CENTER", -100, 0);
transmogFrame.SetBackdropColor(0, 0, 0, 0.5);
// Create a dressup model
const model = CreateFrame()
}
}
transmogHandlers.ShowFrame = (player: Player) => {
mainFrame(player);
}
}

View File

@@ -1,3 +0,0 @@
/** @ts-expect-error */
let aio: AIO = {};

2873
ets.examples.combined.ts Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -217,6 +217,7 @@ function ShowSlots(player: Player) {
gamblerHandlers.StartSpin = (player: Player) => { gamblerHandlers.StartSpin = (player: Player) => {
SpinSlots(Slots, [Slot1, Slot2, Slot3]); SpinSlots(Slots, [Slot1, Slot2, Slot3]);
SendChatMessage("Started a spin", "CHANNEL", null, "7");
} }
GamblerMainFrame.Show(); GamblerMainFrame.Show();

View File

@@ -8,12 +8,12 @@ if(!aio.AddAddon()) {
const mythicPlusHandlers = aio.AddHandlers('MythicPlus', {}); const mythicPlusHandlers = aio.AddHandlers('MythicPlus', {});
const selectImages = [ const selectImages = [
"Interface/MythicPlus/mythic", "Interface/Modules/MythicPlus/Textures/mythic",
"Interface/MythicPlus/mythic-selected", "Interface/Modules/MythicPlus/Textures/mythic-selected",
"Interface/MythicPlus/legendary", "Interface/Modules/MythicPlus/Textures/legendary",
"Interface/MythicPlus/legendary-selected", "Interface/Modules/MythicPlus/Textures/legendary-selected",
"Interface/MythicPlus/ascendant", "Interface/Modules/MythicPlus/Textures/ascendant",
"Interface/MythicPlus/ascendant-selected" "Interface/Modules/MythicPlus/Textures/ascendant-selected"
]; ];
const Difficulty = { const Difficulty = {
@@ -289,14 +289,14 @@ function CreateSkullFrame(difficulty: Difficulty, title: string, imageIndex: num
PlaySound("PVPTHROUGHQUEUE"); PlaySound("PVPTHROUGHQUEUE");
if(MythicClientState.difficulty == f.GetID()) { // if(MythicClientState.difficulty == f.GetID()) {
MythicClientState.difficulty = GetDungeonDifficultyID() - 1; // MythicClientState.difficulty = GetDungeonDifficultyID() - 1;
refreshUIState(); // refreshUIState();
} else { // } else {
MythicClientState.difficulty = f.GetID(); // MythicClientState.difficulty = f.GetID();
// always assume heoric for map setting for scaling under the hood. // // always assume heoric for map setting for scaling under the hood.
SetDungeonDifficulty(2); // SetDungeonDifficulty(2);
} // }
aio.Handle("MythicPlus", "SetDifficulty", MythicClientState.difficulty); aio.Handle("MythicPlus", "SetDifficulty", MythicClientState.difficulty);
refreshUIState(); refreshUIState();
@@ -414,7 +414,51 @@ function ShowUIButton(): void {
// btnTexture.SetTexture(selectImages[0]); // btnTexture.SetTexture(selectImages[0]);
} }
ShowUIButton(); ShowUIPanel();
function AddMythicPlusMicroButton(): void {
// Attach to MicroButtonAndBagsBar or UIParent for visibility
const anchorButton = _G["HelpMicroButton"] ?? _G["SpellbookMicroButton"] ?? _G["MicroButtonAndBagsBar"] ?? UIParent;
} // Create the button using Blizzard UI conventions with TypeScript syntax
const microButton: WoWAPI.Button = CreateFrame("Button", "MythicPlusMicroButton", _G["MicroButtonAndBagsBar"] ?? UIParent);
microButton.SetSize(25, 53);
microButton.SetPoint("LEFT", anchorButton, "RIGHT", 2, 0);
microButton.SetFrameLevel(anchorButton.GetFrameLevel() + 1);
microButton.SetFrameStrata("DIALOG");
microButton.EnableMouse(true);
microButton.RegisterForClicks("LeftButtonUp", "RightButtonUp");
// Set Blizzard-style micro button textures using TypeScript API
const normalTex = microButton.CreateTexture("MythicPlusNormalTex", "BACKGROUND");
normalTex.SetTexture("Interface\\Buttons\\UI-MicroButton-Socials-Up");
normalTex.SetAllPoints();
microButton.SetNormalTexture(normalTex);
const highlightTex = microButton.CreateTexture("MythicPlusHighlightTex", "HIGHLIGHT");
highlightTex.SetTexture("Interface\\Buttons\\UI-MicroButton-Socials-Highlight");
highlightTex.SetAllPoints();
microButton.SetHighlightTexture(highlightTex);
const pushedTex = microButton.CreateTexture("MythicPlusPushedTex", "ARTWORK");
pushedTex.SetTexture("Interface\\Buttons\\UI-MicroButton-Socials-Down");
pushedTex.SetAllPoints();
microButton.SetPushedTexture(pushedTex);
microButton.SetScript("OnClick", (f: WoWAPI.Frame, button: string) => {
if(button !== "LeftButton") {
return;
}
PlaySound("GAMEDIALOGOPEN");
aio.Handle("MythicPlus", "ShowUI");
});
microButton.Show();
}
// Call this function to add the button to the Micro Menu on load
AddMythicPlusMicroButton();
}

View File

@@ -131,27 +131,27 @@ const MPStartState: player_event_on_login = (_event: number, player: Player): vo
// On login set up the mythic panel mod state for the player // On login set up the mythic panel mod state for the player
RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOGIN, (...args) => MPStartState(...args)); RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOGIN, (...args) => MPStartState(...args));
const MPGroupDisband: group_event_on_disband = (_event: number, group: Group): void => { // const MPGroupDisband: group_event_on_disband = (_event: number, group: Group): void => {
const members = group.GetMembers(); // const members = group.GetMembers();
for(let i = 0; i < members.length; i++) { // for(let i = 0; i < members.length; i++) {
_refreshState(members[i]); // _refreshState(members[i]);
aio.Handle(members[i], 'MythicPlus', 'UpdateState', StateStorage.get(members[i].GetGUIDLow())); // aio.Handle(members[i], 'MythicPlus', 'UpdateState', StateStorage.get(members[i].GetGUIDLow()));
} // }
} // }
RegisterGroupEvent(GroupEvents.GROUP_EVENT_ON_DISBAND, (...args) => MPGroupDisband(...args)); // RegisterGroupEvent(GroupEvents.GROUP_EVENT_ON_DISBAND, (...args) => MPGroupDisband(...args));
// When a leader change happens need to update the state storage for each leader to enable changes in the panel. // When a leader change happens need to update the state storage for each leader to enable changes in the panel.
const MPLeaderChange: group_event_on_leader_change = (_event: number,group: Group, leader: number, oldLeader: number): void => { // const MPLeaderChange: group_event_on_leader_change = (_event: number,group: Group, leader: number, oldLeader: number): void => {
_refreshState(GetPlayerByGUID(leader)); // _refreshState(GetPlayerByGUID(leader));
aio.Handle(GetPlayerByGUID(leader), 'MythicPlus', 'UpdateState', StateStorage.get(leader)); // aio.Handle(GetPlayerByGUID(leader), 'MythicPlus', 'UpdateState', StateStorage.get(leader));
_refreshState(GetPlayerByGUID(oldLeader)); // _refreshState(GetPlayerByGUID(oldLeader));
aio.Handle(GetPlayerByGUID(oldLeader), 'MythicPlus', 'UpdateState', StateStorage.get(oldLeader)); // aio.Handle(GetPlayerByGUID(oldLeader), 'MythicPlus', 'UpdateState', StateStorage.get(oldLeader));
} // }
RegisterGroupEvent(GroupEvents.GROUP_EVENT_ON_LEADER_CHANGE, (...args) => MPLeaderChange(...args)); // RegisterGroupEvent(GroupEvents.GROUP_EVENT_ON_LEADER_CHANGE, (...args) => MPLeaderChange(...args));
const DeletePlayerState: player_event_on_logout = (event: number, player: Player) => { const DeletePlayerState: player_event_on_logout = (event: number, player: Player) => {

17
modules/classes/group.ts Normal file
View File

@@ -0,0 +1,17 @@
export function GetGroupSize(player: Player): number {
const group = player.GetGroup();
let groupCount = 0;
if(group != undefined) {
const members = group.GetMembers();
for(let member of members) {
member.GetName();
groupCount += 1;
}
}
return groupCount;
}

View File

@@ -1,23 +0,0 @@
import { SetTrigger, GetTrigger } from "../classes/triggers";
/**
* Show the Burning Crusade moving on first login.
*
* @param event
* @param player
*/
const ShowBCMovie: player_event_on_login = (event: number, player: Player) => {
const movieShown = GetTrigger(player.GetGUIDLow(), "tbc_movie_shown");
if(movieShown === false) {
player.SendMovieStart(1);
SetTrigger({
triggerName: "tbc_movie_shown",
characterGuid: player.GetGUIDLow(),
isSet: true
});
}
}
RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOGIN,
(...args) => ShowBCMovie(...args)
);

View File

@@ -1,62 +1,163 @@
/** @ts-expect-error */ /** @ts-expect-error */
let aio: AIO = {}; let aio: AIO = {};
import { run } from "node:test";
import { GetGroupSize } from "../classes/group";
const GambleChestID = 910001; const GambleChestID = 910001;
const TrapSounds = [ const TrapSounds = [
"Sound\\Effects\\hell-no.mp3", "Sound\\Effects\\dumb.mp3",
"Sound\\Effects\\bad-to-the-bone.mp3", "Sound\\Effects\\bad-to-the-bone.mp3",
"Sound\\Effects\\shit_here_go.mp3",
"Sound\\Effects\\there_you_are.mp3",
"Sound\\Effects\\steve.mp3",
"Sound\\Effects\\end_career.mp3",
"Sound\\Effects\\fucked-up.mp3", "Sound\\Effects\\fucked-up.mp3",
"Sound\\Effects\\mission_failed.mp3",
"Sound\\Effects\\say_goodbye.mp3",
"Sound\\Effects\\emotional.mp3",
"Sound\\Effects\\laugh.mp3",
"Sound\\Effects\\trombone.mp3",
"Sound\\Effects\\win_error.mp3",
"Sound\\Effects\\brass_fail.mp3",
"Sound\\Effects\\gonna_hurt.mp3",
"Sound\\Effects\\oh_hell_no.mp3",
"Sound\\Effects\\you_die.mp3",
"Sound\\Effects\\skill_issue.mp3",
]; ];
const OpeningSounds = [ const OpeningSounds = [
"Sound\\Effects\\crab-rave.mp3", "Sound\\Effects\\crab-rave.mp3",
"Sound\\Effects\\outro-song.mp3", "Sound\\Effects\\xao.mp3",
"Sound\\Effects\\fortnite.mp3",
"Sound\\Effects\\money.mp3",
"Sound\\Effects\\name_fart.mp3",
"Sound\\Effects\\rick_roll.mp3",
"Sound\\Effects\\memento.mp3",
"Sound\\Effects\\halogen.mp3",
"Sound\\Effects\\spongebob.mp3",
"Sound\\Effects\\cotton_eye.mp3",
"Sound\\Effects\\lethal_company.mp3",
"Sound\\Effects\\senor_noche.mp3",
"Sound\\Effects\\jojo_gold.mp3",
"Sound\\Effects\\meme_credits.mp3",
"Sound\\Effects\\gas_credits.mp3",
"Sound\\Effects\\jojo_ay.mp3",
"Sound\\Effects\\evil_morty.mp3",
"Sound\\Effects\\party_music.mp3",
"Sound\\Effects\\got_that.mp3",
"Sound\\Effects\\snoop.mp3",
"Sound\\Effects\\run-away-sax.mp3", "Sound\\Effects\\run-away-sax.mp3",
"Sound\\Effects\\africa.mp3",
"Sound\\Effects\\allstar.mp3",
"Sound\\Effects\\dont-hurt-me.mp3",
"Sound\\Effects\\blowmeaway.mp3",
"Sound\\Effects\\bones.mp3",
"Sound\\Effects\\coolio.mp3",
"Sound\\Effects\\doom.mp3",
"Sound\\Effects\\dropkick.mp3",
"Sound\\Effects\\lose-yourself.mp3",
"Sound\\Effects\\gank-plank-galleon.mp3",
"Sound\\Effects\\sir-mixalot-baby-got-back.mp3",
"Sound\\Effects\\tetris.mp3",
"Sound\\Effects\\thunder.mp3",
"Sound\\Effects\\memory-remain.mp3",
"Sound\\Effects\\meglovania.mp3",
"Sound\\Effects\\halo-2.mp3",
"Sound\\Effects\\tacos.mp3",
"Sound\\Effects\\mortal-kombat.mp3",
"Sound\\Effects\\hello_its_john_cena.mp3",
]; ];
const LootGoodSound = "Sound\\Effects\\gold-coins.mp3"; const LootGoodSound = "Sound\\Effects\\gold-coins.mp3";
const LivingBombSpell = 63801; const LivingBombSpell = 63801;
const GrowSpell = 70345;
const ShrinkSpell = 71555;
const KnockUpSpell = 46014;
const DeathSpell = 7;
const CorpseExplodeSpell = 53730;
const SpinSpell = 51581;
const KnockbackSpell = 40532; // works
const LightningSpell = 36896;
const CatSpell = 23398;
// const Murloc = 49935;
const Gumbo = 42760;
const Drunk = 37591;
const FunBomb = 20547;
const Worm = 518;
const Timberling = 5666;
// const Haunted = 7056;
const LichEyes = 57889;
const FuryLich = 72350;
const FuryStorm = 62702;
// const Skelly = 24724; // broke
const ExplodeSheep = 44276;
const ExpUp = 42138;
const DrunkBarf = 67486;
const Aggro = 1;
const Venom = 24596;
// const DarkDwarf = 5268; // broke
const GotoDark = 445;
const Sacrifice = 34661;
const Cosmic = 47044;
const RedOgre = 30167;
const RunAway = 6614;
const Levitate = 31704; // broke
const Murloc = 42365;
// const Ghost = 24737; // broke
// const Mini = 13463; // broke
const RandomCostume = 24720;
const SummonDuke = 24763;
const Meteors = 45227;
const Corrupted = 24328;
const LongOpenChestSpellID = 24390; const LongOpenChestSpellID = 24390;
const BombCreature = 19896; const BombCreature = 19896;
const effectSpells = [
LightningSpell, GrowSpell, ShrinkSpell, KnockUpSpell, DeathSpell, CorpseExplodeSpell, SpinSpell, KnockbackSpell, LivingBombSpell, CatSpell, Murloc, Gumbo,Drunk,Worm, FunBomb, Timberling,
LichEyes, FuryLich, FuryStorm, ExplodeSheep, ExpUp, DrunkBarf, Aggro, Venom, GotoDark, Sacrifice, Cosmic, RedOgre, RunAway, Levitate, Murloc, RandomCostume, SummonDuke,
Meteors, Corrupted
];
// Contains which chests are trapped; // Contains which chests are trapped;
const LootTrapMap: Record<number, boolean> = {}; const LootTrapMap: Record<number, boolean> = {};
// Who won the gamblers chest.
const ChestAssignment: Record<number, number> = {};
function RollLootTrap(object: GameObject) { function RollLootTrap(object: GameObject) {
const roll = Math.floor(Math.random() * 100); const roll = Math.floor(Math.random() * 100);
// print(`Guid ${object.GetGUIDLow()}`);
// print(`Roll: ${roll}`); // TEST TRAP
if(roll > 98) { // LootTrapMap[object.GetGUIDLow()] = true;
object.AddLoot(43347, 1); // Satchel of Spoils 2% // return
if(roll > 99) {
object.AddLoot(911001, 1); // Mind Spike
LootTrapMap[object.GetGUIDLow()] = false; LootTrapMap[object.GetGUIDLow()] = false;
return; return;
} else if(roll > 89) { } else if(roll > 85) {
object.AddLoot(43346, 1); // Large Satchel of Spoils 18% // Get a random number of tokens between 1-3
const tokens = Math.floor(Math.random() * 3) + 1;
object.AddLoot(910001, tokens); // Araxia Token
LootTrapMap[object.GetGUIDLow()] = false; LootTrapMap[object.GetGUIDLow()] = false;
return; return;
} else if(roll > 82) { } else if(roll > 65) {
object.AddLoot(49294, 1); // Ashen Sack of Spoils 7% // get a random number of ancient dice between 2-5
const dice = Math.floor(Math.random() * 4) + 2;
object.AddLoot(911000, dice); // Ancient Dice
LootTrapMap[object.GetGUIDLow()] = false; LootTrapMap[object.GetGUIDLow()] = false;
return; return;
} else if(roll > 79) {
object.AddLoot(43347, 1); // Large Sack of Uldaur Spoils 3%
LootTrapMap[object.GetGUIDLow()] = false;
return;
} else if(roll > 67) {
object.AddLoot(910001, 10); // Araxia Tokens 12%
LootTrapMap[object.GetGUIDLow()] = false;
return;
} else if(roll > 55) { } else if(roll > 55) {
object.AddLoot(19182, 25); // Darkmoon Fair Tickets 12% object.AddLoot(92301, 1); // Huge Sack of Coins
LootTrapMap[object.GetGUIDLow()] = false;
return;
} else if(roll > 45) {
object.AddLoot(52005, 1); // Satchel of Helpful Goods 10%
LootTrapMap[object.GetGUIDLow()] = false;
return;
} else if(roll > 20) {
object.AddLoot(43102, 1); // Frozen Orb 25%
LootTrapMap[object.GetGUIDLow()] = false; LootTrapMap[object.GetGUIDLow()] = false;
return; return;
} else { } else {
@@ -65,46 +166,115 @@ function RollLootTrap(object: GameObject) {
} }
} }
const assignChestWinner = (go: GameObject) => {
const players = go.GetPlayersInRange(100);
if(players.length == 0) {
return;
}
const winner = players[Math.floor(Math.random() * players.length)];
ChestAssignment[go.GetGUIDLow()] = winner.GetGUIDLow();
const group: Group = winner.GetGroup();
if(group) {
const members = group.GetMembers();
for(let i = 0; i < members.length; i++) {
members[i].SendChatMessageToPlayer(ChatMsg.CHAT_MSG_RAID_BOSS_EMOTE,Language.LANG_COMMON,`${winner.GetName()} has won the Gamblers Chest!`, members[i]);
}
}
}
const onKillCreature: player_event_on_kill_creature = (event: number, killer: Player, killed: Creature) => { const onKillCreature: player_event_on_kill_creature = (event: number, killer: Player, killed: Creature) => {
const map: EMap = killed.GetMap(); const map: EMap = killed.GetMap();
return false;
if(!map.IsDungeon() && !map.IsRaid()) { if(!map.IsDungeon() && !map.IsRaid()) {
return false; return false;
} }
// if(!map.IsHeroic()) {
// return false;
// }
if(killed.GetLevel() < (killer.GetLevel() - 5)) { // Must not be solo
const groupCount = GetGroupSize(killer);
if(groupCount < 2) {
return false;
}
if(killed.GetLevel() < 83) {
// return false;
}
if(killed.GetLevel() < 3) {
return false; return false;
} }
const [x,y,z,o] = killed.GetLocation(); const [x,y,z,o] = killed.GetLocation();
let roll = Math.floor(Math.random() * 100); let roll = Math.floor(Math.random() * 100);
if(roll > 4) { if(roll > 25) {
return;
}
// if there are other gamble chests nearby don't spawn another one.
const chests = killer.GetGameObjectsInRange(10, GambleChestID);
if(chests.length > 0) {
return; return;
} }
const object = killer.SummonGameObject(GambleChestID,x,y,z+0.3,0,100); const object = killer.SummonGameObject(GambleChestID,x,y,z+0.3,0,100);
const objectHighlight = killer.SummonGameObject(146083,x,y,z+0.35,0,40); const objectHighlight = killer.SummonGameObject(146083,x,y,z+0.35,0,40);
assignChestWinner(object);
RollLootTrap(object); RollLootTrap(object);
} }
const onSpell: player_event_on_spell_cast = (event: number, player: Player, spell: Spell, skipCheck: boolean) => {
let target;
if(spell.GetEntry() == LongOpenChestSpellID) {
const go = player.GetNearestGameObject(7, GambleChestID);
if(!go || go.GetEntry() != GambleChestID) {
player.SendBroadcastMessage(`There is no Gamblers Chest nearby!`);
return false;
}
const guid = go.GetGUIDLow();
if(ChestAssignment[guid] != player.GetGUIDLow()) {
player.SendChatMessageToPlayer(ChatMsg.CHAT_MSG_RAID_BOSS_EMOTE,Language.LANG_COMMON,`You did not win this Gambler Chest!`, player);
spell.Cancel();
return true;
}
const sound = OpeningSounds[Math.floor(Math.random() * OpeningSounds.length)];
const members = player.GetGroup().GetMembers();
for(let i = 0; i < members.length; i++) {
player.SendChatMessageToPlayer(ChatMsg.CHAT_MSG_RAID_BOSS_EMOTE,Language.LANG_COMMON,`${player.GetName()} is taking a gamble!`, members[i]);
aio.Handle(members[i], 'AIOAudioPlayer', 'PlaySingleSound',sound);
}
}
return false;
};
// Handle when the chest is ready to be looted.
const onLootStateChange: gameobject_event_on_loot_state_change = (event: number, gameObject: GameObject, state: number) => { const onLootStateChange: gameobject_event_on_loot_state_change = (event: number, gameObject: GameObject, state: number) => {
if(state == 2) { if(state == 2) {
// return;
// print(`LootTrapped ${LootTrapMap[gameObject.GetGUIDLow()]}`); // print(`LootTrapped ${LootTrapMap[gameObject.GetGUIDLow()]}`);
// print(`InState GUID ${gameObject.GetGUIDLow()}`); // print(`InState GUID ${gameObject.GetGUIDLow()}`);
// if it is a trap time to do some killing! // if it is a trap time to do some killing!
if(LootTrapMap[gameObject.GetGUIDLow()] == true) { if(LootTrapMap[gameObject.GetGUIDLow()] == true) {
const creature1: Creature = <Creature>PerformIngameSpawn(1, BombCreature, gameObject.GetMapId(), gameObject.GetInstanceId(), gameObject.GetX(), gameObject.GetY(), gameObject.GetZ(),gameObject.GetO(), false, 100);
const player = gameObject.GetNearestPlayer(50); const player = gameObject.GetNearestPlayer(50);
const sound = TrapSounds[Math.floor(Math.random() * TrapSounds.length)]; const sound = TrapSounds[Math.floor(Math.random() * TrapSounds.length)];
@@ -114,13 +284,37 @@ const onLootStateChange: gameobject_event_on_loot_state_change = (event: number,
aio.Handle(player, 'AIOAudioPlayer', 'PlaySingleSound', sound); aio.Handle(player, 'AIOAudioPlayer', 'PlaySingleSound', sound);
} }
for(let i =0; i < 20; i++) { if(player.IsAlive()) {
if(player.IsAlive()) { const effect = effectSpells[Math.floor(Math.random() * effectSpells.length)];
creature1.CastSpell(player, LivingBombSpell);
if(effect == Aggro) {
const creatures = gameObject.GetCreaturesInRange(100);
for(let i = 0; i < creatures.length; i++) {
creatures[i].AddThreat(player, 1000);
creatures[i].Attack(player);
}
for(let i = 0; i < players.length; i++) {
players[i].SendChatMessageToPlayer(ChatMsg.CHAT_MSG_RAID_BOSS_EMOTE,Language.LANG_COMMON,`You have angered the creatures!`, players[i]);
}
} else {
const members = player.GetGroup().GetMembers();
for(let i = 0; i < members.length; i++) {
members[i].SendBroadcastMessage(`{player.GetName()} has triggered trap number ${effect}, hate that guy!`);
aio.Handle(members[i], 'AIOAudioPlayer', 'PlaySingleSound',sound);
}
player.CastSpell(player, effect, true);
} }
} }
creature1.DespawnOrUnsummon();
} else { } else {
const players = gameObject.GetPlayersInRange(50); const players = gameObject.GetPlayersInRange(50);
for(let i = 0; i < players.length; i++) { for(let i = 0; i < players.length; i++) {
@@ -130,7 +324,9 @@ const onLootStateChange: gameobject_event_on_loot_state_change = (event: number,
} }
gameObject.RemoveEventById(event); gameObject.RemoveEventById(event);
gameObject.Despawn();
gameObject.SetLootState(0);
} }
}; };
@@ -140,18 +336,57 @@ RegisterGameObjectEvent(GambleChestID,GameObjectEvents.GAMEOBJECT_EVENT_ON_LOOT_
// Register Kill Event for Mystery Chest Pop // Register Kill Event for Mystery Chest Pop
RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_KILL_CREATURE, (...args) => onKillCreature(...args)); RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_KILL_CREATURE, (...args) => onKillCreature(...args));
// Validate player can open chest and play opening sound.
RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_SPELL_CAST, (...args) => onSpell(...args));
const Growers = new Map<number, number>();
const onSpell: player_event_on_spell_cast = (event: number, player: Player, spell: Spell, skipCheck: boolean) => { const CheckGrowthDeath: map_event_on_update = (event: number, map: EMap, diff: number) => {
// Implementation const team1players = map.GetPlayers(1);
const gameObjects = player.GetGameObjectsInRange(10, GambleChestID); const team2players = map.GetPlayers(0);
if(gameObjects.length > 0) {
if(spell.GetEntry() == LongOpenChestSpellID) { // combine team1 and team2 players
const sound = OpeningSounds[Math.floor(Math.random() * OpeningSounds.length)]; const allPlayers = team1players.concat(team2players);
aio.Handle(player, 'AIOAudioPlayer', 'PlaySingleSound',sound);
for(let i = 0; i < allPlayers.length; i++) {
const player = allPlayers[i];
if(player.HasAura(GrowSpell)) {
if(!Growers.has(player.GetGUIDLow())) {
Growers.set(player.GetGUIDLow(),diff);
} else {
let lastTime = Growers.get(player.GetGUIDLow());
if(lastTime + diff > 75000 && lastTime + diff < 10500) {
player.CastSpell(player, 51874, true);
} else if(lastTime + diff > 70500 && lastTime + diff < 30600) {
let groupies = player.GetGroup().GetMembers();
for(let i = 0; i < groupies.length; i++) {
groupies[i].SendChatMessageToPlayer(ChatMsg.CHAT_MSG_RAID_BOSS_EMOTE,Language.LANG_COMMON,`${player.GetName()} is going to explode!`, groupies[i]);
}
Growers.set(player.GetGUIDLow(),lastTime + diff);
} else if(lastTime + diff > 77000) {
let group = player.GetPlayersInRange(50);
for(let i = 0; i < group.length; i++) {
player.Kill(group[i], false);
}
player.Kill(player, false);
player.RemoveAura(GrowSpell);
Growers.delete(player.GetGUIDLow());
} else {
Growers.set(player.GetGUIDLow(),lastTime + diff);
}
}
} }
} }
};
// Register
RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_SPELL_CAST, (...args) => onSpell(...args)); }
// Register Map Event on Update
RegisterServerEvent(ServerEvents.MAP_EVENT_ON_UPDATE, (...args) => CheckGrowthDeath(...args));

25
modules/gm/play-leeroy.ts Normal file
View File

@@ -0,0 +1,25 @@
/** @ts-expect-error */
let aio: AIO = {};
const onChat: player_event_on_chat = (event: number, player: Player, msg: string, type: ChatMsg, lang: Language): string | boolean => {
if(msg.includes("leeroy")) {
const members = player.GetGroup().GetMembers();
for(let i = 0; i < members.length; i++) {
aio.Handle(members[i], 'AIOAudioPlayer', 'PlaySingleSound', "Sound\\Effects\\leroy.swf.mp3");
}
print("lerrrooooooy jenkins")
aio.Handle(player, 'AIOAudioPlayer', 'PlaySingleSound', "Sound\\Effects\\leroy.swf.mp3");
}
return ''
}
RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_CHAT,(...args) => onChat(...args))

View File

@@ -0,0 +1,126 @@
// let aio: AIO = {};
// if(!aio.AddAddon()) {
// const myFrame = CreateFrame("Frame", "MythicEventListener", UIParent);
// myFrame.RegisterEvent("CHAT_MSG_ADDON");
// myFrame.SetScript("OnEvent", (frame, event, ...args) => {
// if(event === "CHAT_MSG_ADDON") {
// // Ensure args is treated as an array
// const argsArray = [...args];
// // Explicitly destructure the arguments
// const prefix = argsArray[0];
// const message = argsArray[1];
// const channel = argsArray[2];
// const sender = argsArray[3];
// if(prefix === "MPUi") {
// print(` >>>>> MPUI Mythic+ Message received from ${sender} on channel ${channel}: ${message}`);
// } else {
// print(`Addon Message received from ${sender} on channel ${channel} with prefix ${prefix}: ${message}`);
// }
// }
// });
// }
// const TestHiddenChannel: player_event_on_chat = (event: number, player: Player, msg: string, Type: ChatMsg, lang: Language): string | boolean => {
// if(msg.includes("#debug")) {
// player.SendAddonMessage("MpUi", "Sending Addon Message from Client 7", 7, player);
// player.SendAddonMessage("MpUi", "Sending Addon Message from Client 0", 0, player);
// player.SendAddonMessage("MpUi", "Sending Addon Message from Client 17", 17, player);
// PrintInfo(`Player ${player.GetName()} sent a hidden message to channel MpUi`);
// // const message = "hidden message sent to channel 100";
// // const chatTag = player.GetChatTag();
// // let size = 35 + message.length;
// /*
// std::string prefix = Eluna::CHECKVAL<std::string>(L, 2);
// std::string message = Eluna::CHECKVAL<std::string>(L, 3);
// uint8 channel = Eluna::CHECKVAL<uint8>(L, 4);
// Player* receiver = Eluna::CHECKOBJ<Player>(L, 5);
// std::string fullmsg = prefix + "\t" + message;/script
// WorldPacket data(SMSG_MESSAGECHAT, 100);
// data << uint8(channel);
// data << int32(LANG_ADDON);
// data << player->GET_GUID();
// #ifndef CLASSIC
// data << uint32(0);
// data << receiver->GET_GUID();
// #endif
// data << uint32(fullmsg.length() + 1);
// data << fullmsg;
// data << uint8(0);
// #ifdef CMANGOS*/
// const message = "Hello from a packet test"
// const chatPacket = CreatePacket(0x096,100);
// chatPacket.WriteUByte(ChatMsg.CHAT_MSG_WHISPER);
// chatPacket.WriteULong(Language.LANG_ADDON);
// chatPacket.WriteGUID(player.GetGUID());
// chatPacket.WriteULong(0);
// chatPacket.WriteGUID(player.GetGUID());
// chatPacket.WriteULong(message.length + 1);
// chatPacket.WriteString(message);
// chatPacket.WriteUByte(0);
// player.SendPacket(chatPacket, true);
// // player.SendAddonMessage("DebugTest", "hidden message sent to channel 100", 100, player);
// }
// return 'hidden message sent to channel 100';
// };
// // Register
// RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_CHAT, (...args) => TestHiddenChannel(...args));
// const PlayerListenChannel: player_event_on_channel_chat = (event: number, player: Player, msg: string, Type: ChatMsg, lang: Language, channel: number): string | boolean => {
// PrintInfo(`Player ${player.GetName()} sent a message to channel ${channel} with the message: ${msg}`);
// return true; // Return false to block the message, or return true to allow the message;
// };
// // Register
// RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_CHANNEL_CHAT, (...args) => PlayerListenChannel(...args));
// const TestDoAddon: player_event_on_spell_cast = (event: number, player: Player, spell: Spell, skipCheck: boolean) => {
// // Implementation
// PrintInfo("Player " + player.GetName() + " cast spell " + spell.GetEntry());
// const message = "Hello from a packet test"
// const chatPacket = CreatePacket(0x096,100);
// chatPacket.WriteUByte(ChatMsg.CHAT_MSG_SAY);
// chatPacket.WriteULong(Language.LANG_UNIVERSAL);
// chatPacket.WriteGUID(player.GetGUID());
// chatPacket.WriteULong(0);
// chatPacket.WriteGUID(player.GetGUID());
// chatPacket.WriteULong(message.length + 1);
// chatPacket.WriteString(message);
// chatPacket.WriteUByte(0);
// player.SendPacket(chatPacket, false);
// player.SendAddonMessage("MpUi", "Sending Addon Message from Client 7", 7, player);
// player.SendAddonMessage("MpUi", "Sending Addon Message from Client 0", 0, player);
// player.SendAddonMessage("MpUi", "Sending Addon Message from Client 17", 17, player);
// };
// // Register
// RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_SPELL_CAST, (...args) => TestDoAddon(...args));

View File

@@ -5,9 +5,73 @@ import { PlayerStats, StatEvents } from "../classes/stats";
*/ */
const TOKEN_ROLL_CHANCE = 5; const TOKEN_ROLL_CHANCE = 5;
const NORMAL_ROLL_CHANCE = 5; const NORMAL_ROLL_CHANCE = 5;
const TOKEN_ROLL_CAP = 2000; const TOKEN_ROLL_CAP = 1500;
const TOKEN_GROUP_SIZE = 2; const TOKEN_GROUP_SIZE = 2;
const bosses = {
11520: true, // Taragaman the Hungerer (Ragefire Chasm)
3654: true, // Mutanus the Devourer (Wailing Caverns)
639: true, // Edwin VanCleef (The Deadmines)
4275: true, // Archmage Arugal (Shadowfang Keep)
4829: true, // Aku'mai (Blackfathom Deeps)
1716: true, // Bazil Thredd (Stormwind Stockade)
7800: true, // Mekgineer Thermaplugg (Gnomeregan)
4421: true, // Charlga Razorflank (Razorfen Kraul)
4543: true, // Bloodmage Thalnos (Scarlet Monastery Graveyard)
6487: true, // Arcanist Doan (Scarlet Monastery Library)
3975: true, // Herod (Scarlet Monastery Armory)
3977: true, // High Inquisitor Whitemane (Scarlet Monastery Cathedral)
7358: true, // Amnennar the Coldbringer (Razorfen Downs)
2748: true, // Archaedas (Uldaman)
7267: true, // Chief Ukorz Sandscalp (Zul'Farrak)
12201: true, // Princess Theradras (Maraudon)
8443: true, // Avatar of Hakkar (Sunken Temple)
9019: true, // Emperor Dagran Thaurissan (Blackrock Depths)
9568: true, // Overlord Wyrmthalak (Lower Blackrock Spire)
10363: true, // General Drakkisath (Upper Blackrock Spire)
11492: true, // Alzzin the Wildshaper (Dire Maul East)
11489: true, // Tendris Warpwood (Dire Maul West)
11501: true, // King Gordok (Dire Maul North)
10440: true, // Baron Rivendare (Stratholme Undead Side)
10813: true, // Balnazzar (Stratholme Live Side)
1853: true, // Darkmaster Gandling (Scholomance)
17307: true, // Vazruden (Hellfire Ramparts)
17536: true, // Nazan (Hellfire Ramparts)
17377: true, // Keli'dan the Breaker (The Blood Furnace)
16808: true, // Warchief Kargath Bladefist (The Shattered Halls)
17942: true, // Quagmirran (The Slave Pens)
17826: true, // Swamplord Musel'ek (The Underbog)
17798: true, // Warlord Kalithresh (The Steamvault)
18344: true, // Nexus-Prince Shaffar (Mana-Tombs)
18373: true, // Exarch Maladaar (Auchenai Crypts)
18473: true, // Talon King Ikiss (Sethekk Halls)
18708: true, // Murmur (Shadow Labyrinth)
19220: true, // Pathaleon the Calculator (The Mechanar)
17977: true, // Warp Splinter (The Botanica)
20912: true, // Harbinger Skyriss (The Arcatraz)
17881: true, // Aeonus (The Black Morass)
18096: true, // Epoch Hunter (Old Hillsbrad Foothills)
24664: true, // Kael'thas Sunstrider (Magisters' Terrace)
23954: true, // Ingvar the Plunderer (Utgarde Keep)
26723: true, // Keristrasza (The Nexus)
29120: true, // Anub'arak (Azjol-Nerub)
29311: true, // Herald Volazj (Ahn'kahet: The Old Kingdom)
26632: true, // The Prophet Tharon'ja (Drak'Tharon Keep)
31134: true, // Cyanigosa (Violet Hold)
29306: true, // Gal'darah (Gundrak)
27978: true, // Sjonnir the Ironshaper (Halls of Stone)
28923: true, // Loken (Halls of Lightning)
27656: true, // Ley-Guardian Eregos (The Oculus)
26533: true, // Mal'Ganis (Culling of Stratholme)
26861: true, // King Ymiron (Utgarde Pinnacle)
35451: true, // The Black Knight (Trial of the Champion)
36502: true, // Devourer of Souls (Forge of Souls)
36658: true, // Scourgelord Tyrannus (Pit of Saron)
37226: true, // The Lich King (Halls of Reflection)
};
const createChest = (player: Player, creature: Creature, direction: string): void => { const createChest = (player: Player, creature: Creature, direction: string): void => {
const [x,y,z,o] = creature.GetLocation(); const [x,y,z,o] = creature.GetLocation();
@@ -106,12 +170,15 @@ const TokenKillEvent: player_event_on_kill_creature = (event: number, player: Pl
} }
let chestShown = false;
PrintDebug(`Player: ${player.GetName()} Roll: ${roll} Roll Modifer: ${rollModifer} Chance: ${rollModifer}`) PrintDebug(`Player: ${player.GetName()} Roll: ${roll} Roll Modifer: ${rollModifer} Chance: ${rollModifer}`)
if(roll <= rollModifer) { if(roll <= rollModifer) {
createChest(player, creature, 'center'); createChest(player, creature, 'center');
createChest(player, creature, 'left'); // createChest(player, creature, 'left');
chestShown = true;
// Add player stat they created token // Add player stat they created token
const pStats = new PlayerStats(player); const pStats = new PlayerStats(player);
@@ -119,18 +186,25 @@ const TokenKillEvent: player_event_on_kill_creature = (event: number, player: Pl
pStats.save(); pStats.save();
} }
if (bosses[creature.GetEntry()]) {
createChest(player, creature, 'right');
}
// if it is a larger group roll again! // if it is a larger group roll again!
if(groupCount >= TOKEN_GROUP_SIZE) { // if(groupCount >= TOKEN_GROUP_SIZE) {
if(creature.IsWorldBoss() || creature.IsDungeonBoss()) { // if(creature.IsDungeonBoss()) {
roll = Math.floor(Math.random() * TOKEN_ROLL_CAP); // roll = Math.floor(Math.random() * TOKEN_ROLL_CAP);
if(roll <= rollModifer+100 ) { // if(roll <= rollModifer+100 ) {
createChest(player, creature,'right'); // createChest(player, creature,'right');
} // }
} // }
} // }
} }
RegisterPlayerEvent( RegisterPlayerEvent(
PlayerEvents.PLAYER_EVENT_ON_KILL_CREATURE, PlayerEvents.PLAYER_EVENT_ON_KILL_CREATURE,
(...args) => TokenKillEvent(...args) (...args) => TokenKillEvent(...args)
); );

919
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -5,18 +5,22 @@
"dev": "npm run clean && ets build && npm run dev-copy", "dev": "npm run clean && ets build && npm run dev-copy",
"dev-copy": "dotenv -e ets.env cross-var ncp %ETS_BUILD_ROOT% %DEV_MODULE_PATH%", "dev-copy": "dotenv -e ets.env cross-var ncp %ETS_BUILD_ROOT% %DEV_MODULE_PATH%",
"dev:watch": "ets build -w", "dev:watch": "ets build -w",
"deploy:dev": "npm run build && npx ets deploy -e dev" "deploy:dev": "npm run clean && ets build && npx ets deploy -e dev",
"deploy:prod": "npm run clean && ets build && npx ets deploy -e prod",
"reload-eluna": "./scripts/reload-eluna.exp",
"watch:dev": "nodemon --watch modules --ext ts --ignore node_modules/ --exec \"npm run deploy:dev && npm run reload-eluna\""
}, },
"devDependencies": { "devDependencies": {
"cross-var": "^1.1.0", "cross-var": "^1.1.0",
"dotenv-cli": "^7.3.0", "dotenv-cli": "^7.3.0",
"nodemon": "^3.1.9",
"rimraf": "^5.0.5", "rimraf": "^5.0.5",
"typescript": "^5.2.2", "typescript": "^5.2.2",
"typescript-to-lua": "^1.23.0" "typescript-to-lua": "^1.23.0"
}, },
"dependencies": { "dependencies": {
"@types/fs-extra": "^11.0.4", "@types/fs-extra": "^11.0.4",
"@types/node": "^20.11.15", "@types/node": "^20.11.15",
"fs-extra": "^11.2.0", "fs-extra": "^11.2.0",
"ts-node": "^10.9.1", "ts-node": "^10.9.1",
"wow-eluna-ts-module": "^1.9.3" "wow-eluna-ts-module": "^1.9.3"

7
scripts/reload-eluna.exp Executable file
View File

@@ -0,0 +1,7 @@
#!/usr/bin/expect -f
spawn docker attach ac-worldserver
expect ">"
send ".reload eluna\r"
sleep 1
send "\x10\x11"
expect eof

View File

@@ -26,7 +26,7 @@
"rootDir": "modules" "rootDir": "modules"
}, },
"include": [ "include": [
"modules/**/*.ts", "modules/**/*.ts", "development/tbc-launch.ts",
], ],
"exclude": [ "exclude": [
"node_modules", "node_modules",