mirror of
https://github.com/araxiaonline/ets-module-collection.git
synced 2026-06-13 02:52:20 -04:00
latest changes on botequipment
This commit is contained in:
@@ -1,5 +1,10 @@
|
||||
import { BotData } from './botmgr.server';
|
||||
import { Equipment } from './botmgr.server';
|
||||
|
||||
/**
|
||||
* This is the UI bot data manager class to make it easier
|
||||
* to managed bot data in the UI.
|
||||
*/
|
||||
export class BotStorage {
|
||||
|
||||
private storage: Map<number, BotData> = new Map();
|
||||
@@ -9,7 +14,7 @@ export class BotStorage {
|
||||
return this.storage.get(entry);
|
||||
}
|
||||
|
||||
GetBotItem(botId: number, slot: BotEquipmentSlotNum): number | undefined {
|
||||
GetBotItem(botId: number, slot: BotEquipmentSlotNum): Equipment | undefined {
|
||||
const bot = this.GetBotData(botId);
|
||||
if(bot) {
|
||||
return bot.equipment[slot];
|
||||
@@ -20,7 +25,7 @@ export class BotStorage {
|
||||
|
||||
}
|
||||
|
||||
SetBotItem(botId: number, slot: BotEquipmentSlotNum, item: number): void {
|
||||
SetBotItem(botId: number, slot: BotEquipmentSlotNum, item: Equipment): void {
|
||||
const bot = this.GetBotData(botId);
|
||||
if(bot) {
|
||||
bot.equipment[slot] = item;
|
||||
|
||||
78
modules/UI/botmgr/botUnit.ts
Normal file
78
modules/UI/botmgr/botUnit.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
import * as Common from '../../constants/idmaps';
|
||||
import { Equipment, EquipmentList } from './botmgr.server';
|
||||
|
||||
type CharInfo = {
|
||||
name: string,
|
||||
level: number,
|
||||
className: Common.CharacterClass,
|
||||
classId: keyof typeof Common.ClassesMapping,
|
||||
raceName: Common.CharacterRace,
|
||||
raceId: keyof typeof Common.RacesMapping
|
||||
}
|
||||
|
||||
type CharStats = Record<keyof typeof Common.BotStat, number>;
|
||||
type CharTalentSpec = typeof Common.BotTalentSpecs[keyof typeof Common.BotTalentSpecs];
|
||||
type CharRoles = typeof Common.BotRoles[keyof typeof Common.BotRoles];
|
||||
|
||||
export class BotUnit {
|
||||
|
||||
protected myself: Creature;
|
||||
protected myOwner: Player;
|
||||
protected charinfo: CharInfo;
|
||||
protected equipment: EquipmentList;
|
||||
protected stats: CharStats;
|
||||
protected talentSpecId: CharTalentSpec;
|
||||
protected roles: CharRoles;
|
||||
|
||||
constructor(creature: Creature) {
|
||||
if(!creature.IsNPCBot()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.myself = creature;
|
||||
this.myOwner = <Player>creature.GetOwner();
|
||||
this.charinfo = {
|
||||
name: creature.GetName(),
|
||||
level: creature.GetLevel(),
|
||||
className: Common.ClassesMapping[creature.GetClass()],
|
||||
classId: creature.GetClass(),
|
||||
raceName: Common.RacesMapping[creature.GetRace()],
|
||||
raceId: creature.GetRace()
|
||||
};
|
||||
this.equipment = this._lookupEquipment();
|
||||
this.roles = creature.GetBotRoles();
|
||||
|
||||
}
|
||||
|
||||
// public isMeleeDps(): boolean {
|
||||
// const meleeClassMap = [
|
||||
// Common.Characte
|
||||
|
||||
// ]
|
||||
|
||||
// if(this.charinfo.classId)
|
||||
|
||||
// // return this.roles === Common.BotRoles.MeleeDps;
|
||||
// }
|
||||
|
||||
private _lookupEquipment(): EquipmentList {
|
||||
const myEquipment = {} as EquipmentList;
|
||||
for(let slot=0; slot <= Common.BotEquipLast; slot++) {
|
||||
const equipment = this.myself.GetBotEquipment(<BotEquipmentSlotNum>slot);
|
||||
|
||||
if(equipment) {
|
||||
myEquipment[slot] = {
|
||||
entry: equipment.GetEntry(),
|
||||
link: equipment.GetItemLink(),
|
||||
quality: <Common.QualityType>equipment.GetQuality(),
|
||||
itemLevel: equipment.GetItemLevel(),
|
||||
enchantmentId: equipment.GetEnchantmentId(0), // Only the permenant enchantments
|
||||
}
|
||||
} else {
|
||||
myEquipment[slot] = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
return myEquipment;
|
||||
}
|
||||
}
|
||||
@@ -19,12 +19,11 @@ let aio: AIO = {};
|
||||
*/
|
||||
|
||||
|
||||
import { UIInvSlot, BotEquipSlot, BotSlotName } from "../../constants/idmaps";
|
||||
import { BotData } from "./botmgr.server";
|
||||
import { UIInvSlot, BotEquipSlot, BotSlotName, BotStat } from "../../constants/idmaps";
|
||||
import { BotData, Equipment } from "./botmgr.server";
|
||||
import { BotStorage } from "./bot";
|
||||
|
||||
|
||||
|
||||
// Helper functions to create unique ids for frames and components
|
||||
const id = (name: string, entry: number = null) => `BotMgr${name}` + (entry ? entry : '');
|
||||
const compId = (botId: number, name: string) => `${botId}:BotMgr${name}`;
|
||||
|
||||
@@ -42,7 +41,6 @@ function ucase(input: string): string {
|
||||
return firstLetter + restOfTheString;
|
||||
}
|
||||
|
||||
|
||||
// If we are a client file. aio.AddAddon() will return false and this file will be serialized and sent to client.
|
||||
if(!aio.AddAddon()) {
|
||||
|
||||
@@ -50,7 +48,6 @@ if(!aio.AddAddon()) {
|
||||
const InfoFramePool: Map<number, WoWAPI.Frame> = new Map();
|
||||
const ComponentsPool: Map<string, unknown> = new Map(); // key botId + ":" + componentid
|
||||
const botStorage: BotStorage = new BotStorage();
|
||||
|
||||
|
||||
let BotItemTooltip: WoWAPI.GameTooltip;
|
||||
|
||||
@@ -65,7 +62,6 @@ if(!aio.AddAddon()) {
|
||||
resistFrame.SetSize(32, 160);
|
||||
resistFrame.SetPoint("TOPRIGHT", parent, "TOPLEFT", 297, -77);
|
||||
|
||||
|
||||
const magicRes1 = CreateFrame("Frame", id("MagicResFrame1"), resistFrame, "MagicResistanceFrameTemplate", 6);
|
||||
magicRes1.SetPoint("TOP", resistFrame, "TOP", 0, 0);
|
||||
magicRes1.SetSize(32, 32);
|
||||
@@ -82,7 +78,7 @@ if(!aio.AddAddon()) {
|
||||
|
||||
/**
|
||||
* This is for the Characters left picture and class,race, name details.
|
||||
* Only created once.
|
||||
* Only created once per bot panel.
|
||||
*/
|
||||
function AddPortrait(parent: WoWAPI.Frame, botData: BotData) {
|
||||
const portrait = parent.CreateTexture(id("Portrait", botData.entry), "ARTWORK");
|
||||
@@ -122,14 +118,16 @@ if(!aio.AddAddon()) {
|
||||
infoTextFont.SetPoint("CENTER",0,0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
function AddCharacterModel(parent: WoWAPI.Frame, botData: BotData) {
|
||||
const frameChar = CreateFrame("PlayerModel", id("ModelFrame", botData.entry), parent, null, botData.entry);
|
||||
frameChar.SetPoint("TOP", -5, -82);
|
||||
frameChar.SetSize(240, 160);
|
||||
frameChar.SetSize(240, 175);
|
||||
frameChar.SetUnit("target");
|
||||
frameChar.SetFacing(0.3);
|
||||
frameChar.SetFrameStrata("MEDIUM");
|
||||
frameChar.SetFacing(0.3);
|
||||
frameChar.SetAlpha(0.65);
|
||||
frameChar.SetGlow(0.9);
|
||||
frameChar.SetFrameStrata("MEDIUM");
|
||||
}
|
||||
|
||||
function UpdateEquipFrame(group: 'left' | 'right' | 'weapons', parent: WoWAPI.Frame, botData: BotData) {
|
||||
@@ -156,12 +154,13 @@ if(!aio.AddAddon()) {
|
||||
equipSlot.SetPoint("TOPLEFT", i*40+1, 0);
|
||||
else
|
||||
equipSlot.SetPoint("TOPLEFT", 0, -i*40-1);
|
||||
|
||||
equipSlot.SetSize(40, 40);
|
||||
equipSlot.SetScript("OnEnter", ItemSlotOnEnter);
|
||||
equipSlot.SetScript("OnLeave", ItemSlotOnLeave);
|
||||
equipSlot.SetScript("OnClick", ItemSlotOnClick);
|
||||
|
||||
const equippedItemId = botData.equipment[slotOrder[i]];
|
||||
const equippedItem: Equipment = botData.equipment[slotOrder[i]];
|
||||
let itemIcon: WoWAPI.TexturePath;
|
||||
let itemId: number;
|
||||
let idsuffix: string | number;
|
||||
@@ -174,13 +173,13 @@ if(!aio.AddAddon()) {
|
||||
}
|
||||
|
||||
// If we have a piece of equipment add the icon template
|
||||
if(equippedItemId && equippedItemId > 0) {
|
||||
itemIcon = GetItemIcon(equippedItemId);
|
||||
if(equippedItem && equippedItem.entry > 0) {
|
||||
itemIcon = GetItemIcon(equippedItem.entry);
|
||||
idsuffix = slotOrder[i];
|
||||
}
|
||||
|
||||
// If there is not a piece of equipment add the background texture
|
||||
if(!equippedItemId && slotOrder[i] > 0) {
|
||||
if(!equippedItem && slotOrder[i] > 0) {
|
||||
let slotName = BotSlotName[slotOrder[i]];
|
||||
|
||||
if(slotOrder[i] === BotEquipSlot.FINGER1) slotName = "FINGER0";
|
||||
@@ -196,11 +195,11 @@ if(!aio.AddAddon()) {
|
||||
const itemTexture = equipSlot.CreateTexture(id(`ItemTexture-${idsuffix}`), "OVERLAY");
|
||||
itemTexture.SetTexture(itemIcon);
|
||||
itemTexture.SetPoint("CENTER", 0, 0);
|
||||
itemTexture.SetSize(36,36);
|
||||
itemTexture.SetSize(36,36);
|
||||
ComponentsPool.set(compId(botData.entry, `ItemSlotTexture-${itemSlotId}`), itemTexture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function AddEquipmentFrames(parent: WoWAPI.Frame, botData: BotData) {
|
||||
|
||||
// Get all our frames
|
||||
@@ -215,7 +214,7 @@ if(!aio.AddAddon()) {
|
||||
equipFrame = CreateFrame("Frame", id("LeftEquipment"), parent, null, 1);
|
||||
equipFrame.SetPoint("TOPLEFT", 20, -73);
|
||||
equipFrame.SetSize(40, 330);
|
||||
UpdateEquipFrame('left', equipFrame, botData);
|
||||
UpdateEquipFrame('left', equipFrame, botData);
|
||||
ComponentsPool.set(compId(botData.entry, "LeftEquipment"), equipFrame);
|
||||
|
||||
}
|
||||
@@ -225,7 +224,7 @@ if(!aio.AddAddon()) {
|
||||
equipFrame.SetPoint("TOPRIGHT", -40, -73);
|
||||
equipFrame.SetSize(40, 330);
|
||||
ComponentsPool.set(compId(botData.entry, "RightEquipment"), equipFrame);
|
||||
UpdateEquipFrame('right', equipFrame, botData);
|
||||
UpdateEquipFrame('right', equipFrame, botData);
|
||||
|
||||
}
|
||||
|
||||
@@ -239,8 +238,68 @@ if(!aio.AddAddon()) {
|
||||
// placeholder.SetAllPoints(equipFrame);
|
||||
// placeholder.SetTexture(0,0,0,0.8);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function CreateStats(parent: WoWAPI.Frame, botData: BotData) {
|
||||
|
||||
const reverseObject = (obj: { [key: string]: any }): { [key: string]: string } =>
|
||||
Object.fromEntries(Object.entries(obj).map(([k, v]) => [v, k]));
|
||||
const lookup = reverseObject(BotStat);
|
||||
|
||||
|
||||
|
||||
const statsFrame = CreateFrame("Frame", id("CharacterAttr"), parent, null, 1);
|
||||
statsFrame.SetSize(230,78);
|
||||
statsFrame.SetPoint("TOPLEFT", 67, -231);
|
||||
statsFrame.SetFrameStrata("HIGH");
|
||||
statsFrame.SetAlpha(1.0);
|
||||
statsFrame.SetBackdropColor(0,0,0,1.0);
|
||||
|
||||
const leftTop = statsFrame.CreateTexture(id("StatLeftTop"), "BACKGROUND");
|
||||
leftTop.SetTexture("Interface\\PaperDollInfoFrame\\UI-Character-StatBackground");
|
||||
leftTop.SetSize(115,16);
|
||||
leftTop.SetPoint("TOPLEFT", 0, 0);
|
||||
leftTop.SetTexCoord(0, 0.8984375, 0, 0.125);
|
||||
|
||||
const leftmiddle = statsFrame.CreateTexture(id("StatLeftMiddle"), "BACKGROUND");
|
||||
leftmiddle.SetTexture("Interface\\PaperDollInfoFrame\\UI-Character-StatBackground");
|
||||
leftmiddle.SetSize(115,113);
|
||||
leftmiddle.SetPoint("TOPLEFT", leftTop, "BOTTOMLEFT", 0, 0);
|
||||
leftmiddle.SetTexCoord(0, 0.8984375, 0.125, 0.1953125);
|
||||
|
||||
const leftBottom = statsFrame.CreateTexture(id("StatLeftBottom"), "BACKGROUND");
|
||||
leftBottom.SetTexture("Interface\\PaperDollInfoFrame\\UI-Character-StatBackground");
|
||||
leftBottom.SetSize(115,16);
|
||||
leftBottom.SetPoint("TOPLEFT", leftmiddle, "BOTTOMLEFT", 0, 0);
|
||||
leftBottom.SetTexCoord(0, 0.8984375, 0.484375, 0.609375);
|
||||
|
||||
const rightTop = statsFrame.CreateTexture(id("StatRightTop"), "BACKGROUND");
|
||||
rightTop.SetTexture("Interface\\PaperDollInfoFrame\\UI-Character-StatBackground");
|
||||
rightTop.SetSize(115,16);
|
||||
rightTop.SetPoint("TOPLEFT", leftTop, "TOPRIGHT",0, 0);
|
||||
rightTop.SetTexCoord(0, 0.8984375, 0, 0.125);
|
||||
|
||||
const rightMiddle = statsFrame.CreateTexture(id("StatRightMiddle"), "BACKGROUND");
|
||||
rightMiddle.SetTexture("Interface\\PaperDollInfoFrame\\UI-Character-StatBackground");
|
||||
rightMiddle.SetSize(115,113);
|
||||
rightMiddle.SetPoint("TOPLEFT", leftmiddle, "TOPRIGHT", 0, 0);
|
||||
rightMiddle.SetTexCoord(0, 0.8984375, 0.125, 0.1953125);
|
||||
|
||||
const rightBottom = statsFrame.CreateTexture(id("StatRightBottom"), "BACKGROUND");
|
||||
rightBottom.SetTexture("Interface\\PaperDollInfoFrame\\UI-Character-StatBackground");
|
||||
rightBottom.SetSize(115,16);
|
||||
rightBottom.SetPoint("TOPLEFT", leftBottom, "TOPRIGHT", 0, 0);
|
||||
rightBottom.SetTexCoord(0, 0.8984375, 0.484375, 0.609375);
|
||||
|
||||
let counter = 0;
|
||||
// for(const stats in botData.stats.left) {
|
||||
// const stat = statsFrame.CreateFontString(id(`Stat-${stats}`), "ARTWORK", "GameFontNormalSmall");
|
||||
// stat.SetPoint("TOPLEFT", statsFrame, "TOPLEFT", 10, -10 - (counter * 14));
|
||||
// stat.SetText(lookup[stats] + " " + botData.stats[stats]);
|
||||
// counter++;
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
function SetBackground(parent: WoWAPI.Frame) {
|
||||
@@ -286,12 +345,16 @@ if(!aio.AddAddon()) {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* START OF EVENT HANDLERS
|
||||
*/
|
||||
|
||||
function ItemSlotOnEnter(frame: WoWAPI.Button) {
|
||||
const botId = botStorage.GetActive();
|
||||
const itemId = botStorage.GetBotItem(botId, <BotEquipmentSlotNum>frame.GetID());
|
||||
const theItem = botStorage.GetBotItem(botId, <BotEquipmentSlotNum>frame.GetID());
|
||||
GameTooltip.SetOwner(frame, "ANCHOR_RIGHT");
|
||||
if(itemId) {
|
||||
GameTooltip.SetHyperlink(`item:${itemId}:0:0:0:0:0:0:0`);
|
||||
if(theItem) {
|
||||
GameTooltip.SetHyperlink(theItem.link);
|
||||
} else {
|
||||
if(frame.GetID() == 90) {
|
||||
GameTooltip.SetText("Tabard");
|
||||
@@ -325,14 +388,14 @@ if(!aio.AddAddon()) {
|
||||
|
||||
function ItemSlotOnClick(frame: WoWAPI.Button, button: string) {
|
||||
const botId = botStorage.GetActive();
|
||||
const itemId = botStorage.GetBotItem(botId, <BotEquipmentSlotNum>frame.GetID());
|
||||
const theItem = botStorage.GetBotItem(botId, <BotEquipmentSlotNum>frame.GetID());
|
||||
|
||||
const [compItem, compItemId, compItemLink] = GetCursorInfo();
|
||||
print(`CursorHasItem: ${compItemLink}`);
|
||||
|
||||
if(itemId && !compItem) {
|
||||
if(theItem && !compItem) {
|
||||
if(button == "LeftButton") {
|
||||
PickupItem(itemId);
|
||||
PickupItem(theItem.link);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -340,21 +403,29 @@ if(!aio.AddAddon()) {
|
||||
if(compItem) {
|
||||
const slot = frame.GetID();
|
||||
|
||||
aio.Handle("BotMgr", "EquipItem",botId, slot, compItemId);
|
||||
aio.Handle("BotMgr", "EquipTheItem", GetUnitName("player", false), botId, slot, compItemId, compItemLink);
|
||||
// Attempt to equip the item.
|
||||
PlaySound("INTERFACESOUND_CURSORDROPOBJECT");
|
||||
ClearCursor();
|
||||
}
|
||||
|
||||
|
||||
// else {
|
||||
// if(CursorHasItem()) {
|
||||
// const [compItem, compItemId, compItemLink] = GetCursorInfo();
|
||||
// botStorage.EquipBotItem(botId, <BotEquipmentSlotNum>frame.GetID(), compItemId);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
botMgrHandlers.OnEquipSuccess = (botId: number, slot: BotEquipmentSlotNum, itemId: number, itemLink: string) => {
|
||||
const itemTexture = <WoWAPI.Texture>ComponentsPool.get(compId(botId, `ItemSlotTexture-${slot}`));
|
||||
itemTexture.SetTexture(GetItemIcon(itemId));
|
||||
|
||||
// Hide Tooltips otherwise it will show old item.
|
||||
const BotTooltip = <WoWAPI.GameTooltip>ComponentsPool.get(compId(botId, "tooltip"));
|
||||
BotTooltip.Hide();
|
||||
GameTooltip.Hide();
|
||||
}
|
||||
|
||||
botMgrHandlers.OnEquipFail = (botId: number, slot: BotEquipmentSlotNum, itemId: number, itemLink: string) => {
|
||||
PlaySound("ITEMGENERICSOUND");
|
||||
ClearCursor();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Shows or Creates a new Bot Equipment Management Frame
|
||||
* Every NPC Bot that is requested to be managed will get their own unique frame. This
|
||||
@@ -394,7 +465,23 @@ if(!aio.AddAddon()) {
|
||||
mainFrame.SetScript("OnLeave", (frame) => {
|
||||
frame.SetFrameLevel(5);
|
||||
});
|
||||
|
||||
mainFrame.RegisterEvent("CURSOR_UPDATE");
|
||||
mainFrame.RegisterEvent("ITEM_LOCK_CHANGED");
|
||||
mainFrame.RegisterEvent("ITEM_UNLOCKED");
|
||||
|
||||
mainFrame.SetScript("OnEvent", (frame: WoWAPI.Frame, eventName: WoWAPI.Event, ...args) => {
|
||||
if(eventName == "ITEM_LOCKED") {
|
||||
GetCursorInfo()
|
||||
print(args);
|
||||
for(const arg of args) {
|
||||
print(arg);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
// mainFrame.Hide();
|
||||
|
||||
BotItemTooltip = CreateFrame("GameTooltip", id("ItemToolTip"+botData.entry), mainFrame, "GameTooltipTemplate", botData.entry);
|
||||
@@ -407,8 +494,10 @@ if(!aio.AddAddon()) {
|
||||
AddCharacterModel(mainFrame, botData);
|
||||
AddResistFrame(mainFrame);
|
||||
AddEquipmentFrames(mainFrame, botData);
|
||||
CreateStats(mainFrame, botData);
|
||||
AddSoundEffects(mainFrame);
|
||||
|
||||
|
||||
InfoFramePool.set(botData.entry, mainFrame);
|
||||
ComponentsPool.set(compId(botData.entry, "tooltip"), <WoWAPI.GameTooltip>BotItemTooltip);
|
||||
|
||||
@@ -501,11 +590,11 @@ if(!aio.AddAddon()) {
|
||||
|
||||
}
|
||||
|
||||
botMgrHandlers.ShowFrame = (botData: BotData) => {
|
||||
|
||||
// Update the botData manager for this Bot on panel show.
|
||||
|
||||
botMgrHandlers.ShowFrame = (botData: BotData) =>{
|
||||
botStorage.UpdateBotData(botData.entry, botData);
|
||||
ShowBotFrame(botData);
|
||||
}
|
||||
ShowBotFrame(botData);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -14,10 +14,20 @@ import {
|
||||
ClassesMapping,
|
||||
CharacterClass,
|
||||
RacesMapping,
|
||||
CharacterRace
|
||||
CharacterRace,
|
||||
ItemQuality,
|
||||
QualityType
|
||||
} from "../../constants/idmaps";
|
||||
|
||||
export type Equipment = {
|
||||
entry: number,
|
||||
link: string,
|
||||
quality?: QualityType,
|
||||
itemLevel?: number,
|
||||
enchantmentId?: number,
|
||||
}
|
||||
|
||||
export type EquipmentList = Record<BotEquipmentSlotNum, Equipment>;
|
||||
|
||||
/**
|
||||
* Everything we ever wanted to know about the bot info on load
|
||||
@@ -30,7 +40,7 @@ import {
|
||||
classId: number,
|
||||
race: CharacterRace,
|
||||
raceId: number,
|
||||
equipment?: Record<string, number>, // SlotName - ItemId See BotEquipSlot
|
||||
equipment?: EquipmentList, // SlotName - ItemId See BotEquipSlot
|
||||
stats?: Record<number, number>, // StatId - Value
|
||||
};
|
||||
|
||||
@@ -39,9 +49,6 @@ import {
|
||||
*/
|
||||
const NpcDetailStorage = {} as Record<number, BotData>;
|
||||
|
||||
// // cheap way to load everything on the server side and force so client as access. (Don't love this at all will need to work back into plugin);
|
||||
// const loader = BotStat || BotEquipSlot || BotEquipLast || BotStatLast || ClassesMapping || RacesMapping;
|
||||
|
||||
/**
|
||||
* Get the current targetted npc bot or returns undefined if not a bot.
|
||||
* @param player
|
||||
@@ -83,12 +90,42 @@ function TargetIsEligible(player: Player) {
|
||||
return false;
|
||||
}
|
||||
|
||||
function GetMeleeStats () {
|
||||
return {
|
||||
left: [
|
||||
BotStat.STRENGTH,
|
||||
BotStat.AGILITY,
|
||||
BotStat.DAMAGE_MIN,
|
||||
BotStat.DAMAGE_MAX,
|
||||
BotStat.ATTACK_POWER,
|
||||
BotStat.HIT_RATING,
|
||||
BotStat.CRIT_RATING,
|
||||
BotStat.EXPERTISE,
|
||||
BotStat.ARMOR_PENETRATION_RATING,
|
||||
],
|
||||
right: [
|
||||
BotStat.HASTE_RATING,
|
||||
BotStat.ARMOR,
|
||||
BotStat.STAMINA,
|
||||
BotStat.DEFENSE_SKILL_RATING,
|
||||
BotStat.DODGE_RATING,
|
||||
BotStat.PARRY_RATING,
|
||||
BotStat.BLOCK_RATING,
|
||||
BotStat.BLOCK_VALUE
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
function GetCasterStats() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @noSelf
|
||||
*/
|
||||
function GetBotDetails(bot: Creature): BotData {
|
||||
|
||||
const owner = bot.GetBotOwner();
|
||||
const owner = bot.GetBotOwner();
|
||||
|
||||
// We can use bot entrys since they are 1:1 with GUIDs for shorter storage keys
|
||||
NpcDetailStorage[bot.GetEntry()] = {
|
||||
@@ -98,21 +135,44 @@ function GetBotDetails(bot: Creature): BotData {
|
||||
class: ClassesMapping[bot.GetBotClass()],
|
||||
classId: bot.GetBotClass(),
|
||||
race: RacesMapping[bot.GetRace()],
|
||||
raceId: bot.GetRace(),
|
||||
equipment: {},
|
||||
// stats: {},
|
||||
raceId: bot.GetRace(),
|
||||
equipment: {} as EquipmentList,
|
||||
stats: {},
|
||||
};
|
||||
|
||||
print(bot.GetBotRoles());
|
||||
|
||||
|
||||
// Get all the equipment
|
||||
for(let slot=0; slot <= BotEquipLast; slot++) {
|
||||
const equipment = bot.GetBotEquipment(<BotEquipmentSlotNum>slot);
|
||||
|
||||
if(equipment) {
|
||||
NpcDetailStorage[bot.GetEntry()].equipment[slot] = equipment.GetEntry();
|
||||
print(`Slot: ${BotSlotName[slot]} Item: ${equipment.GetEntry()}`);
|
||||
if(equipment) {
|
||||
NpcDetailStorage[bot.GetEntry()].equipment[slot] = {
|
||||
entry: equipment.GetEntry(),
|
||||
link: equipment.GetItemLink(),
|
||||
quality: <QualityType>equipment.GetQuality(),
|
||||
itemLevel: equipment.GetItemLevel(),
|
||||
enchantmentId: equipment.GetEnchantmentId(0),
|
||||
}
|
||||
} else {
|
||||
NpcDetailStorage[bot.GetEntry()].equipment[slot] = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
// get the stats we care about by Class
|
||||
// This will determine what stats to lookup for the bot.
|
||||
const lookups = GetMeleeStats();
|
||||
|
||||
|
||||
lookups.left.forEach(stat => {
|
||||
const result = bot.GetBotStat(stat);
|
||||
NpcDetailStorage[bot.GetEntry()].stats[stat] = result;
|
||||
});
|
||||
lookups.right.forEach(stat => {
|
||||
const result = bot.GetBotStat(stat);
|
||||
NpcDetailStorage[bot.GetEntry()].stats[stat] = result;
|
||||
});
|
||||
|
||||
return NpcDetailStorage[bot.GetEntry()];
|
||||
}
|
||||
@@ -124,27 +184,30 @@ function GetBotDetails(bot: Creature): BotData {
|
||||
* @param command
|
||||
* @returns
|
||||
*/
|
||||
function EquipItem(botEntry: number, slot: BotEquipmentSlotNum, item: number): void {
|
||||
|
||||
function EquipTheItem(player: string, botEntry: number, slot: BotEquipmentSlotNum, item: number, link: string ): void {
|
||||
if(botEntry && typeof botEntry !== 'number') {
|
||||
return;
|
||||
}
|
||||
|
||||
print(`Bot: ${botEntry} Slot: ${slot} Item: ${item}`);
|
||||
|
||||
// const isEligible = bot.BotCanEquipItem(item, slot);
|
||||
const owner = GetPlayerByName(player);
|
||||
const creatures = owner.GetCreaturesInRange(60, botEntry) as Creature[];
|
||||
const bot = creatures[0];
|
||||
|
||||
|
||||
const isEligible = bot.BotCanEquipItem(item, slot);
|
||||
if(!isEligible) {
|
||||
log.error(`Bot cannot equip item: ${item} in slot: ${slot}`);
|
||||
return;
|
||||
}
|
||||
|
||||
// if(!isEligible) {
|
||||
// log.error(`Bot cannot equip item: ${item} in slot: ${slot}`);
|
||||
// return;
|
||||
// }
|
||||
|
||||
// if(bot.BotEquipItem(item, slot)) {
|
||||
// NpcDetailStorage[bot.GetEntry()].equipment[slot] = item;
|
||||
// aio.Handle(bot.GetBotOwner(), 'BotMgr', 'EquipSuccess', { slot, item});
|
||||
// } else {
|
||||
// log.error(`Bot failed to equip item: ${item} in slot: ${slot}`);
|
||||
// aio.Handle(bot.GetBotOwner(), 'BotMgr', 'EquipFail', { slot, item});
|
||||
// }
|
||||
if(bot.BotEquipItem(item, slot)) {
|
||||
GetBotDetails(bot);
|
||||
log.log(`Bot successfully equipped item: ${item} in slot: ${slot}`);
|
||||
aio.Handle(bot.GetBotOwner(), 'BotMgr', 'OnEquipSuccess',botEntry, slot, item, link);
|
||||
} else {
|
||||
log.error(`Bot failed to equip item: ${item} in slot: ${slot}`);
|
||||
aio.Handle(bot.GetBotOwner(), 'BotMgr', 'OnEquipFail', botEntry, slot, item, link);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -201,10 +264,11 @@ function GetBotPanelInfo(player: Player): void {
|
||||
const botMgrHandlers = aio.AddHandlers('BotMgr', {
|
||||
TargetIsEligible,
|
||||
GetBotPanelInfo,
|
||||
EquipItem
|
||||
"EquipTheItem": EquipTheItem
|
||||
});
|
||||
|
||||
|
||||
RegisterPlayerEvent(
|
||||
PlayerEvents.PLAYER_EVENT_ON_COMMAND,
|
||||
(...args) => ShowBotMgr(...args)
|
||||
);
|
||||
);
|
||||
@@ -101,7 +101,7 @@ export const BotStat = {
|
||||
BOT_STAT_MOD_RESISTANCE_START: 51, // Assuming BOT_STAT_MOD_ARMOR is defined somewhere
|
||||
} as const;
|
||||
|
||||
export const BotStatLast = 58;
|
||||
export const BotStatLast = 58;
|
||||
|
||||
export const UIInvSlot = {
|
||||
AMMOSLOT: "AMMOSLOT",
|
||||
@@ -165,4 +165,158 @@ export const RacesMapping: Record<number, string> = {
|
||||
12: "Worgen",
|
||||
} as const;
|
||||
|
||||
export type CharacterRace = typeof RacesMapping[keyof typeof RacesMapping];
|
||||
export type CharacterRace = typeof RacesMapping[keyof typeof RacesMapping];
|
||||
|
||||
export const BotTalentSpecs = {
|
||||
WARRIOR_ARMS : 1,
|
||||
WARRIOR_FURY : 2,
|
||||
WARRIOR_PROTECTION : 3,
|
||||
PALADIN_HOLY : 4,
|
||||
PALADIN_PROTECTION : 5,
|
||||
PALADIN_RETRIBUTION : 6,
|
||||
HUNTER_BEASTMASTERY : 7,
|
||||
HUNTER_MARKSMANSHIP : 8,
|
||||
HUNTER_SURVIVAL : 9,
|
||||
ROGUE_ASSASSINATION : 10,
|
||||
ROGUE_COMBAT : 11,
|
||||
ROGUE_SUBTLETY : 12,
|
||||
PRIEST_DISCIPLINE : 13,
|
||||
PRIEST_HOLY : 14,
|
||||
PRIEST_SHADOW : 15,
|
||||
DK_BLOOD : 16,
|
||||
DK_FROST : 17,
|
||||
DK_UNHOLY : 18,
|
||||
SHAMAN_ELEMENTAL : 19,
|
||||
SHAMAN_ENHANCEMENT : 20,
|
||||
SHAMAN_RESTORATION : 21,
|
||||
MAGE_ARCANE : 22,
|
||||
MAGE_FIRE : 23,
|
||||
MAGE_FROST : 24,
|
||||
WARLOCK_AFFLICTION : 25,
|
||||
WARLOCK_DEMONOLOGY : 26,
|
||||
WARLOCK_DESTRUCTION : 27,
|
||||
DRUID_BALANCE : 28,
|
||||
DRUID_FERAL : 29,
|
||||
DRUID_RESTORATION : 30,
|
||||
DEFAULT : 31,
|
||||
BEGIN : 1,
|
||||
END : 31
|
||||
} as const;
|
||||
|
||||
export function talentSpecName(id: number) {
|
||||
return Object.keys(BotTalentSpecs).find(key => BotTalentSpecs[key] === id);
|
||||
}
|
||||
|
||||
export const BotRoles = {
|
||||
NONE : 0,
|
||||
TANK : 1,
|
||||
TANK_OFF : 2,
|
||||
DPS : 4,
|
||||
HEAL : 8,
|
||||
RANGED : 16,
|
||||
PARTY : 32, // hidden
|
||||
GATHERING_MINING : 64,
|
||||
GATHERING_HERBALISM : 128,
|
||||
GATHERING_SKINNING : 256,
|
||||
GATHERING_ENGINEERING : 512,
|
||||
AUTOLOOT : 1024,
|
||||
AUTOLOOT_POOR : 2048,
|
||||
AUTOLOOT_COMMON : 4096,
|
||||
AUTOLOOT_UNCOMMON : 8192,
|
||||
AUTOLOOT_RARE : 16384,
|
||||
AUTOLOOT_EPIC : 32768,
|
||||
AUTOLOOT_LEGENDARY : 65536,
|
||||
MASK_MAIN : (1 | 2 | 4 | 8 | 16),
|
||||
MASK_GATHERING : (64 | 128 | 256 | 512),
|
||||
MASK_LOOTING : (2048 | 4096 | 8192 | 16384 | 32768 | 65536),
|
||||
BOT_MAX_ROLE : 131072,
|
||||
} as const;
|
||||
|
||||
|
||||
/**************** ITEM CONSTANTS *************************/
|
||||
|
||||
export const ItemQuality = {
|
||||
Poor: 0,
|
||||
Common: 1,
|
||||
Uncommon: 2,
|
||||
Rare: 3,
|
||||
Epic: 4,
|
||||
Legendary: 5,
|
||||
Artifact: 6,
|
||||
Heirlooms: 7,
|
||||
} as const;
|
||||
|
||||
export const ItemStat = {
|
||||
MANA: 0,
|
||||
HEALTH: 1,
|
||||
AGILITY: 3,
|
||||
STRENGTH: 4,
|
||||
INTELLECT: 5,
|
||||
SPIRIT: 6,
|
||||
STAMINA: 7,
|
||||
DEFENSE_SKILL_RATING: 12,
|
||||
DODGE_RATING: 13,
|
||||
PARRY_RATING: 14,
|
||||
BLOCK_RATING: 15,
|
||||
HIT_MELEE_RATING: 16,
|
||||
HIT_RANGED_RATING: 17,
|
||||
HIT_SPELL_RATING: 18,
|
||||
CRIT_MELEE_RATING: 19,
|
||||
CRIT_RANGED_RATING: 20,
|
||||
CRIT_SPELL_RATING: 21,
|
||||
HIT_TAKEN_MELEE_RATING: 22,
|
||||
HIT_TAKEN_RANGED_RATING: 23,
|
||||
HIT_TAKEN_SPELL_RATING: 24,
|
||||
CRIT_TAKEN_MELEE_RATING: 25,
|
||||
CRIT_TAKEN_RANGED_RATING: 26,
|
||||
CRIT_TAKEN_SPELL_RATING: 27,
|
||||
HASTE_MELEE_RATING: 28,
|
||||
HASTE_RANGED_RATING: 29,
|
||||
HASTE_SPELL_RATING: 30,
|
||||
HIT_RATING: 31,
|
||||
CRIT_RATING: 32,
|
||||
HIT_TAKEN_RATING: 33,
|
||||
CRIT_TAKEN_RATING: 34,
|
||||
RESILIENCE_RATING: 35,
|
||||
HASTE_RATING: 36,
|
||||
EXPERTISE_RATING: 37,
|
||||
ATTACK_POWER: 38,
|
||||
RANGED_ATTACK_POWER: 39,
|
||||
FERAL_ATTACK_POWER: 40, // Note: This is not used as of 3.3
|
||||
SPELL_HEALING_DONE: 41,
|
||||
SPELL_DAMAGE_DONE: 42,
|
||||
MANA_REGENERATION: 43,
|
||||
ARMOR_PENETRATION_RATING: 44,
|
||||
SPELL_POWER: 45,
|
||||
HEALTH_REGEN: 46,
|
||||
SPELL_PENETRATION: 47,
|
||||
BLOCK_VALUE: 48,
|
||||
} as const;
|
||||
|
||||
export const DamageType = {
|
||||
Physical: 0,
|
||||
Holy: 1,
|
||||
Fire: 2,
|
||||
Nature: 3,
|
||||
Frost: 4,
|
||||
Shadow: 5,
|
||||
Arcane: 6,
|
||||
} as const;
|
||||
|
||||
export const SocketColor = {
|
||||
Meta: 1,
|
||||
Red: 2,
|
||||
Yellow: 4,
|
||||
Blue: 8,
|
||||
} as const;
|
||||
|
||||
export const SocketBonus = {
|
||||
3312: '+8 Strength',
|
||||
3313: '+8 Agility',
|
||||
3305: '+12 Stamina',
|
||||
3: '+8 Intellect',
|
||||
2872: '+9 Healing',
|
||||
3753: '+9 Spell Power',
|
||||
3877: '+16 Attack Power',
|
||||
} as const;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user