diff --git a/.gitignore b/.gitignore index a047121..279698f 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,5 @@ node_modules node_modules/* dist wow-wotlk-declarations - +.DS_Store diff --git a/.vscode/eluna.code-snippets b/.vscode/eluna.code-snippets new file mode 100644 index 0000000..88afe95 --- /dev/null +++ b/.vscode/eluna.code-snippets @@ -0,0 +1,1832 @@ +{ + "Battleground Start": { + "prefix": "bg_start", + "body": [ + "const $1: bg_event_on_start = (event: number, bg: BattleGround, bgId: BattleGroundTypeId, instanceId: number) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterBGEvent(BGEvents.BG_EVENT_ON_START, (...args) => $1(...args));" + ], + "description": "Battleground Event on Start", + "scope": "typescript" + }, + "Battleground End": { + "prefix": "bg_end", + "body": [ + "const $1: bg_event_on_end = (event: number, bg: BattleGround, bgId: BattleGroundTypeId, instanceId: number, winner: Team) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterBGEvent(BGEvents.BG_EVENT_ON_END, (...args) => $1(...args));" + ], + "description": "Battleground Event on End", + "scope": "typescript" + }, + "Battleground Create": { + "prefix": "bg_create", + "body": [ + "const $1: bg_event_on_create = (event: number, bg: BattleGround, bgId: BattleGroundTypeId, instanceId: number) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterBGEvent(BGEvents.BG_EVENT_ON_CREATE, (...args) => $1(...args));" + ], + "description": "Battleground Event on Create", + "scope": "typescript" + }, + "Battleground Pre-Destroy": { + "prefix": "bg_pre_destroy", + "body": [ + "const $1: bg_event_on_pre_destroy = (event: number, bg: BattleGround, bgId: BattleGroundTypeId, instanceId: number) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterBGEvent(BGEvents.BG_EVENT_ON_PRE_DESTROY, (...args) => $1(...args));" + ], + "description": "Battleground Event on Pre-Destroy", + "scope": "typescript" + }, + "Creature Enter Combat": { + "prefix": "creature_enter_combat", + "body": [ + "const $1: creature_event_on_enter_combat = (event: number, creature: Creature, target: Creature): boolean => {", + "\t// Implementation", + "\treturn false; // return true to stop normal action", + "};", + "", + "// Register Creature Event on Enter Combat", + "RegisterCreatureEvent(${2:MyCreatureEntry}, CreatureEvents.CREATURE_EVENT_ON_ENTER_COMBAT, (...args) => $1(...args));" + ], + "description": "Creature Enter Combat", + "scope": "typescript" + }, + "Creature Leave Combat": { + "prefix": "creature_leave_combat", + "body": [ + "const $1: creature_event_on_leave_combat = (event: number, creature: Creature): boolean => {", + "\t// Implementation", + "\treturn false; // return true to stop normal action", + "};", + "", + "// Register Creature Event on Leave Combat", + "RegisterCreatureEvent(${2:MyCreatureEntry}, CreatureEvents.CREATURE_EVENT_ON_LEAVE_COMBAT, (...args) => $1(...args));" + ], + "description": "Creature Leave Combat", + "scope": "typescript" + }, + "Creature Target Died": { + "prefix": "creature_target_died", + "body": [ + "const $1: creature_event_on_target_died = (event: number, creature: Creature, victim: Creature): boolean => {", + "\t// Implementation", + "\treturn false; // return true to stop normal action", + "};", + "", + "// Register Creature Event on Target Died", + "RegisterCreatureEvent(${2:MyCreatureEntry}, CreatureEvents.CREATURE_EVENT_ON_TARGET_DIED, (...args) => $1(...args));" + ], + "description": "Creature Target Died", + "scope": "typescript" + }, + "Creature Died": { + "prefix": "creature_died", + "body": [ + "const $1: creature_event_on_died = (event: number, creature: Creature, killer: Creature): boolean => {", + "\t// Implementation", + "\treturn false; // return true to stop normal action", + "};", + "", + "// Register Creature Event on Died", + "RegisterCreatureEvent(${2:MyCreatureEntry}, CreatureEvents.CREATURE_EVENT_ON_DIED, (...args) => $1(...args));" + ], + "description": "Creature Died", + "scope": "typescript" + }, + "Creature Spawn": { + "prefix": "creature_spawn", + "body": [ + "const $1: creature_event_on_spawn = (event: number, creature: Creature): boolean => {", + "\t// Implementation", + "\treturn false; // return true to stop normal action", + "};", + "", + "// Register Creature Event on Spawn", + "RegisterCreatureEvent(${2:MyCreatureEntry}, CreatureEvents.CREATURE_EVENT_ON_SPAWN, (...args) => $1(...args));" + ], + "description": "Creature Spawn", + "scope": "typescript" + }, + "Creature Reach Waypoint": { + "prefix": "creature_reach_waypoint", + "body": [ + "const $1: creature_event_on_reach_wp = (event: number, creature: Creature, type: number, id: number): boolean => {", + "\t// Implementation", + "\treturn false;", + "};", + "", + "// Register Creature Event on Reach Waypoint", + "RegisterCreatureEvent(${2:MyCreatureEntry}, CreatureEvents.CREATURE_EVENT_ON_REACH_WP, (...args) => $1(...args));" + ], + "description": "Creature Reach Waypoint", + "scope": "typescript" + }, + "Creature AI Update": { + "prefix": "creature_ai_update", + "body": [ + "const $1: creature_event_on_aiupdate = (event: number, creature: Creature, diff: number): boolean => {", + "\t// Implementation", + "\treturn false; // return true to stop normal action", + "};", + "", + "// Register Creature Event on AI Update", + "RegisterCreatureEvent(${2:MyCreatureEntry}, CreatureEvents.CREATURE_EVENT_ON_AIUPDATE, (...args) => $1(...args));" + ], + "description": "Creature AI Update", + "scope": "typescript" + }, + "Creature Receive Emote": { + "prefix": "creature_receive_emote", + "body": [ + "const $1: creature_event_on_receive_emote = (event: number, creature: Creature, player: Player, emoteId: number): boolean => {", + "\t// Implementation", + "\treturn false; // return true to stop normal action", + "};", + "", + "// Register Creature Event on Receive Emote", + "RegisterCreatureEvent(${2:MyCreatureEntry}, CreatureEvents.CREATURE_EVENT_ON_RECEIVE_EMOTE, (...args) => $1(...args));" + ], + "description": "Creature Receive Emote", + "scope": "typescript" + }, + "Creature Damage Taken": { + "prefix": "creature_damage_taken", + "body": [ + "const $1: creature_event_on_damage_taken = (event: number, creature: Creature, attacker: Creature, damage: number): boolean => {", + "\t// Implementation", + "\treturn false; // return true to stop normal action", + "};", + "", + "// Register Creature Event on Damage Taken", + "RegisterCreatureEvent(${2:MyCreatureEntry}, CreatureEvents.CREATURE_EVENT_ON_DAMAGE_TAKEN, (...args) => $1(...args));" + ], + "description": "Creature Damage Taken", + "scope": "typescript" + }, + "Creature Pre Combat": { + "prefix": "creature_pre_combat", + "body": [ + "const $1: creature_event_on_pre_combat = (event: number, creature: Creature, target: Creature): boolean => {", + "\t// Implementation", + "\treturn false; // return true to stop normal action", + "};", + "", + "// Register Creature Event on Pre Combat", + "RegisterCreatureEvent(${2:MyCreatureEntry}, CreatureEvents.CREATURE_EVENT_ON_PRE_COMBAT, (...args) => $1(...args));" + ], + "description": "Creature Pre Combat", + "scope": "typescript" + }, + "Creature Hit By Spell": { + "prefix": "creature_hit_by_spell", + "body": [ + "const $1: creature_event_on_hit_by_spell = (event: number, creature: Creature, caster: Creature, spellId: number): boolean => {", + "\t// Implementation", + "\treturn false; // return true to stop normal action", + "};", + "", + "// Register Creature Event on Hit By Spell", + "RegisterCreatureEvent(${2:MyCreatureEntry}, CreatureEvents.CREATURE_EVENT_ON_HIT_BY_SPELL, (...args) => $1(...args));" + ], + "description": "Creature Hit By Spell", + "scope": "typescript" + }, + "Creature Owner Attacked": { + "prefix": "creature_owner_attacked", + "body": [ + "const $1: creature_event_on_owner_attacked = (event: number, creature: Creature, target: Creature): boolean => {", + "\t// Implementation", + "\treturn false; // return true to stop normal action", + "};", + "", + "// Register Creature Event on Owner Attacked", + "RegisterCreatureEvent(${2:MyCreatureEntry}, CreatureEvents.CREATURE_EVENT_ON_OWNER_ATTACKED, (...args) => $1(...args));" + ], + "description": "Creature Owner Attacked", + "scope": "typescript" + }, + "Creature Owner Attacked At": { + "prefix": "creature_owner_attacked_at", + "body": [ + "const $1: creature_event_on_owner_attacked_at = (event: number, creature: Creature, attacker: Creature): boolean => {", + "\t// Implementation", + "\treturn false; // return true to stop normal action", + "};", + "", + "// Register Creature Event on Owner Attacked At", + "RegisterCreatureEvent(${2:MyCreatureEntry}, CreatureEvents.CREATURE_EVENT_ON_OWNER_ATTACKED_AT, (...args) => $1(...args));" + ], + "description": "Creature Owner Attacked At", + "scope": "typescript" + }, + "Creature Spell Hit Target": { + "prefix": "creature_spell_hit_target", + "body": [ + "const $1: creature_event_on_spell_hit_target = (event: number, creature: Creature, target: Creature, spellId: number): boolean => {", + "\t// Implementation", + "\treturn false; // return true to stop normal action", + "};", + "", + "// Register Creature Event on Spell Hit Target", + "RegisterCreatureEvent(${2:MyCreatureEntry}, CreatureEvents.CREATURE_EVENT_ON_SPELL_HIT_TARGET, (...args) => $1(...args));" + ], + "description": "Creature Spell Hit Target", + "scope": "typescript" + }, + "Creature Just Summoned Creature": { + "prefix": "creature_just_summoned_creature", + "body": [ + "const $1: creature_event_on_just_summoned_creature = (event: number, creature: Creature, summon: Creature): boolean => {", + "\t// Implementation", + "\treturn false; // return true to stop normal action", + "};", + "", + "// Register Creature Event on Just Summoned Creature", + "RegisterCreatureEvent(${2:MyCreatureEntry}, CreatureEvents.CREATURE_EVENT_ON_JUST_SUMMONED_CREATURE, (...args) => $1(...args));" + ], + "description": "Creature Just Summoned Creature", + "scope": "typescript" + }, + "Creature Summoned Creature Despawn": { + "prefix": "creature_summoned_creature_despawn", + "body": [ + "const $1: creature_event_on_summoned_creature_despawn = (event: number, creature: Creature, summon: Creature): boolean => {", + "\t// Implementation", + "\treturn false; // return true to stop normal action", + "};", + "", + "// Register Creature Event on Summoned Creature Despawn", + "RegisterCreatureEvent(${2:MyCreatureEntry}, CreatureEvents.CREATURE_EVENT_ON_SUMMONED_CREATURE_DESPAWN, (...args) => $1(...args));" + ], + "description": "Creature Summoned Creature Despawn", + "scope": "typescript" + }, + "Creature Summoned Creature Died": { + "prefix": "creature_summoned_creature_died", + "body": [ + "const $1: creature_event_on_summoned_creature_died = (event: number, creature: Creature, summon: Creature, killer: Creature): boolean => {", + "\t// Implementation", + "\treturn false; // return true to stop normal action", + "};", + "", + "// Register Creature Event on Summoned Creature Died", + "RegisterCreatureEvent(${2:MyCreatureEntry}, CreatureEvents.CREATURE_EVENT_ON_SUMMONED_CREATURE_DIED, (...args) => $1(...args));" + ], + "description": "Creature Summoned Creature Died", + "scope": "typescript" + }, + "Creature Summoned": { + "prefix": "creature_summoned", + "body": [ + "const $1: creature_event_on_summoned = (event: number, creature: Creature, summoner: Creature): boolean => {", + "\t// Implementation", + "\treturn false; // return true to stop normal action", + "};", + "", + "// Register Creature Event on Summoned", + "RegisterCreatureEvent(${2:MyCreatureEntry}, CreatureEvents.CREATURE_EVENT_ON_SUMMONED, (...args) => $1(...args));" + ], + "description": "Creature Summoned", + "scope": "typescript" + }, + "Creature Reset": { + "prefix": "creature_reset", + "body": [ + "const $1: creature_event_on_reset = (event: number, creature: Creature): boolean => {", + "\t// Implementation", + "\treturn false; // return true to stop normal action", + "};", + "", + "// Register Creature Event on Reset", + "RegisterCreatureEvent(${2:MyCreatureEntry}, CreatureEvents.CREATURE_EVENT_ON_RESET, (...args) => $1(...args));" + ], + "description": "Creature Reset", + "scope": "typescript" + }, + "Creature Reach Home": { + "prefix": "creature_reach_home", + "body": [ + "const $1: creature_event_on_reach_home = (event: number, creature: Creature): boolean => {", + "\t// Implementation", + "\treturn false; // return true to stop normal action", + "};", + "", + "// Register Creature Event on Reach Home", + "RegisterCreatureEvent(${2:MyCreatureEntry}, CreatureEvents.CREATURE_EVENT_ON_REACH_HOME, (...args) => $1(...args));" + ], + "description": "Creature Reach Home", + "scope": "typescript" + }, + "Creature Corpse Removed": { + "prefix": "creature_corpse_removed", + "body": [ + "const $1: creature_event_on_corpse_removed = (event: number, creature: Creature, respawnDelay: number): boolean => {", + "\t// Implementation", + "\treturn false; // return true to stop normal action", + "};", + "", + "// Register Creature Event on Corpse Removed", + "RegisterCreatureEvent(${2:MyCreatureEntry}, CreatureEvents.CREATURE_EVENT_ON_CORPSE_REMOVED, (...args) => $1(...args));" + ], + "description": "Creature Corpse Removed", + "scope": "typescript" + }, + "Creature Move in Line of Sight": { + "prefix": "creature_move_in_los", + "body": [ + "const $1: creature_event_on_move_in_los = (event: number, creature: Creature, unit: Unit): boolean => {", + "\t// Implementation", + "\treturn false; // return true to stop normal action", + "};", + "", + "// Register Creature Event on Move in Line of Sight", + "RegisterCreatureEvent(${2:MyCreatureEntry}, CreatureEvents.CREATURE_EVENT_ON_MOVE_IN_LOS, (...args) => $1(...args));" + ], + "description": "Creature Move in Line of Sight", + "scope": "typescript" + }, + "Creature Dummy Effect": { + "prefix": "creature_dummy_effect", + "body": [ + "const $1: creature_event_on_dummy_effect = (event: number, caster: Unit, spellId: number, effIndex: number, creature: Creature): boolean => {", + "\t// Implementation", + "\treturn false; // return true to stop normal action", + "};", + "", + "// Register Creature Event on Dummy Effect", + "RegisterCreatureEvent(${2:MyCreatureEntry}, CreatureEvents.CREATURE_EVENT_ON_DUMMY_EFFECT, (...args) => $1(...args));" + ], + "description": "Creature Dummy Effect", + "scope": "typescript" + }, + "Creature Quest Accept": { + "prefix": "creature_quest_accept", + "body": [ + "const $1: creature_event_on_quest_accept = (event: number, player: Player, creature: Creature, quest: Quest): boolean => {", + "\t// Implementation", + "\treturn false; // return true to stop normal action", + "};", + "", + "// Register Creature Event on Quest Accept", + "RegisterCreatureEvent(${2:MyCreatureEntry}, CreatureEvents.CREATURE_EVENT_ON_QUEST_ACCEPT, (...args) => $1(...args));" + ], + "description": "Creature Quest Accept", + "scope": "typescript" + }, + "Creature Quest Reward": { + "prefix": "creature_quest_reward", + "body": [ + "const $1: creature_event_on_quest_reward = (event: number, player: Player, creature: Creature, quest: Quest, opt: number): boolean => {", + "\t// Implementation", + "\treturn false; // return true to stop normal action", + "};", + "", + "// Register Creature Event on Quest Reward", + "RegisterCreatureEvent(${2:MyCreatureEntry}, CreatureEvents.CREATURE_EVENT_ON_QUEST_REWARD, (...args) => $1(...args));" + ], + "description": "Creature Quest Reward", + "scope": "typescript" + }, + "Creature Dialog Status": { + "prefix": "creature_dialog_status", + "body": [ + "const $1: creature_event_on_dialog_status = (event: number, player: Player, creature: Creature): boolean => {", + "\t// Implementation", + "\treturn false; // return true to stop normal action", + "};", + "", + "// Register Creature Event on Dialog Status", + "RegisterCreatureEvent(${2:MyCreatureEntry}, CreatureEvents.CREATURE_EVENT_ON_DIALOG_STATUS, (...args) => $1(...args));" + ], + "description": "Creature Dialog Status", + "scope": "typescript" + }, + "Creature Add": { + "prefix": "creature_add", + "body": [ + "const $1: creature_event_on_add = (event: number, creature: Creature): boolean => {", + "\t// Implementation", + "\treturn false; // return true to stop normal action", + "};", + "", + "// Register Creature Event on Add", + "RegisterCreatureEvent(${2:MyCreatureEntry}, CreatureEvents.CREATURE_EVENT_ON_ADD, (...args) => $1(...args));" + ], + "description": "Creature Add", + "scope": "typescript" + }, + "Creature Remove": { + "prefix": "creature_remove", + "body": [ + "const $1: creature_event_on_remove = (event: number, creature: Creature): boolean => {", + "\t// Implementation", + "\treturn false; // return true to stop normal action", + "};", + "", + "// Register Creature Event on Remove", + "RegisterCreatureEvent(${2:MyCreatureEntry}, CreatureEvents.CREATURE_EVENT_ON_REMOVE, (...args) => $1(...args));" + ], + "description": "Creature Remove", + "scope": "typescript" + }, + "GameObject AI Update": { + "prefix": "gameobject_on_aiupdate", + "body": [ + "const $1: gameobject_event_on_aiupdate = (event: number, gameObject: GameObject, diff: number) => {", + "\t// Implementation", + "};", + "", + "// Register GameObject Event on AI Update", + "RegisterGameObjectEvent(${2:MyGameObjectID},GameObjectEvents.GAMEOBJECT_EVENT_ON_AIUPDATE, (...args) => $1(...args));" + ], + "description": "GameObject AI Update", + "scope": "typescript" + }, + "GameObject Spawn": { + "prefix": "gameobject_on_spawn", + "body": [ + "const $1: gameobject_event_on_spawn = (event: number, gameObject: GameObject) => {", + "\t// Implementation", + "};", + "", + "// Register GameObject Event on Spawn", + "RegisterGameObjectEvent(${2:MyGameObjectID},GameObjectEvents.GAMEOBJECT_EVENT_ON_SPAWN, (...args) => $1(...args));" + ], + "description": "GameObject Spawn", + "scope": "typescript" + }, + "GameObject Dummy Effect": { + "prefix": "gameobject_on_dummy_effect", + "body": [ + "const $1: gameobject_event_on_dummy_effect = (event: number, caster: any, spellId: number, effectIndex: number, gameObject: GameObject): boolean => {", + "\t// Implementation", + "\treturn false;", + "};", + "", + "// Register GameObject Event on Dummy Effect", + "RegisterGameObjectEvent(${2:MyGameObjectID},GameObjectEvents.GAMEOBJECT_EVENT_ON_DUMMY_EFFECT, (...args) => $1(...args));" + ], + "description": "GameObject Dummy Effect", + "scope": "typescript" + }, + "GameObject Quest Accept": { + "prefix": "gameobject_on_quest_accept", + "body": [ + "const $1: gameobject_event_on_quest_accept = (event: number, player: Player, gameObject: GameObject, quest: any): boolean => {", + "\t// Implementation", + "\treturn false;", + "};", + "", + "// Register GameObject Event on Quest Accept", + "RegisterGameObjectEvent(${2:MyGameObjectID},GameObjectEvents.GAMEOBJECT_EVENT_ON_QUEST_ACCEPT, (...args) => $1(...args));" + ], + "description": "GameObject Quest Accept", + "scope": "typescript" + }, + "GameObject Quest Reward": { + "prefix": "gameobject_on_quest_reward", + "body": [ + "const $1: gameobject_event_on_quest_reward = (event: number, player: Player, gameObject: GameObject, quest: any, option: any): boolean => {", + "\t// Implementation", + "\treturn false;", + "};", + "", + "// Register GameObject Event on Quest Reward", + "RegisterGameObjectEvent(${2:MyGameObjectID},GameObjectEvents.GAMEOBJECT_EVENT_ON_QUEST_REWARD, (...args) => $1(...args));" + ], + "description": "GameObject Quest Reward", + "scope": "typescript" + }, + "GameObject Dialog Status": { + "prefix": "gameobject_on_dialog_status", + "body": [ + "const $1: gameobject_event_on_dialog_status = (event: number, player: Player, gameObject: GameObject) => {", + "\t// Implementation", + "};", + "", + "// Register GameObject Event on Dialog Status", + "RegisterGameObjectEvent(${2:MyGameObjectID},GameObjectEvents.GAMEOBJECT_EVENT_ON_DIALOG_STATUS, (...args) => $1(...args));" + ], + "description": "GameObject Dialog Status", + "scope": "typescript" + }, + "GameObject Destroyed": { + "prefix": "gameobject_on_destroyed", + "body": [ + "const $1: gameobject_event_on_destroyed = (event: number, gameObject: GameObject, attacker: any) => {", + "\t// Implementation", + "};", + "", + "// Register GameObject Event on Destroyed", + "RegisterGameObjectEvent(${2:MyGameObjectID},GameObjectEvents.GAMEOBJECT_EVENT_ON_DESTROYED, (...args) => $1(...args));" + ], + "description": "GameObject Destroyed", + "scope": "typescript" + }, + "GameObject Damaged": { + "prefix": "gameobject_on_damaged", + "body": [ + "const $1: gameobject_event_on_damaged = (event: number, gameObject: GameObject, attacker: any) => {", + "\t// Implementation", + "};", + "", + "// Register GameObject Event on Damaged", + "RegisterGameObjectEvent(${2:MyGameObjectID},GameObjectEvents.GAMEOBJECT_EVENT_ON_DAMAGED, (...args) => $1(...args));" + ], + "description": "GameObject Damaged", + "scope": "typescript" + }, + "GameObject Loot State Change": { + "prefix": "gameobject_on_loot_state_change", + "body": [ + "const $1: gameobject_event_on_loot_state_change = (event: number, gameObject: GameObject, state: any) => {", + "\t// Implementation", + "};", + "", + "// Register GameObject Event on Loot State Change", + "RegisterGameObjectEvent(${2:MyGameObjectID},GameObjectEvents.GAMEOBJECT_EVENT_ON_LOOT_STATE_CHANGE, (...args) => $1(...args));" + ], + "description": "GameObject Loot State Change", + "scope": "typescript" + }, + "GameObject State Changed": { + "prefix": "gameobject_on_state_changed", + "body": [ + "const $1: gameobject_event_on_go_state_changed = (event: number, gameObject: GameObject, state: any) => {", + "\t// Implementation", + "};", + "", + "// Register GameObject Event on State Changed", + "RegisterGameObjectEvent(${2:MyGameObjectID},GameObjectEvents.GAMEOBJECT_EVENT_ON_GO_STATE_CHANGED, (...args) => $1(...args));" + ], + "description": "GameObject State Changed", + "scope": "typescript" + }, + "GameObject Add": { + "prefix": "gameobject_on_add", + "body": [ + "const $1: gameobject_event_on_add = (event: number, gameObject: GameObject) => {", + "\t// Implementation", + "};", + "", + "// Register GameObject Event on Add", + "RegisterGameObjectEvent(${2:MyGameObjectID},GameObjectEvents.GAMEOBJECT_EVENT_ON_ADD, (...args) => $1(...args));" + ], + "description": "GameObject Add", + "scope": "typescript" + }, + "GameObject Remove": { + "prefix": "gameobject_on_remove", + "body": [ + "const $1: gameobject_event_on_remove = (event: number, gameObject: GameObject) => {", + "\t// Implementation", + "};", + "", + "// Register GameObject Event on Remove", + "RegisterGameObjectEvent(${2:MyGameObjectID},GameObjectEvents.GAMEOBJECT_EVENT_ON_REMOVE, (...args) => $1(...args));" + ], + "description": "GameObject Remove", + "scope": "typescript" + }, + "GameObject Use": { + "prefix": "gameobject_on_use", + "body": [ + "const $1: gameobject_event_on_use = (event: number, gameObject: GameObject, player: Player): boolean => {", + "\t// Implementation", + "\treturn false;", + "};", + "", + "// Register GameObject Event on Use", + "RegisterGameObjectEvent(${2:MyGameObjectID},GameObjectEvents.GAMEOBJECT_EVENT_ON_USE, (...args) => $1(...args));" + ], + "description": "GameObject Use", + "scope": "typescript" + }, + "Item Gossip Hello": { + "prefix": "item_gossip_on_hello", + "body": [ + "const $1: gossip_event_on_hello = (event: number, player: Player, item: Item): boolean => {", + "\t// Implementation", + "\treturn true;", + "};", + "", + "// Register Item Gossip Event on Hello", + "RegisterItemGossipEvent(${2:MyItemEntry}, GossipEvents.GOSSIP_EVENT_ON_HELLO, (...args) => $1(...args));" + ], + "description": "Item Gossip Hello", + "scope": "typescript" + }, + "Item Gossip Select": { + "prefix": "item_gossip_on_select", + "body": [ + "const $1: gossip_event_on_select = (event: number, player: Player, item: Item, sender: number, intid: number, code: string, menuId?: number): boolean => {", + "\t// Implementation", + "\treturn true;", + "};", + "", + "// Register Item Gossip Event on Select", + "RegisterItemGossipEvent(${2:MyItemEntry}, GossipEvents.GOSSIP_EVENT_ON_SELECT, (...args) => $1(...args));" + ], + "description": "Item Gossip Select", + "scope": "typescript" + }, + "Player Gossip Hello": { + "prefix": "player_gossip_on_hello", + "body": [ + "const $1: gossip_event_on_hello = (event: number, player: Player, object: Object): boolean => {", + "\t// Implementation", + "\treturn true;", + "};", + "", + "// Register Player Gossip Event on Hello", + "RegisterPlayerGossipEvent(${2:MyMenuId}, GossipEvents.GOSSIP_EVENT_ON_HELLO, (...args) => $1(...args));" + ], + "description": "Player Gossip Hello", + "scope": "typescript" + }, + "Player Gossip Select": { + "prefix": "player_gossip_on_select", + "body": [ + "const $1: gossip_event_on_select = (event: number, player: Player, object: Object, sender: number, intid: number, code: string, menuId?: number): boolean => {", + "\t// Implementation", + "\treturn true;", + "};", + "", + "// Register Player Gossip Event on Select", + "RegisterItemGossipEvent(${2:MyMenuId}, GossipEvents.GOSSIP_EVENT_ON_SELECT, (...args) => $1(...args));" + ], + "description": "Player Gossip Select", + "scope": "typescript" + }, + "GameObject Gossip Hello": { + "prefix": "gameobject_gossip_on_hello", + "body": [ + "const $1: gossip_event_on_hello = (event: number, player: Player, gameObject: GameObject): boolean => {", + "\t// Implementation", + "\treturn true;", + "};", + "", + "// Register GameObject Gossip Event on Hello", + "RegisterGameObjectGossipEvent(${2:MyGameObjectEntry}, GossipEvents.GOSSIP_EVENT_ON_HELLO, (...args) => $1(...args));" + ], + "description": "GameObject Gossip Hello", + "scope": "typescript" + }, + "GameObject Gossip Select": { + "prefix": "gameobject_gossip_on_select", + "body": [ + "const $1: gossip_event_on_select = (event: number, player: Player, gameObject: GameObject, sender: number, intid: number, code: string, menuId?: number): boolean => {", + "\t// Implementation", + "\treturn true;", + "};", + "", + "// Register GameObject Gossip Event on Select", + "RegisterGameObjectGossipEvent(${2:MyGameObjectEntry}, GossipEvents.GOSSIP_EVENT_ON_SELECT, (...args) => $1(...args));" + ], + "description": "GameObject Gossip Select", + "scope": "typescript" + }, + "Creature Gossip Hello": { + "prefix": "creature_gossip_on_hello", + "body": [ + "const $1: gossip_event_on_hello = (event: number, player: Player, creature: Creature): boolean => {", + "\t// Implementation", + "\treturn true;", + "};", + "", + "// Register Creature Gossip Event on Hello", + "RegisterCreatureGossipEvent(${2:MyCreatureEntry}, GossipEvents.GOSSIP_EVENT_ON_HELLO, (...args) => $1(...args));" + ], + "description": "Creature Gossip Hello", + "scope": "typescript" + }, + "Creature Gossip Select": { + "prefix": "creature_gossip_on_select", + "body": [ + "const $1: gossip_event_on_select = (event: number, player: Player, creature: Creature, sender: number, intid: number, code: string, menuId?: number): boolean => {", + "\t// Implementation", + "\treturn true;", + "};", + "", + "// Register Creature Gossip Event on Select", + "RegisterCreatureGossipEvent(${2:MyCreatureEntry}, GossipEvents.GOSSIP_EVENT_ON_SELECT, (...args) => $1(...args));" + ], + "description": "Creature Gossip Select", + "scope": "typescript" + }, + "Group Member Add": { + "prefix": "group_member_add", + "body": [ + "const $1: group_event_on_member_add = (event: number, group: Group, guid: number) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterGroupEvent(GroupEvents.GROUP_EVENT_ON_MEMBER_ADD, (...args) => $1(...args));" + ], + "description": "Group Event on Member Add", + "scope": "typescript" + }, + "Group Member Invite": { + "prefix": "group_member_invite", + "body": [ + "const $1: group_event_on_member_invite = (event: number, group: Group, guid: number) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterGroupEvent(GroupEvents.GROUP_EVENT_ON_MEMBER_INVITE, (...args) => $1(...args));" + ], + "description": "Group Event on Member Invite", + "scope": "typescript" + }, + "Group Member Remove": { + "prefix": "group_member_remove", + "body": [ + "const $1: group_event_on_member_remove = (event: number, group: Group, guid: number, method: number) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterGroupEvent(GroupEvents.GROUP_EVENT_ON_MEMBER_REMOVE, (...args) => $1(...args));" + ], + "description": "Group Event on Member Remove", + "scope": "typescript" + }, + "Group Leader Change": { + "prefix": "group_leader_change", + "body": [ + "const $1: group_event_on_leader_change = (event: number, group: Group, newLeaderGuid: number, oldLeaderGuid: number) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterGroupEvent(GroupEvents.GROUP_EVENT_ON_LEADER_CHANGE, (...args) => $1(...args));" + ], + "description": "Group Event on Leader Change", + "scope": "typescript" + }, + "Group Disband": { + "prefix": "group_disband", + "body": [ + "const $1: group_event_on_disband = (event: number, group: Group) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterGroupEvent(GroupEvents.GROUP_EVENT_ON_DISBAND, (...args) => $1(...args));" + ], + "description": "Group Event on Disband", + "scope": "typescript" + }, + "Group Create": { + "prefix": "group_create", + "body": [ + "const $1: group_event_on_create = (event: number, group: Group, leaderGuid: number, groupType: number) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterGroupEvent(GroupEvents.GROUP_EVENT_ON_CREATE, (...args) => $1(...args));" + ], + "description": "Group Event on Create", + "scope": "typescript" + }, + "Guild Add Member": { + "prefix": "guild_add_member", + "body": [ + "const $1: guild_event_on_add_member = (event: number, guild: Guild, player: Player, rank: number) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterGuildEvent(GuildEvents.GUILD_EVENT_ON_ADD_MEMBER, (...args) => $1(...args));" + ], + "description": "Guild Event on Add Member", + "scope": "typescript" + }, + "Guild Remove Member": { + "prefix": "guild_remove_member", + "body": [ + "const $1: guild_event_on_remove_member = (event: number, guild: Guild, player: Player, isDisbanding: boolean) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterGuildEvent(GuildEvents.GUILD_EVENT_ON_REMOVE_MEMBER, (...args) => $1(...args));" + ], + "description": "Guild Event on Remove Member", + "scope": "typescript" + }, + "Guild MOTD Change": { + "prefix": "guild_motd_change", + "body": [ + "const $1: guild_event_on_motd_change = (event: number, guild: Guild, newMotd: string) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterGuildEvent(GuildEvents.GUILD_EVENT_ON_MOTD_CHANGE, (...args) => $1(...args));" + ], + "description": "Guild Event on MOTD Change", + "scope": "typescript" + }, + "Guild Info Change": { + "prefix": "guild_info_change", + "body": [ + "const $1: guild_event_on_info_change = (event: number, guild: Guild, newInfo: string) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterGuildEvent(GuildEvents.GUILD_EVENT_ON_INFO_CHANGE, (...args) => $1(...args));" + ], + "description": "Guild Event on Info Change", + "scope": "typescript" + }, + "Guild Create": { + "prefix": "guild_create", + "body": [ + "const $1: guild_event_on_create = (event: number, guild: Guild, leader: Player, name: string) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterGuildEvent(GuildEvents.GUILD_EVENT_ON_CREATE, (...args) => $1(...args));" + ], + "description": "Guild Event on Create", + "scope": "typescript" + }, + "Guild Disband": { + "prefix": "guild_disband", + "body": [ + "const $1: guild_event_on_disband = (event: number, guild: Guild) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterGuildEvent(GuildEvents.GUILD_EVENT_ON_DISBAND, (...args) => $1(...args));" + ], + "description": "Guild Event on Disband", + "scope": "typescript" + }, + "Guild Money Withdraw": { + "prefix": "guild_money_withdraw", + "body": [ + "const $1: guild_event_on_money_withdraw = (event: number, guild: Guild, player: Player, amount: number, isRepair: boolean) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterGuildEvent(GuildEvents.GUILD_EVENT_ON_MONEY_WITHDRAW, (...args) => $1(...args));" + ], + "description": "Guild Event on Money Withdraw", + "scope": "typescript" + }, + "Guild Money Deposit": { + "prefix": "guild_money_deposit", + "body": [ + "const $1: guild_event_on_money_deposit = (event: number, guild: Guild, player: Player, amount: number) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterGuildEvent(GuildEvents.GUILD_EVENT_ON_MONEY_DEPOSIT, (...args) => $1(...args));" + ], + "description": "Guild Event on Money Deposit", + "scope": "typescript" + }, + "Guild Item Move": { + "prefix": "guild_item_move", + "body": [ + "const $1: guild_event_on_item_move = (event: number, guild: Guild, player: Player, item: Item, isSrcBank: boolean, srcContainer: number, srcSlotId: number, isDestBank: boolean, destContainer: number, destSlotId: number) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterGuildEvent(GuildEvents.GUILD_EVENT_ON_ITEM_MOVE, (...args) => $1(...args));" + ], + "description": "Guild Event on Item Move", + "scope": "typescript" + }, + "Guild Event": { + "prefix": "guild_event", + "body": [ + "const $1: guild_event_on_event = (event: number, guild: Guild, eventType: number, plrGUIDLow1: number, plrGUIDLow2: number, newRank: GuildRank) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterGuildEvent(GuildEvents.GUILD_EVENT_ON_EVENT, (...args) => $1(...args));" + ], + "description": "Guild Event on Event", + "scope": "typescript" + }, + "Guild Bank Event": { + "prefix": "guild_bank_event", + "body": [ + "const $1: guild_event_on_bank_event = (event: number, guild: Guild, eventType: number, tabId: number, playerGUIDLow: number, itemOrMoney: number, itemStackCount: number, destTabId: number) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterGuildEvent(GuildEvents.GUILD_EVENT_ON_BANK_EVENT, (...args) => $1(...args));" + ], + "description": "Guild Event on Bank Event", + "scope": "typescript" + }, + "Instance Initialize": { + "prefix": "instance_initialize", + "body": [ + "const $1: instance_event_on_initialize = (event: number, instanceData: number[], map: EMap) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterMapEvent($2, InstanceEvents.INSTANCE_EVENT_ON_INITIALIZE, (...args) => $1(...args));" + ], + "description": "Instance Event on Initialize", + "scope": "typescript" + }, + "Instance Load": { + "prefix": "instance_load", + "body": [ + "const $1: instance_event_on_load = (event: number, instanceData: number[], map: EMap) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterMapEvent($2, InstanceEvents.INSTANCE_EVENT_ON_LOAD, (...args) => $1(...args));" + ], + "description": "Instance Event on Load", + "scope": "typescript" + }, + "Instance Update": { + "prefix": "instance_update", + "body": [ + "const $1: instance_event_on_update = (event: number, instanceData: number[], map: EMap, diff: number) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterMapEvent($2, InstanceEvents.INSTANCE_EVENT_ON_UPDATE, (...args) => $1(...args));" + ], + "description": "Instance Event on Update", + "scope": "typescript" + }, + "Instance Player Enter": { + "prefix": "instance_player_enter", + "body": [ + "const $1: instance_event_on_player_enter = (event: number, instanceData: number[], map: EMap, player: Player) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterMapEvent($2, InstanceEvents.INSTANCE_EVENT_ON_PLAYER_ENTER, (...args) => $1(...args));" + ], + "description": "Instance Event on Player Enter", + "scope": "typescript" + }, + "Instance Creature Create": { + "prefix": "instance_creature_create", + "body": [ + "const $1: instance_event_on_creature_create = (event: number, instanceData: number[], map: EMap, creature: Creature) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterMapEvent($2, InstanceEvents.INSTANCE_EVENT_ON_CREATURE_CREATE, (...args) => $1(...args));" + ], + "description": "Instance Event on Creature Create", + "scope": "typescript" + }, + "Instance GameObject Create": { + "prefix": "instance_gameobject_create", + "body": [ + "const $1: instance_event_on_gameobject_create = (event: number, instanceData: number[], map: EMap, gameObject: GameObject) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterMapEvent($2, InstanceEvents.INSTANCE_EVENT_ON_GAMEOBJECT_CREATE, (...args) => $1(...args));" + ], + "description": "Instance Event on GameObject Create", + "scope": "typescript" + }, + "Instance Check Encounter in Progress": { + "prefix": "instance_check_encounter_in_progress", + "body": [ + "const $1: instance_event_on_check_encounter_in_progress = (event: number, instanceData: number[], map: EMap): boolean => {", + "\t// Implementation", + "\treturn true;", + "};", + "", + "// Register", + "RegisterMapEvent($2, InstanceEvents.INSTANCE_EVENT_ON_CHECK_ENCOUNTER_IN_PROGRESS, (...args) => $1(...args));" + ], + "description": "Instance Event on Check Encounter in Progress", + "scope": "typescript" + }, + "Item Dummy Effect": { + "prefix": "item_dummy_effect", + "body": [ + "const $1: item_event_on_dummy_effect = (event: number, caster: Player, spellId: number, effIndex: number, item: Item) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterItemEvent($2, ItemEvents.ITEM_EVENT_ON_DUMMY_EFFECT, (...args) => $1(...args));" + ], + "description": "Item Event on Dummy Effect", + "scope": "typescript" + }, + "Item Use": { + "prefix": "item_use", + "body": [ + "const $1: item_event_on_use = (event: number, player: Player, item: Item, target: Unit): boolean => {", + "\t// Implementation", + "\treturn true; // Return false to stop the spell casting", + "};", + "", + "// Register", + "RegisterItemEvent($2, ItemEvents.ITEM_EVENT_ON_USE, (...args) => $1(...args));" + ], + "description": "Item Event on Use", + "scope": "typescript" + }, + "Item Quest Accept": { + "prefix": "item_quest_accept", + "body": [ + "const $1: item_event_on_quest_accept = (event: number, player: Player, item: Item, quest: Quest): boolean => {", + "\t// Implementation", + "\treturn false; // Returning true will stop the action from happening", + "};", + "", + "// Register", + "RegisterItemEvent($2, ItemEvents.ITEM_EVENT_ON_QUEST_ACCEPT, (...args) => $1(...args));" + ], + "description": "Item Event on Quest Accept", + "scope": "typescript" + }, + "Item Expire": { + "prefix": "item_expire", + "body": [ + "const $1: item_event_on_expire = (event: number, player: Player, itemId: number): boolean => {", + "\t// Implementation", + "\treturn false; // Returning true will stop the action from happening", + "};", + "", + "// Register", + "RegisterItemEvent($2, ItemEvents.ITEM_EVENT_ON_EXPIRE, (...args) => $1(...args));" + ], + "description": "Item Event on Expire", + "scope": "typescript" + }, + "Item Remove": { + "prefix": "item_remove", + "body": [ + "const $1: item_event_on_remove = (event: number, player: Player, item: Item): boolean => {", + "\t// Implementation", + "\treturn false; // Returning true will stop the action from happening", + "};", + "", + "// Register", + "RegisterItemEvent($2, ItemEvents.ITEM_EVENT_ON_REMOVE, (...args) => $1(...args));" + ], + "description": "Item Event on Remove", + "scope": "typescript" + }, + "Character Create": { + "prefix": "player_character_create", + "body": [ + "const $1: player_event_on_character_create = (event: number, player: Player) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_CHARACTER_CREATE, (...args) => $1(...args));" + ], + "description": "Player Event on Character Create", + "scope": "typescript" + }, + "Character Delete": { + "prefix": "player_character_delete", + "body": [ + "const $1: player_event_on_character_delete = (event: number, guid: number) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_CHARACTER_DELETE, (...args) => $1(...args));" + ], + "description": "Player Event on Character Delete", + "scope": "typescript" + }, + "Login": { + "prefix": "player_login", + "body": [ + "const $1: player_event_on_login = (event: number, player: Player) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOGIN, (...args) => $1(...args));" + ], + "description": "Player Event on Login", + "scope": "typescript" + }, + "Logout": { + "prefix": "player_logout", + "body": [ + "const $1: player_event_on_logout = (event: number, player: Player) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOGOUT, (...args) => $1(...args));" + ], + "description": "Player Event on Logout", + "scope": "typescript" + }, + "Spell Cast": { + "prefix": "player_spell_cast", + "body": [ + "const $1: player_event_on_spell_cast = (event: number, player: Player, spell: Spell, skipCheck: boolean) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_SPELL_CAST, (...args) => $1(...args));" + ], + "description": "Player Event on Spell Cast", + "scope": "typescript" + }, + "Kill Player": { + "prefix": "player_kill_player", + "body": [ + "const $1: player_event_on_kill_player = (event: number, killer: Player, killed: Player) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_KILL_PLAYER, (...args) => $1(...args));" + ], + "description": "Player Event on Kill Player", + "scope": "typescript" + }, + "Kill Creature": { + "prefix": "player_kill_creature", + "body": [ + "const $1: player_event_on_kill_creature = (event: number, killer: Player, killed: Creature) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_KILL_CREATURE, (...args) => $1(...args));" + ], + "description": "Player Event on Kill Creature", + "scope": "typescript" + }, + "Killed by Creature": { + "prefix": "player_killed_by_creature", + "body": [ + "const $1: player_event_on_killed_by_creature = (event: number, killer: Creature, killed: Player) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_KILLED_BY_CREATURE, (...args) => $1(...args));" + ], + "description": "Player Event on Killed by Creature", + "scope": "typescript" + }, + "Duel Request": { + "prefix": "player_duel_request", + "body": [ + "const $1: player_event_on_duel_request = (event: number, target: Player, challenger: Player) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_DUEL_REQUEST, (...args) => $1(...args));" + ], + "description": "Player Event on Duel Request", + "scope": "typescript" + }, + "Duel Start": { + "prefix": "player_duel_start", + "body": [ + "const $1: player_event_on_duel_start = (event: number, starter: Player, challenger: Player) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_DUEL_START, (...args) => $1(...args));" + ], + "description": "Player Event on Duel Start", + "scope": "typescript" + }, + "Duel End": { + "prefix": "player_duel_end", + "body": [ + "const $1: player_event_on_duel_end = (event: number, winner: Player, loser: Player, type: DuelCompleteType) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_DUEL_END, (...args) => $1(...args));" + ], + "description": "Player Event on Duel End", + "scope": "typescript" + }, + "Give XP": { + "prefix": "player_give_xp", + "body": [ + "const $1: player_event_on_give_xp = (event: number, player: Player, amount: number, victim: Player) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_GIVE_XP, (...args) => $1(...args));" + ], + "description": "Player Event on Give XP", + "scope": "typescript" + }, + "Level Change": { + "prefix": "player_level_change", + "body": [ + "const $1: player_event_on_level_change = (event: number, player: Player, oldLevel: number) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LEVEL_CHANGE, (...args) => $1(...args));" + ], + "description": "Player Event on Level Change", + "scope": "typescript" + }, + "Money Change": { + "prefix": "player_money_change", + "body": [ + "const $1: player_event_on_money_change = (event: number, player: Player, amount: number) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_MONEY_CHANGE, (...args) => $1(...args));" + ], + "description": "Player Event on Money Change", + "scope": "typescript" + }, + "Reputation Change": { + "prefix": "player_reputation_change", + "body": [ + "const $1: player_event_on_reputation_change = (event: number, player: Player, factionId: number, standing: number, incremental: boolean) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_REPUTATION_CHANGE, (...args) => $1(...args));" + ], + "description": "Player Event on Reputation Change", + "scope": "typescript" + }, + "Talents Change": { + "prefix": "player_talents_change", + "body": [ + "const $1: player_event_on_talents_change = (event: number, player: Player, points: number) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_TALENTS_CHANGE, (...args) => $1(...args));" + ], + "description": "Player Event on Talents Change", + "scope": "typescript" + }, + "Talents Reset": { + "prefix": "player_talents_reset", + "body": [ + "const $1: player_event_on_talents_reset = (event: number, player: Player, noCost: boolean) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_TALENTS_RESET, (...args) => $1(...args));" + ], + "description": "Player Event on Talents Reset", + "scope": "typescript" + }, + "Chat": { + "prefix": "player_chat", + "body": [ + "const $1: player_event_on_chat = (event: number, player: Player, msg: string, Type: ChatMsg, lang: Language): string | boolean => {", + "\t// Implementation", + "\treturn '' // Return a string to override the message, or return nothing to keep the original message;", + "\treturn false // Return false to block the message, or return true to allow the message;", + "};", + "", + "// Register", + "RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_CHAT, (...args) => $1(...args));" + ], + "description": "Player Event on Chat", + "scope": "typescript" + }, + "Whisper": { + "prefix": "player_whisper", + "body": [ + "const $1: player_event_on_whisper = (event: number, player: Player, msg: string, Type: ChatMsg, lang: Language, receiver: Player): string | boolean => {", + "\t// Implementation", + "\treturn '' // Return a string to override the message, or return nothing to keep the original message;", + "\treturn false // Return false to block the message, or return true to allow the message;", + "};", + "", + "// Register", + "RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_WHISPER, (...args) => $1(...args));" + ], + "description": "Player Event on Whisper", + "scope": "typescript" + }, + "Group Chat": { + "prefix": "player_group_chat", + "body": [ + "const $1: player_event_on_group_chat = (event: number, player: Player, msg: string, Type: ChatMsg, lang: Language, group: Group): string | boolean => {", + "\t// Implementation", + "\treturn '' // Return a string to override the message, or return nothing to keep the original message;", + "\treturn false // Return false to block the message, or return true to allow the message;", + "};", + "", + "// Register", + "RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_GROUP_CHAT, (...args) => $1(...args));" + ], + "description": "Player Event on Group Chat", + "scope": "typescript" + }, + "Guild Chat": { + "prefix": "player_guild_chat", + "body": [ + "const $1: player_event_on_guild_chat = (event: number, player: Player, msg: string, Type: ChatMsg, lang: Language, guild: Guild): string | boolean => {", + "\t// Implementation", + "\treturn '' // Return a string to override the message, or return nothing to keep the original message;", + "\treturn false // Return false to block the message, or return true to allow the message;", + "};", + "", + "// Register", + "RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_GUILD_CHAT, (...args) => $1(...args));" + ], + "description": "Player Event on Guild Chat", + "scope": "typescript" + }, + "Channel Chat": { + "prefix": "player_channel_chat", + "body": [ + "const $1: player_event_on_channel_chat = (event: number, player: Player, msg: string, Type: ChatMsg, lang: Language, channel: number): string | boolean => {", + "\t// Implementation", + "\treturn '' // Return a string to override the message, or return nothing to keep the original message;", + "\treturn false // Return false to block the message, or return true to allow the message;", + "};", + "", + "// Register", + "RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_CHANNEL_CHAT, (...args) => $1(...args));" + ], + "description": "Player Event on Channel Chat", + "scope": "typescript" + }, + "Emote": { + "prefix": "player_emote", + "body": [ + "const $1: player_event_on_emote = (event: number, player: Player, emote: EmoteType) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_EMOTE, (...args) => $1(...args));" + ], + "description": "Player Event on Emote", + "scope": "typescript" + }, + "Text Emote": { + "prefix": "player_text_emote", + "body": [ + "const $1: player_event_on_text_emote = (event: number, player: Player, textEmote: string, emoteNum: number, guid: number) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_TEXT_EMOTE, (...args) => $1(...args));" + ], + "description": "Player Event on Text Emote", + "scope": "typescript" + }, + "Save": { + "prefix": "player_save", + "body": [ + "const $1: player_event_on_save = (event: number, player: Player) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_SAVE, (...args) => $1(...args));" + ], + "description": "Player Event on Save", + "scope": "typescript" + }, + "Bind to Instance": { + "prefix": "player_bind_to_instance", + "body": [ + "const $1: player_event_on_bind_to_instance = (event: number, player: Player, difficulty: Difficulty, mapid: number, permanent: boolean) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_BIND_TO_INSTANCE, (...args) => $1(...args));" + ], + "description": "Player Event on Bind to Instance", + "scope": "typescript" + }, + "Update Zone": { + "prefix": "player_update_zone", + "body": [ + "const $1: player_event_on_update_zone = (event: number, player: Player, newZone: ZoneIdType, newArea: number) => {", + "\tif(newZone === ZoneIdType.Dalaran) {", + "\t\t// Implementation", + "\t}", + "};", + "", + "// Register", + "RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_UPDATE_ZONE, (...args) => $1(...args));" + ], + "description": "Player Event on Update Zone", + "scope": "typescript" + }, + "Map Change": { + "prefix": "player_map_change", + "body": [ + "const $1: player_event_on_map_change = (event: number, player: Player) => {", + "\t// Implementation", + "};", + "", + "// Register", + "RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_MAP_CHANGE, (...args) => $1(...args));" + ], + "description": "Player Event on Map Change", + "scope": "typescript" + }, + "Server Packet Receive": { + "prefix": "server_packet_receive", + "body": [ + "const $1: server_event_on_packet_receive_any = (event: number, packet: WorldPacket, player?: Player): boolean | WorldPacket => {", + "\t// Implementation", + "\treturn false;", + "\treturn packet;", + "};", + "", + "// Register Server Event on Packet Receive", + "RegisterServerEvent(ServerEvents.SERVER_EVENT_ON_PACKET_RECEIVE, (...args) => $1(...args));" + ], + "description": "Server Event on Packet Receive", + "scope": "typescript" + }, + "Server Packet Send": { + "prefix": "server_packet_send", + "body": [ + "const $1: server_event_on_packet_send_any = (event: number, packet: WorldPacket, player?: Player): boolean | WorldPacket => {", + "\t// Implementation", + "\treturn false;", + "\treturn packet;", + "};", + "", + "// Register Server Event on Packet Send", + "RegisterServerEvent(ServerEvents.SERVER_EVENT_ON_PACKET_SEND, (...args) => $1(...args));" + ], + "description": "Server Event on Packet Send", + "scope": "typescript" + }, + "Server Open State Change": { + "prefix": "server_open_state_change", + "body": [ + "const $1: world_event_on_open_state_change = (event: number, open: boolean) => {", + "\t// Implementation", + "};", + "", + "// Register Server Event on Open State Change", + "RegisterServerEvent(ServerEvents.WORLD_EVENT_ON_OPEN_STATE_CHANGE, (...args) => $1(...args));" + ], + "description": "World Event on Open State Change", + "scope": "typescript" + }, + "Server Config Load": { + "prefix": "server_config_load", + "body": [ + "const $1: world_event_on_config_load = (event: number, reload: boolean) => {", + "\t// Implementation", + "};", + "", + "// Register Server Event on Config Load", + "RegisterServerEvent(ServerEvents.WORLD_EVENT_ON_CONFIG_LOAD, (...args) => $1(...args));" + ], + "description": "World Event on Config Load", + "scope": "typescript" + }, + "Server Shutdown Init": { + "prefix": "server_shutdown_init", + "body": [ + "const $1: world_event_on_shutdown_init = (event: number, code: number, mask: number) => {", + "\t// Implementation", + "};", + "", + "// Register Server Event on Shutdown Init", + "RegisterServerEvent(ServerEvents.WORLD_EVENT_ON_SHUTDOWN_INIT, (...args) => $1(...args));" + ], + "description": "World Event on Shutdown Init", + "scope": "typescript" + }, + "Server Shutdown Cancel": { + "prefix": "server_shutdown_cancel", + "body": [ + "const $1: world_event_on_shutdown_cancel = (event: number) => {", + "\t// Implementation", + "};", + "", + "// Register Server Event on Shutdown Cancel", + "RegisterServerEvent(ServerEvents.WORLD_EVENT_ON_SHUTDOWN_CANCEL, (...args) => $1(...args));" + ], + "description": "World Event on Shutdown Cancel", + "scope": "typescript" + }, + "Server Update": { + "prefix": "server_update", + "body": [ + "const $1: world_event_on_update = (event: number, diff: number) => {", + "\t// Implementation", + "};", + "", + "// Register Server Event on Update", + "RegisterServerEvent(ServerEvents.WORLD_EVENT_ON_UPDATE, (...args) => $1(...args));" + ], + "description": "World Event on Update", + "scope": "typescript" + }, + "Server Startup": { + "prefix": "server_startup", + "body": [ + "const $1: world_event_on_startup = (event: number) => {", + "\t// Implementation", + "};", + "", + "// Register Server Event on Startup", + "RegisterServerEvent(ServerEvents.WORLD_EVENT_ON_STARTUP, (...args) => $1(...args));" + ], + "description": "World Event on Startup", + "scope": "typescript" + }, + "Server Shutdown": { + "prefix": "server_shutdown", + "body": [ + "const $1: world_event_on_shutdown = (event: number) => {", + "\t// Implementation", + "};", + "", + "// Register Server Event on Shutdown", + "RegisterServerEvent(ServerEvents.WORLD_EVENT_ON_SHUTDOWN, (...args) => $1(...args));" + ], + "description": "World Event on Shutdown", + "scope": "typescript" + }, + "Server Lua State Open": { + "prefix": "server_lua_state_open", + "body": [ + "const $1: eluna_event_on_lua_state_open = (event: number) => {", + "\t// Implementation", + "};", + "", + "// Register Server Event on Lua State Open", + "RegisterServerEvent(ServerEvents.ELUNA_EVENT_ON_LUA_STATE_OPEN, (...args) => $1(...args));" + ], + "description": "Eluna Event on Lua State Open", + "scope": "typescript" + }, + "Server Delete Creature": { + "prefix": "server_delete_creature", + "body": [ + "const $1: world_event_on_delete_creature = (event: number, creature: Creature) => {", + "\t// Implementation", + "};", + "", + "// Register Server Event on Delete Creature", + "RegisterServerEvent(ServerEvents.WORLD_EVENT_ON_DELETE_CREATURE, (...args) => $1(...args));" + ], + "description": "World Event on Delete Creature", + "scope": "typescript" + }, + "Server Delete Gameobject": { + "prefix": "server_delete_gameobject", + "body": [ + "const $1: world_event_on_delete_gameobject = (event: number, gameObject: GameObject) => {", + "\t// Implementation", + "};", + "", + "// Register Server Event on Delete Gameobject", + "RegisterServerEvent(ServerEvents.WORLD_EVENT_ON_DELETE_GAMEOBJECT, (...args) => $1(...args));" + ], + "description": "World Event on Delete Gameobject", + "scope": "typescript" + }, + "Server Game Event Start": { + "prefix": "server_game_event_start", + "body": [ + "const $1: game_event_start = (event: number, gameEventId: number) => {", + "\t// Implementation", + "};", + "", + "// Register Server Event on Game Event Start", + "RegisterServerEvent(ServerEvents.GAME_EVENT_START, (...args) => $1(...args));" + ], + "description": "Game Event Start", + "scope": "typescript" + }, + "Server Game Event Stop": { + "prefix": "server_game_event_stop", + "body": [ + "const $1: game_event_stop = (event: number, gameEventId: number) => {", + "\t// Implementation", + "};", + "", + "// Register Server Event on Game Event Stop", + "RegisterServerEvent(ServerEvents.GAME_EVENT_STOP, (...args) => $1(...args));" + ], + "description": "Game Event Stop", + "scope": "typescript" + }, + "EMap Event on Create": { + "prefix": "server_map_on_create", + "body": [ + "const $1: map_event_on_create = (event: number, map: EMap) => {", + "\t// Implementation", + "};", + "", + "// Register Map Event on Create", + "RegisterServerEvent(ServerEvents.MAP_EVENT_ON_CREATE, (...args) => $1(...args));" + ], + "description": "Map Event on Create", + "scope": "typescript" + }, + "Map Event on Destroy": { + "prefix": "server_map_on_destroy", + "body": [ + "const $1: map_event_on_destroy = (event: number, map: EMap) => {", + "\t// Implementation", + "};", + "", + "// Register Map Event on Destroy", + "RegisterServerEvent(ServerEvents.MAP_EVENT_ON_DESTROY, (...args) => $1(...args));" + ], + "description": "Map Event on Destroy", + "scope": "typescript" + }, + "Map Event on Player Enter": { + "prefix": "server_map_on_player_enter", + "body": [ + "const $1: map_event_on_player_enter = (event: number, map: EMap, player: Player) => {", + "\t// Implementation", + "};", + "", + "// Register Map Event on Player Enter", + "RegisterServerEvent(ServerEvents.MAP_EVENT_ON_PLAYER_ENTER, (...args) => $1(...args));" + ], + "description": "Map Event on Player Enter", + "scope": "typescript" + }, + "Map Event on Player Leave": { + "prefix": "server_map_on_player_leave", + "body": [ + "const $1: map_event_on_player_leave = (event: number, map: EMap, player: Player) => {", + "\t// Implementation", + "};", + "", + "// Register Map Event on Player Leave", + "RegisterServerEvent(ServerEvents.MAP_EVENT_ON_PLAYER_LEAVE, (...args) => $1(...args));" + ], + "description": "Map Event on Player Leave", + "scope": "typescript" + }, + "Map Event on Update": { + "prefix": "server_map_on_update", + "body": [ + "const $1: map_event_on_update = (event: number, map: EMap, diff: number) => {", + "\t// Implementation", + "};", + "", + "// Register Map Event on Update", + "RegisterServerEvent(ServerEvents.MAP_EVENT_ON_UPDATE, (...args) => $1(...args));" + ], + "description": "Map Event on Update", + "scope": "typescript" + }, + "Trigger Event on Trigger": { + "prefix": "server_trigger", + "body": [ + "const $1: trigger_event_on_trigger = (event: number, player: Player, triggerId: number): boolean => {", + "\t// Implementation", + "\treturn false;", + "};", + "", + "// Register Trigger Event on Trigger", + "RegisterServerEvent(ServerEvents.TRIGGER_EVENT_ON_TRIGGER, (...args) => $1(...args));" + ], + "description": "Trigger Event on Trigger", + "scope": "typescript" + }, + "Weather Event on Change": { + "prefix": "weather_on_change", + "body": [ + "const $1: weather_event_on_change = (event: number, zoneId: number, state: WeatherState, grade: number) => {", + "\t// Implementation", + "};", + "", + "// Register Weather Event on Change", + "RegisterServerEvent(ServerEvents.WEATHER_EVENT_ON_CHANGE, (...args) => $1(...args));" + ], + "description": "Weather Event on Change", + "scope": "typescript" + }, + "Auction Event on Add": { + "prefix": "auction_on_add", + "body": [ + "const $1: auction_event_on_add = (event: number, auctionId: number, owner: Player, item: Item, expireTime: number, buyout: number, startBid: number, currentBid: number, bidderGUIDLow: number) => {", + "\t// Implementation", + "};", + "", + "// Register Auction Event on Add", + "RegisterServerEvent(ServerEvents.AUCTION_EVENT_ON_ADD, (...args) => $1(...args));" + ], + "description": "Auction Event on Add", + "scope": "typescript" + }, + "Auction Event on Remove": { + "prefix": "auction_on_remove", + "body": [ + "const $1: auction_event_on_remove = (event: number, auctionId: number, owner: Player, item: Item, expireTime: number, buyout: number, startBid: number, currentBid: number, bidderGUIDLow: number) => {", + "\t// Implementation", + "};", + "", + "// Register Auction Event on Remove", + "RegisterServerEvent(ServerEvents.AUCTION_EVENT_ON_REMOVE, (...args) => $1(...args));" + ], + "description": "Auction Event on Remove", + "scope": "typescript" + }, + "Auction Event on Successful": { + "prefix": "auction_on_successful", + "body": [ + "const $1: auction_event_on_successful = (event: number, auctionId: number, owner: Player, item: Item, expireTime: number, buyout: number, startBid: number, currentBid: number, bidderGUIDLow: number) => {", + "\t// Implementation", + "};", + "", + "// Register Auction Event on Successful", + "RegisterServerEvent(ServerEvents.AUCTION_EVENT_ON_SUCCESSFUL, (...args) => $1(...args));" + ], + "description": "Auction Event on Successful", + "scope": "typescript" + }, + "Auction Event on Expire": { + "prefix": "auction_on_expire", + "body": [ + "const $1: auction_event_on_expire = (event: number, auctionId: number, owner: Player, item: Item, expireTime: number, buyout: number, startBid: number, currentBid: number, bidderGUIDLow: number) => {", + "\t// Implementation", + "};", + "", + "// Register Auction Event on Expire", + "RegisterServerEvent(ServerEvents.AUCTION_EVENT_ON_EXPIRE, (...args) => $1(...args));" + ], + "description": "Auction Event on Expire", + "scope": "typescript" + }, + "AddOn Event on Message": { + "prefix": "addon_on_message", + "body": [ + "const $1: addon_event_on_message = (event: number, sender: string, type: AddonMessageType, prefix: string, msg: string, target?: string) => {", + "\t// Implementation", + "};", + "", + "// Register AddOn Event on Message", + "RegisterServerEvent(ServerEvents.ADDON_EVENT_ON_MESSAGE, (...args) => $1(...args));" + ], + "description": "AddOn Event on Message", + "scope": "typescript" + } +} diff --git a/development/dungeon-elites.ts b/development/dungeon-elites.ts deleted file mode 100644 index ac50063..0000000 --- a/development/dungeon-elites.ts +++ /dev/null @@ -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 onUtPlayerEnter(...args)); \ No newline at end of file diff --git a/development/gameplay/dungeon-elites.ts b/development/gameplay/dungeon-elites.ts new file mode 100644 index 0000000..9fd7c7d --- /dev/null +++ b/development/gameplay/dungeon-elites.ts @@ -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 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)); \ No newline at end of file diff --git a/development/gameplay/goblin-chaos.ts b/development/gameplay/goblin-chaos.ts new file mode 100644 index 0000000..2c8e058 --- /dev/null +++ b/development/gameplay/goblin-chaos.ts @@ -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]); + +}); \ No newline at end of file diff --git a/development/player_command.ts b/development/gameplay/player_command.ts similarity index 100% rename from development/player_command.ts rename to development/gameplay/player_command.ts diff --git a/development/specialty_items/index.ts b/development/gameplay/special_miner.ts similarity index 100% rename from development/specialty_items/index.ts rename to development/gameplay/special_miner.ts diff --git a/development/gm/player_command.ts b/development/gm/player_command.ts new file mode 100644 index 0000000..4dae2ea --- /dev/null +++ b/development/gm/player_command.ts @@ -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) +) diff --git a/development/gothuk-oakenstein.lua b/development/gothuk-oakenstein.lua deleted file mode 100644 index e20165c..0000000 --- a/development/gothuk-oakenstein.lua +++ /dev/null @@ -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 diff --git a/development/gothuk-oakenstein.ts b/development/gothuk-oakenstein.ts deleted file mode 100644 index dc26ae5..0000000 --- a/development/gothuk-oakenstein.ts +++ /dev/null @@ -1,245 +0,0 @@ -import { ToGold, ToCopper, GetPlayerTax } from "../modules/classes/money"; -import { AccountInfo } from "../modules/classes/account"; - -const spawned:Array = []; -const NPCS = { - GOTHUK: 9000003, - BERNIE: 9000004, - EDWARD: 9000005, - LUNA: 9000006, - BOB_B: 9000007, - SHIVA: 9000008 -}; -const selectedItem: Record = {}; -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)); - diff --git a/development/mythic/mythic_advancement.client.ts b/development/mythic/mythic_advancement.client.ts new file mode 100644 index 0000000..5d586db --- /dev/null +++ b/development/mythic/mythic_advancement.client.ts @@ -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 = new Map(); + const itemSlots: Map = 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(); + }; +} diff --git a/development/mythic/mythic_advancement.server.ts b/development/mythic/mythic_advancement.server.ts new file mode 100644 index 0000000..24b31b4 --- /dev/null +++ b/development/mythic/mythic_advancement.server.ts @@ -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)); + diff --git a/development/rift-teleport.ts b/development/rift-teleport.ts deleted file mode 100644 index 59a48b1..0000000 --- a/development/rift-teleport.ts +++ /dev/null @@ -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)); - diff --git a/development/soulswapper/soulswapper-client.ts b/development/soulswapper/soulswapper-client.ts deleted file mode 100644 index 7f1f8a0..0000000 --- a/development/soulswapper/soulswapper-client.ts +++ /dev/null @@ -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(); - -} \ No newline at end of file diff --git a/development/soulswapper/soulswapper-server.ts b/development/soulswapper/soulswapper-server.ts deleted file mode 100644 index 60a1812..0000000 --- a/development/soulswapper/soulswapper-server.ts +++ /dev/null @@ -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) -); - \ No newline at end of file diff --git a/development/transmog/transmog.client.ts b/development/transmog/transmog.client.ts deleted file mode 100644 index ad9e713..0000000 --- a/development/transmog/transmog.client.ts +++ /dev/null @@ -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); - } - -} diff --git a/development/transmog/transmog.server.ts b/development/transmog/transmog.server.ts deleted file mode 100644 index 6bdc190..0000000 --- a/development/transmog/transmog.server.ts +++ /dev/null @@ -1,3 +0,0 @@ -/** @ts-expect-error */ -let aio: AIO = {}; - diff --git a/ets.examples.combined.ts b/ets.examples.combined.ts new file mode 100644 index 0000000..99e5aca --- /dev/null +++ b/ets.examples.combined.ts @@ -0,0 +1,2873 @@ +import { BotData } from './botmgr.server'; +import { Equipment } from './botmgr.server'; + +type ItemInHand = { + entry: number | undefined, + link: string | undefined, + bot: number | undefined, + slot: number | undefined +} + +/** + * 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 = new Map(); + private active: number = null; + private pickedUp: boolean = false; + private itemInHand: ItemInHand = { entry: undefined, link: undefined, bot: undefined, slot: undefined }; + private bankItem: { entry: number, link: string, slot: number } = { entry: 0, link: '', slot: 0 }; + + public GetBotData(entry: number): BotData | undefined { + return this.storage.get(entry); + } + + GetBotItem(botId: number, slot: BotEquipmentSlotNum): Equipment | undefined { + const bot = this.GetBotData(botId); + if(bot) { + return bot.equipment[slot]; + } + } + + SetBotData(entry: number, data: BotData): void { + this.storage.set(entry, data); + } + + SetBotItem(botId: number, slot: BotEquipmentSlotNum, item: Equipment): void { + const botData = this.GetBotData(botId); + if(botData) { + botData.equipment[slot] = item; + } + + this.SetBotData(botId, botData); + } + + UpdateBotData(entry: number, data: BotData): void { + this.storage.set(entry, data); + } + + SetActive(botId: number): void { + this.active = botId; + } + + GetActive(): number { + return this.active; + } + + ClearActive(): void { + this.active = null; + } + + IsPickedUp(): boolean { + return this.pickedUp; + } + + BotItemPickedUp(botId: number, entry: number, link: string): void { + const bot = this.GetBotData(botId); + if(bot) { + this.itemInHand.entry = entry; + this.itemInHand.link = link; + this.itemInHand.bot = botId; + this.itemInHand.slot = this.GetSlotByItemId(entry); + } + this.pickedUp = true; + + } + + GetItemInHand(): ItemInHand { + return this.itemInHand; + } + + GetFromBank(): { entry: number, link: string, slot: number } | undefined { + if(!this.bankItem) { + return undefined; + } + + return this.bankItem; + } + + SetFromBank(item: { entry: number, link: string, slot: number }): void { + this.bankItem = item; + } + + ClearFromBank(): void { + this.bankItem = undefined; + } + + BotItemCursorClear(): void { + this.itemInHand = undefined; + this.pickedUp = false; + } + + GetSlotByItemId(entry: number): number | undefined { + const botData = this.GetBotData(this.GetActive()); + const allItems = Object.entries(botData.equipment) + for(const [slot, item] of allItems) { + if(item.entry === entry) { + return parseInt(slot); + } + } + return; + } + + +}import * as Common from '../../constants/idmaps'; +import { BotData, 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 = Partial>; + +function humanizeTalentName(input: string): string { + if (input.length === 0) { + return input; // Return unchanged if the input is an empty string + } + + try { + const parts = input.split("_"); + parts[0] = parts[0].toLowerCase(); + parts[0] = parts[0].charAt(0).toUpperCase() + parts[0].slice(1); + parts[1] = parts[1].toLowerCase(); + parts[1] = parts[1].charAt(0).toUpperCase() + parts[1].slice(1); + + return `${parts[1]} ${parts[0]}`; + } catch (e) { + print(`failed to humanize talent name: ${input}` + e); + } + +} +export class BotUnit { + + protected myself: Creature; + protected myOwner: Player; + protected charinfo: CharInfo; + protected equipment: EquipmentList; + protected statsLeft: Record[]; + protected statsRight: Record[]; + protected talentSpecId: number; + protected roles: number; + protected allStats: Record = {}; + + constructor(creature: Creature) { + if(!creature.IsNPCBot()) { + return; + } + + this.myself = creature; + this.myOwner = creature.GetBotOwner(); + 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.talentSpecId = creature.GetTalentSpec(); + this.parseStats(creature.GetBotDump()); + try { + this.statsLeft = this._lookupStats('left'); + this.statsRight = this._lookupStats('right'); + } catch (e) { + print("failed to get stats for bot:" + e); + } + + this.roles = creature.GetBotRoles(); + + + } + + public toBotData(): BotData { + return { + name: this.charinfo.name, + entry: this.myself.GetEntry(), + owner: this.myOwner.GetName(), + level: this.charinfo.level, + class: this.charinfo.className, + classId: this.charinfo.classId, + race: this.charinfo.raceName, + raceId: this.charinfo.raceId, + talentSpec: this.talentSpecId, + talentSpecName: humanizeTalentName(this.talentSpecName()), + roles: this.roles, + equipment: this.equipment, + leftStats: this.statsLeft, + rightStats: this.statsRight, + allStats: this.allStats + } + } + + public isHealer(): boolean { + if(this.talentSpecId == Common.TalentSpecs.SHAMAN_RESTORATION || + this.talentSpecId == Common.TalentSpecs.PRIEST_DISCIPLINE || + this.talentSpecId == Common.TalentSpecs.PRIEST_HOLY || + this.talentSpecId == Common.TalentSpecs.PALADIN_HOLY || + this.talentSpecId == Common.TalentSpecs.DRUID_RESTORATION) { + return true; + } + return false; + } + + public isDualWield(): boolean { + if(this.talentSpecId == Common.TalentSpecs.ROGUE_COMBAT || + this.talentSpecId == Common.TalentSpecs.ROGUE_SUBTLETY || + this.talentSpecId == Common.TalentSpecs.ROGUE_ASSASSINATION || + this.talentSpecId == Common.TalentSpecs.SHAMAN_ENHANCEMENT || + this.talentSpecId == Common.TalentSpecs.WARRIOR_FURY) { + if(this.equipment[Common.BotEquipSlot.MAINHAND] && + this.equipment[Common.BotEquipSlot.OFFHAND]) { + return true; + } + + } + } + + + public GetMeleeStats (): Record{ + const botStatValues = Object.values(Common.BotStatLabel); + type BotStatValues = typeof botStatValues[number]; + + return { + left: [ + "Strength", + "Agility", + "Damage", + "Power", + "Hit Rating", + "Crit %", + "Expertise", + "Armor Pen" + ], + right: [ + "Haste Rating", + "Armor", + "Stamina", + "Defense", + "Dodge", + "Parry", + "Block", + "Physical Res." + ] + } + } + + public GetRangedStats (): Record{ + return { + left: [ + "Strength", + "Agility", + "Damage Rng", + "Speed", + "Power", + "Hit Rating", + "Crit %", + "Armor Pen" + ], + right: [ + "Expertise", + "Haste Rating", + "Armor", + "Stamina", + "Defense", + "Dodge", + "Parry", + "Block", + ] + } + } + + public GetCasterStats (): Record { + return { + left: [ + "Intellect", + "Spirit", + "Stamina", + "Bonus Dmg", + "Crit %", + "Hit Rating", + "Spell Pen" + ], + right: [ + "Haste Rating", + "MP5", + "Spell Res.", + "Dodge", + "Armor", + "Parry", + ] + } + } + + public GetStatMappings() { + + switch(this.talentSpecId) { + case Common.TalentSpecs.WARRIOR_ARMS: + case Common.TalentSpecs.WARRIOR_FURY: + case Common.TalentSpecs.WARRIOR_PROTECTION: + case Common.TalentSpecs.PALADIN_PROTECTION: + case Common.TalentSpecs.PALADIN_RETRIBUTION: + case Common.TalentSpecs.DK_BLOOD: + case Common.TalentSpecs.DK_FROST: + case Common.TalentSpecs.DK_UNHOLY: + case Common.TalentSpecs.ROGUE_ASSASSINATION: + case Common.TalentSpecs.ROGUE_COMBAT: + case Common.TalentSpecs.ROGUE_SUBTLETY: + case Common.TalentSpecs.SHAMAN_ENHANCEMENT: + case Common.TalentSpecs.DRUID_FERAL: + return this.GetMeleeStats(); + + case Common.TalentSpecs.HUNTER_SURVIVAL: + case Common.TalentSpecs.HUNTER_MARKSMANSHIP: + case Common.TalentSpecs.HUNTER_BEASTMASTERY: + return this.GetRangedStats(); + + case Common.TalentSpecs.MAGE_ARCANE: + case Common.TalentSpecs.MAGE_FIRE: + case Common.TalentSpecs.MAGE_FROST: + case Common.TalentSpecs.WARLOCK_AFFLICTION: + case Common.TalentSpecs.WARLOCK_DEMONOLOGY: + case Common.TalentSpecs.WARLOCK_DESTRUCTION: + case Common.TalentSpecs.PRIEST_DISCIPLINE: + case Common.TalentSpecs.PRIEST_HOLY: + case Common.TalentSpecs.PRIEST_SHADOW: + case Common.TalentSpecs.SHAMAN_ELEMENTAL: + case Common.TalentSpecs.SHAMAN_RESTORATION: + case Common.TalentSpecs.DRUID_BALANCE: + case Common.TalentSpecs.DRUID_RESTORATION: + return this.GetCasterStats(); + + default: + print(`Unknown Talent Spec: ${this.talentSpecId}`); + } + } + + public talentSpecName() { + // print(`Talent Spec: ${this.talentSpecId}`); + const keys = Object.keys(Common.TalentSpecs); + for(let i=0; i < keys.length; i++) { + if(Common.TalentSpecs[keys[i]] === this.talentSpecId) { + return keys[i]; + } + } + } + + private _lookupEquipment(): EquipmentList { + const myEquipment = {} as EquipmentList; + for(let slot=0; slot <= Common.BotEquipLast; slot++) { + const equipment = this.myself.GetBotEquipment(slot); + + if(equipment) { + myEquipment[slot] = { + entry: equipment.GetEntry(), + link: equipment.GetItemLink(), + quality: equipment.GetQuality(), + itemLevel: equipment.GetItemLevel(), + enchantmentId: equipment.GetEnchantmentId(0), // Only the permenant enchantments + } + } else { + myEquipment[slot] = undefined; + } + } + + return myEquipment; + } + + private _lookupStats(panel: 'left' | 'right'): Record[] { + const statMappings = this.GetStatMappings(); + const classStats: Record[] = [] + + for(let stat = 0; stat < statMappings[panel].length; stat++) { + const statName = statMappings[panel][stat]; + let statValue = this.allStats[statName]; + const statRecord= {}; + + // skip offhand stats will be handled with main hand + if(statName === 'Dmg Off') { + continue; + } + + // handle some special cases for stats + if(statName === 'Damage') { + statRecord[statName] = statValue; + classStats.push(statRecord); + + // Go ahead and add dual wield damage also + if(this.isDualWield()) { + //statRecord['Dmg Off'] = statValue; + //classStats.push(statRecord); + } + continue; + } + + if(this.isHealer() && statName === 'Bonus Dmg') { + statRecord['Bonus Heals'] = statValue; + classStats.push(statRecord); + // print(`Stat: Bonus Heals = ${statValue}`); + continue; + } + + if(statName && statValue) { + statRecord[statName] = statValue; + classStats.push(statRecord); + // print(`Stat: ${statName} = ${statValue}`); + } else { + // print("failed to get stat: " + statName); + } + + } + + return classStats; + } + + private parseStats(botdump: string) { + const stats = botdump.split('\n'); + for(let i=0; i `BotMgr${name}` + (entry ? entry : ''); +const compId = (botId: number, name: string) => `${botId}:BotMgr${name}`; + +// includes of global polyfills in main file for submodules +let incObjectEntries = { 1: 'inlude'}; Object.entries(incObjectEntries); +let incParseInt = parseInt('1'); + +function ucase(input: string): string { + if (input.length === 0) { + return input; // Return unchanged if the input is an empty string + } + const firstLetter = input.charAt(0).toUpperCase(); + let restOfTheString = input.slice(1).toLowerCase(); + + if(input.slice(-1) == "1" || input.slice(-1) == "2") { + restOfTheString = restOfTheString.slice(0, -1); + } + + return firstLetter + restOfTheString; +} + +function humanizeName(input: string): string { + if (input.length === 0) { + return input; // Return unchanged if the input is an empty string + } + + const parts = input.split("_"); + parts[0] = parts[0].toLowerCase(); + parts[0] = parts[0].charAt(0).toUpperCase() + parts[0].slice(1); + parts[1] = parts[1].toLowerCase(); + parts[1] = parts[1].charAt(0).toUpperCase() + parts[1].slice(1); + + return `${parts[1]} ${parts[0]}`; +} + +// If we are a client file. aio.AddAddon() will return false and this file will be serialized and sent to client. +if(!aio.AddAddon()) { + + const botMgrHandlers = aio.AddHandlers('BotMgr', {}); + const InfoFramePool: Map = new Map(); + const ComponentsPool: Map = new Map(); // key botId + ":" + componentid + const ItemClickFuncs: Map = new Map(); // containerid (1-13):itemslotId (1-36) => click function + const botStorage: BotStorage = new BotStorage(); + + let BotItemTooltip: WoWAPI.GameTooltip; + + function AddResistFrame(parent: WoWAPI.Frame, botData: BotData) { + const resistFrame = CreateFrame("Frame", id("ResistsFrame"), parent); + resistFrame.SetSize(32, 160); + resistFrame.SetPoint("TOPRIGHT", parent, "TOPLEFT", 297, -77); + + const magicRes1 = CreateFrame("Frame", id("MagicResFrame1"), resistFrame, "MagicResistanceFrameTemplate", 1); + magicRes1.SetPoint("TOP", 0, 0); + magicRes1.SetSize(32, 32); + + const magResBack1 = magicRes1.CreateTexture(id("MagicResTexture1"), "BACKGROUND"); + magResBack1.SetTexture("Interface\\PaperDollInfoFrame\\UI-Character-ResistanceIcons"); + magResBack1.SetTexCoord(0, 1, 0.2265, 0.3398); + magResBack1.SetAllPoints(magicRes1); + + const magResFont1 = magicRes1.CreateFontString(id("Resist2"), "BACKGROUND", "GameFontHighlightSmall"); + magResFont1.SetPoint("BOTTOM", magResBack1, null, 0, 3); + magResFont1.SetText(`${GREEN_FONT_COLOR_CODE}${botData.allStats["Resistance: arcane"]}`); + ComponentsPool.set(compId(botData.entry, "Resist1"), magResFont1); + + // End Arcance Resistance + + const magicRes2 = CreateFrame("Frame", id("MagicResFrame2"), resistFrame, "MagicResistanceFrameTemplate", 2); + magicRes2.SetPoint("TOP", magicRes1, "BOTTOM", 0, 0); + magicRes2.SetSize(32, 32); + + const magResBack2 = magicRes2.CreateTexture(id("MagicResTexture2"), "BACKGROUND"); + magResBack2.SetTexture("Interface\\PaperDollInfoFrame\\UI-Character-ResistanceIcons"); + magResBack2.SetTexCoord(0, 1, 0, 0.11328125); + magResBack2.SetAllPoints(magicRes2); + + const magResFont2 = magicRes1.CreateFontString(id("Resist2"), "BACKGROUND", "GameFontHighlightSmall"); + magResFont2.SetPoint("BOTTOM", magicRes2, null, 0, 3); + magResFont2.SetText(`${GREEN_FONT_COLOR_CODE}${botData.allStats["Resistance: fire"]}`); + ComponentsPool.set(compId(botData.entry, "Resist2"), magResFont2); + + // end fire resistance + + const magicRes3 = CreateFrame("Frame", id("MagicResFrame3"), resistFrame, "MagicResistanceFrameTemplate", 3); + magicRes3.SetPoint("TOP", magicRes2, "BOTTOM", 0, 0); + magicRes3.SetSize(32, 32); + + const magResBack3 = magicRes3.CreateTexture(id("MagicResTexture3"), "BACKGROUND"); + magResBack3.SetTexture("Interface\\PaperDollInfoFrame\\UI-Character-ResistanceIcons"); + magResBack3.SetTexCoord(0, 1, 0.11328125, 0.2265625); + magResBack3.SetAllPoints(magicRes3); + + const magResFont3 = magicRes3.CreateFontString(id("Resist3"), "BACKGROUND", "GameFontHighlightSmall"); + magResFont3.SetPoint("BOTTOM", magicRes3, null, 0, 3); + magResFont3.SetText(`${GREEN_FONT_COLOR_CODE}${botData.allStats["Resistance: nature"]}`); + ComponentsPool.set(compId(botData.entry, "Resist3"), magResFont3); + + // end nature resistance + + const magicRes4 = CreateFrame("Frame", id("MagicResFrame4"), resistFrame, "MagicResistanceFrameTemplate", 4); + magicRes4.SetPoint("TOP", magicRes3, "BOTTOM", 0, 0); + magicRes4.SetSize(32, 32); + + const magResBack4 = magicRes4.CreateTexture(id("MagicResTexture4"), "BACKGROUND"); + magResBack4.SetTexture("Interface\\PaperDollInfoFrame\\UI-Character-ResistanceIcons"); + magResBack4.SetTexCoord(0, 1, 0.33984375, 0.453125); + magResBack4.SetAllPoints(magicRes4); + + const magResFont4 = magicRes4.CreateFontString(id("Resist4"), "BACKGROUND", "GameFontHighlightSmall"); + magResFont4.SetPoint("BOTTOM", magicRes4, null, 0, 3); + magResFont4.SetText(`${GREEN_FONT_COLOR_CODE}${botData.allStats["Resistance: frost"]}`); + ComponentsPool.set(compId(botData.entry, "Resist4"), magResFont4); + + // end frost resistance + + const magicRes5 = CreateFrame("Frame", id("MagicResFrame5"), resistFrame, "MagicResistanceFrameTemplate", 5); + magicRes5.SetPoint("TOP", magicRes4, "BOTTOM", 0, 0); + magicRes5.SetSize(32, 32); + + const magResBack5 = magicRes5.CreateTexture(id("MagicResTexture5"), "BACKGROUND"); + magResBack5.SetTexture("Interface\\PaperDollInfoFrame\\UI-Character-ResistanceIcons"); + magResBack5.SetTexCoord(0, 1, 0.453125, 0.56640625); + magResBack5.SetAllPoints(magicRes5); + + const magResFont5 = magicRes5.CreateFontString(id("Resist5"), "BACKGROUND", "GameFontHighlightSmall"); + magResFont5.SetPoint("BOTTOM", magicRes5, null, 0, 3); + magResFont5.SetText(`${GREEN_FONT_COLOR_CODE}${botData.allStats["Resistance: shadow"]}`); + ComponentsPool.set(compId(botData.entry, "Resist5"), magResFont5); + + // end shadow resistance + } + + function AddPortrait(parent: WoWAPI.Frame, botData: BotData) { + const portrait = parent.CreateTexture(id("Portrait", botData.entry), "ARTWORK"); + portrait.SetPoint("TOPLEFT", 10, -7); + portrait.SetSize(58, 58); + + SetPortraitTexture(portrait, "target"); + + const characterName = CreateFrame("Frame", id("CharacterName", botData.entry), parent); + characterName.SetSize(109,12); + characterName.SetPoint("CENTER",6,232); + characterName.SetScript("OnLoad", (frame) => { + RaiseFrameLevel(frame); + }); + + const charFont = characterName.CreateFontString(id("CharacterNameFont", botData.entry), "BACKGROUND", "GameFontNormal"); + charFont.SetText(GetUnitName("target", false)); + charFont.SetSize(300,12); + charFont.SetPoint("CENTER",0,0); + charFont.SetTextColor(1,1,1,1); + + const infoTextFrame = CreateFrame("Frame", id("InfoTextFrame", botData.entry), parent); + infoTextFrame.SetSize(200,12); + infoTextFrame.SetPoint("CENTER", characterName, "BOTTOM", 0, -15); + infoTextFrame.SetScript("OnLoad", (frame) => { + RaiseFrameLevel(frame); + }); + + const infoTextFont = infoTextFrame.CreateFontString(id("InfoTextFont", botData.entry), "BACKGROUND", "GameFontHighlightSmall"); + if(botData.classId > 10) { + infoTextFont.SetText(`${YELLOW_FONT_COLOR_CODE} Level ${UnitLevel("target")} ${botData.class}`); + } else { + infoTextFont.SetText(`${YELLOW_FONT_COLOR_CODE} Level ${UnitLevel("target")} ${botData.race} ${botData.class}`); + } + + const spec = infoTextFrame.CreateFontString(id("SpecFont", botData.entry), "BACKGROUND", "GameFontHighlightSmall"); + spec.SetText(`${botData.talentSpecName}`); + spec.SetPoint("TOP", infoTextFont, "BOTTOM", 0, -2); + ComponentsPool.set(compId(botData.entry, "SpecFont"), spec); + + infoTextFont.SetSize(300,12); + 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, 175); + frameChar.SetUnit("target"); + 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) { + let slotOrder = []; + + switch(group) { + case 'left': + slotOrder = [BotEquipSlot.HEAD,BotEquipSlot.NECK,BotEquipSlot.SHOULDERS,BotEquipSlot.BACK,BotEquipSlot.CHEST,-1,-2,BotEquipSlot.WRIST]; + break; + case 'right': + slotOrder = [BotEquipSlot.HANDS,BotEquipSlot.WAIST,BotEquipSlot.LEGS,BotEquipSlot.FEET,BotEquipSlot.FINGER1,BotEquipSlot.FINGER2,BotEquipSlot.TRINKET1,BotEquipSlot.TRINKET2]; + break; + case 'weapons': + slotOrder = [BotEquipSlot.MAINHAND,BotEquipSlot.OFFHAND,BotEquipSlot.RANGED]; + break; + } + + // loop through the left equipment and create the buttons and texture. + for(let i = 0; i < slotOrder.length; i++) { + const itemSlotId = slotOrder[i] >= 0 ? slotOrder[i] : 92+slotOrder[i]; + const equipSlot = CreateFrame("Button", id(`${group}-EquipmentSlot-${slotOrder[i]}`), parent, "ItemButtonTemplate", itemSlotId); + + if(group === 'weapons') + 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 equippedItem: Equipment = botData.equipment[slotOrder[i]]; + let itemIcon: WoWAPI.TexturePath; + let itemId: number; + let idsuffix: string | number; + + // If it is a shirt or tabard which are not supported just show the background texture. + if(slotOrder[i] < 0) { + const shirtOrTabard = (slotOrder[i] === -1) ? "SHIRT" : "TABARD"; + [itemId, itemIcon] = GetInventorySlotInfo(UIInvSlot[`${shirtOrTabard}SLOT`]); + idsuffix = shirtOrTabard + } + + // If we have a piece of equipment add the icon template + 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(!equippedItem && slotOrder[i] > 0) { + let slotName = BotSlotName[slotOrder[i]]; + + if(slotOrder[i] === BotEquipSlot.FINGER1) slotName = "FINGER0"; + if(slotOrder[i] === BotEquipSlot.FINGER2) slotName = "FINGER1"; + if(slotOrder[i] === BotEquipSlot.TRINKET1) slotName = "TRINKET0"; + if(slotOrder[i] === BotEquipSlot.TRINKET2) slotName = "TRINKET1"; + if(slotOrder[i] === BotEquipSlot.OFFHAND) slotName = "SECONDARYHAND"; + + [itemId, itemIcon] = GetInventorySlotInfo(UIInvSlot[`${slotName}SLOT`]); + idsuffix = slotOrder[i]; + } + + const itemTexture = equipSlot.CreateTexture(id(`ItemTexture-${idsuffix}`), "OVERLAY"); + itemTexture.SetTexture(itemIcon); + itemTexture.SetPoint("CENTER", 0, 0); + itemTexture.SetSize(36,36); + ComponentsPool.set(compId(botData.entry, `ItemSlotTexture-${itemSlotId}`), itemTexture); + } + } + + function AddEquipmentFrames(parent: WoWAPI.Frame, botData: BotData) { + + // Get all our frames + const frames = { + left: ComponentsPool.get(compId(botData.entry, "LeftEquipment")), + right: ComponentsPool.get(compId(botData.entry, "RightEquipment")), + weapons: ComponentsPool.get(compId(botData.entry, "WeaponsEquipment")) + }; + + let equipFrame: WoWAPI.Frame; + if(!frames.left) { + equipFrame = CreateFrame("Frame", id("LeftEquipment"), parent, null, 1); + equipFrame.SetPoint("TOPLEFT", 20, -73); + equipFrame.SetSize(40, 330); + UpdateEquipFrame('left', equipFrame, botData); + ComponentsPool.set(compId(botData.entry, "LeftEquipment"), equipFrame); + + } + + if(!frames.right) { + equipFrame = CreateFrame("Frame", id("RightEquipment"), parent, null, 2); + equipFrame.SetPoint("TOPRIGHT", -40, -73); + equipFrame.SetSize(40, 330); + UpdateEquipFrame('right', equipFrame, botData); + ComponentsPool.set(compId(botData.entry, "RightEquipment"), equipFrame); + } + + if(!frames.weapons) { + equipFrame = CreateFrame("Frame", id("WeaponEquipment"), parent, null, 3); + equipFrame.SetPoint("CENTER", -10, -147); + equipFrame.SetSize(129, 40); + UpdateEquipFrame('weapons', equipFrame, botData); + ComponentsPool.set(compId(botData.entry, "WeaponsEquipment"), equipFrame); + } + + } + + function AddStats(parent: WoWAPI.Frame | undefined, botData: BotData) { + const leftStats = botData.leftStats; + const rightStats = botData.rightStats; + for(let i =0; i < leftStats.length; i++) { + const statName = Object.keys(leftStats[i])[0]; + + let statLabel = ComponentsPool.get(compId(botData.entry, `StatName-${statName}`)); + if(!statLabel) { + statLabel = parent.CreateFontString(id(`StatName-${statName}`), "ARTWORK", "GameFontNormalSmall"); + statLabel.SetPoint("TOPLEFT", parent, "TOPLEFT", 5, -7 - (i * 14)); + statLabel.SetJustifyH("LEFT"); + statLabel.SetText(`${statName}:`); + ComponentsPool.set(compId(botData.entry, `StatName-${statName}`), statLabel); + } + + let statValue = ComponentsPool.get(compId(botData.entry, `StatValue-${statName}`)); + // if there is not an existing component create a new one + if(!statValue) { + statValue = parent.CreateFontString(id(`StatValue-${statName}`), "ARTWORK", "GameFontNormalSmall"); + statValue.SetPoint("TOPRIGHT", parent, "TOP", -4, -5 - (i * 14)); + if(statName === "Damage") { + statValue.SetSize(90, 14); + } else { + statValue.SetSize(50, 14); + } + statValue.SetJustifyH("RIGHT"); + ComponentsPool.set(compId(botData.entry, `StatValue-${statName}`), statValue); + } + statValue.SetText(`${colors('white')}${leftStats[i][statName]}`); + } + + for(let i =0; i < rightStats.length; i++) { + const statName = Object.keys(rightStats[i])[0]; + let statLabel = ComponentsPool.get(compId(botData.entry, `StatName-${statName}`)); + if(!statLabel) { + statLabel = parent.CreateFontString(id(`StatName-${statName}`), "ARTWORK", "GameFontNormalSmall"); + statLabel.SetPoint("TOPLEFT", parent, "TOPLEFT", 118, -7 - (i * 14)); + statLabel.SetText(`${statName}:`); + statLabel.SetJustifyH("LEFT"); + ComponentsPool.set(compId(botData.entry, `StatName-${statName}`), statLabel); + } + + let statValue = ComponentsPool.get(compId(botData.entry, `StatValue-${statName}`)); + if(!statValue) { + statValue = parent.CreateFontString(id(`StatValue-${statName}`), "ARTWORK", "GameFontNormalSmall"); + statValue.SetPoint("TOPRIGHT", parent, "TOPRIGHT", -4, -5 - (i * 14)); + statValue.SetSize(50, 14); + statValue.SetJustifyH("RIGHT"); + ComponentsPool.set(compId(botData.entry, `StatValue-${statName}`), statValue); + } + statValue.SetText(`${colors('white')}${rightStats[i][statName]}`); + + } + } + + function CreateStats(parent: WoWAPI.Frame, botData: BotData) { + + const statsFrame = CreateFrame("Frame", id("CharacterAttr"), parent, null, 1); + statsFrame.SetSize(230,78); + statsFrame.SetPoint("TOPLEFT", 67, -251); + statsFrame.SetFrameLevel(parent.GetFrameLevel() + 1); + // statsFrame.SetFrameStrata("LOW"); + 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,95); + 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,95); + 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); + + AddStats(statsFrame, botData); + } + + function SetBackground(parent: WoWAPI.Frame) { + // Left corner + const leftUpper = parent.CreateTexture(id("BgUpperLeft"), "BACKGROUND"); + leftUpper.SetTexture("Interface\\PaperDollInfoFrame\\UI-Character-CharacterTab-L1"); + leftUpper.SetSize(256,256); + leftUpper.SetPoint("TOPLEFT"); + + // Right corner + const rightUpper = parent.CreateTexture(id("BgUpperRight"), "BACKGROUND"); + rightUpper.SetTexture("Interface\\PaperDollInfoFrame\\UI-Character-CharacterTab-R1"); + rightUpper.SetSize(128,256); + rightUpper.SetPoint("TOPRIGHT"); + + // left bottom + const leftBottom = parent.CreateTexture(id("BgBottomLeft"), "BACKGROUND"); + leftBottom.SetTexture("Interface\\PaperDollInfoFrame\\UI-Character-CharacterTab-L2"); + leftBottom.SetSize(256,256); + leftBottom.SetPoint("BOTTOMLEFT"); + + // right bottom + const rightBottom = parent.CreateTexture(id("BgBottomRight"), "BACKGROUND"); + rightBottom.SetTexture("Interface\\PaperDollInfoFrame\\UI-Character-CharacterTab-R2"); + rightBottom.SetSize(128,256); + rightBottom.SetPoint("BOTTOMRIGHT"); + + // Close Button + const closeButton = CreateFrame("Button", id("CloseButton"), parent, "UIPanelCloseButton"); + closeButton.SetPoint("CENTER", parent, "TOPRIGHT", -44, -25); + closeButton.SetScript("OnClick", () => { + parent.Hide(); + }); + } + + function AddSoundEffects(frame: WoWAPI.Frame) { + frame.SetScript("OnShow", (frame) => { + PlaySound("igCharacterInfoOpen"); + }); + + frame.SetScript("OnHide", (frame) => { + PlaySound("igCharacterInfoClose"); + }); + } + + /** + * START OF EVENT HANDLERS + */ + + function ItemSlotOnEnter(frame: WoWAPI.Button) { + const botId = botStorage.GetActive(); + const theItem = botStorage.GetBotItem(botId, frame.GetID()); + GameTooltip.SetOwner(frame, "ANCHOR_RIGHT"); + if(theItem) { + GameTooltip.SetHyperlink(theItem.link); + } else { + if(frame.GetID() == 90) { + GameTooltip.SetText("Tabard"); + } else if(frame.GetID() == 91) { + GameTooltip.SetText("Shirt"); + } else { + GameTooltip.SetText( + ucase(BotSlotName[frame.GetID()]) + ); + + } + } + + if(CursorHasItem()) { + const [compItem, compItemId, compItemLink] = GetCursorInfo(); + const BotTooltip = ComponentsPool.get(compId(botId, "tooltip")); + BotTooltip.SetOwner(frame, "ANCHOR_LEFT"); + BotTooltip.SetHyperlink(compItemLink); + BotTooltip.Show(); + } + GameTooltip.Show(); + + } + + function ItemSlotOnLeave(frame: WoWAPI.Button) { + const botId = botStorage.GetActive(); + const BotTooltip = ComponentsPool.get(compId(botId, "tooltip")); + BotTooltip.Hide(); + GameTooltip.Hide(); + } + + function ItemSlotOnClick(frame: WoWAPI.Button, button: string) { + const botId = botStorage.GetActive(); + + const theItem = botStorage.GetBotItem(botId, frame.GetID()); + const [compItem, compItemId, compItemLink] = GetCursorInfo(); + + // IF we have a bank item since it is not our inventory it will crash the server so store it then send equip + const bankItem = botStorage.GetFromBank(); + if(bankItem) { + for(let i=0; i <= 4; i++) { + if(GetContainerNumFreeSlots(i)) { + if(i === 0) { + PutItemInBackpack(); + } else { + PutItemInBag(i); + } + } + } + } + + // Special case to handle unquipping items via modified click + if(IsModifiedClick("AUTOLOOTTOGGLE")) { + if(theItem && !compItem) { + aio.Handle("BotMgr", "UnequipTheItem", GetUnitName("player", false), frame.GetID(), botId); + return; + } + } + + if(theItem && !compItem) { + if(button == "LeftButton") { + PickupItem(theItem.link); + // print('Set Bot Pickup Item', botId, theItem.entry, theItem.link); + botStorage.BotItemPickedUp(botId, theItem.entry, theItem.link); + return; + } + } + + if(compItem) { + const slot = frame.GetID(); + + // if we have a bot virtual item in hand + if(botStorage.IsPickedUp()) { + const botItemInHand = botStorage.GetItemInHand(); + // first unequip item on target bot + aio.Handle("BotMgr", "UnequipTheItem", GetUnitName("player", false), slot, botItemInHand.bot); + aio.Handle("BotMgr", "EquipTheItem", GetUnitName("player", false), botId, slot, compItemId, compItemLink); + } else { + aio.Handle("BotMgr", "EquipTheItem", GetUnitName("player", false), botId, slot, compItemId, compItemLink); + } + + // Attempt to equip the item. + PlaySound("INTERFACESOUND_CURSORDROPOBJECT"); + ClearCursor(); + } + } + + botMgrHandlers.OnEquipSuccess = (botId: number, slot: BotEquipmentSlotNum, item: Equipment) => { + const itemTexture = ComponentsPool.get(compId(botId, `ItemSlotTexture-${slot}`)); + itemTexture.SetTexture(GetItemIcon(item.entry)); + + // Hide Tooltips otherwise it will show old item. + const BotTooltip = ComponentsPool.get(compId(botId, "tooltip")); + botStorage.SetBotItem(botId, slot, item); + + BotTooltip.Hide(); + GameTooltip.Hide(); + } + + botMgrHandlers.OnUnEquipSuccess = (botId: number, slot: BotEquipmentSlotNum) => { + const itemTexture = ComponentsPool.get(compId(botId, `ItemSlotTexture-${slot}`)); + /** TO DO move to generic function for getting textures right now is copy/paste */ + let slotName: string = BotSlotName[slot]; + + if(slot === BotEquipSlot.FINGER1) slotName = "FINGER0"; + if(slot === BotEquipSlot.FINGER2) slotName = "FINGER1"; + if(slot === BotEquipSlot.TRINKET1) slotName = "TRINKET0"; + if(slot === BotEquipSlot.TRINKET2) slotName = "TRINKET1"; + if(slot === BotEquipSlot.OFFHAND) slotName = "SECONDARYHAND"; + + const [, itemIcon] = GetInventorySlotInfo(UIInvSlot[`${slotName}SLOT`]); + itemTexture.SetTexture(itemIcon); + + // Hide Tooltips otherwise it will show old item. + const BotTooltip = ComponentsPool.get(compId(botId, "tooltip")); + BotTooltip.Hide(); + GameTooltip.Hide(); + } + + botMgrHandlers.OnEquipFail = (botId: number, slot: BotEquipmentSlotNum, itemId: number, itemLink: string) => { + PlaySound("ITEMGENERICSOUND"); + botStorage.BotItemCursorClear(); + ClearCursor(); + } + + + botMgrHandlers.OnUnEquipFail = (botId: number, slot: BotEquipmentSlotNum) => { + PlaySound("ITEMGENERICSOUND"); + botStorage.BotItemCursorClear(); + ClearCursor(); + } + + botMgrHandlers.UpdateBotData = (data: BotData) => { + botStorage.SetBotData(data.entry, data); + UpdateBotFrame(data); + } + + function HandleUnequipItem(itemButton: WoWAPI.Button, isBankSlot: boolean = false): void { + + const slotNum = itemButton.GetID(); + const bagId = itemButton.GetParent().GetID(); + if(!GetContainerItemLink((isBankSlot) ? -1 : bagId, slotNum)) { + if(botStorage.IsPickedUp()) { + const item = botStorage.GetItemInHand(); + aio.Handle("BotMgr", "UnequipTheItem", GetUnitName("player", false), item.slot, item.bot); + } + } + } + + /** + * This handles listening on Bot Items being dragged to the bag. Attaches + * to the default handler before run and handles bot items specifically. + */ + function StoreItemSlotHandlers(): void { + + // Intercept Bank Item Slots Click Event + for(let bankSlot = 1; bankSlot <= _G[`NUM_BANKGENERIC_SLOTS`]; bankSlot++) { + ItemClickFuncs.set(`bank:${bankSlot}`, _G[`BankFrameItem${bankSlot}`].GetScript("OnClick")); + + _G[`BankFrameItem${bankSlot}`].SetScript("OnClick", (frame: WoWAPI.Button, ...args) => { + + HandleUnequipItem(frame, true); + const callback = ItemClickFuncs.get(`bank:${frame.GetID()}`); + (callback) ? callback(frame, ...args) : null; + //print(`No callback for bank:${bankSlot}`) + + if(CursorHasItem()) { + const [compItem, compItemId, compItemLink] = GetCursorInfo(); + botStorage.SetFromBank({ + slot: frame.GetID(), + link: compItemLink, + entry: compItemId + }); + } + }); + } + + } + + function UpdateBotFrame(botData: BotData) { + + // Set the new Talent Spec + const talentSpec = ComponentsPool.get(compId(botData.entry, "SpecFont")); + talentSpec.SetText(botData.talentSpecName); + + // Update Resist Frames + let resist = ComponentsPool.get(compId(botData.entry, "Resist1")); + resist.SetText(`${GREEN_FONT_COLOR_CODE}${botData.allStats['Resistance: arcane']}`); + resist = ComponentsPool.get(compId(botData.entry, "Resist2")); + resist.SetText(`${GREEN_FONT_COLOR_CODE}${botData.allStats['Resistance: fire']}`); + resist = ComponentsPool.get(compId(botData.entry, "Resist3")); + resist.SetText(`${GREEN_FONT_COLOR_CODE}${botData.allStats['Resistance: nature']}`); + resist = ComponentsPool.get(compId(botData.entry, "Resist4")); + resist.SetText(`${GREEN_FONT_COLOR_CODE}${botData.allStats['Resistance: frost']}`); + resist = ComponentsPool.get(compId(botData.entry, "Resist5")); + resist.SetText(`${GREEN_FONT_COLOR_CODE}${botData.allStats['Resistance: shadow']}`); + + // Update the stats frame + AddStats(undefined, botData); + } + + + /** + * 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 + * reduces what textures and subframes need to be reloaded. For instance 3d models, portraits. + * + * Each Frame will be keyed on a Frame Manager by EntryID. This should not cause performance issues as + * each player is limited to the number of NPC bots they can manage. + * + * @param player + * @param botdetails + * @returns + * @noSelf + */ + function ShowBotFrame(botData: BotData) { + + let mainFrame: WoWAPI.Frame = null; + mainFrame = InfoFramePool.get(botData.entry); + + // Build the complete frame if we do not already have one in the pool. + if(!mainFrame) { + mainFrame = CreateFrame("Frame", id("MainFrame"+botData.entry), UIParent, null, botData.entry); + mainFrame.SetPoint("TOPLEFT", 300, -204); + mainFrame.SetSize(384, 512); + mainFrame.SetFrameLevel(5); + mainFrame.SetMovable(true); + mainFrame.EnableMouse(true); + mainFrame.RegisterForDrag("LeftButton"); + mainFrame.SetScript("OnDragStart", mainFrame.StartMoving); + mainFrame.SetScript("OnHide", mainFrame.StopMovingOrSizing); + mainFrame.SetScript("OnDragStop", mainFrame.StopMovingOrSizing); + mainFrame.SetScript("OnEnter", (frame) => { + botStorage.SetActive(frame.GetID()); + frame.SetFrameLevel(20); + }); + mainFrame.SetScript("OnLeave", (frame) => { + frame.SetFrameLevel(5); + }); + + BotItemTooltip = CreateFrame("GameTooltip", id("ItemToolTip"+botData.entry), mainFrame, "GameTooltipTemplate", botData.entry); + BotItemTooltip.SetOwner(mainFrame, "ANCHOR_NONE"); + BotItemTooltip.Hide(); + + // Build all elements of the frame on creation. + SetBackground(mainFrame); + AddPortrait(mainFrame, botData); + AddCharacterModel(mainFrame, botData); + AddResistFrame(mainFrame, botData); + AddEquipmentFrames(mainFrame, botData); + CreateStats(mainFrame, botData); + AddSoundEffects(mainFrame); + + InfoFramePool.set(botData.entry, mainFrame); + ComponentsPool.set(compId(botData.entry, "tooltip"), BotItemTooltip); + mainFrame.Show(); + + // 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_UNLOCKED") { + botStorage.ClearFromBank(); + } + }); + + } else { + mainFrame.Show(); + UpdateBotFrame(botData); + } + + + } + + botMgrHandlers.ShowFrame = (botData: BotData) => { + botStorage.UpdateBotData(botData.entry, botData); + ShowBotFrame(botData); + } + + // Global calls to set things up + StoreItemSlotHandlers(); + +} + + /** @ts-expect-error */ +let aio: AIO = {}; + +const SCRIPT_NAME = 'BotMgr'; +import { Logger } from "../../classes/logger"; +import { BotUnit } from "./botUnit"; +const log = new Logger(SCRIPT_NAME); + +import { + BotStat, + BotEquipLast, + ClassesMapping, + CharacterClass, + RacesMapping, + CharacterRace, + QualityType + } from "../../constants/idmaps"; + +export type Equipment = { + entry: number, + link: string, + quality?: QualityType, + itemLevel?: number, + enchantmentId?: number, +} + +export type EquipmentList = Record; + + /** + * Everything we ever wanted to know about the bot info on load + */ + export type BotData = { + owner: string, + name: string, + level: number, + talentSpec: number, + talentSpecName: string, + roles: number, + entry: number, + class: CharacterClass, + classId: number, + race: CharacterRace, + raceId: number, + equipment?: EquipmentList, // SlotName - ItemId See BotEquipSlot + leftStats?: Record[], + rightStats?: Record[], + allStats?: Record // StatId - Value +}; + +/** + * @todo Move to a data mgr class eventually + */ +const NpcDetailStorage = {} as Record; + +/** + * Get the current targetted npc bot or returns undefined if not a bot. + * @param player + * @returns Creature | undefined + * @noSelf + */ +function GetBotNpc(player: Player): Creature | undefined { + try { + const target = player.GetSelection(); + const creature = target.ToCreature(); + + if(!creature.IsNPCBot()) { + return; + } + + return creature; + } catch (e) { + log.error(`Could not lookup bot npc: ${e}`); + } +} + +/** + * This target is eligible for the player to manage otherwise ship them a friendly error message + * @param player + * @returns boolean + * @noSelf + */ +function TargetIsEligible(player: Player) { + const creature = GetBotNpc(player); + + if(creature) { + const botOwner = creature.GetBotOwner(); + if(botOwner.GetGUID() == player.GetGUID()) { + log.info(`Target is a NPCBot that can be managed by the player`); + return true; + } + } + + return false; +} + +/** + * Used to retrieve the bot for the player + * @param player + * @returns Creature + */ +function GetBotForPlayer(player: string, botEntry: number) { + try { + const owner = GetPlayerByName(player); + const creatures = owner.GetCreaturesInRange(300, botEntry) as Creature[]; + const bot = creatures[0]; + return bot; + } catch (e) { + log.error(`Could not get bot for player ${player}: ${e}`); + } +} + +/** + * @noSelf + */ +function GetBotDetails(bot: Creature): BotData { + + try { + const botUnit = new BotUnit(bot); + NpcDetailStorage[bot.GetEntry()] = botUnit.toBotData(); + } catch (e) { + log.error(`Could not get bot details: ${e}`); + } + + return NpcDetailStorage[bot.GetEntry()]; +} + +/** + * Sends a client message with update bot details typically fired + * after an equipment event. + * @param player + * @param botEntry + */ +function RefreshBotData(bot: Creature): void { + try { + bot.RegisterEvent((delay:number, repeats:number, bot: Creature) => { + const data = GetBotDetails(bot); + log.info(`Sending bot details to player: ${bot.GetBotOwner().GetName()}`); + aio.Handle(bot.GetBotOwner(), 'BotMgr', 'UpdateBotData', data); + }, 650, 1); + + } catch (e) { + log.error(`Could not send bot details: ${e}`); + } +} + +/** + * Equip an item for the bot and update bot details + * @param event + * @param player + * @param command + * @returns + */ +function EquipTheItem(player: string, botEntry: number, slot: BotEquipmentSlotNum, item: number, link: string ): void { + if(botEntry && typeof botEntry !== 'number') { + return; + } + + try { + const bot = GetBotForPlayer(player, botEntry); + let data; + + const isEligible = bot.BotCanEquipItem(item, slot); + if(!isEligible) { + log.error(`Bot cannot equip item: ${item} in slot: ${slot}`); + return; + } + // already equipped + + if(bot.BotEquipItem(item, slot)) { + data = GetBotDetails(bot); + // log.log(`Bot successfully equipped item: ${item} in slot: ${slot}`); + aio.Handle(bot.GetBotOwner(), 'BotMgr', 'OnEquipSuccess',bot.GetEntry(), slot, data.equipment[slot]); + RefreshBotData(bot); + } else { + // log.error(`Bot failed to equip item: ${item} in slot: ${slot}`); + aio.Handle(bot.GetBotOwner(), 'BotMgr', 'OnEquipFail', bot.GetEntry(), slot, item, link); + } + } catch (error) { + log.error(`Error equipping item: ${error}`); + } + +} + +function UnequipTheItem(player: string, slot: number, botEntry: number): void { + try { + const bot = GetBotForPlayer(player, botEntry); + + if(bot.BotUnequipBotItem(slot)) { + let data = GetBotDetails(bot); + log.log(`Bot successfully unequipped item at slot: ${slot}`); + aio.Handle(bot.GetBotOwner(), 'BotMgr', 'OnUnEquipSuccess',bot.GetEntry(), slot); + + RefreshBotData(bot); + } else { + log.error(`Bot failed to equip item in slot: ${slot}`); + aio.Handle(bot.GetBotOwner(), 'BotMgr', 'OnUnEquipFail', bot.GetEntry(), slot); + } + } catch (error) { + log.error(`Error unequipping item: ${error}`); + } +} + + +const ShowBotMgr: player_event_on_command = (event: number,player: Player, command: string): boolean => { + if(command == 'botmgr') { + + if(TargetIsEligible(player)) { + const botdetails = GetBotDetails(GetBotNpc(player)); + + aio.Handle(player, 'BotMgr', 'ShowFrame', botdetails); + return false; + } else { + player.PlayDirectSound(8959, player); // Play error sound (no money sound + player.SendNotification("That is not a NPCBot that you can manage!"); + return false; + } + } + + return true; +} + + + +/*** + * @noSelf + */ +function GetBotPanelInfo(player: Player): void { + const target = player.GetSelection(); + const creature = target.ToCreature(); + + if(!creature.IsNPCBot()) { + return; + } + + try { + + const target = player.GetSelection(); + PrintInfo(`Server ${target.GetGUID()}`); + + const entry = GetGUIDEntry(target.GetGUID()); + print(`BotMgr: Parsing Bot Entry: ${entry}`); + + + } catch (e) { + print(`BotMgr: Error parsing bot entry: ${e}`); + } +} +const botMgrHandlers = aio.AddHandlers('BotMgr', { + TargetIsEligible, + GetBotPanelInfo, + "EquipTheItem": EquipTheItem, + "UnequipTheItem": UnequipTheItem +}); + + +RegisterPlayerEvent( + PlayerEvents.PLAYER_EVENT_ON_COMMAND, + (...args) => ShowBotMgr(...args) +); /** @ts-expect-error */ +let aio: AIO = {}; +if(!aio.AddAddon()) { + +const gamblerHandlers = aio.AddHandlers('GamblerMain', {}); + +const classImages = [ + "Interface/Gambler/druid", + "Interface/Gambler/deathknight", + "Interface/Gambler/hunter", + "Interface/Gambler/mage", + "Interface/Gambler/paladin", + "Interface/Gambler/priest", + "Interface/Gambler/rogue", + "Interface/Gambler/shaman", + "Interface/Gambler/warlock", + "Interface/Gambler/warrior", +]; + +let slotSpin = []; +let multiplier = 1; + +// this function will randomly select a class image from the array above +function getRandomClassImage() { + const spinIndex = Math.floor(Math.random() * classImages.length); + slotSpin.push(spinIndex); + + return classImages[spinIndex]; +} + +// reset the spin +function resetSpin () { + slotSpin = []; +} + + +function determineWin(): number { + let win = 0; + let gold = 0; + let tokens = 0; + + // Jackpot is all 3 slots as deathknight arthas + if(slotSpin[0] == 1 && slotSpin[1] == 1 && slotSpin[2] == 1) { + + if(multiplier == 3) { + tokens = 100; + } + gold = multiplier * 2000; + win = 2; + } + + if(slotSpin[0] == slotSpin[1] && slotSpin[1] == slotSpin[2]) { + if(multiplier == 3) { + tokens = 50; + } + gold = multiplier * 500; + win = 1; + } + + // Deathknights are considered wild cards + if( + (slotSpin[0] == slotSpin[1] && slotSpin[2] === 1) || + (slotSpin[0] == slotSpin[2] && slotSpin[1] === 1) || + (slotSpin[1] == slotSpin[2] && slotSpin[0] === 1) || + (slotSpin[0] == 1 && slotSpin[1] === 1) || + (slotSpin[0] == 1 && slotSpin[2] === 1) || + (slotSpin[1] == 1 && slotSpin[2] === 1) + + ) { + if(multiplier == 3) { + tokens = 3; + } + gold = multiplier * 300; + win = 1; + } + + // handle two of the same class in a row + if((slotSpin[0] == slotSpin[1]) && win == 0) { + gold = multiplier * 150; + win = 1; + + if(slotSpin[1] == 1) { + if(multiplier == 3) { + tokens = 3; + } + gold = multiplier * 150; + win = 1; + } + } + + // Return money on any lich king wild + if((slotSpin[0] == 1 || slotSpin[1] == 1 || slotSpin[2] == 1) && win == 0) { + if(multiplier == 3) { + tokens = 0; + gold = 100; + } else { + tokens = 0; + gold = 20; + } + + win = 1; + } + + if(win > 0) { + PlaySoundFile("Sound\\Interface\\LootCoinLarge.wav", "Master"); + aio.Handle("GamblerMain", "AwardSlotWin", gold, tokens); + } + + return win; +} + +function SpinSlots(SlotFrame: WoWAPI.Frame, Slot: WoWAPI.Texture[]) { + let timer = 1; + let counter = 1; + + PlaySoundFile("Sound\\Doodad\\GnomeMachine02StandLoop.wav", "Master"); + SlotFrame.SetScript("OnUpdate", (frame, elapsed) => { + timer = timer + elapsed; + if(timer > 0.20) { + counter = counter + 1; + + resetSpin(); + timer = 0; + Slot[0].SetTexture(getRandomClassImage()); + Slot[1].SetTexture(getRandomClassImage()); + Slot[2].SetTexture(getRandomClassImage()); + + if(counter > 22) { + frame.SetScript("OnUpdate", null); + + determineWin(); + } + } + }); +} + +function ShowSlots(player: Player) { + + const GamblerMainFrame = CreateFrame("Frame", "GamblerMainFrame", UIParent, "UIPanelDialogTemplate"); + + GamblerMainFrame.SetSize(512,324); + GamblerMainFrame.SetMovable(false); + GamblerMainFrame.SetPoint("CENTER"); + GamblerMainFrame.EnableMouse(true); + GamblerMainFrame.EnableKeyboard(true); + GamblerMainFrame.Hide(); + + const Title = GamblerMainFrame.CreateFontString("TitleFrame", "OVERLAY", "GameFontHighlight"); + Title.SetPoint("TOPLEFT", 15, -10); + Title.SetText("Heros Slots"); + Title.SetFont("Fonts\\FRIZQT__.TTF", 10); + + // Slots Display Window + const Slots = CreateFrame("Frame", "SlotsFrame", GamblerMainFrame); + Slots.SetSize(420,160); + Slots.SetPoint("CENTER", 0, 25); + Slots.SetFrameLevel(1); + Slots.SetBackdrop({ + bgFile: "Interface/DialogFrame/UI-DialogBox-Background", + edgeFile: "Interface/DialogFrame/UI-DialogBox-Border", + tile: true, + tileSize: 32, + edgeSize: 32, + insets: { + left: 11, + right: 12, + top: 12, + bottom: 11 + } + }); + + // Slot Columns 1 - 3 + const Slot1 = Slots.CreateTexture("Slot1Texture", null, Slots); + Slot1.SetSize(128,128); + Slot1.SetAlpha(0.85); + Slot1.SetPoint("TOPLEFT", 13, -16); + Slot1.SetTexture(getRandomClassImage()); + + let [ Slot1Point, Slot1Region, Slot1RelPoint, x1offset, y1offset ] = Slot1.GetPoint(); + + const Slot2 = Slots.CreateTexture("Slot2Texture", null, Slots); + Slot2.SetSize(128,128); + Slot2.SetAlpha(0.85); + Slot2.SetPoint("TOPLEFT", Slot1Region, Slot1RelPoint, x1offset + 128 + 5, y1offset); + Slot2.SetTexture(getRandomClassImage()); + + let [ Slot2Point, Slot2Region, Slot2RelPoint, x2offset, y2offset ] = Slot2.GetPoint(); + + const Slot3 = Slots.CreateTexture("Slot3Texture", null, Slots); + Slot3.SetSize(128,128); + Slot3.SetAlpha(0.85); + Slot3.SetPoint("TOPLEFT", Slot2Region, Slot2RelPoint, x2offset + 128 + 5, y2offset); + Slot3.SetTexture(getRandomClassImage()); + + // Low bet button. + const SpinButton = CreateFrame("Button", "SpinButtonLow", GamblerMainFrame, "UIPanelButtonTemplate"); + SpinButton.SetSize(128,32); + SpinButton.SetPoint("CENTER", -80, -80); + SpinButton.SetText("Bet 20g Spin"); + SpinButton.SetFrameLevel(2); + SpinButton.SetScript("OnClick", (frame, mouse, button) => { + resetSpin(); + multiplier = 1; + aio.Handle("GamblerMain", "PayForSpin", 20*10000); + }); + + const SpinButtonHigh = CreateFrame("Button", "SpinButtonHigh", GamblerMainFrame, "UIPanelButtonTemplate"); + SpinButtonHigh.SetSize(128,32); + SpinButtonHigh.SetPoint("CENTER", 80, -80); + SpinButtonHigh.SetText("Bet 100g Spin"); + SpinButtonHigh.SetFrameLevel(2); + SpinButtonHigh.SetScript("OnClick", (frame, mouse, button) => { + resetSpin(); + multiplier = 3; + aio.Handle("GamblerMain", "PayForSpin", 100*10000); + }); + + gamblerHandlers.StartSpin = (player: Player) => { + SpinSlots(Slots, [Slot1, Slot2, Slot3]); + SendChatMessage("Started a spin", "CHANNEL", null, "7"); + } + + GamblerMainFrame.Show(); + + return GamblerMainFrame; +} + +gamblerHandlers.ShowFrame = (player: Player) => { + ShowSlots(player); +} + +} + +/** @ts-expect-error */ +let aio: AIO = {}; + +/** + * Gambler - Slot Machine + * This is the server side code used to add gambling games to the server. + */ + + +/** + * Game OBject that will start the slot machine up + */ +const SLOT_GAME_OBJECT = 750001; + + +const ShowGambler: player_event_on_command = (event: number,player: Player, command: string): boolean => { + if(command == 'gamble') { + aio.Handle(player, 'GamblerMain', 'ShowFrame'); + return false; + } + return true; +}; + +/** + * @noSelf + */ +function PayForSpin(this:void, player: Player, cost: number): void { + const money = player.GetCoinage(); + if(money >= cost) { + player.ModifyMoney(cost * -1); + aio.Handle(player, 'GamblerMain', 'StartSpin'); + } else { + player.SendNotification("You don't have enough money to spin the slots!"); + player.PlayDirectSound(8959, player); + } +} + +function AwardSlotWin(this:void, player: Player, gold: number, tokens: number): void { + player.ModifyMoney(gold*10000); + if(tokens > 0) { + player.AddItem(910001, tokens); + } + + if(tokens > 75) { + player.SendChatMessageToPlayer(ChatMsg.CHAT_MSG_GUILD, 0, `|cff1eff00I HIT THE JACKPOT! I won ${gold} gold and ${tokens} tokens!`, player); + } else { + if(tokens > 0) { + player.SendChatMessageToPlayer(ChatMsg.CHAT_MSG_GUILD, 0, `|cff1eff00I won ${gold} gold and ${tokens} tokens!`, player); + } else { + player.SendChatMessageToPlayer(ChatMsg.CHAT_MSG_GUILD, 0, `|cff1eff00I won ${gold} gold`, player); + } + } + +} + +const SendSlotStart: gameobject_event_on_use = (event: number, gameobject: GameObject, player: Player): boolean => { + aio.Handle(player, 'GamblerMain', 'ShowFrame'); + return true; +} + +const gamblerHandlers = aio.AddHandlers('GamblerMain', { + PayForSpin, + AwardSlotWin +}); + +RegisterPlayerEvent( + PlayerEvents.PLAYER_EVENT_ON_COMMAND, + (...args) => ShowGambler(...args) +); + +RegisterGameObjectEvent(SLOT_GAME_OBJECT, GameObjectEvents.GAMEOBJECT_EVENT_ON_USE, (...args) => SendSlotStart(...args)); +/** + * Class for find out information about an account + */ +export type BasicCharacter = { + guid: number, + name: string +} + +export class AccountInfo { + private accountId: number; + + constructor(accountId: number) { + this.accountId = accountId; + } + + GetAccountMoney(): number { + const result = CharDBQuery(`SELECT SUM(Money) as AccountMoney from acore_characters.characters WHERE account = ${this.accountId}`); + const row = result.GetRow() as Record; + return row.AccountMoney; + } + + GetCharacters(): BasicCharacter[] { + const result = CharDBQuery(`SELECT guid, name from characters WHERE account = ${this.accountId}`); + const characters: BasicCharacter[] = []; + + for(let i=0; i < result.GetRowCount(); i++) { + const row = result.GetRow(); + characters.push({ guid: row.guid as number, name: row.name as string }); + result.NextRow(); + } + + return characters; + } + +} +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; +}const CLASS_WEAPON = 2; +const CLASS_ARMOR = 4; + +const WEAPON_TYPES = { + 0: "Axe", + 1: "2H Axe", + 2: "Bow", + 3: "Gun", + 4: "Mace", + 5: "2H Mace", + 6: "Polearm", + 7: "Sword", + 8: "2H Sword", + 10: "Staff", + 13: "Fist Weapon", + 15: "Dagger", + 16: "Thrown", + 17: "Spear", + 18: "Crossbow", + 19: "Wand", +}; + +const ARMOR_TYPES = { + 0: "Misc", + 1: "Cloth", + 2: "Leather", + 3: "Mail", + 4: "Plate", + 6: "Shield", +}; + +type ArmorType = "Range" | "Melee" | "Caster" | "Tank" ; + +export class ItemDetails { + item: Item; + stats: Record; + + constructor(item: Item) { + this.item = item; + this.stats = {}; + } + + IsWeapon(): boolean { + return this.item.GetClass() === CLASS_WEAPON; + } + + IsArmor(): boolean { + return this.item.GetClass() === CLASS_ARMOR; + } + + GetWeaponType(): string | false { + if (!this.IsWeapon()) { + return false; + } + + if(this.HasRangedStats()) { + return "Ranged"; + } + + if(this.HasCasterStats()) { + return "Caster"; + } + + if(this.HasMeleeStats()) { + return "Melee"; + } + + if(this.HasDefensiveStats()) { + return "Tank"; + } + + const stats = this.GetStats(); + if (stats.Description) { + + const desc: string = stats.Description; + + if (desc.includes("attack power") || desc.includes("critical strike rating") || desc.includes("hit rating") || desc.includes("melee haste rating") || desc.includes("armor penetration rating")) { + return "Melee"; + } + + if (desc.includes("defense rating") || desc.includes("block") || desc.includes("parry") ) { + return "Tank"; + } + + if (desc.includes("spell power") || desc.includes("spell critical strike rating") || desc.includes("spell hit rating") || desc.includes("spell haste rating") || desc.includes("spell penetration")) { + return "Caster"; + } + + if (desc.includes("ranged attack power") || desc.includes("ranged critical strike rating") || desc.includes("ranged hit rating") || desc.includes("ranged haste rating") || desc.includes("ranged weapon penetration")) { + return "Range"; + } + } + + // still nothing? Then just do the best guess based on what the hell it is. + + if(this.IsMeleeWeapon()) { + return "Melee"; + } + + if(this.IsRangedWeapon()) { + return "Range"; + } + + if(this.IsCasterWeapon()) { + return "Caster"; + } + + if(this.IsArmor() && ARMOR_TYPES[this.item.GetSubClass()] === "Plate") { + return "Tank"; + } + + if(this.IsArmor() && ARMOR_TYPES[this.item.GetSubClass()] === "Mail") { + return "Ranged"; + } + + if(this.IsArmor() && ARMOR_TYPES[this.item.GetSubClass()] === "Leather") { + return "Melee"; + } + if(this.IsArmor() && ARMOR_TYPES[this.item.GetSubClass()] === "Cloth") { + return "Caster"; + } + + if(this.item.GetSubClass() === 6) { + return "Tank"; + } + + return false; + } + + GetArmorType(): ArmorType | false { + + if(!this.IsArmor()) { + return false; + } + + if(this.IsRangedArmor()) { + return "Range"; + } + if(this.IsCasterArmor()) { + return "Caster"; + } + if(this.IsTankArmor()) { + return "Tank"; + } + if(this.IsMeleeArmor()) { + return "Melee"; + } + + return false + } + + IsMeleeWeapon(): boolean { + if (!this.IsWeapon()) { + return false; + } + + const subClass = this.item.GetSubClass(); + switch (WEAPON_TYPES[subClass]) { + case "Axe": + case "2H Axe": + case "Mace": + case "2H Mace": + case "Polearm": + case "Sword": + case "2H Sword": + case "Fist Weapon": + case "Dagger": + case "Spear": + if (this.HasCasterStats()) { + return false; + } + return true; + default: + return false; + } + } + + IsCasterWeapon() { + if (!this.IsWeapon()) { + return false; + } + + switch (WEAPON_TYPES[this.item.GetSubClass()]) { + case "Mace": + case "2H Mace": + case "Sword": + case "Dagger": + case "Wand": + case "Staff": + if (this.HasCasterStats()) { + return true; + } + return false; + default: + return false; + } + } + + IsRangedWeapon() { + if (!this.IsWeapon()) { + return false; + } + + switch (WEAPON_TYPES[this.item.GetSubClass()]) { + case "Bow": + case "Gun": + case "Thrown": + case "Crossbow": + return true; + default: + return false; + } + } + + Is2HWeapon() { + if (!this.IsWeapon()) { + return false; + } + + switch (WEAPON_TYPES[this.item.GetSubClass()]) { + case "2H Axe": + case "2H Mace": + case "Polearm": + case "2H Sword": + case "Staff": + return true; + default: + return false; + } + } + + IsCasterArmor(): boolean { + if (!this.IsArmor()) { + return false; + } + + const type = ARMOR_TYPES[this.item.GetSubClass()]; + if (type === "Cloth") { + return true; + } + + if (this.HasCasterStats()) { + return true; + } + + return false; + } + + IsMeleeArmor(): boolean { + if (!this.IsArmor()) { + return false; + } + + const type = ARMOR_TYPES[this.item.GetSubClass()]; + if (type === "Cloth") { + return false; + } + + if(this.HasMeleeStats()) { + return true; + } + + return false; + } + + IsRangedArmor(): boolean { + if (!this.IsArmor()) { + return false; + } + + const type = ARMOR_TYPES[this.item.GetSubClass()]; + if (type === "Cloth" || type === "Plate") { + return false; + } + + if(this.HasRangedStats()) { + return true; + } + + return false; + } + + IsTankArmor(): boolean { + if (!this.IsArmor()) { + return false; + } + + const type = ARMOR_TYPES[this.item.GetSubClass()]; + if (type === "Cloth" || type === "Mail") { + return false; + } + + if(this.HasDefensiveStats()) { + return true; + } + + return false; + } + + HasCasterStats(): boolean { + const stats = this.GetStats(); + + if (Object.keys(stats).length === 0) { + return false; + } + + const casterStats = [5, 6, 18, 21, 27, 30, 41, 42, 43, 45, 47]; + for (let i = 1; i <= 8; i++) { + let statType = stats[`stat_type${i}`] ? stats[`stat_type${i}`] : 0; + if (casterStats.includes(statType)) { + return true; + } + } + + return false; + } + + HasDefensiveStats(): boolean { + const stats = this.GetStats(); + if (Object.keys(stats).length === 0) { + return false; + } + + const defStats = [1,12, 13, 14, 15, 22, 23, 24, 25, 26, 27, 48]; + for (let i = 1; i <= 8; i++) { + let statType = stats[`stat_type${i}`] ? stats[`stat_type${i}`] : 0; + + if (defStats.includes(statType)) { + return true; + } + } + + return false; + } + + HasMeleeStats(): boolean { + const stats = this.GetStats(); + if (Object.keys(stats).length === 0) { + return false; + } + + const meleeStats = [3, 16,19,28,31,32,36,37,38,44] + for (let i = 1; i <= 8; i++) { + let statType = stats[`stat_type${i}`] ? stats[`stat_type${i}`] : 0; + if (meleeStats.includes(statType)) { + return true; + } + } + + return false; + } + + HasRangedStats(): boolean { + const stats = this.GetStats(); + if (Object.keys(stats).length === 0) { + return false; + } + + const rangedStats = [17,20,29,39]; + for (let i = 1; i <= 8; i++) { + let statType = stats[`stat_type${i}`] ? stats[`stat_type${i}`] : 0; + if (rangedStats.includes(statType)) { + return true; + } + } + } + + GetStats(): Record { + // return stats if we have already parsed them. + if (Object.keys(this.stats).length != 0) { + return this.stats; + } + + const entry = this.item.GetEntry(); + const sql = `SELECT + stat_type1, stat_value1, + stat_type2, stat_value2, + stat_type3, stat_value3, + stat_type4, stat_value4, + stat_type5, stat_value5, + stat_type6, stat_value6, + stat_type7, stat_value7, + stat_type8, stat_value8, + spell_dbc.Description_Lang_enUS as Description + + FROM item_template + LEFT JOIN spell_dbc ON item_template.spellid_1 = spell_dbc.ID + WHERE entry = ${entry}`; + const query = WorldDBQuery(sql); + // print(`GetStats: ${sql}`); + + if(query) { + return query.GetRow(); + } else { + PrintError("ItemDetails/GetStats: Failed to get ITem Stats: ", sql); + return {}; + } + } +} +// Purpose: Logger class to log messages to the console. +export class Logger { + + public logname: string; + + constructor(name: string) { + this.logname = name; + } + + + log(message: string) { + const info = debug.getinfo(2, "Sl"); + 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}`); + } + + warn(message: string) { + const info = debug.getinfo(2, "Sl"); + print(`\\27[33m[${this.logname}][Warn]: ${message} was printed from ${info.short_src}:${info.currentline}\\27[0m`); + } + + error(message: string) { + const info = debug.getinfo(2, "Sl"); + PrintError(`[${this.logname}][Error]: ${message} was printed from ${info.short_src}:${info.currentline}`); + } + +}import { AccountInfo } from "./account"; + +export const GOLD_TO_COPPER = 10000; + +/** + * Converts a copper cost to gold + * @param cost Cost of item in copper + * @returns number + */ +export function ToGold(cost: number) : number { + return Math.floor(cost / GOLD_TO_COPPER); +} + +/** + * Converts a gold cost to copper + * @param gold Cost of item in gold + * @returns number + */ +export function ToCopper(gold: number) : number { + return gold*GOLD_TO_COPPER; +} + +/** + * Gets a scaling tax for players to help with balancing the economy for guild features. + * @param player Player + * @param tax amount of tax against player to levy number (0-100) + * @returns number result in copper + */ +export function GetPlayerTax(player: Player, tax: number) : number { + const account = new AccountInfo(player.GetAccountId()); + return (tax/100) * account.GetAccountMoney(); +} +// A function that will take a min and a max and return a random number between them +export function rollDice(min: number, max: number): number { + return Math.floor(Math.random() * (max - min + 1) + min); +}declare function GetGameTime(): number; + +const PLAYER_TYPE = 'player'; +export const StatEvents = { + TOKEN_CREATED: 'token_created', + TICKETS_AWARDED: 'darkmoon_tickets_awarded', +}; + +export class Stats { + + stats = new Map(); + entity: StatEntity; + + constructor(entity: StatEntity) { + this.entity = entity; + this.load(); + } + + static GetStatsByType(type: string, name: string) : Map { + const result = CharDBQuery(`SELECT id, name, value, updated FROM ${type}_stats WHERE name = '${name}'`); + const stats = new Map(); + if(!result) { + return stats; + } + for(let i=0; i < result.GetRowCount(); i++) { + const row = result.GetRow(); + stats.set(row.id as number, row.value as number); + result.NextRow(); + } + return stats; + }; + + load() : boolean { + const result = CharDBQuery(`SELECT id, name, value, updated FROM ${this.entity.type}_stats WHERE id = ${this.entity.id}`); + if(!result) { + return false; + } + for(let i=0; i < result.GetRowCount(); i++) { + const row = result.GetRow(); + const stat: Stat = { + name: row.name as string, + type: this.entity.type, + value: row.value as number, + updated: row.updated as number, + loaded: true + } + this.stats.set(stat.name, stat); + result.NextRow(); + } + return true; + } + + save() : void { + + for(const stat of this.stats.values()) { + if(!stat.loaded) { + CharDBExecute(`INSERT INTO ${this.entity.type}_stats (id, name, value, updated) VALUES (${this.entity.id}, '${stat.name}', ${stat.value}, ${stat.updated})`); + PrintDebug(`Inserted ${stat.name} for ${this.entity.type} ${this.entity.id} with value ${stat.value}`); + } else { + CharDBExecute(`UPDATE ${this.entity.type}_stats SET value = ${stat.value}, updated = ${stat.updated} WHERE id = ${this.entity.id} AND name = '${stat.name}'`); + PrintDebug(`Updated ${stat.name} for ${this.entity.type} ${this.entity.id} to ${stat.value}`); + } + } + } + + getStat(name: string) : Stat | undefined { + return this.stats.get(name); + } + + setStat(name: string, value: number) : void { + const stat = this.stats.get(name); + if(stat) { + stat.value = value; + stat.updated = GetGameTime(); + } else { + this.stats.set(name, { + name: name, + type: PLAYER_TYPE, + value: value, + updated: GetGameTime(), + loaded: false + }); + } + } + + increment(name: string, amount: number = 1) : void { + const stat = this.stats.get(name); + if(stat) { + stat.value += amount; + stat.updated = GetGameTime(); + } else { + this.stats.set(name, { + name: name, + type: PLAYER_TYPE, + value: 0, + updated: GetGameTime(), + loaded: false + }); + } + } +} + +/** + * Custom player stats that will be + */ +export class PlayerStats extends Stats { + + player: Player; + playerStats: Stat[] = []; + + constructor(player: Player) { + super({ + id: player.GetGUID(), + type: PLAYER_TYPE + }); + this.player = player; + } + +} + +interface StatEntity { + type: string, + id: number +} + +interface Stat { + type: string, + name: string, + value: number, + updated: number, + loaded: boolean +} + +/* @noSelfInFile */ + +type TriggerInput = { + triggerName: string, + characterGuid: number, + isSet: boolean +} + +/** + * Sets a player trigger boolean that can be retieved later as needed + * @param charTrigger TriggerInput + */ +export function SetTrigger(charTrigger: TriggerInput) { + let sql = `INSERT INTO player_trigger (triggerName, characterGuid, isSet) `+ + `VALUES ("${charTrigger.triggerName}", ${charTrigger.characterGuid}, ${charTrigger.isSet})`+ + `ON DUPLICATE KEY UPDATE isSet=${charTrigger.isSet}`; + print(sql); + CharDBExecute(sql); +} + +/** + * Will return the value of the trigger if it exists, otherwise it will return false + * @param charGuid number + * @param triggerName string + * @returns boolean + */ +export function GetTrigger(charGuid: number, triggerName: string) { + let sql = `SELECT isSet from player_trigger WHERE triggerName="${triggerName}" and characterGuid=${charGuid}`; + const result = CharDBQuery(sql); + + if(result && result.GetRowCount() > 0) { + return result.GetBool(0) + } else { + return false; + } + +} +export function colors(name: string) { + const colors = { + GREY: "|cff999999", + RED: "|cffff0000", + WHITE: "|cffFFFFFF", + GREEN: "|cff1eff00", + PURPLE: "|cff9F3FFF", + BLUE: "|cff0070dd", + ORANGE: "|cffFF8400", + YELLOW: "|cffFFFF00", + }; + + const keyName = name.toUpperCase(); + if(colors[keyName]) { + return colors[keyName]; + } else { + return colors.WHITE; + } +}export const BotEquipSlot = { + MAINHAND: 0, + OFFHAND: 1, + RANGED: 2, + HEAD: 3, + SHOULDERS: 4, + CHEST: 5, + WAIST: 6, + LEGS: 7, + FEET: 8, + WRIST: 9, + HANDS: 10, + BACK: 11, + BODY: 12, + FINGER1: 13, + FINGER2: 14, + TRINKET1: 15, + TRINKET2: 16, + NECK: 17, + } as const; + +export const BotSlotName = { + 0: "MAINHAND", + 1: "OFFHAND", + 2: "RANGED", + 3: "HEAD", + 4: "SHOULDER", + 5: "CHEST", + 6: "WAIST", + 7: "LEGS", + 8: "FEET", + 9: "WRIST", + 10: "HANDS", + 11: "BACK", + 12: "BODY", + 13: "FINGER1", + 14: "FINGER2", + 15: "TRINKET1", + 16: "TRINKET2", + 17: "NECK", +} as const; + +export const BotEquipLast = 17; +export const BotStatLabel = { + "total str": "Strength", + "total agi": "Agility", + "total sta": "Stamina", + "total int": "Intellect", + "total spi": "Spirit", + "Melee AP": "Power", + "Ranged AP": "Power", + "armor": "Armor", + "crit": "Crit %", + "defense": "Defense", + "miss": "Miss", + "dodge": "Dodge", + "parry": "Parry", + "block": "Block", + "block value": "Block Value", + "Damage taken melee": "Physical Res.", + "Damage taken spell": "Spell Res.", + "Damage range mainhand": "Damage", + "Damage range offhand": "Dmg Off", + "Attack time offhand": "Speed Off", + "Damage mult mainhand": "Damage Multiplier (Mainhand)", + "Attack time mainhand": "Speed Main", + "Damage range ranged": "Damage Rng", + "Damage mult ranged": "Damage Multiplier (Ranged)", + "Attack time ranged": "Speed", + "base hp": "Base Health", + "total hp": "Total Health", + "base mana": "Base Mana", + "total mana": "Total Mana", + "spell power": "Bonus Dmg", + "health regen_5 bonus": "Health Regen (5s Bonus)", + "haste": "Haste Rating", + "hit": "Hit Rating", + "expertise": "Expertise", + "mana regen_5 casting": "MP5", + "armor penetration": "Armor Pen", + "spell penetration": "Spell Pen", + "Resistance: holy": "Resist Holy", + "Resistance: fire": "Resist Fire", + "Resistance: nature": "Resist Nature", + "Resistance: frost": "Resist Frost", + "Resistance: shadow": "Resist Shadow", + "Resistance: arcane": "Resist Arcane", +} as const; + +export type BotStatName = Partial; + +export const BotStat = { + 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, + 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, + DAMAGE_MIN: 49, + DAMAGE_MAX: 50, + ARMOR: 51, + RESIST_HOLY: 52, + RESIST_FIRE: 53, + RESIST_NATURE: 54, + RESIST_FROST: 55, + RESIST_SHADOW: 56, + RESIST_ARCANE: 57, + EXPERTISE: 58, + MAX_BOT_ITEM_MOD: 59, + BOT_STAT_MOD_RESISTANCE_START: 51, // Assuming BOT_STAT_MOD_ARMOR is defined somewhere + } as const; + +export const BotStatLast = 58; + +export const UIInvSlot = { + AMMOSLOT: "AMMOSLOT", + HEADSLOT: "HEADSLOT", + NECKSLOT: "NECKSLOT", + SHOULDERSLOT: "SHOULDERSLOT", + SHIRTSLOT: "SHIRTSLOT", + CHESTSLOT: "CHESTSLOT", + WAISTSLOT: "WAISTSLOT", + LEGSSLOT: "LEGSSLOT", + FEETSLOT: "FEETSLOT", + WRISTSLOT: "WRISTSLOT", + HANDSSLOT: "HANDSSLOT", + FINGER0SLOT: "FINGER0SLOT", + FINGER1SLOT: "FINGER1SLOT", + TRINKET0SLOT: "TRINKET0SLOT", + TRINKET1SLOT: "TRINKET1SLOT", + BACKSLOT: "BACKSLOT", + MAINHANDSLOT: "MAINHANDSLOT", + SECONDARYHANDSLOT: "SECONDARYHANDSLOT", + RANGEDSLOT: "RANGEDSLOT", + TABARDSLOT: "TABARDSLOT", + } as const; + + export const ClassesMapping: Record = { + 1: "Warrior", + 2: "Paladin", + 3: "Hunter", + 4: "Rogue", + 5: "Priest", + 6: "Death Knight", + 7: "Shaman", + 8: "Mage", + 9: "Warlock", + 10: "Druid", + 11: "Blade Master", + 12: "Sphynx", + 13: "Archmage", + 14: "Dreadlord", + 15: "Spellbreaker", + 16: "Dark Ranger", + 17: "Necromancer", + 18: "Sea Witch", + 19: "Crypt Lord", + } as const; + +export type CharacterClass = typeof ClassesMapping[keyof typeof ClassesMapping]; + +export const RacesMapping: Record = { + 1: "Human", + 2: "Orc", + 3: "Dwarf", + 4: "Night Elf", + 5: "Undead", + 6: "Tauren", + 7: "Gnome", + 8: "Troll", + 9: "Goblin", + 10: "Blood Elf", + 11: "Draenei", + 12: "Worgen", +} as const; + +export type CharacterRace = typeof RacesMapping[keyof typeof RacesMapping]; + +export const TalentSpecs = { + 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 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 type QualityType = typeof ItemQuality[keyof typeof ItemQuality]; + + +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; + diff --git a/modules/UI/gambler/gambler.client.ts b/modules/UI/gambler/gambler.client.ts index 7e9f596..fe0a4c3 100644 --- a/modules/UI/gambler/gambler.client.ts +++ b/modules/UI/gambler/gambler.client.ts @@ -217,6 +217,7 @@ function ShowSlots(player: Player) { gamblerHandlers.StartSpin = (player: Player) => { SpinSlots(Slots, [Slot1, Slot2, Slot3]); + SendChatMessage("Started a spin", "CHANNEL", null, "7"); } GamblerMainFrame.Show(); diff --git a/modules/UI/mythicplus/mythicplus.client.ts b/modules/UI/mythicplus/mythicplus.client.ts index 7955e33..725a56e 100644 --- a/modules/UI/mythicplus/mythicplus.client.ts +++ b/modules/UI/mythicplus/mythicplus.client.ts @@ -8,12 +8,12 @@ if(!aio.AddAddon()) { const mythicPlusHandlers = aio.AddHandlers('MythicPlus', {}); const selectImages = [ - "Interface/MythicPlus/mythic", - "Interface/MythicPlus/mythic-selected", - "Interface/MythicPlus/legendary", - "Interface/MythicPlus/legendary-selected", - "Interface/MythicPlus/ascendant", - "Interface/MythicPlus/ascendant-selected" + "Interface/Modules/MythicPlus/Textures/mythic", + "Interface/Modules/MythicPlus/Textures/mythic-selected", + "Interface/Modules/MythicPlus/Textures/legendary", + "Interface/Modules/MythicPlus/Textures/legendary-selected", + "Interface/Modules/MythicPlus/Textures/ascendant", + "Interface/Modules/MythicPlus/Textures/ascendant-selected" ]; const Difficulty = { @@ -289,14 +289,14 @@ function CreateSkullFrame(difficulty: Difficulty, title: string, imageIndex: num PlaySound("PVPTHROUGHQUEUE"); - if(MythicClientState.difficulty == f.GetID()) { - MythicClientState.difficulty = GetDungeonDifficultyID() - 1; - refreshUIState(); - } else { - MythicClientState.difficulty = f.GetID(); - // always assume heoric for map setting for scaling under the hood. - SetDungeonDifficulty(2); - } + // if(MythicClientState.difficulty == f.GetID()) { + // MythicClientState.difficulty = GetDungeonDifficultyID() - 1; + // refreshUIState(); + // } else { + // MythicClientState.difficulty = f.GetID(); + // // always assume heoric for map setting for scaling under the hood. + // SetDungeonDifficulty(2); + // } aio.Handle("MythicPlus", "SetDifficulty", MythicClientState.difficulty); refreshUIState(); @@ -414,7 +414,51 @@ function ShowUIButton(): void { // 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; -} \ No newline at end of file + // 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(); +} + + + + diff --git a/modules/UI/mythicplus/mythicplus.server.ts b/modules/UI/mythicplus/mythicplus.server.ts index 9a57af2..373d7a9 100644 --- a/modules/UI/mythicplus/mythicplus.server.ts +++ b/modules/UI/mythicplus/mythicplus.server.ts @@ -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 RegisterPlayerEvent(PlayerEvents.PLAYER_EVENT_ON_LOGIN, (...args) => MPStartState(...args)); -const MPGroupDisband: group_event_on_disband = (_event: number, group: Group): void => { - const members = group.GetMembers(); +// const MPGroupDisband: group_event_on_disband = (_event: number, group: Group): void => { +// const members = group.GetMembers(); - for(let i = 0; i < members.length; i++) { - _refreshState(members[i]); - aio.Handle(members[i], 'MythicPlus', 'UpdateState', StateStorage.get(members[i].GetGUIDLow())); - } -} +// for(let i = 0; i < members.length; i++) { +// _refreshState(members[i]); +// 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. -const MPLeaderChange: group_event_on_leader_change = (_event: number,group: Group, leader: number, oldLeader: number): void => { - _refreshState(GetPlayerByGUID(leader)); - aio.Handle(GetPlayerByGUID(leader), 'MythicPlus', 'UpdateState', StateStorage.get(leader)); +// const MPLeaderChange: group_event_on_leader_change = (_event: number,group: Group, leader: number, oldLeader: number): void => { +// _refreshState(GetPlayerByGUID(leader)); +// aio.Handle(GetPlayerByGUID(leader), 'MythicPlus', 'UpdateState', StateStorage.get(leader)); - _refreshState(GetPlayerByGUID(oldLeader)); - aio.Handle(GetPlayerByGUID(oldLeader), 'MythicPlus', 'UpdateState', StateStorage.get(oldLeader)); -} +// _refreshState(GetPlayerByGUID(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) => { diff --git a/modules/classes/group.ts b/modules/classes/group.ts new file mode 100644 index 0000000..b153158 --- /dev/null +++ b/modules/classes/group.ts @@ -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; +} \ No newline at end of file diff --git a/modules/events/tbc-launch.ts b/modules/events/tbc-launch.ts deleted file mode 100644 index 763b969..0000000 --- a/modules/events/tbc-launch.ts +++ /dev/null @@ -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) -); diff --git a/modules/gameobject/gamblechest.ts b/modules/gameobject/gamblechest.ts index 409e2e9..7cd8eff 100644 --- a/modules/gameobject/gamblechest.ts +++ b/modules/gameobject/gamblechest.ts @@ -1,62 +1,163 @@ /** @ts-expect-error */ let aio: AIO = {}; +import { run } from "node:test"; +import { GetGroupSize } from "../classes/group"; + const GambleChestID = 910001; const TrapSounds = [ - "Sound\\Effects\\hell-no.mp3", + "Sound\\Effects\\dumb.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\\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 = [ "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\\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 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 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; const LootTrapMap: Record = {}; +// Who won the gamblers chest. +const ChestAssignment: Record = {}; + function RollLootTrap(object: GameObject) { const roll = Math.floor(Math.random() * 100); - // print(`Guid ${object.GetGUIDLow()}`); - // print(`Roll: ${roll}`); - if(roll > 98) { - object.AddLoot(43347, 1); // Satchel of Spoils 2% + + // TEST TRAP +// LootTrapMap[object.GetGUIDLow()] = true; +// return + + if(roll > 99) { + object.AddLoot(911001, 1); // Mind Spike LootTrapMap[object.GetGUIDLow()] = false; - return; - } else if(roll > 89) { - object.AddLoot(43346, 1); // Large Satchel of Spoils 18% + return; + } else if(roll > 85) { + // 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; - return; - } else if(roll > 82) { - object.AddLoot(49294, 1); // Ashen Sack of Spoils 7% + return; + } else if(roll > 65) { + // 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; - 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; + return; } else if(roll > 55) { - object.AddLoot(19182, 25); // Darkmoon Fair Tickets 12% - 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% + object.AddLoot(92301, 1); // Huge Sack of Coins LootTrapMap[object.GetGUIDLow()] = false; return; } 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 map: EMap = killed.GetMap(); - return false; - if(!map.IsDungeon() && !map.IsRaid()) { 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; } + const [x,y,z,o] = killed.GetLocation(); 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; } 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); } + +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) => { if(state == 2) { + // return; + // print(`LootTrapped ${LootTrapMap[gameObject.GetGUIDLow()]}`); // print(`InState GUID ${gameObject.GetGUIDLow()}`); // if it is a trap time to do some killing! if(LootTrapMap[gameObject.GetGUIDLow()] == true) { - - const creature1: Creature = PerformIngameSpawn(1, BombCreature, gameObject.GetMapId(), gameObject.GetInstanceId(), gameObject.GetX(), gameObject.GetY(), gameObject.GetZ(),gameObject.GetO(), false, 100); + const player = gameObject.GetNearestPlayer(50); 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); } - for(let i =0; i < 20; i++) { - if(player.IsAlive()) { - creature1.CastSpell(player, LivingBombSpell); + if(player.IsAlive()) { + const effect = effectSpells[Math.floor(Math.random() * effectSpells.length)]; + + 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 { const players = gameObject.GetPlayersInRange(50); 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 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(); -const onSpell: player_event_on_spell_cast = (event: number, player: Player, spell: Spell, skipCheck: boolean) => { - // Implementation - const gameObjects = player.GetGameObjectsInRange(10, GambleChestID); - if(gameObjects.length > 0) { - if(spell.GetEntry() == LongOpenChestSpellID) { - const sound = OpeningSounds[Math.floor(Math.random() * OpeningSounds.length)]; - aio.Handle(player, 'AIOAudioPlayer', 'PlaySingleSound',sound); +const CheckGrowthDeath: map_event_on_update = (event: number, map: EMap, diff: number) => { + const team1players = map.GetPlayers(1); + const team2players = map.GetPlayers(0); + + // combine team1 and team2 players + const allPlayers = team1players.concat(team2players); + + 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)); \ No newline at end of file diff --git a/modules/gm/play-leeroy.ts b/modules/gm/play-leeroy.ts new file mode 100644 index 0000000..06b8633 --- /dev/null +++ b/modules/gm/play-leeroy.ts @@ -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)) \ No newline at end of file diff --git a/modules/gm/test-hidden-channel.ts b/modules/gm/test-hidden-channel.ts new file mode 100644 index 0000000..6e2ac7d --- /dev/null +++ b/modules/gm/test-hidden-channel.ts @@ -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(L, 2); +// std::string message = Eluna::CHECKVAL(L, 3); +// uint8 channel = Eluna::CHECKVAL(L, 4); +// Player* receiver = Eluna::CHECKOBJ(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)); \ No newline at end of file diff --git a/modules/items/tokens.ts b/modules/items/tokens.ts index 60a8b48..db8fb7b 100644 --- a/modules/items/tokens.ts +++ b/modules/items/tokens.ts @@ -5,9 +5,73 @@ import { PlayerStats, StatEvents } from "../classes/stats"; */ const TOKEN_ROLL_CHANCE = 5; const NORMAL_ROLL_CHANCE = 5; -const TOKEN_ROLL_CAP = 2000; +const TOKEN_ROLL_CAP = 1500; 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 [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}`) if(roll <= rollModifer) { createChest(player, creature, 'center'); - createChest(player, creature, 'left'); + // createChest(player, creature, 'left'); + chestShown = true; // Add player stat they created token const pStats = new PlayerStats(player); @@ -119,18 +186,25 @@ const TokenKillEvent: player_event_on_kill_creature = (event: number, player: Pl pStats.save(); } + + if (bosses[creature.GetEntry()]) { + createChest(player, creature, 'right'); + } + // if it is a larger group roll again! - if(groupCount >= TOKEN_GROUP_SIZE) { - if(creature.IsWorldBoss() || creature.IsDungeonBoss()) { - roll = Math.floor(Math.random() * TOKEN_ROLL_CAP); - if(roll <= rollModifer+100 ) { - createChest(player, creature,'right'); - } - } - } + // if(groupCount >= TOKEN_GROUP_SIZE) { + // if(creature.IsDungeonBoss()) { + // roll = Math.floor(Math.random() * TOKEN_ROLL_CAP); + // if(roll <= rollModifer+100 ) { + // createChest(player, creature,'right'); + // } + // } + // } } RegisterPlayerEvent( PlayerEvents.PLAYER_EVENT_ON_KILL_CREATURE, (...args) => TokenKillEvent(...args) ); + + diff --git a/package-lock.json b/package-lock.json index 9b9ff39..5ed1fcb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,20 +14,23 @@ "devDependencies": { "cross-var": "^1.1.0", "dotenv-cli": "^7.3.0", + "nodemon": "^3.1.9", "rimraf": "^5.0.5", "typescript": "^5.2.2", "typescript-to-lua": "^1.23.0" } }, "node_modules/@araxiaonline/wow-wotlk-declarations": { - "version": "3.3.5-8", - "resolved": "https://registry.npmjs.org/@araxiaonline/wow-wotlk-declarations/-/wow-wotlk-declarations-3.3.5-8.tgz", - "integrity": "sha512-E8xoJph6EddGBu+9hI6VZ5FJNeVYWQog3GXV5MyIILchS5aDhJaix/2trhe8NWWyhZqaPJQrzB+psCFp76HY0A==" + "version": "3.3.5-9", + "resolved": "https://registry.npmjs.org/@araxiaonline/wow-wotlk-declarations/-/wow-wotlk-declarations-3.3.5-9.tgz", + "integrity": "sha512-vo/I5jIq/a2jUzOkSNbjw0ZFEDk7TZ+9qOKJS6vRQKhej5HlWXNEr0dYB3i+zw6fxDW4dJrR0YnpKB7fgxJUmg==", + "license": "MIT" }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -40,6 +43,7 @@ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", "dev": true, + "license": "ISC", "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", @@ -53,10 +57,11 @@ } }, "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -69,6 +74,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -83,19 +89,22 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -106,35 +115,41 @@ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", "dev": true, + "license": "MIT", "optional": true, "engines": { "node": ">=14" } }, "node_modules/@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==" + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "license": "MIT" }, "node_modules/@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "license": "MIT" }, "node_modules/@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "license": "MIT" }, "node_modules/@tsconfig/node16": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==" + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "license": "MIT" }, "node_modules/@types/fs-extra": { "version": "11.0.4", "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.4.tgz", "integrity": "sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==", + "license": "MIT", "dependencies": { "@types/jsonfile": "*", "@types/node": "*" @@ -144,27 +159,31 @@ "version": "6.1.4", "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.4.tgz", "integrity": "sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==", + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/node": { - "version": "20.11.20", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.20.tgz", - "integrity": "sha512-7/rR21OS+fq8IyHTgtLkDK949uzsa6n8BkziAKtPVpugIkO6D+/ooXMvzXxDnZrmtXVfjb1bKQafYpb8s89LOg==", + "version": "20.17.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.9.tgz", + "integrity": "sha512-0JOXkRyLanfGPE2QRCwgxhzlBAvaRdCNMcvbd7jFfpmD4eEXll7LRwy5ymJmyeZqk7Nh7eD2LeUyQ68BbndmXw==", + "license": "MIT", "dependencies": { - "undici-types": "~5.26.4" + "undici-types": "~6.19.2" } }, "node_modules/@typescript-to-lua/language-extensions": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/@typescript-to-lua/language-extensions/-/language-extensions-1.19.0.tgz", - "integrity": "sha512-Os5wOKwviTD4LeqI29N0btYOjokSJ97iCf45EOjIABlb5IwNQy7AE/AqZJobRw3ywHH8+KzJUMkEirWPzh2tUA==" + "integrity": "sha512-Os5wOKwviTD4LeqI29N0btYOjokSJ97iCf45EOjIABlb5IwNQy7AE/AqZJobRw3ywHH8+KzJUMkEirWPzh2tUA==", + "license": "MIT" }, "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -173,9 +192,13 @@ } }, "node_modules/acorn-walk": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", - "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, "engines": { "node": ">=0.4.0" } @@ -185,6 +208,7 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -194,19 +218,36 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "license": "MIT" }, "node_modules/asn1": { "version": "0.2.6", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "license": "MIT", "dependencies": { "safer-buffer": "~2.1.0" } @@ -216,6 +257,7 @@ "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", "integrity": "sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^1.1.3", "esutils": "^2.0.2", @@ -227,6 +269,7 @@ "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", "dev": true, + "license": "MIT", "dependencies": { "babel-code-frame": "^6.26.0", "babel-generator": "^6.26.0", @@ -254,6 +297,7 @@ "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", "dev": true, + "license": "MIT", "dependencies": { "babel-messages": "^6.23.0", "babel-runtime": "^6.26.0", @@ -270,6 +314,7 @@ "resolved": "https://registry.npmjs.org/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz", "integrity": "sha512-TYX2QQATKA6Wssp6j7jqlw4QLmABDN1olRdEHndYvBXdaXM5dcx6j5rN0+nd+aVL+Th40fAEYvvw/Xxd/LETuQ==", "dev": true, + "license": "MIT", "dependencies": { "babel-runtime": "^6.22.0", "babel-traverse": "^6.24.1", @@ -281,6 +326,7 @@ "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", "integrity": "sha512-gCtfYORSG1fUMX4kKraymq607FWgMWg+j42IFPc18kFQEsmtaibP4UrqsXt8FlEJle25HUd4tsoDR7H2wDhe9Q==", "dev": true, + "license": "MIT", "dependencies": { "babel-helper-explode-assignable-expression": "^6.24.1", "babel-runtime": "^6.22.0", @@ -292,6 +338,7 @@ "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", "integrity": "sha512-RL8n2NiEj+kKztlrVJM9JT1cXzzAdvWFh76xh/H1I4nKwunzE4INBXn8ieCZ+wh4zWszZk7NBS1s/8HR5jDkzQ==", "dev": true, + "license": "MIT", "dependencies": { "babel-helper-hoist-variables": "^6.24.1", "babel-runtime": "^6.22.0", @@ -304,6 +351,7 @@ "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", "integrity": "sha512-bHkmjcC9lM1kmZcVpA5t2om2nzT/xiZpo6TJq7UlZ3wqKfzia4veeXbIhKvJXAMzhhEBd3cR1IElL5AenWEUpA==", "dev": true, + "license": "MIT", "dependencies": { "babel-helper-function-name": "^6.24.1", "babel-runtime": "^6.26.0", @@ -316,6 +364,7 @@ "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", "integrity": "sha512-qe5csbhbvq6ccry9G7tkXbzNtcDiH4r51rrPUbwwoTzZ18AqxWYRZT6AOmxrpxKnQBW0pYlBI/8vh73Z//78nQ==", "dev": true, + "license": "MIT", "dependencies": { "babel-runtime": "^6.22.0", "babel-traverse": "^6.24.1", @@ -327,6 +376,7 @@ "resolved": "https://registry.npmjs.org/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz", "integrity": "sha512-SFbWewr0/0U4AiRzsHqwsbOQeLXVa9T1ELdqEa2efcQB5KopTnunAqoj07TuHlN2lfTQNPGO/rJR4FMln5fVcA==", "dev": true, + "license": "MIT", "dependencies": { "babel-helper-bindify-decorators": "^6.24.1", "babel-runtime": "^6.22.0", @@ -339,6 +389,7 @@ "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", "integrity": "sha512-Oo6+e2iX+o9eVvJ9Y5eKL5iryeRdsIkwRYheCuhYdVHsdEQysbc2z2QkqCLIYnNxkT5Ss3ggrHdXiDI7Dhrn4Q==", "dev": true, + "license": "MIT", "dependencies": { "babel-helper-get-function-arity": "^6.24.1", "babel-runtime": "^6.22.0", @@ -352,6 +403,7 @@ "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", "integrity": "sha512-WfgKFX6swFB1jS2vo+DwivRN4NB8XUdM3ij0Y1gnC21y1tdBoe6xjVnd7NSI6alv+gZXCtJqvrTeMW3fR/c0ng==", "dev": true, + "license": "MIT", "dependencies": { "babel-runtime": "^6.22.0", "babel-types": "^6.24.1" @@ -362,6 +414,7 @@ "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", "integrity": "sha512-zAYl3tqerLItvG5cKYw7f1SpvIxS9zi7ohyGHaI9cgDUjAT6YcY9jIEH5CstetP5wHIVSceXwNS7Z5BpJg+rOw==", "dev": true, + "license": "MIT", "dependencies": { "babel-runtime": "^6.22.0", "babel-types": "^6.24.1" @@ -372,6 +425,7 @@ "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", "integrity": "sha512-Op9IhEaxhbRT8MDXx2iNuMgciu2V8lDvYCNQbDGjdBNCjaMvyLf4wl4A3b8IgndCyQF8TwfgsQ8T3VD8aX1/pA==", "dev": true, + "license": "MIT", "dependencies": { "babel-runtime": "^6.22.0", "babel-types": "^6.24.1" @@ -382,6 +436,7 @@ "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", "integrity": "sha512-VlPiWmqmGJp0x0oK27Out1D+71nVVCTSdlbhIVoaBAj2lUgrNjBCRR9+llO4lTSb2O4r7PJg+RobRkhBrf6ofg==", "dev": true, + "license": "MIT", "dependencies": { "babel-runtime": "^6.26.0", "babel-types": "^6.26.0", @@ -393,6 +448,7 @@ "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", "integrity": "sha512-RYqaPD0mQyQIFRu7Ho5wE2yvA/5jxqCIj/Lv4BXNq23mHYu/vxikOy2JueLiBxQknwapwrJeNCesvY0ZcfnlHg==", "dev": true, + "license": "MIT", "dependencies": { "babel-helper-function-name": "^6.24.1", "babel-runtime": "^6.22.0", @@ -406,6 +462,7 @@ "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", "integrity": "sha512-sLI+u7sXJh6+ToqDr57Bv973kCepItDhMou0xCP2YPVmR1jkHSCY+p1no8xErbV1Siz5QE8qKT1WIwybSWlqjw==", "dev": true, + "license": "MIT", "dependencies": { "babel-helper-optimise-call-expression": "^6.24.1", "babel-messages": "^6.23.0", @@ -420,6 +477,7 @@ "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", "integrity": "sha512-n7pFrqQm44TCYvrCDb0MqabAF+JUBq+ijBvNMUxpkLjJaAu32faIexewMumrH5KLLJ1HDyT0PTEqRyAe/GwwuQ==", "dev": true, + "license": "MIT", "dependencies": { "babel-runtime": "^6.22.0", "babel-template": "^6.24.1" @@ -430,6 +488,7 @@ "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", "integrity": "sha512-Bl3ZiA+LjqaMtNYopA9TYE9HP1tQ+E5dLxE0XrAzcIJeK2UqF0/EaqXwBn9esd4UmTfEab+P+UYQ1GnioFIb/w==", "dev": true, + "license": "MIT", "dependencies": { "babel-runtime": "^6.22.0" } @@ -439,6 +498,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", "integrity": "sha512-B1M5KBP29248dViEo1owyY32lk1ZSH2DaNNrXLGt8lyjjHm7pBqAdQ7VKUPR6EEDO323+OvT3MQXbCin8ooWdA==", "dev": true, + "license": "MIT", "dependencies": { "babel-runtime": "^6.22.0" } @@ -447,79 +507,92 @@ "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", "integrity": "sha512-4Zp4unmHgw30A1eWI5EpACji2qMocisdXhAftfhXoSV9j0Tvj6nRFE3tOmRY912E0FMRm/L5xWE7MGVT2FoLnw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/babel-plugin-syntax-async-generators": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz", "integrity": "sha512-EbciFN5Jb9iqU9bqaLmmFLx2G8pAUsvpWJ6OzOWBNrSY9qTohXj+7YfZx6Ug1Qqh7tCb1EA7Jvn9bMC1HBiucg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/babel-plugin-syntax-class-constructor-call": { "version": "6.18.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-constructor-call/-/babel-plugin-syntax-class-constructor-call-6.18.0.tgz", "integrity": "sha512-EEuBcXz/wZ81Jaac0LnMHtD4Mfz9XWn2oH2Xj+CHwz2SZWUqqdtR2BgWPSdTGMmxN/5KLSh4PImt9+9ZedDarA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/babel-plugin-syntax-class-properties": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz", "integrity": "sha512-chI3Rt9T1AbrQD1s+vxw3KcwC9yHtF621/MacuItITfZX344uhQoANjpoSJZleAmW2tjlolqB/f+h7jIqXa7pA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/babel-plugin-syntax-decorators": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz", "integrity": "sha512-AWj19x2aDm8qFQ5O2JcD6pwJDW1YdcnO+1b81t7gxrGjz5VHiUqeYWAR4h7zueWMalRelrQDXprv2FrY1dbpbw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/babel-plugin-syntax-do-expressions": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-do-expressions/-/babel-plugin-syntax-do-expressions-6.13.0.tgz", "integrity": "sha512-HD/5qJB9oSXzl0caxM+aRD7ENICXqcc3Up/8toDQk7zNIDE7TzsqtxC5f4t9Rwhu2Ya8l9l4j6b3vOsy+a6qxg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/babel-plugin-syntax-dynamic-import": { "version": "6.18.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz", "integrity": "sha512-MioUE+LfjCEz65Wf7Z/Rm4XCP5k2c+TbMd2Z2JKc7U9uwjBhAfNPE48KC4GTGKhppMeYVepwDBNO/nGY6NYHBA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/babel-plugin-syntax-exponentiation-operator": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", "integrity": "sha512-Z/flU+T9ta0aIEKl1tGEmN/pZiI1uXmCiGFRegKacQfEJzp7iNsKloZmyJlQr+75FCJtiFfGIK03SiCvCt9cPQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/babel-plugin-syntax-export-extensions": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-6.13.0.tgz", "integrity": "sha512-Eo0rcRaIDMld/W6mVhePiudIuLW+Cr/8eveW3mBREfZORScZgx4rh6BAPyvzdEc/JZvQ+LkC80t0VGFs6FX+lg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/babel-plugin-syntax-function-bind": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-function-bind/-/babel-plugin-syntax-function-bind-6.13.0.tgz", "integrity": "sha512-m8yMoh9LIiNyeLdQs5I9G+3YXo4nqVsKQkk7YplrG4qAFbNi9hkZlow8HDHxhH9QOVFPHmy8+03NzRCdyChIKw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/babel-plugin-syntax-object-rest-spread": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", "integrity": "sha512-C4Aq+GaAj83pRQ0EFgTvw5YO6T3Qz2KGrNRwIj9mSoNHVvdZY4KO2uA6HNtNXCw993iSZnckY1aLW8nOi8i4+w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/babel-plugin-syntax-trailing-function-commas": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", "integrity": "sha512-Gx9CH3Q/3GKbhs07Bszw5fPTlU+ygrOGfAhEt7W2JICwufpC4SuO0mG0+4NykPBSYPMJhqvVlDBU17qB1D+hMQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/babel-plugin-transform-async-generator-functions": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz", "integrity": "sha512-uT7eovUxtXe8Q2ufcjRuJIOL0hg6VAUJhiWJBLxH/evYAw+aqoJLcYTR8hqx13iOx/FfbCMHgBmXWZjukbkyPg==", "dev": true, + "license": "MIT", "dependencies": { "babel-helper-remap-async-to-generator": "^6.24.1", "babel-plugin-syntax-async-generators": "^6.5.0", @@ -531,6 +604,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", "integrity": "sha512-7BgYJujNCg0Ti3x0c/DL3tStvnKS6ktIYOmo9wginv/dfZOrbSZ+qG4IRRHMBOzZ5Awb1skTiAsQXg/+IWkZYw==", "dev": true, + "license": "MIT", "dependencies": { "babel-helper-remap-async-to-generator": "^6.24.1", "babel-plugin-syntax-async-functions": "^6.8.0", @@ -542,6 +616,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-constructor-call/-/babel-plugin-transform-class-constructor-call-6.24.1.tgz", "integrity": "sha512-RvYukT1Nh7njz8P8326ztpQUGCKwmjgu6aRIx1lkvylWITYcskg29vy1Kp8WXIq7FvhXsz0Crf2kS94bjB690A==", "dev": true, + "license": "MIT", "dependencies": { "babel-plugin-syntax-class-constructor-call": "^6.18.0", "babel-runtime": "^6.22.0", @@ -553,6 +628,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz", "integrity": "sha512-n4jtBA3OYBdvG5PRMKsMXJXHfLYw/ZOmtxCLOOwz6Ro5XlrColkStLnz1AS1L2yfPA9BKJ1ZNlmVCLjAL9DSIg==", "dev": true, + "license": "MIT", "dependencies": { "babel-helper-function-name": "^6.24.1", "babel-plugin-syntax-class-properties": "^6.8.0", @@ -565,6 +641,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz", "integrity": "sha512-skQ2CImwDkCHu0mkWvCOlBCpBIHW4/49IZWVwV4A/EnWjL9bB6UBvLyMNe3Td5XDStSZNhe69j4bfEW8dvUbew==", "dev": true, + "license": "MIT", "dependencies": { "babel-helper-explode-class": "^6.24.1", "babel-plugin-syntax-decorators": "^6.13.0", @@ -578,6 +655,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-do-expressions/-/babel-plugin-transform-do-expressions-6.22.0.tgz", "integrity": "sha512-yQwYqYg+Tnj1InA8W1rsItsZVhkv1Euc4KVua9ledtPz5PDWYz7LVyy6rDBpVYUWFZj5k6GUm3YZpCbIm8Tqew==", "dev": true, + "license": "MIT", "dependencies": { "babel-plugin-syntax-do-expressions": "^6.8.0", "babel-runtime": "^6.22.0" @@ -588,6 +666,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", "integrity": "sha512-PCqwwzODXW7JMrzu+yZIaYbPQSKjDTAsNNlK2l5Gg9g4rz2VzLnZsStvp/3c46GfXpwkyufb3NCyG9+50FF1Vg==", "dev": true, + "license": "MIT", "dependencies": { "babel-runtime": "^6.22.0" } @@ -597,6 +676,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", "integrity": "sha512-2+ujAT2UMBzYFm7tidUsYh+ZoIutxJ3pN9IYrF1/H6dCKtECfhmB8UkHVpyxDwkj0CYbQG35ykoz925TUnBc3A==", "dev": true, + "license": "MIT", "dependencies": { "babel-runtime": "^6.22.0" } @@ -606,6 +686,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", "integrity": "sha512-YiN6sFAQ5lML8JjCmr7uerS5Yc/EMbgg9G8ZNmk2E3nYX4ckHR01wrkeeMijEf5WHNK5TW0Sl0Uu3pv3EdOJWw==", "dev": true, + "license": "MIT", "dependencies": { "babel-runtime": "^6.26.0", "babel-template": "^6.26.0", @@ -619,6 +700,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", "integrity": "sha512-5Dy7ZbRinGrNtmWpquZKZ3EGY8sDgIVB4CU8Om8q8tnMLrD/m94cKglVcHps0BCTdZ0TJeeAWOq2TK9MIY6cag==", "dev": true, + "license": "MIT", "dependencies": { "babel-helper-define-map": "^6.24.1", "babel-helper-function-name": "^6.24.1", @@ -636,6 +718,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", "integrity": "sha512-C/uAv4ktFP/Hmh01gMTvYvICrKze0XVX9f2PdIXuriCSvUmV9j+u+BB9f5fJK3+878yMK6dkdcq+Ymr9mrcLzw==", "dev": true, + "license": "MIT", "dependencies": { "babel-runtime": "^6.22.0", "babel-template": "^6.24.1" @@ -646,6 +729,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", "integrity": "sha512-aNv/GDAW0j/f4Uy1OEPZn1mqD+Nfy9viFGBfQ5bZyT35YqOiqx7/tXdyfZkJ1sC21NyEsBdfDY6PYmLHF4r5iA==", "dev": true, + "license": "MIT", "dependencies": { "babel-runtime": "^6.22.0" } @@ -655,6 +739,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", "integrity": "sha512-ossocTuPOssfxO2h+Z3/Ea1Vo1wWx31Uqy9vIiJusOP4TbF7tPs9U0sJ9pX9OJPf4lXRGj5+6Gkl/HHKiAP5ug==", "dev": true, + "license": "MIT", "dependencies": { "babel-runtime": "^6.22.0", "babel-types": "^6.24.1" @@ -665,6 +750,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", "integrity": "sha512-DLuRwoygCoXx+YfxHLkVx5/NpeSbVwfoTeBykpJK7JhYWlL/O8hgAK/reforUnZDlxasOrVPPJVI/guE3dCwkw==", "dev": true, + "license": "MIT", "dependencies": { "babel-runtime": "^6.22.0" } @@ -674,6 +760,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", "integrity": "sha512-iFp5KIcorf11iBqu/y/a7DK3MN5di3pNCzto61FqCNnUX4qeBwcV1SLqe10oXNnCaxBUImX3SckX2/o1nsrTcg==", "dev": true, + "license": "MIT", "dependencies": { "babel-helper-function-name": "^6.24.1", "babel-runtime": "^6.22.0", @@ -685,6 +772,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", "integrity": "sha512-tjFl0cwMPpDYyoqYA9li1/7mGFit39XiNX5DKC/uCNjBctMxyL1/PT/l4rSlbvBG1pOKI88STRdUsWXB3/Q9hQ==", "dev": true, + "license": "MIT", "dependencies": { "babel-runtime": "^6.22.0" } @@ -694,6 +782,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", "integrity": "sha512-LnIIdGWIKdw7zwckqx+eGjcS8/cl8D74A3BpJbGjKTFFNJSMrjN4bIh22HY1AlkUbeLG6X6OZj56BDvWD+OeFA==", "dev": true, + "license": "MIT", "dependencies": { "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", "babel-runtime": "^6.22.0", @@ -705,6 +794,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz", "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", "dev": true, + "license": "MIT", "dependencies": { "babel-plugin-transform-strict-mode": "^6.24.1", "babel-runtime": "^6.26.0", @@ -717,6 +807,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", "integrity": "sha512-ONFIPsq8y4bls5PPsAWYXH/21Hqv64TBxdje0FvU3MhIV6QM2j5YS7KvAzg/nTIVLot2D2fmFQrFWCbgHlFEjg==", "dev": true, + "license": "MIT", "dependencies": { "babel-helper-hoist-variables": "^6.24.1", "babel-runtime": "^6.22.0", @@ -728,6 +819,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", "integrity": "sha512-LpVbiT9CLsuAIp3IG0tfbVo81QIhn6pE8xBJ7XSeCtFlMltuar5VuBV6y6Q45tpui9QWcy5i0vLQfCfrnF7Kiw==", "dev": true, + "license": "MIT", "dependencies": { "babel-plugin-transform-es2015-modules-amd": "^6.24.1", "babel-runtime": "^6.22.0", @@ -739,6 +831,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", "integrity": "sha512-8G5hpZMecb53vpD3mjs64NhI1au24TAmokQ4B+TBFBjN9cVoGoOvotdrMMRmHvVZUEvqGUPWL514woru1ChZMA==", "dev": true, + "license": "MIT", "dependencies": { "babel-helper-replace-supers": "^6.24.1", "babel-runtime": "^6.22.0" @@ -749,6 +842,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", "integrity": "sha512-8HxlW+BB5HqniD+nLkQ4xSAVq3bR/pcYW9IigY+2y0dI+Y7INFeTbfAQr+63T3E4UDsZGjyb+l9txUnABWxlOQ==", "dev": true, + "license": "MIT", "dependencies": { "babel-helper-call-delegate": "^6.24.1", "babel-helper-get-function-arity": "^6.24.1", @@ -763,6 +857,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", "integrity": "sha512-mDdocSfUVm1/7Jw/FIRNw9vPrBQNePy6wZJlR8HAUBLybNp1w/6lr6zZ2pjMShee65t/ybR5pT8ulkLzD1xwiw==", "dev": true, + "license": "MIT", "dependencies": { "babel-runtime": "^6.22.0", "babel-types": "^6.24.1" @@ -773,6 +868,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", "integrity": "sha512-3Ghhi26r4l3d0Js933E5+IhHwk0A1yiutj9gwvzmFbVV0sPMYk2lekhOufHBswX7NCoSeF4Xrl3sCIuSIa+zOg==", "dev": true, + "license": "MIT", "dependencies": { "babel-runtime": "^6.22.0" } @@ -782,6 +878,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", "integrity": "sha512-CYP359ADryTo3pCsH0oxRo/0yn6UsEZLqYohHmvLQdfS9xkf+MbCzE3/Kolw9OYIY4ZMilH25z/5CbQbwDD+lQ==", "dev": true, + "license": "MIT", "dependencies": { "babel-helper-regex": "^6.24.1", "babel-runtime": "^6.22.0", @@ -793,6 +890,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", "integrity": "sha512-x8b9W0ngnKzDMHimVtTfn5ryimars1ByTqsfBDwAqLibmuuQY6pgBQi5z1ErIsUOWBdw1bW9FSz5RZUojM4apg==", "dev": true, + "license": "MIT", "dependencies": { "babel-runtime": "^6.22.0" } @@ -802,6 +900,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", "integrity": "sha512-fz6J2Sf4gYN6gWgRZaoFXmq93X+Li/8vf+fb0sGDVtdeWvxC9y5/bTD7bvfWMEq6zetGEHpWjtzRGSugt5kNqw==", "dev": true, + "license": "MIT", "dependencies": { "babel-runtime": "^6.22.0" } @@ -811,6 +910,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", "integrity": "sha512-v61Dbbihf5XxnYjtBN04B/JBvsScY37R1cZT5r9permN1cp+b70DY3Ib3fIkgn1DI9U3tGgBJZVD8p/mE/4JbQ==", "dev": true, + "license": "MIT", "dependencies": { "babel-helper-regex": "^6.24.1", "babel-runtime": "^6.22.0", @@ -822,6 +922,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", "integrity": "sha512-LzXDmbMkklvNhprr20//RStKVcT8Cu+SQtX18eMHLhjHf2yFzwtQ0S2f0jQ+89rokoNdmwoSqYzAhq86FxlLSQ==", "dev": true, + "license": "MIT", "dependencies": { "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", "babel-plugin-syntax-exponentiation-operator": "^6.8.0", @@ -833,6 +934,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-export-extensions/-/babel-plugin-transform-export-extensions-6.22.0.tgz", "integrity": "sha512-mtzELzINaYqdVglyZrDDVwkcFRuE7s6QUFWXxwffKAHB/NkfbJ2NJSytugB43ytIC8UVt30Ereyx+7gNyTkDLg==", "dev": true, + "license": "MIT", "dependencies": { "babel-plugin-syntax-export-extensions": "^6.8.0", "babel-runtime": "^6.22.0" @@ -843,6 +945,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-function-bind/-/babel-plugin-transform-function-bind-6.22.0.tgz", "integrity": "sha512-9Ec4KYf1GurT39mlUjDSlN7HWSlB3u3mWRMogQbb+Y88lO0ZM3rJ0ADhPnQwWK9TbO6e/4E+Et1rrfGY9mFimA==", "dev": true, + "license": "MIT", "dependencies": { "babel-plugin-syntax-function-bind": "^6.8.0", "babel-runtime": "^6.22.0" @@ -853,6 +956,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", "integrity": "sha512-ocgA9VJvyxwt+qJB0ncxV8kb/CjfTcECUY4tQ5VT7nP6Aohzobm8CDFaQ5FHdvZQzLmf0sgDxB8iRXZXxwZcyA==", "dev": true, + "license": "MIT", "dependencies": { "babel-plugin-syntax-object-rest-spread": "^6.8.0", "babel-runtime": "^6.26.0" @@ -863,6 +967,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", "integrity": "sha512-LS+dBkUGlNR15/5WHKe/8Neawx663qttS6AGqoOUhICc9d1KciBvtrQSuc0PI+CxQ2Q/S1aKuJ+u64GtLdcEZg==", "dev": true, + "license": "MIT", "dependencies": { "regenerator-transform": "^0.10.0" } @@ -872,6 +977,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", "integrity": "sha512-j3KtSpjyLSJxNoCDrhwiJad8kw0gJ9REGj8/CqL0HeRyLnvUNYV9zcqluL6QJSXh3nfsLEmSLvwRfGzrgR96Pw==", "dev": true, + "license": "MIT", "dependencies": { "babel-runtime": "^6.22.0", "babel-types": "^6.24.1" @@ -883,6 +989,7 @@ "integrity": "sha512-XfwUqG1Ry6R43m4Wfob+vHbIVBIqTg/TJY4Snku1iIzeH7mUnwHA8Vagmv+ZQbPwhS8HgsdQvy28Py3k5zpoFQ==", "deprecated": "🙌 Thanks for using Babel: we recommend using babel-preset-env now: please read https://babeljs.io/env to update!", "dev": true, + "license": "MIT", "dependencies": { "babel-plugin-check-es2015-constants": "^6.22.0", "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", @@ -915,6 +1022,7 @@ "resolved": "https://registry.npmjs.org/babel-preset-stage-0/-/babel-preset-stage-0-6.24.1.tgz", "integrity": "sha512-MJD+xBbpsApbKlzAX0sOBF+VeFaUmv5s8FSOO7SSZpes1QgphCjq/UIGRFWSmQ/0i5bqQjLGCTXGGXqcLQ9JDA==", "dev": true, + "license": "MIT", "dependencies": { "babel-plugin-transform-do-expressions": "^6.22.0", "babel-plugin-transform-function-bind": "^6.22.0", @@ -926,6 +1034,7 @@ "resolved": "https://registry.npmjs.org/babel-preset-stage-1/-/babel-preset-stage-1-6.24.1.tgz", "integrity": "sha512-rn+UOcd7BHDniq1SVxv2/AVVSVI1NK+hfS0I/iR6m6KbOi/aeBRcqBilqO73pd9VUpRXF2HFtlDuC9F2BEQqmg==", "dev": true, + "license": "MIT", "dependencies": { "babel-plugin-transform-class-constructor-call": "^6.24.1", "babel-plugin-transform-export-extensions": "^6.22.0", @@ -937,6 +1046,7 @@ "resolved": "https://registry.npmjs.org/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz", "integrity": "sha512-9F+nquz+37PrlTSBdpeQBKnQfAMNBnryXw+m4qBh35FNbJPfzZz+sjN2G5Uf1CRedU9PH7fJkTbYijxmkLX8Og==", "dev": true, + "license": "MIT", "dependencies": { "babel-plugin-syntax-dynamic-import": "^6.18.0", "babel-plugin-transform-class-properties": "^6.24.1", @@ -949,6 +1059,7 @@ "resolved": "https://registry.npmjs.org/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz", "integrity": "sha512-eCbEOF8uN0KypFXJmZXn2sTk7bPV9uM5xov7G/7BM08TbQEObsVs0cEWfy6NQySlfk7JBi/t+XJP1JkruYfthA==", "dev": true, + "license": "MIT", "dependencies": { "babel-plugin-syntax-trailing-function-commas": "^6.22.0", "babel-plugin-transform-async-generator-functions": "^6.24.1", @@ -962,6 +1073,7 @@ "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", "integrity": "sha512-veliHlHX06wjaeY8xNITbveXSiI+ASFnOqvne/LaIJIqOWi2Ogmj91KOugEz/hoh/fwMhXNBJPCv8Xaz5CyM4A==", "dev": true, + "license": "MIT", "dependencies": { "babel-core": "^6.26.0", "babel-runtime": "^6.26.0", @@ -977,6 +1089,7 @@ "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", "integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==", "dev": true, + "license": "MIT", "dependencies": { "core-js": "^2.4.0", "regenerator-runtime": "^0.11.0" @@ -987,6 +1100,7 @@ "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", "integrity": "sha512-PCOcLFW7/eazGUKIoqH97sO9A2UYMahsn/yRQ7uOk37iutwjq7ODtcTNF+iFDSHNfkctqsLRjLP7URnOx0T1fg==", "dev": true, + "license": "MIT", "dependencies": { "babel-runtime": "^6.26.0", "babel-traverse": "^6.26.0", @@ -1000,6 +1114,7 @@ "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", "integrity": "sha512-iSxeXx7apsjCHe9c7n8VtRXGzI2Bk1rBSOJgCCjfyXb6v1aCqE1KSEpq/8SXuVN8Ka/Rh1WDTF0MDzkvTA4MIA==", "dev": true, + "license": "MIT", "dependencies": { "babel-code-frame": "^6.26.0", "babel-messages": "^6.23.0", @@ -1017,6 +1132,7 @@ "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", "integrity": "sha512-zhe3V/26rCWsEZK8kZN+HaQj5yQ1CilTObixFzKW1UWjqG7618Twz6YEsCnjfg5gBcJh02DrpCkS9h98ZqDY+g==", "dev": true, + "license": "MIT", "dependencies": { "babel-runtime": "^6.26.0", "esutils": "^2.0.2", @@ -1029,6 +1145,7 @@ "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", "dev": true, + "license": "MIT", "bin": { "babylon": "bin/babylon.js" } @@ -1037,26 +1154,55 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "license": "BSD-3-Clause", "dependencies": { "tweetnacl": "^0.14.3" } }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/buildcheck": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/buildcheck/-/buildcheck-0.0.6.tgz", @@ -1071,6 +1217,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^2.2.1", "escape-string-regexp": "^1.0.2", @@ -1082,11 +1229,37 @@ "node": ">=0.10.0" } }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -1098,12 +1271,14 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/commander": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "license": "MIT", "engines": { "node": ">= 10" } @@ -1112,13 +1287,15 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/convert-source-map": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/core-js": { "version": "2.6.12", @@ -1126,17 +1303,18 @@ "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.", "dev": true, - "hasInstallScript": true + "hasInstallScript": true, + "license": "MIT" }, "node_modules/cpu-features": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.9.tgz", - "integrity": "sha512-AKjgn2rP2yJyfbepsmLfiYcmtNn/2eUvocUyM/09yB0YDiz39HteK/5/T4Onf0pmdYDMgkBoGvRLvEguzyL7wQ==", + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.10.tgz", + "integrity": "sha512-9IkYqtX3YHPCzoVg1Py+o9057a3i0fp7S530UWokCSaFVTc7CwXPRiOjRjBQQ18ZCNafx78YfnG+HALxtVmOGA==", "hasInstallScript": true, "optional": true, "dependencies": { "buildcheck": "~0.0.6", - "nan": "^2.17.0" + "nan": "^2.19.0" }, "engines": { "node": ">=10.0.0" @@ -1145,13 +1323,15 @@ "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "license": "MIT" }, "node_modules/cross-spawn": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==", "dev": true, + "license": "MIT", "dependencies": { "lru-cache": "^4.0.1", "shebang-command": "^1.2.0", @@ -1163,6 +1343,7 @@ "resolved": "https://registry.npmjs.org/cross-var/-/cross-var-1.1.0.tgz", "integrity": "sha512-wIcFax9RNm5ayuORUeJ5MLxPbfh8XdZhhUpKutIszU46Fs9UIhEdPJ7+YguM+7FxEj+68hSQVyathVsIu84SiA==", "dev": true, + "license": "MIT", "dependencies": { "babel-preset-es2015": "^6.18.0", "babel-preset-stage-0": "^6.16.0", @@ -1179,6 +1360,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -1188,6 +1370,7 @@ "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", "integrity": "sha512-BDKtmHlOzwI7iRuEkhzsnPoi5ypEhWAJB5RvHWe1kMr06js3uK5B3734i3ui5Yd+wOJV1cpE4JnivPD283GU/A==", "dev": true, + "license": "MIT", "dependencies": { "repeating": "^2.0.0" }, @@ -1199,15 +1382,17 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } }, "node_modules/dotenv": { - "version": "16.4.5", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", - "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "version": "16.4.6", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.6.tgz", + "integrity": "sha512-JhcR/+KIjkkjiU8yEpaB/USlzVi3i5whwOjpIRNGi9svKEXZSe+Qp6IWAjFjv+2GViAoDRCUv/QLNziQxsLqDg==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=12" }, @@ -1216,12 +1401,13 @@ } }, "node_modules/dotenv-cli": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/dotenv-cli/-/dotenv-cli-7.3.0.tgz", - "integrity": "sha512-314CA4TyK34YEJ6ntBf80eUY+t1XaFLyem1k9P0sX1gn30qThZ5qZr/ZwE318gEnzyYP9yj9HJk6SqwE0upkfw==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/dotenv-cli/-/dotenv-cli-7.4.4.tgz", + "integrity": "sha512-XkBYCG0tPIes+YZr4SpfFv76SQrV/LeCE8CI7JSEMi3VR9MvTihCGTOtbIexD6i2mXF+6px7trb1imVCXSNMDw==", "dev": true, + "license": "MIT", "dependencies": { - "cross-spawn": "^7.0.3", + "cross-spawn": "^7.0.6", "dotenv": "^16.3.0", "dotenv-expand": "^10.0.0", "minimist": "^1.2.6" @@ -1231,10 +1417,11 @@ } }, "node_modules/dotenv-cli/node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -1249,6 +1436,7 @@ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, + "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -1261,6 +1449,7 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -1270,6 +1459,7 @@ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -1285,6 +1475,7 @@ "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-10.0.0.tgz", "integrity": "sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=12" } @@ -1292,24 +1483,28 @@ "node_modules/duplexer": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "license": "MIT" }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/enhanced-resolve": { - "version": "5.15.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", - "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz", + "integrity": "sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==", + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -1323,6 +1518,7 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.0" } @@ -1332,6 +1528,7 @@ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } @@ -1340,6 +1537,7 @@ "version": "3.3.4", "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", "integrity": "sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==", + "license": "MIT", "dependencies": { "duplexer": "~0.1.1", "from": "~0", @@ -1359,11 +1557,25 @@ "node": ">= 0.8.0" } }, - "node_modules/foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/foreground-child": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "dev": true, + "license": "ISC", "dependencies": { "cross-spawn": "^7.0.0", "signal-exit": "^4.0.1" @@ -1376,10 +1588,11 @@ } }, "node_modules/foreground-child/node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -1394,6 +1607,7 @@ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, + "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -1406,6 +1620,7 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -1415,6 +1630,7 @@ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -1428,12 +1644,14 @@ "node_modules/from": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", - "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==" + "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==", + "license": "MIT" }, "node_modules/fs-extra": { "version": "11.2.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -1443,50 +1661,80 @@ "node": ">=14.14" } }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/glob": { - "version": "10.3.10", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", - "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "dev": true, + "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", - "jackspeak": "^2.3.5", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/glob/node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/glob/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -1502,6 +1750,7 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1509,13 +1758,15 @@ "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" }, "node_modules/has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^2.0.0" }, @@ -1523,10 +1774,21 @@ "node": ">=0.10.0" } }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/hasown": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", - "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, @@ -1539,6 +1801,7 @@ "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", "integrity": "sha512-ycURW7oUxE2sNiPVw1HVEFsW+ecOpJ5zaj7eC0RlwhibhRBod20muUN8qu/gzx956YrLolVvs1MTXwKgC2rVEg==", "dev": true, + "license": "MIT", "dependencies": { "os-homedir": "^1.0.0", "os-tmpdir": "^1.0.1" @@ -1547,31 +1810,67 @@ "node": ">=0.10.0" } }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true, + "license": "ISC" + }, "node_modules/invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", "dev": true, + "license": "MIT", "dependencies": { "loose-envify": "^1.0.0" } }, - "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", "dependencies": { - "hasown": "^2.0.0" + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-finite": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" }, @@ -1584,26 +1883,49 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" }, "node_modules/jackspeak": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", - "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" }, - "engines": { - "node": ">=14" - }, "funding": { "url": "https://github.com/sponsors/isaacs" }, @@ -1615,13 +1937,15 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", "integrity": "sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/jsesc": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", "integrity": "sha512-Mke0DA0QjUWuJlhsE0ZPPhYiJkRap642SmI/4ztCFaUs6V2AiH1sfecc+57NgaryfAA2VR3v6O+CSjC1jZJKOA==", "dev": true, + "license": "MIT", "bin": { "jsesc": "bin/jsesc" } @@ -1631,6 +1955,7 @@ "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", "integrity": "sha512-4xrs1aW+6N5DalkqSVA8fxh458CXvR99WU8WLKmq4v8eWAL86Xo3BVqyd3SkA9wEVjCMqyvvRRkshAdOnBp5rw==", "dev": true, + "license": "MIT", "bin": { "json5": "lib/cli.js" } @@ -1639,6 +1964,7 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "license": "MIT", "dependencies": { "universalify": "^2.0.0" }, @@ -1649,13 +1975,15 @@ "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", "dev": true, + "license": "MIT", "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, @@ -1668,6 +1996,7 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", "dev": true, + "license": "ISC", "dependencies": { "pseudomap": "^1.0.2", "yallist": "^2.1.2" @@ -1676,12 +2005,14 @@ "node_modules/lua-types": { "version": "2.13.1", "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.13.1.tgz", - "integrity": "sha512-rRwtvX6kS+5MpuO3xpvKsnYjdSDDI064Qq1OqX8gY+r+0l7m3dFLiZPDFoHqH22jaBpEvcHcPs6+WD7qkdmFsA==" + "integrity": "sha512-rRwtvX6kS+5MpuO3xpvKsnYjdSDDI064Qq1OqX8gY+r+0l7m3dFLiZPDFoHqH22jaBpEvcHcPs6+WD7qkdmFsA==", + "license": "MIT" }, "node_modules/make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "license": "ISC" }, "node_modules/map-stream": { "version": "0.1.0", @@ -1693,6 +2024,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -1705,15 +2037,17 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "dev": true, + "license": "ISC", "engines": { "node": ">=16 || 14 >=14.17" } @@ -1723,6 +2057,7 @@ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", "dev": true, + "license": "MIT", "dependencies": { "minimist": "^1.2.6" }, @@ -1734,32 +2069,114 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/nan": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.18.0.tgz", - "integrity": "sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w==", + "version": "2.22.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.22.0.tgz", + "integrity": "sha512-nbajikzWTMwsW+eSsNm3QwlOs7het9gGJU5dDZzRTQGk03vyBOauxgI4VakDzE0PtsGTmXPsXTbbjVhRwR5mpw==", + "license": "MIT", "optional": true }, "node_modules/node-cleanup": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/node-cleanup/-/node-cleanup-2.1.2.tgz", - "integrity": "sha512-qN8v/s2PAJwGUtr1/hYTpNKlD6Y9rc4p8KSmJXyGdYGZsDGKXrGThikLFP9OCHFeLeEpQzPwiAtdIvBLqm//Hw==" + "integrity": "sha512-qN8v/s2PAJwGUtr1/hYTpNKlD6Y9rc4p8KSmJXyGdYGZsDGKXrGThikLFP9OCHFeLeEpQzPwiAtdIvBLqm//Hw==", + "license": "MIT" }, "node_modules/node-scp": { "version": "0.0.23", "resolved": "https://registry.npmjs.org/node-scp/-/node-scp-0.0.23.tgz", "integrity": "sha512-He+Jxt1WwuAZBfdPxoq+wQSrXMSHobB4+oo1LUDhKGqzbub7D/Q6JpDja3SzFvaxIhhnhgituP91BU97viCMjA==", + "license": "MIT", "dependencies": { "ssh2": "^1.14.0" } }, + "node_modules/nodemon": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.9.tgz", + "integrity": "sha512-hdr1oIb2p6ZSxu3PB2JWWYS7ZQ0qvaZsc3hK8DR8f02kRzc8rjYmxAIvdz+aYC+8F2IjNaB7HMcSDg8nQpJxyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^4", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^7.5.3", + "simple-update-notifier": "^2.0.0", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/nodemon/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/nodemon/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nodemon/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1769,15 +2186,24 @@ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1786,6 +2212,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", "engines": { "node": ">=8" } @@ -1793,37 +2220,41 @@ "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" }, "node_modules/path-scurry": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", - "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "lru-cache": "^9.1.1 || ^10.0.0", + "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=16 || 14 >=14.18" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", - "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "dev": true, - "engines": { - "node": "14 || >=16.14" - } + "license": "ISC" }, "node_modules/pause-stream": { "version": "0.0.11", "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==", + "license": [ + "MIT", + "Apache2" + ], "dependencies": { "through": "~2.3" } @@ -1832,6 +2263,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", "engines": { "node": ">=8.6" }, @@ -1844,6 +2276,7 @@ "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -1852,6 +2285,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.2.0.tgz", "integrity": "sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==", + "license": "MIT", "dependencies": { "event-stream": "=3.3.4" }, @@ -1866,25 +2300,49 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", - "dev": true + "dev": true, + "license": "ISC" + }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true, + "license": "MIT" + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } }, "node_modules/regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/regenerator-runtime": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/regenerator-transform": { "version": "0.10.1", "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", "dev": true, + "license": "BSD", "dependencies": { "babel-runtime": "^6.18.0", "babel-types": "^6.19.0", @@ -1896,6 +2354,7 @@ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", "integrity": "sha512-tJ9+S4oKjxY8IZ9jmjnp/mtytu1u3iyIQAfmI51IKWH6bFf7XR1ybtaO6j7INhZKXOTYADk7V5qxaqLkmNxiZQ==", "dev": true, + "license": "MIT", "dependencies": { "regenerate": "^1.2.1", "regjsgen": "^0.2.0", @@ -1906,13 +2365,15 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", "integrity": "sha512-x+Y3yA24uF68m5GA+tBjbGYo64xXVJpbToBaWCoSNSc1hdk6dfctaRWrNFTVJZIIhL5GxW8zwjoixbnifnK59g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/regjsparser": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", "integrity": "sha512-jlQ9gYLfk2p3V5Ag5fYhA7fv7OHzd1KUH0PRP46xc3TgwjwgROIW572AfYg/X9kaNq/LJnu6oJcFRXlIrGoTRw==", "dev": true, + "license": "BSD", "dependencies": { "jsesc": "~0.5.0" }, @@ -1934,6 +2395,7 @@ "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", "integrity": "sha512-ZqtSMuVybkISo2OWvqvm7iHSWngvdaW3IpsT9/uP8v4gMi591LY6h35wdOfvQdWCKFWZWm2Y1Opp4kV7vQKT6A==", "dev": true, + "license": "MIT", "dependencies": { "is-finite": "^1.0.0" }, @@ -1945,6 +2407,7 @@ "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "license": "MIT", "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -1958,19 +2421,17 @@ } }, "node_modules/rimraf": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", - "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", "dev": true, + "license": "ISC", "dependencies": { "glob": "^10.3.7" }, "bin": { "rimraf": "dist/esm/bin.mjs" }, - "engines": { - "node": ">=14" - }, "funding": { "url": "https://github.com/sponsors/isaacs" } @@ -1978,13 +2439,28 @@ "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } }, "node_modules/shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", "dev": true, + "license": "MIT", "dependencies": { "shebang-regex": "^1.0.0" }, @@ -1997,6 +2473,7 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -2006,6 +2483,7 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, + "license": "ISC", "engines": { "node": ">=14" }, @@ -2013,11 +2491,25 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/simple-update-notifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/slash": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", "integrity": "sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -2027,6 +2519,7 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -2036,6 +2529,7 @@ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", "dev": true, + "license": "MIT", "dependencies": { "source-map": "^0.5.6" } @@ -2044,6 +2538,7 @@ "version": "0.3.3", "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", "integrity": "sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==", + "license": "MIT", "dependencies": { "through": "2" }, @@ -2052,9 +2547,9 @@ } }, "node_modules/ssh2": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.15.0.tgz", - "integrity": "sha512-C0PHgX4h6lBxYx7hcXwu3QWdh4tg6tZZsTfXcdvc5caW/EMxaB4H9dWsl7qk+F7LAW762hp8VbXOX7x4xUYvEw==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.16.0.tgz", + "integrity": "sha512-r1X4KsBGedJqo7h8F5c4Ybpcr5RjyP+aWIG007uBPRjmdQWfEiVLzSK71Zji1B9sKxwaCvD8y8cwSkYrlLiRRg==", "hasInstallScript": true, "dependencies": { "asn1": "^0.2.6", @@ -2064,14 +2559,15 @@ "node": ">=10.16.0" }, "optionalDependencies": { - "cpu-features": "~0.0.9", - "nan": "^2.18.0" + "cpu-features": "~0.0.10", + "nan": "^2.20.0" } }, "node_modules/stream-combiner": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", "integrity": "sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==", + "license": "MIT", "dependencies": { "duplexer": "~0.1.1" } @@ -2080,6 +2576,7 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", + "license": "MIT", "engines": { "node": ">=0.6.19" } @@ -2089,6 +2586,7 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": true, + "license": "MIT", "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -2107,6 +2605,7 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -2121,6 +2620,7 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -2129,13 +2629,15 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/string-width-cjs/node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -2144,10 +2646,11 @@ } }, "node_modules/string-width/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -2160,6 +2663,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -2175,6 +2679,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^2.0.0" }, @@ -2188,6 +2693,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -2200,6 +2706,7 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -2209,6 +2716,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.0" } @@ -2217,6 +2725,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -2228,6 +2737,7 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "license": "MIT", "engines": { "node": ">=6" } @@ -2235,22 +2745,48 @@ "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "license": "MIT" }, "node_modules/to-fast-properties": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", "integrity": "sha512-lxrWP8ejsq+7E3nNjwYmUBMAgjMTZoTI+sdBOpvNyijeDLa29LUn9QaoXAHv4+Z578hbmHHJKZknzxVtvo77og==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/touch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", + "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==", + "dev": true, + "license": "ISC", + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, "node_modules/trim-right": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", "integrity": "sha512-WZGXGstmCWgeevgTL54hrCuw1dyMQIzWy7ZfqRJfSmJZBwklI15egmQytFP6bPidmw3M8d5yEowl1niq4vmqZw==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -2259,6 +2795,7 @@ "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "license": "MIT", "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -2298,9 +2835,10 @@ } }, "node_modules/tsc-watch": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/tsc-watch/-/tsc-watch-6.0.4.tgz", - "integrity": "sha512-cHvbvhjO86w2aGlaHgSCeQRl+Aqw6X6XN4sQMPZKF88GoP30O+oTuh5lRIJr5pgFWrRpF1AgXnJJ2DoFEIPHyg==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tsc-watch/-/tsc-watch-6.2.1.tgz", + "integrity": "sha512-GLwdz5Dy9K3sVm3RzgkLcyDpl5cvU9HEcE1A3gf5rqEwlUe7gDLxNCgcuNEw3zoKOiegMo3LnbF1t6HLqxhrSA==", + "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", "node-cleanup": "^2.1.2", @@ -2318,9 +2856,10 @@ } }, "node_modules/tsc-watch/node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -2334,6 +2873,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -2345,6 +2885,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", "engines": { "node": ">=8" } @@ -2353,6 +2894,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -2366,12 +2908,14 @@ "node_modules/tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "license": "Unlicense" }, "node_modules/typescript": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", - "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", + "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -2381,12 +2925,13 @@ } }, "node_modules/typescript-to-lua": { - "version": "1.24.1", - "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.24.1.tgz", - "integrity": "sha512-IqHKVMkgRk9cd8S8nhu5wKP+AiK9QeCJ9OUphKcNzQMNpEirrQKHvbQwoeVNWNsIaiCUvrdM1SuyxDX1B3TRZw==", + "version": "1.28.1", + "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.28.1.tgz", + "integrity": "sha512-4Ah8bco9X7BNrDcVUHEDDWbZL2whoUg8CCLnUJWsoopmV43aDZuEqOlhtsWAjsH+3Wq5SugYcmyFRrZ+mWyCYw==", + "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", - "enhanced-resolve": "^5.8.2", + "enhanced-resolve": "5.8.2", "picomatch": "^2.3.1", "resolve": "^1.15.1", "source-map": "^0.7.3" @@ -2398,26 +2943,36 @@ "node": ">=16.10.0" }, "peerDependencies": { - "typescript": "5.3.3" + "typescript": "5.7.2" } }, "node_modules/typescript-to-lua/node_modules/source-map": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "license": "BSD-3-Clause", "engines": { "node": ">= 8" } }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true, + "license": "MIT" + }, "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "license": "MIT" }, "node_modules/universalify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", "engines": { "node": ">= 10.0.0" } @@ -2425,13 +2980,15 @@ "node_modules/v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "license": "MIT" }, "node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -2440,9 +2997,10 @@ } }, "node_modules/wow-eluna-ts-module": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/wow-eluna-ts-module/-/wow-eluna-ts-module-1.10.0.tgz", - "integrity": "sha512-Qf/tiNa1moPdfzTSi5zLQqr8hYnMvMdmzGLKG1JGzx4UNoeo7FVxRNpWcRB0v5h6NwSeb2EuOoJ9lyq2jkRjrA==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/wow-eluna-ts-module/-/wow-eluna-ts-module-1.11.1.tgz", + "integrity": "sha512-ZqeIz2O+uTZl1Q/XBsbbGBPQwoM11/0v8JNJ8wKlM3pLzihwU/xStgYWKeLy/fE+McChokM5mCCTUxhV+Go5Ew==", + "license": "AGPL-3.0-or-later", "dependencies": { "@araxiaonline/wow-wotlk-declarations": "^3.3.5-7", "@typescript-to-lua/language-extensions": "^1.19.0", @@ -2465,6 +3023,7 @@ "version": "9.0.2", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-9.0.2.tgz", "integrity": "sha512-I9OvvrHp4pIARv4+x9iuewrWycX6CcZtoAu1XrzPxc5UygMJXJZYmBsynku8IkrJwgypE5DGNjDPmPRhDCptUg==", + "license": "BSD-2-Clause", "engines": { "node": ">=10" } @@ -2474,6 +3033,7 @@ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", @@ -2492,6 +3052,7 @@ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -2509,6 +3070,7 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -2518,6 +3080,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -2532,13 +3095,15 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/wrap-ansi-cjs/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -2553,6 +3118,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -2561,10 +3127,11 @@ } }, "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -2577,6 +3144,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -2589,6 +3157,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -2603,12 +3172,14 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "license": "MIT", "engines": { "node": ">=6" } diff --git a/package.json b/package.json index 6ba6ec2..3ec557c 100644 --- a/package.json +++ b/package.json @@ -5,18 +5,22 @@ "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: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": { "cross-var": "^1.1.0", "dotenv-cli": "^7.3.0", + "nodemon": "^3.1.9", "rimraf": "^5.0.5", "typescript": "^5.2.2", "typescript-to-lua": "^1.23.0" }, "dependencies": { "@types/fs-extra": "^11.0.4", - "@types/node": "^20.11.15", + "@types/node": "^20.11.15", "fs-extra": "^11.2.0", "ts-node": "^10.9.1", "wow-eluna-ts-module": "^1.9.3" diff --git a/scripts/reload-eluna.exp b/scripts/reload-eluna.exp new file mode 100755 index 0000000..8d2a190 --- /dev/null +++ b/scripts/reload-eluna.exp @@ -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 diff --git a/tsconfig.json b/tsconfig.json index 1dcc247..7ec5928 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -26,7 +26,7 @@ "rootDir": "modules" }, "include": [ - "modules/**/*.ts", + "modules/**/*.ts", "development/tbc-launch.ts", ], "exclude": [ "node_modules",