annotate Main.lua @ 32:81d7d84df629

Record the player's current standing with a given faction when recording faction gains.
author James D. Callahan III <jcallahan@curse.com>
date Wed, 30 May 2012 14:56:19 -0500
parents 728f1e5dcdc8
children 6422f3b61962
rev   line source
jcallahan@0 1 -----------------------------------------------------------------------
jcallahan@0 2 -- Upvalued Lua API.
jcallahan@0 3 -----------------------------------------------------------------------
jcallahan@0 4 local _G = getfenv(0)
jcallahan@0 5
jcallahan@0 6 local pairs = _G.pairs
jcallahan@1 7 local tonumber = _G.tonumber
jcallahan@1 8
jcallahan@1 9 local bit = _G.bit
jcallahan@1 10 local math = _G.math
jcallahan@1 11 local table = _G.table
jcallahan@1 12
jcallahan@0 13
jcallahan@0 14 -----------------------------------------------------------------------
jcallahan@0 15 -- AddOn namespace.
jcallahan@0 16 -----------------------------------------------------------------------
jcallahan@0 17 local ADDON_NAME, private = ...
jcallahan@0 18
jcallahan@0 19 local LibStub = _G.LibStub
jcallahan@0 20 local WDP = LibStub("AceAddon-3.0"):NewAddon(ADDON_NAME, "AceEvent-3.0", "AceTimer-3.0")
jcallahan@0 21
jcallahan@4 22 local DatamineTT = _G.CreateFrame("GameTooltip", "WDPDatamineTT", _G.UIParent, "GameTooltipTemplate")
jcallahan@5 23 DatamineTT:SetOwner(_G.WorldFrame, "ANCHOR_NONE")
jcallahan@5 24
jcallahan@0 25
jcallahan@0 26 -----------------------------------------------------------------------
jcallahan@0 27 -- Local constants.
jcallahan@0 28 -----------------------------------------------------------------------
jcallahan@0 29 local DATABASE_DEFAULTS = {
jcallahan@0 30 global = {
jcallahan@0 31 items = {},
jcallahan@0 32 npcs = {},
jcallahan@0 33 objects = {},
jcallahan@0 34 quests = {},
jcallahan@17 35 zones = {},
jcallahan@0 36 }
jcallahan@0 37 }
jcallahan@0 38
jcallahan@0 39
jcallahan@1 40 local EVENT_MAPPING = {
jcallahan@23 41 COMBAT_LOG_EVENT_UNFILTERED = true,
jcallahan@18 42 COMBAT_TEXT_UPDATE = true,
jcallahan@1 43 LOOT_OPENED = true,
jcallahan@7 44 MERCHANT_SHOW = "UpdateMerchantItems",
jcallahan@7 45 MERCHANT_UPDATE = "UpdateMerchantItems",
jcallahan@25 46 PET_BAR_UPDATE = true,
jcallahan@2 47 PLAYER_TARGET_CHANGED = true,
jcallahan@9 48 QUEST_COMPLETE = true,
jcallahan@9 49 QUEST_DETAIL = true,
jcallahan@9 50 QUEST_LOG_UPDATE = true,
jcallahan@27 51 TRAINER_SHOW = true,
jcallahan@4 52 UNIT_QUEST_LOG_CHANGED = true,
jcallahan@1 53 UNIT_SPELLCAST_FAILED = "HandleSpellFailure",
jcallahan@1 54 UNIT_SPELLCAST_FAILED_QUIET = "HandleSpellFailure",
jcallahan@1 55 UNIT_SPELLCAST_INTERRUPTED = "HandleSpellFailure",
jcallahan@1 56 UNIT_SPELLCAST_SENT = true,
jcallahan@1 57 UNIT_SPELLCAST_SUCCEEDED = true,
jcallahan@0 58 }
jcallahan@0 59
jcallahan@4 60
jcallahan@1 61 local AF = private.ACTION_TYPE_FLAGS
jcallahan@0 62
jcallahan@4 63
jcallahan@27 64 local PLAYER_CLASS = _G.select(2, _G.UnitClass("player"))
jcallahan@27 65
jcallahan@27 66
jcallahan@0 67 -----------------------------------------------------------------------
jcallahan@0 68 -- Local variables.
jcallahan@0 69 -----------------------------------------------------------------------
jcallahan@0 70 local db
jcallahan@0 71 local durability_timer_handle
jcallahan@2 72 local target_location_timer_handle
jcallahan@1 73 local action_data = {}
jcallahan@32 74 local faction_standings = {}
jcallahan@0 75
jcallahan@1 76
jcallahan@1 77 -----------------------------------------------------------------------
jcallahan@1 78 -- Helper Functions.
jcallahan@1 79 -----------------------------------------------------------------------
jcallahan@29 80 local function InstanceDifficultyToken()
jcallahan@29 81 local _, instance_type, instance_difficulty, difficulty_name, _, _, is_dynamic = _G.GetInstanceInfo()
jcallahan@29 82 if difficulty_name == "" then
jcallahan@29 83 difficulty_name = "NONE"
jcallahan@29 84 end
jcallahan@29 85 return ("%s:%s:%s"):format(instance_type:upper(), difficulty_name:upper():gsub(" ", "_"), _G.tostring(is_dynamic))
jcallahan@29 86 end
jcallahan@29 87
jcallahan@29 88
jcallahan@19 89 local function DBEntry(data_type, unit_id)
jcallahan@19 90 if not data_type or not unit_id then
jcallahan@6 91 return
jcallahan@6 92 end
jcallahan@19 93 local unit = db[data_type][unit_id]
jcallahan@6 94
jcallahan@10 95 if not unit then
jcallahan@19 96 db[data_type][unit_id] = {}
jcallahan@19 97 unit = db[data_type][unit_id]
jcallahan@6 98 end
jcallahan@10 99 return unit
jcallahan@6 100 end
jcallahan@6 101
jcallahan@6 102
jcallahan@29 103 local function NPCEntry(identifier)
jcallahan@29 104 local npc = DBEntry("npcs", identifier)
jcallahan@29 105
jcallahan@29 106 if not npc then
jcallahan@29 107 return
jcallahan@22 108 end
jcallahan@29 109 local instance_token = InstanceDifficultyToken()
jcallahan@29 110 npc.encounter_data = npc.encounter_data or {}
jcallahan@29 111 npc.encounter_data[instance_token] = npc.encounter_data[instance_token] or {}
jcallahan@30 112 npc.encounter_data[instance_token].stats = npc.encounter_data[instance_token].stats or {}
jcallahan@29 113 return npc
jcallahan@22 114 end
jcallahan@22 115
jcallahan@22 116
jcallahan@1 117 local function CurrentLocationData()
jcallahan@1 118 local map_level = _G.GetCurrentMapDungeonLevel() or 0
jcallahan@1 119 local x, y = _G.GetPlayerMapPosition("player")
jcallahan@1 120
jcallahan@1 121 x = x or 0
jcallahan@1 122 y = y or 0
jcallahan@1 123
jcallahan@1 124 if x == 0 and y == 0 then
jcallahan@1 125 for level_index = 1, _G.GetNumDungeonMapLevels() do
jcallahan@1 126 _G.SetDungeonMapLevel(level_index)
jcallahan@1 127 x, y = _G.GetPlayerMapPosition("player")
jcallahan@1 128
jcallahan@1 129 if x and y and (x > 0 or y > 0) then
jcallahan@1 130 _G.SetDungeonMapLevel(map_level)
jcallahan@1 131 map_level = level_index
jcallahan@1 132 break
jcallahan@1 133 end
jcallahan@1 134 end
jcallahan@1 135 end
jcallahan@1 136
jcallahan@1 137 if _G.DungeonUsesTerrainMap() then
jcallahan@1 138 map_level = map_level - 1
jcallahan@1 139 end
jcallahan@31 140 local x = _G.floor(x * 1000)
jcallahan@31 141 local y = _G.floor(y * 1000)
jcallahan@28 142
jcallahan@31 143 if x % 2 ~= 0 then
jcallahan@31 144 x = x + 1
jcallahan@28 145 end
jcallahan@28 146
jcallahan@31 147 if y % 2 ~= 0 then
jcallahan@31 148 y = y + 1
jcallahan@28 149 end
jcallahan@31 150 return _G.GetRealZoneText(), _G.GetCurrentMapAreaID(), x, y, map_level, InstanceDifficultyToken()
jcallahan@1 151 end
jcallahan@1 152
jcallahan@1 153
jcallahan@1 154 local function ItemLinkToID(item_link)
jcallahan@1 155 if not item_link then
jcallahan@1 156 return
jcallahan@1 157 end
jcallahan@7 158 return tonumber(item_link:match("item:(%d+)"))
jcallahan@1 159 end
jcallahan@0 160
jcallahan@4 161
jcallahan@4 162 do
jcallahan@4 163 local UNIT_TYPE_BITMASK = 0x007
jcallahan@4 164
jcallahan@4 165 function WDP:ParseGUID(guid)
jcallahan@5 166 if not guid then
jcallahan@5 167 return
jcallahan@5 168 end
jcallahan@4 169 local types = private.UNIT_TYPES
jcallahan@4 170 local unit_type = _G.bit.band(tonumber(guid:sub(1, 5)), UNIT_TYPE_BITMASK)
jcallahan@4 171
jcallahan@10 172 if unit_type ~= types.PLAYER and unit_type ~= types.PET then
jcallahan@4 173 return unit_type, tonumber(guid:sub(-12, -9), 16)
jcallahan@4 174 end
jcallahan@4 175
jcallahan@4 176 return unit_type
jcallahan@4 177 end
jcallahan@4 178 end -- do-block
jcallahan@4 179
jcallahan@4 180
jcallahan@10 181 local function UpdateObjectLocation(identifier)
jcallahan@10 182 if not identifier then
jcallahan@10 183 return
jcallahan@10 184 end
jcallahan@31 185 local zone_name, area_id, x, y, map_level, difficulty_token = CurrentLocationData()
jcallahan@19 186 local object = DBEntry("objects", identifier)
jcallahan@31 187 object[difficulty_token] = object[difficulty_token] or {}
jcallahan@31 188 object[difficulty_token].locations = object[difficulty_token].locations or {}
jcallahan@10 189
jcallahan@31 190 local zone_token = ("%s:%d"):format(zone_name, area_id)
jcallahan@31 191 local zone_data = object[difficulty_token].locations[zone_token]
jcallahan@24 192
jcallahan@31 193 if not zone_data then
jcallahan@31 194 zone_data = {}
jcallahan@31 195 object[difficulty_token].locations[zone_token] = zone_data
jcallahan@10 196 end
jcallahan@31 197 zone_data[("%s:%s:%s"):format(map_level, x, y)] = true
jcallahan@10 198 end
jcallahan@10 199
jcallahan@10 200
jcallahan@19 201 local function HandleItemUse(item_link, bag_index, slot_index)
jcallahan@19 202 if not item_link then
jcallahan@19 203 return
jcallahan@19 204 end
jcallahan@19 205 local item_id = ItemLinkToID(item_link)
jcallahan@19 206
jcallahan@19 207 if not bag_index or not slot_index then
jcallahan@19 208 for new_bag_index = 0, _G.NUM_BAG_FRAMES do
jcallahan@19 209 for new_slot_index = 1, _G.GetContainerNumSlots(new_bag_index) do
jcallahan@19 210 if item_id == ItemLinkToID(_G.GetContainerItemLink(new_bag_index, new_slot_index)) then
jcallahan@19 211 bag_index = new_bag_index
jcallahan@19 212 slot_index = new_slot_index
jcallahan@19 213 break
jcallahan@19 214 end
jcallahan@19 215 end
jcallahan@19 216 end
jcallahan@19 217 end
jcallahan@19 218
jcallahan@19 219 if not bag_index or not slot_index then
jcallahan@19 220 return
jcallahan@19 221 end
jcallahan@19 222 local _, _, _, _, _, is_lootable = _G.GetContainerItemInfo(bag_index, slot_index)
jcallahan@19 223
jcallahan@19 224 if not is_lootable then
jcallahan@19 225 return
jcallahan@19 226 end
jcallahan@19 227 DatamineTT:ClearLines()
jcallahan@19 228 DatamineTT:SetBagItem(bag_index, slot_index)
jcallahan@19 229
jcallahan@19 230 for line_index = 1, DatamineTT:NumLines() do
jcallahan@19 231 local current_line = _G["WDPDatamineTTTextLeft" .. line_index]
jcallahan@19 232
jcallahan@19 233 if not current_line then
jcallahan@19 234 break
jcallahan@19 235 end
jcallahan@19 236
jcallahan@19 237 if current_line:GetText() == _G.ITEM_OPENABLE then
jcallahan@19 238 table.wipe(action_data)
jcallahan@19 239 action_data.type = AF.ITEM
jcallahan@28 240 action_data.identifier = item_id
jcallahan@25 241 action_data.label = "contains"
jcallahan@19 242 break
jcallahan@19 243 end
jcallahan@19 244 end
jcallahan@19 245 end
jcallahan@19 246
jcallahan@19 247
jcallahan@32 248 local UpdateFactionData
jcallahan@32 249 do
jcallahan@32 250 local MAX_FACTION_INDEX = 1000
jcallahan@20 251
jcallahan@32 252 local STANDING_NAMES = {
jcallahan@32 253 "HATED",
jcallahan@32 254 "HOSTILE",
jcallahan@32 255 "UNFRIENDLY",
jcallahan@32 256 "NEUTRAL",
jcallahan@32 257 "FRIENDLY",
jcallahan@32 258 "HONORED",
jcallahan@32 259 "REVERED",
jcallahan@32 260 "EXALTED",
jcallahan@32 261 }
jcallahan@32 262
jcallahan@32 263 function UpdateFactionData()
jcallahan@32 264 for faction_index = 1, MAX_FACTION_INDEX do
jcallahan@32 265 local faction_name, _, current_standing, _, _, _, _, _, is_header = _G.GetFactionInfo(faction_index)
jcallahan@32 266
jcallahan@32 267 if faction_name and not is_header then
jcallahan@32 268 faction_standings[faction_name] = STANDING_NAMES[current_standing]
jcallahan@32 269 elseif not faction_name then
jcallahan@32 270 break
jcallahan@32 271 end
jcallahan@20 272 end
jcallahan@20 273 end
jcallahan@32 274 end -- do-block
jcallahan@20 275
jcallahan@0 276 -----------------------------------------------------------------------
jcallahan@0 277 -- Methods.
jcallahan@0 278 -----------------------------------------------------------------------
jcallahan@0 279 function WDP:OnInitialize()
jcallahan@0 280 db = LibStub("AceDB-3.0"):New("WoWDBProfilerData", DATABASE_DEFAULTS, "Default").global
jcallahan@14 281
jcallahan@14 282 local raw_db = _G["WoWDBProfilerData"]
jcallahan@14 283
jcallahan@18 284 local build_num = tonumber(private.build_num)
jcallahan@14 285
jcallahan@14 286 if raw_db.build_num and raw_db.build_num < build_num then
jcallahan@14 287 for entry in pairs(DATABASE_DEFAULTS.global) do
jcallahan@14 288 db[entry] = {}
jcallahan@14 289 end
jcallahan@14 290 raw_db.build_num = build_num
jcallahan@14 291 elseif not raw_db.build_num then
jcallahan@14 292 raw_db.build_num = build_num
jcallahan@14 293 end
jcallahan@0 294 end
jcallahan@0 295
jcallahan@0 296
jcallahan@0 297 function WDP:OnEnable()
jcallahan@0 298 for event_name, mapping in pairs(EVENT_MAPPING) do
jcallahan@1 299 self:RegisterEvent(event_name, (_G.type(mapping) ~= "boolean") and mapping or nil)
jcallahan@0 300 end
jcallahan@0 301 durability_timer_handle = self:ScheduleRepeatingTimer("ProcessDurability", 30)
jcallahan@31 302 target_location_timer_handle = self:ScheduleRepeatingTimer("UpdateTargetLocation", 0.5)
jcallahan@19 303
jcallahan@19 304 _G.hooksecurefunc("UseContainerItem", function(bag_index, slot_index, target_unit)
jcallahan@19 305 if target_unit then
jcallahan@19 306 return
jcallahan@19 307 end
jcallahan@19 308 HandleItemUse(_G.GetContainerItemLink(bag_index, slot_index), bag_index, slot_index)
jcallahan@19 309 end)
jcallahan@19 310
jcallahan@19 311 _G.hooksecurefunc("UseItemByName", function(identifier, target_unit)
jcallahan@19 312 if target_unit then
jcallahan@19 313 return
jcallahan@19 314 end
jcallahan@19 315 local _, item_link = _G.GetItemInfo(identifier)
jcallahan@19 316 HandleItemUse(item_link)
jcallahan@19 317 end)
jcallahan@0 318 end
jcallahan@0 319
jcallahan@0 320
jcallahan@0 321 local function RecordDurability(item_id, durability)
jcallahan@0 322 if not durability or durability <= 0 then
jcallahan@0 323 return
jcallahan@0 324 end
jcallahan@0 325
jcallahan@0 326 if not db.items[item_id] then
jcallahan@0 327 db.items[item_id] = {}
jcallahan@0 328 end
jcallahan@0 329 db.items[item_id].durability = durability
jcallahan@0 330 end
jcallahan@0 331
jcallahan@0 332
jcallahan@0 333 function WDP:ProcessDurability()
jcallahan@0 334 for slot_index = 0, _G.INVSLOT_LAST_EQUIPPED do
jcallahan@1 335 local item_id = _G.GetInventoryItemID("player", slot_index)
jcallahan@0 336
jcallahan@0 337 if item_id and item_id > 0 then
jcallahan@1 338 local _, max_durability = _G.GetInventoryItemDurability(slot_index)
jcallahan@0 339 RecordDurability(item_id, max_durability)
jcallahan@0 340 end
jcallahan@0 341 end
jcallahan@0 342
jcallahan@0 343 for bag_index = 0, _G.NUM_BAG_SLOTS do
jcallahan@0 344 for slot_index = 1, _G.GetContainerNumSlots(bag_index) do
jcallahan@1 345 local item_id = _G.GetContainerItemID(bag_index, slot_index)
jcallahan@0 346
jcallahan@0 347 if item_id and item_id > 0 then
jcallahan@1 348 local _, max_durability = _G.GetContainerItemDurability(bag_index, slot_index)
jcallahan@0 349 RecordDurability(item_id, max_durability)
jcallahan@0 350 end
jcallahan@0 351 end
jcallahan@0 352 end
jcallahan@0 353 end
jcallahan@0 354
jcallahan@0 355
jcallahan@31 356 local COORD_MAX = 5
jcallahan@31 357
jcallahan@2 358 function WDP:UpdateTargetLocation()
jcallahan@31 359 if not _G.UnitExists("target") or _G.UnitPlayerControlled("target") or (_G.UnitIsTapped("target") and not _G.UnitIsDead("target")) then
jcallahan@2 360 return
jcallahan@2 361 end
jcallahan@2 362
jcallahan@2 363 for index = 1, 4 do
jcallahan@2 364 if not _G.CheckInteractDistance("target", index) then
jcallahan@2 365 return
jcallahan@2 366 end
jcallahan@2 367 end
jcallahan@22 368 local target_guid = _G.UnitGUID("target")
jcallahan@22 369 local unit_type, unit_idnum = self:ParseGUID(target_guid)
jcallahan@2 370
jcallahan@2 371 if unit_type ~= private.UNIT_TYPES.NPC or not unit_idnum then
jcallahan@2 372 return
jcallahan@2 373 end
jcallahan@31 374 local zone_name, area_id, x, y, map_level, difficulty_token = CurrentLocationData()
jcallahan@31 375 local npc_data = NPCEntry(unit_idnum).encounter_data[difficulty_token].stats[("level_%d"):format(_G.UnitLevel("target"))]
jcallahan@31 376 local zone_token = ("%s:%d"):format(zone_name, area_id)
jcallahan@6 377 npc_data.locations = npc_data.locations or {}
jcallahan@22 378
jcallahan@31 379 local zone_data = npc_data.locations[zone_token]
jcallahan@31 380
jcallahan@31 381 if not zone_data then
jcallahan@31 382 zone_data = {}
jcallahan@31 383 npc_data.locations[zone_token] = zone_data
jcallahan@22 384 end
jcallahan@31 385
jcallahan@31 386 for location_token in pairs(zone_data) do
jcallahan@31 387 local loc_level, loc_x, loc_y = (":"):split(location_token)
jcallahan@31 388 loc_level = tonumber(loc_level)
jcallahan@31 389
jcallahan@31 390 if map_level == loc_level and math.abs(x - loc_x) <= COORD_MAX and math.abs(y - loc_y) <= COORD_MAX then
jcallahan@31 391 return
jcallahan@31 392 end
jcallahan@31 393 end
jcallahan@31 394 zone_data[("%s:%s:%s"):format(map_level, x, y)] = true
jcallahan@2 395 end
jcallahan@2 396
jcallahan@2 397
jcallahan@0 398 -----------------------------------------------------------------------
jcallahan@0 399 -- Event handlers.
jcallahan@0 400 -----------------------------------------------------------------------
jcallahan@23 401 do
jcallahan@23 402 local EXTRACT_GAS_SPELL_ID = 30427
jcallahan@23 403 local FLAGS_NPC = bit.bor(_G.COMBATLOG_OBJECT_TYPE_GUARDIAN, _G.COMBATLOG_OBJECT_CONTROL_NPC)
jcallahan@23 404 local FLAGS_NPC_CONTROL = bit.bor(_G.COMBATLOG_OBJECT_AFFILIATION_OUTSIDER, _G.COMBATLOG_OBJECT_CONTROL_NPC)
jcallahan@23 405
jcallahan@23 406
jcallahan@23 407 local function RecordNPCSpell(sub_event, source_guid, source_name, source_flags, dest_guid, dest_name, dest_flags, spell_id, spell_name)
jcallahan@23 408 if not spell_id then
jcallahan@23 409 return
jcallahan@23 410 end
jcallahan@23 411 local source_type, source_id = WDP:ParseGUID(source_guid)
jcallahan@23 412
jcallahan@23 413 if not source_id or source_type ~= private.UNIT_TYPES.NPC then
jcallahan@23 414 return
jcallahan@23 415 end
jcallahan@23 416
jcallahan@23 417 if bit.band(FLAGS_NPC_CONTROL, source_flags) == FLAGS_NPC_CONTROL and bit.band(FLAGS_NPC, source_flags) ~= 0 then
jcallahan@29 418 local encounter_data = NPCEntry(source_id).encounter_data[InstanceDifficultyToken()]
jcallahan@28 419 encounter_data.spells = encounter_data.spells or {}
jcallahan@28 420 encounter_data.spells[spell_id] = (encounter_data.spells[spell_id] or 0) + 1
jcallahan@23 421 end
jcallahan@23 422 end
jcallahan@23 423
jcallahan@23 424
jcallahan@23 425 local COMBAT_LOG_FUNCS = {
jcallahan@23 426 SPELL_AURA_APPLIED = RecordNPCSpell,
jcallahan@23 427 SPELL_CAST_START = RecordNPCSpell,
jcallahan@23 428 SPELL_CAST_SUCCESS = RecordNPCSpell,
jcallahan@23 429 UNIT_DISSIPATES = function(sub_event, source_guid, source_name, source_flags, dest_guid, dest_name, dest_flags)
jcallahan@23 430 -- TODO: Write this.
jcallahan@23 431 end,
jcallahan@23 432 }
jcallahan@23 433
jcallahan@23 434
jcallahan@23 435 function WDP:COMBAT_LOG_EVENT_UNFILTERED(event, time_stamp, sub_event, hide_caster, source_guid, source_name, source_flags, source_raid_flags, dest_guid, dest_name, dest_flags, dest_raid_flags, ...)
jcallahan@23 436 local combat_log_func = COMBAT_LOG_FUNCS[sub_event]
jcallahan@23 437
jcallahan@23 438 if not combat_log_func then
jcallahan@23 439 return
jcallahan@23 440 end
jcallahan@23 441 combat_log_func(sub_event, source_guid, source_name, source_flags, dest_guid, dest_name, dest_flags, ...)
jcallahan@23 442 end
jcallahan@23 443 end -- do-block
jcallahan@23 444
jcallahan@23 445
jcallahan@18 446 function WDP:COMBAT_TEXT_UPDATE(event, message_type, faction_name, amount)
jcallahan@32 447 if message_type ~= "FACTION" then
jcallahan@32 448 return
jcallahan@32 449 end
jcallahan@29 450 local npc = NPCEntry(action_data.identifier)
jcallahan@21 451
jcallahan@21 452 if not npc then
jcallahan@21 453 return
jcallahan@21 454 end
jcallahan@30 455 local encounter_data = npc.encounter_data[InstanceDifficultyToken()].stats
jcallahan@32 456 local reputation_data = encounter_data[action_data.npc_level].reputations
jcallahan@32 457
jcallahan@32 458 if not reputation_data then
jcallahan@32 459 reputation_data = {}
jcallahan@32 460 encounter_data[action_data.npc_level].reputations = reputation_data
jcallahan@32 461 end
jcallahan@32 462 UpdateFactionData()
jcallahan@32 463 reputation_data[("%s:%s"):format(faction_name, faction_standings[faction_name])] = amount
jcallahan@18 464 end
jcallahan@18 465
jcallahan@18 466
jcallahan@13 467 do
jcallahan@13 468 local re_gold = _G.GOLD_AMOUNT:gsub("%%d", "(%%d+)")
jcallahan@13 469 local re_silver = _G.SILVER_AMOUNT:gsub("%%d", "(%%d+)")
jcallahan@13 470 local re_copper = _G.COPPER_AMOUNT:gsub("%%d", "(%%d+)")
jcallahan@13 471
jcallahan@13 472
jcallahan@13 473 local function _moneyMatch(money, re)
jcallahan@13 474 return money:match(re) or 0
jcallahan@1 475 end
jcallahan@1 476
jcallahan@0 477
jcallahan@13 478 local function _toCopper(money)
jcallahan@13 479 if not money then
jcallahan@13 480 return 0
jcallahan@13 481 end
jcallahan@0 482
jcallahan@13 483 return _moneyMatch(money, re_gold) * 10000 + _moneyMatch(money, re_silver) * 100 + _moneyMatch(money, re_copper)
jcallahan@1 484 end
jcallahan@1 485
jcallahan@1 486
jcallahan@13 487 local LOOT_VERIFY_FUNCS = {
jcallahan@16 488 [AF.ITEM] = function()
jcallahan@16 489 local locked_item_id
jcallahan@16 490
jcallahan@16 491 for bag_index = 0, _G.NUM_BAG_FRAMES do
jcallahan@16 492 for slot_index = 1, _G.GetContainerNumSlots(bag_index) do
jcallahan@16 493 local _, _, is_locked = _G.GetContainerItemInfo(bag_index, slot_index)
jcallahan@16 494
jcallahan@16 495 if is_locked then
jcallahan@16 496 locked_item_id = ItemLinkToID(_G.GetContainerItemLink(bag_index, slot_index))
jcallahan@16 497 end
jcallahan@16 498 end
jcallahan@16 499 end
jcallahan@16 500
jcallahan@28 501 if not locked_item_id or (action_data.identifier and action_data.identifier ~= locked_item_id) then
jcallahan@16 502 return false
jcallahan@16 503 end
jcallahan@28 504 action_data.identifier = locked_item_id
jcallahan@16 505 return true
jcallahan@16 506 end,
jcallahan@13 507 [AF.NPC] = function()
jcallahan@17 508 if not _G.UnitExists("target") or _G.UnitIsFriend("player", "target") or _G.UnitIsPlayer("target") or _G.UnitPlayerControlled("target") then
jcallahan@15 509 return false
jcallahan@13 510 end
jcallahan@15 511 local unit_type, id_num = WDP:ParseGUID(_G.UnitGUID("target"))
jcallahan@27 512 action_data.identifier = id_num
jcallahan@13 513 return true
jcallahan@13 514 end,
jcallahan@14 515 [AF.OBJECT] = true,
jcallahan@17 516 [AF.ZONE] = function()
jcallahan@25 517 return action_data.label and _G.IsFishingLoot()
jcallahan@17 518 end,
jcallahan@13 519 }
jcallahan@13 520
jcallahan@13 521
jcallahan@28 522 local function GenericLootUpdate(data_type, top_field)
jcallahan@27 523 local entry = DBEntry(data_type, action_data.identifier)
jcallahan@22 524
jcallahan@22 525 if not entry then
jcallahan@22 526 return
jcallahan@22 527 end
jcallahan@25 528 local loot_type = action_data.label or "drops"
jcallahan@28 529 local loot_data
jcallahan@28 530
jcallahan@28 531 if top_field then
jcallahan@28 532 entry[top_field] = entry[top_field] or {}
jcallahan@28 533 entry[top_field][loot_type] = entry[top_field][loot_type] or {}
jcallahan@28 534 loot_data = entry[top_field][loot_type]
jcallahan@28 535 else
jcallahan@28 536 entry[loot_type] = entry[loot_type] or {}
jcallahan@28 537 loot_data = entry[loot_type]
jcallahan@28 538 end
jcallahan@22 539
jcallahan@22 540 for index = 1, #action_data.loot_list do
jcallahan@28 541 table.insert(loot_data, action_data.loot_list[index])
jcallahan@22 542 end
jcallahan@22 543 end
jcallahan@22 544
jcallahan@22 545
jcallahan@13 546 local LOOT_UPDATE_FUNCS = {
jcallahan@16 547 [AF.ITEM] = function()
jcallahan@28 548 GenericLootUpdate("items")
jcallahan@28 549 end,
jcallahan@28 550 [AF.NPC] = function()
jcallahan@29 551 local npc = NPCEntry(action_data.identifier)
jcallahan@28 552
jcallahan@28 553 if not npc then
jcallahan@28 554 return
jcallahan@28 555 end
jcallahan@29 556 local encounter_data = npc.encounter_data[InstanceDifficultyToken()]
jcallahan@25 557 local loot_type = action_data.label or "drops"
jcallahan@29 558 encounter_data[loot_type] = encounter_data[loot_type] or {}
jcallahan@16 559
jcallahan@17 560 for index = 1, #action_data.loot_list do
jcallahan@29 561 table.insert(encounter_data[loot_type], action_data.loot_list[index])
jcallahan@16 562 end
jcallahan@16 563 end,
jcallahan@13 564 [AF.OBJECT] = function()
jcallahan@28 565 GenericLootUpdate("objects", InstanceDifficultyToken())
jcallahan@17 566 end,
jcallahan@17 567 [AF.ZONE] = function()
jcallahan@25 568 local loot_type = action_data.label or "drops"
jcallahan@19 569 local zone = DBEntry("zones", action_data.zone)
jcallahan@28 570 zone[action_data.instance_token] = zone[action_data.instance_token] or {}
jcallahan@29 571 zone[action_data.instance_token][loot_type] = zone[action_data.instance_token][loot_type] or {}
jcallahan@17 572
jcallahan@28 573 local location_data = ("%s:%s:%s"):format(action_data.map_level, action_data.x, action_data.y)
jcallahan@28 574 local loot_data = zone[action_data.instance_token][loot_type][location_data]
jcallahan@17 575
jcallahan@17 576 if not loot_data then
jcallahan@28 577 zone[action_data.instance_token][loot_type][location_data] = {}
jcallahan@28 578 loot_data = zone[action_data.instance_token][loot_type][location_data]
jcallahan@17 579 end
jcallahan@17 580
jcallahan@17 581 for index = 1, #action_data.loot_list do
jcallahan@17 582 table.insert(loot_data, action_data.loot_list[index])
jcallahan@13 583 end
jcallahan@13 584 end,
jcallahan@13 585 }
jcallahan@13 586
jcallahan@13 587
jcallahan@13 588 function WDP:LOOT_OPENED()
jcallahan@18 589 if action_data.looting then
jcallahan@18 590 return
jcallahan@18 591 end
jcallahan@18 592
jcallahan@13 593 if not action_data.type then
jcallahan@13 594 action_data.type = AF.NPC
jcallahan@1 595 end
jcallahan@13 596 local verify_func = LOOT_VERIFY_FUNCS[action_data.type]
jcallahan@13 597 local update_func = LOOT_UPDATE_FUNCS[action_data.type]
jcallahan@13 598
jcallahan@14 599 if not verify_func or not update_func then
jcallahan@13 600 return
jcallahan@13 601 end
jcallahan@13 602
jcallahan@14 603 if _G.type(verify_func) == "function" and not verify_func() then
jcallahan@14 604 return
jcallahan@14 605 end
jcallahan@18 606 -- TODO: Remove this check once the MoP client goes live
jcallahan@18 607 local wow_version = private.wow_version
jcallahan@13 608 local loot_registry = {}
jcallahan@17 609 action_data.loot_list = {}
jcallahan@18 610 action_data.looting = true
jcallahan@13 611
jcallahan@18 612 if wow_version == "5.0.1" then
jcallahan@18 613 for loot_slot = 1, _G.GetNumLootItems() do
jcallahan@18 614 local icon_texture, item_text, quantity, quality, locked = _G.GetLootSlotInfo(loot_slot)
jcallahan@13 615
jcallahan@18 616 local slot_type = _G.GetLootSlotType(loot_slot)
jcallahan@18 617
jcallahan@18 618 if slot_type == _G.LOOT_SLOT_ITEM then
jcallahan@18 619 local item_id = ItemLinkToID(_G.GetLootSlotLink(loot_slot))
jcallahan@18 620 loot_registry[item_id] = (loot_registry[item_id]) or 0 + quantity
jcallahan@18 621 elseif slot_type == _G.LOOT_SLOT_MONEY then
jcallahan@18 622 table.insert(action_data.loot_list, ("money:%d"):format(_toCopper(item_text)))
jcallahan@18 623 elseif slot_type == _G.LOOT_SLOT_CURRENCY then
jcallahan@18 624 table.insert(action_data.loot_list, ("currency:%d:%s"):format(quantity, icon_texture:match("[^\\]+$"):lower()))
jcallahan@18 625 end
jcallahan@18 626 end
jcallahan@18 627 else
jcallahan@18 628 for loot_slot = 1, _G.GetNumLootItems() do
jcallahan@18 629 local icon_texture, item_text, quantity, quality, locked = _G.GetLootSlotInfo(loot_slot)
jcallahan@18 630 if _G.LootSlotIsItem(loot_slot) then
jcallahan@18 631 local item_id = ItemLinkToID(_G.GetLootSlotLink(loot_slot))
jcallahan@18 632 loot_registry[item_id] = (loot_registry[item_id]) or 0 + quantity
jcallahan@18 633 elseif _G.LootSlotIsCoin(loot_slot) then
jcallahan@18 634 table.insert(action_data.loot_list, ("money:%d"):format(_toCopper(item_text)))
jcallahan@18 635 elseif _G.LootSlotIsCurrency(loot_slot) then
jcallahan@18 636 table.insert(action_data.loot_list, ("currency:%d:%s"):format(quantity, icon_texture:match("[^\\]+$"):lower()))
jcallahan@18 637 end
jcallahan@13 638 end
jcallahan@13 639 end
jcallahan@13 640
jcallahan@13 641 for item_id, quantity in pairs(loot_registry) do
jcallahan@17 642 table.insert(action_data.loot_list, ("%d:%d"):format(item_id, quantity))
jcallahan@13 643 end
jcallahan@13 644 update_func()
jcallahan@1 645 end
jcallahan@13 646 end -- do-block
jcallahan@0 647
jcallahan@0 648
jcallahan@5 649 local POINT_MATCH_PATTERNS = {
jcallahan@5 650 ("^%s$"):format(_G.ITEM_REQ_ARENA_RATING:gsub("%%d", "(%%d+)")), -- May no longer be necessary
jcallahan@5 651 ("^%s$"):format(_G.ITEM_REQ_ARENA_RATING_3V3:gsub("%%d", "(%%d+)")), -- May no longer be necessary
jcallahan@5 652 ("^%s$"):format(_G.ITEM_REQ_ARENA_RATING_5V5:gsub("%%d", "(%%d+)")), -- May no longer be necessary
jcallahan@5 653 ("^%s$"):format(_G.ITEM_REQ_ARENA_RATING_BG:gsub("%%d", "(%%d+)")),
jcallahan@5 654 ("^%s$"):format(_G.ITEM_REQ_ARENA_RATING_3V3_BG:gsub("%%d", "(%%d+)")),
jcallahan@5 655 }
jcallahan@5 656
jcallahan@5 657
jcallahan@7 658 function WDP:UpdateMerchantItems()
jcallahan@4 659 local unit_type, unit_idnum = self:ParseGUID(_G.UnitGUID("target"))
jcallahan@4 660
jcallahan@4 661 if unit_type ~= private.UNIT_TYPES.NPC or not unit_idnum then
jcallahan@4 662 return
jcallahan@4 663 end
jcallahan@29 664 local merchant = NPCEntry(unit_idnum)
jcallahan@6 665 merchant.sells = merchant.sells or {}
jcallahan@5 666
jcallahan@5 667 for item_index = 1, _G.GetMerchantNumItems() do
jcallahan@5 668 local _, _, copper_price, stack_size, num_available, _, extended_cost = _G.GetMerchantItemInfo(item_index)
jcallahan@5 669 local item_id = ItemLinkToID(_G.GetMerchantItemLink(item_index))
jcallahan@5 670
jcallahan@5 671 if item_id and item_id > 0 then
jcallahan@5 672 local price_string = copper_price
jcallahan@5 673
jcallahan@5 674 if extended_cost then
jcallahan@5 675 local bg_points = 0
jcallahan@5 676 local personal_points = 0
jcallahan@5 677
jcallahan@5 678 DatamineTT:ClearLines()
jcallahan@5 679 DatamineTT:SetMerchantItem(item_index)
jcallahan@5 680
jcallahan@5 681 for line_index = 1, DatamineTT:NumLines() do
jcallahan@5 682 local current_line = _G["WDPDatamineTTTextLeft" .. line_index]
jcallahan@5 683
jcallahan@5 684 if not current_line then
jcallahan@5 685 break
jcallahan@5 686 end
jcallahan@5 687 local breakout
jcallahan@5 688
jcallahan@5 689 for match_index = 1, #POINT_MATCH_PATTERNS do
jcallahan@5 690 local match1, match2 = current_line:GetText():match(POINT_MATCH_PATTERNS[match_index])
jcallahan@5 691 personal_points = personal_points + (match1 or 0)
jcallahan@5 692 bg_points = bg_points + (match2 or 0)
jcallahan@5 693
jcallahan@5 694 if match1 or match2 then
jcallahan@5 695 breakout = true
jcallahan@5 696 break
jcallahan@5 697 end
jcallahan@5 698 end
jcallahan@5 699
jcallahan@5 700 if breakout then
jcallahan@5 701 break
jcallahan@5 702 end
jcallahan@5 703 end
jcallahan@5 704 local currency_list = {}
jcallahan@5 705
jcallahan@5 706 price_string = ("%s:%s:%s"):format(price_string, bg_points, personal_points)
jcallahan@5 707
jcallahan@5 708 for cost_index = 1, _G.GetMerchantItemCostInfo(item_index) do
jcallahan@5 709 local icon_texture, amount_required, currency_link = _G.GetMerchantItemCostItem(item_index, cost_index)
jcallahan@5 710 local currency_id = currency_link and ItemLinkToID(currency_link) or nil
jcallahan@5 711
jcallahan@5 712 if not currency_id or currency_id < 1 then
jcallahan@5 713 if not icon_texture then
jcallahan@5 714 return
jcallahan@5 715 end
jcallahan@5 716 currency_id = icon_texture:match("[^\\]+$"):lower()
jcallahan@5 717 end
jcallahan@5 718 currency_list[#currency_list + 1] = ("(%s:%s)"):format(amount_required, currency_id)
jcallahan@5 719 end
jcallahan@5 720
jcallahan@5 721 for currency_index = 1, #currency_list do
jcallahan@5 722 price_string = ("%s:%s"):format(price_string, currency_list[currency_index])
jcallahan@5 723 end
jcallahan@5 724 end
jcallahan@6 725 merchant.sells[("%s:%s:[%s]"):format(item_id, stack_size, price_string)] = num_available
jcallahan@5 726 end
jcallahan@4 727 end
jcallahan@14 728
jcallahan@14 729 if _G.CanMerchantRepair() then
jcallahan@14 730 merchant.can_repair = true
jcallahan@14 731 end
jcallahan@4 732 end
jcallahan@4 733
jcallahan@4 734
jcallahan@25 735 function WDP:PET_BAR_UPDATE()
jcallahan@25 736 if not action_data.label or not action_data.label == "mind_control" then
jcallahan@25 737 return
jcallahan@25 738 end
jcallahan@25 739 local unit_type, unit_idnum = self:ParseGUID(_G.UnitGUID("pet"))
jcallahan@25 740
jcallahan@25 741 if unit_type ~= private.UNIT_TYPES.NPC or not unit_idnum then
jcallahan@25 742 return
jcallahan@25 743 end
jcallahan@29 744 NPCEntry(unit_idnum).mind_control = true
jcallahan@25 745 table.wipe(action_data)
jcallahan@25 746 end
jcallahan@25 747
jcallahan@25 748
jcallahan@18 749 do
jcallahan@18 750 local GENDER_NAMES = {
jcallahan@18 751 "UNKNOWN",
jcallahan@18 752 "MALE",
jcallahan@18 753 "FEMALE",
jcallahan@18 754 }
jcallahan@2 755
jcallahan@2 756
jcallahan@18 757 local REACTION_NAMES = {
jcallahan@18 758 "HATED",
jcallahan@18 759 "HOSTILE",
jcallahan@18 760 "UNFRIENDLY",
jcallahan@18 761 "NEUTRAL",
jcallahan@18 762 "FRIENDLY",
jcallahan@18 763 "HONORED",
jcallahan@18 764 "REVERED",
jcallahan@18 765 "EXALTED",
jcallahan@18 766 }
jcallahan@2 767
jcallahan@2 768
jcallahan@18 769 local POWER_TYPE_NAMES = {
jcallahan@18 770 ["0"] = "MANA",
jcallahan@18 771 ["1"] = "RAGE",
jcallahan@18 772 ["2"] = "FOCUS",
jcallahan@18 773 ["3"] = "ENERGY",
jcallahan@18 774 ["6"] = "RUNIC_POWER",
jcallahan@18 775 }
jcallahan@2 776
jcallahan@2 777
jcallahan@18 778 function WDP:PLAYER_TARGET_CHANGED()
jcallahan@18 779 if not _G.UnitExists("target") or _G.UnitPlayerControlled("target") then
jcallahan@18 780 return
jcallahan@18 781 end
jcallahan@18 782 local unit_type, unit_idnum = self:ParseGUID(_G.UnitGUID("target"))
jcallahan@2 783
jcallahan@18 784 if unit_type ~= private.UNIT_TYPES.NPC or not unit_idnum then
jcallahan@18 785 return
jcallahan@18 786 end
jcallahan@29 787 local npc = NPCEntry(unit_idnum)
jcallahan@18 788 local _, class_token = _G.UnitClass("target")
jcallahan@18 789 npc.class = class_token
jcallahan@20 790
jcallahan@32 791 UpdateFactionData()
jcallahan@20 792 DatamineTT:ClearLines()
jcallahan@20 793 DatamineTT:SetUnit("target")
jcallahan@20 794
jcallahan@20 795 for line_index = 1, DatamineTT:NumLines() do
jcallahan@20 796 local current_line = _G["WDPDatamineTTTextLeft" .. line_index]
jcallahan@20 797
jcallahan@20 798 if not current_line then
jcallahan@20 799 break
jcallahan@20 800 end
jcallahan@20 801 local line_text = current_line:GetText()
jcallahan@20 802
jcallahan@32 803 if faction_standings[line_text] then
jcallahan@20 804 npc.faction = line_text
jcallahan@20 805 break
jcallahan@20 806 end
jcallahan@20 807 end
jcallahan@26 808 npc.genders = npc.genders or {}
jcallahan@26 809 npc.genders[GENDER_NAMES[_G.UnitSex("target")] or "UNDEFINED"] = true
jcallahan@18 810 npc.is_pvp = _G.UnitIsPVP("target") and true or nil
jcallahan@18 811 npc.reaction = ("%s:%s:%s"):format(_G.UnitLevel("player"), _G.UnitFactionGroup("player"), REACTION_NAMES[_G.UnitReaction("player", "target")])
jcallahan@2 812
jcallahan@30 813 local encounter_data = npc.encounter_data[InstanceDifficultyToken()].stats
jcallahan@18 814 local npc_level = ("level_%d"):format(_G.UnitLevel("target"))
jcallahan@3 815
jcallahan@28 816 if not encounter_data[npc_level] then
jcallahan@28 817 encounter_data[npc_level] = {
jcallahan@18 818 max_health = _G.UnitHealthMax("target"),
jcallahan@18 819 }
jcallahan@3 820
jcallahan@18 821 local max_power = _G.UnitManaMax("target")
jcallahan@18 822
jcallahan@18 823 if max_power > 0 then
jcallahan@18 824 local power_type = _G.UnitPowerType("target")
jcallahan@28 825 encounter_data[npc_level].power = ("%s:%d"):format(POWER_TYPE_NAMES[_G.tostring(power_type)] or power_type, max_power)
jcallahan@18 826 end
jcallahan@3 827 end
jcallahan@21 828 table.wipe(action_data)
jcallahan@21 829 action_data.type = AF.NPC
jcallahan@27 830 action_data.identifier = unit_idnum
jcallahan@21 831 action_data.npc_level = npc_level
jcallahan@31 832
jcallahan@31 833 self:UpdateTargetLocation()
jcallahan@2 834 end
jcallahan@18 835 end -- do-block
jcallahan@2 836
jcallahan@12 837 do
jcallahan@12 838 local function UpdateQuestJuncture(point)
jcallahan@12 839 local unit_name = _G.UnitName("questnpc")
jcallahan@9 840
jcallahan@12 841 if not unit_name then
jcallahan@12 842 return
jcallahan@12 843 end
jcallahan@12 844 local unit_type, unit_id = WDP:ParseGUID(_G.UnitGUID("questnpc"))
jcallahan@9 845
jcallahan@12 846 if unit_type == private.UNIT_TYPES.OBJECT then
jcallahan@12 847 UpdateObjectLocation(unit_id)
jcallahan@12 848 end
jcallahan@19 849 local quest = DBEntry("quests", _G.GetQuestID())
jcallahan@12 850 quest[point] = quest[point] or {}
jcallahan@12 851 quest[point][("%s:%d"):format(private.UNIT_TYPE_NAMES[unit_type + 1], unit_id)] = true
jcallahan@24 852
jcallahan@24 853 return quest
jcallahan@12 854 end
jcallahan@10 855
jcallahan@12 856
jcallahan@12 857 function WDP:QUEST_COMPLETE()
jcallahan@12 858 UpdateQuestJuncture("end")
jcallahan@10 859 end
jcallahan@10 860
jcallahan@12 861
jcallahan@12 862 function WDP:QUEST_DETAIL()
jcallahan@24 863 local quest = UpdateQuestJuncture("begin")
jcallahan@24 864
jcallahan@24 865 quest.classes = quest.classes or {}
jcallahan@27 866 quest.classes[PLAYER_CLASS] = true
jcallahan@24 867
jcallahan@24 868 local _, race = _G.UnitRace("player")
jcallahan@24 869 quest.races = quest.races or {}
jcallahan@24 870 quest.races[race] = true
jcallahan@10 871 end
jcallahan@12 872 end -- do-block
jcallahan@9 873
jcallahan@9 874
jcallahan@4 875 function WDP:QUEST_LOG_UPDATE()
jcallahan@4 876 self:UnregisterEvent("QUEST_LOG_UPDATE")
jcallahan@4 877 end
jcallahan@4 878
jcallahan@4 879
jcallahan@4 880 function WDP:UNIT_QUEST_LOG_CHANGED(event, unit_id)
jcallahan@4 881 if unit_id ~= "player" then
jcallahan@4 882 return
jcallahan@4 883 end
jcallahan@4 884 self:RegisterEvent("QUEST_LOG_UPDATE")
jcallahan@4 885 end
jcallahan@4 886
jcallahan@4 887
jcallahan@27 888 function WDP:TRAINER_SHOW()
jcallahan@27 889 if not _G.IsTradeskillTrainer() then
jcallahan@27 890 return
jcallahan@27 891 end
jcallahan@27 892 local unit_type, unit_idnum = self:ParseGUID(_G.UnitGUID("target"))
jcallahan@29 893 local npc = NPCEntry(unit_idnum)
jcallahan@27 894 npc.teaches = npc.teaches or {}
jcallahan@27 895
jcallahan@27 896 -- Get the initial trainer filters
jcallahan@27 897 local available = _G.GetTrainerServiceTypeFilter("available")
jcallahan@27 898 local unavailable = _G.GetTrainerServiceTypeFilter("unavailable")
jcallahan@27 899 local used = _G.GetTrainerServiceTypeFilter("used")
jcallahan@27 900
jcallahan@27 901 -- Clear the trainer filters
jcallahan@27 902 _G.SetTrainerServiceTypeFilter("available", 1)
jcallahan@27 903 _G.SetTrainerServiceTypeFilter("unavailable", 1)
jcallahan@27 904 _G.SetTrainerServiceTypeFilter("used", 1)
jcallahan@27 905
jcallahan@27 906 for index = 1, _G.GetNumTrainerServices(), 1 do
jcallahan@27 907 local spell_name, rank_name, _, _, required_level = _G.GetTrainerServiceInfo(index)
jcallahan@27 908
jcallahan@27 909 if spell_name then
jcallahan@27 910 DatamineTT:ClearLines()
jcallahan@27 911 DatamineTT:SetTrainerService(index)
jcallahan@27 912
jcallahan@27 913 local _, _, spell_id = DatamineTT:GetSpell()
jcallahan@27 914 local profession, min_skill = _G.GetTrainerServiceSkillReq(index)
jcallahan@27 915 profession = profession or "General"
jcallahan@27 916
jcallahan@27 917 local class_professions = npc.teaches[PLAYER_CLASS]
jcallahan@27 918 if not class_professions then
jcallahan@27 919 npc.teaches[PLAYER_CLASS] = {}
jcallahan@27 920 class_professions = npc.teaches[PLAYER_CLASS]
jcallahan@27 921 end
jcallahan@27 922
jcallahan@27 923 local profession_skills = class_professions[profession]
jcallahan@27 924 if not profession_skills then
jcallahan@27 925 class_professions[profession] = {}
jcallahan@27 926 profession_skills = class_professions[profession]
jcallahan@27 927 end
jcallahan@27 928 profession_skills[spell_id] = ("%d:%d"):format(required_level, min_skill)
jcallahan@27 929 end
jcallahan@27 930 end
jcallahan@27 931
jcallahan@27 932 -- Reset the filters to what they were before
jcallahan@27 933 _G.SetTrainerServiceTypeFilter("available", available or 0)
jcallahan@27 934 _G.SetTrainerServiceTypeFilter("unavailable", unavailable or 0)
jcallahan@27 935 _G.SetTrainerServiceTypeFilter("used", used or 0)
jcallahan@27 936 end
jcallahan@27 937
jcallahan@27 938
jcallahan@1 939 function WDP:UNIT_SPELLCAST_SENT(event_name, unit_id, spell_name, spell_rank, target_name, spell_line)
jcallahan@1 940 if private.tracked_line or unit_id ~= "player" then
jcallahan@1 941 return
jcallahan@1 942 end
jcallahan@1 943 local spell_label = private.SPELL_LABELS_BY_NAME[spell_name]
jcallahan@1 944
jcallahan@1 945 if not spell_label then
jcallahan@1 946 return
jcallahan@1 947 end
jcallahan@18 948 table.wipe(action_data)
jcallahan@1 949
jcallahan@1 950 local tt_item_name, tt_item_link = _G.GameTooltip:GetItem()
jcallahan@1 951 local tt_unit_name, tt_unit_id = _G.GameTooltip:GetUnit()
jcallahan@1 952
jcallahan@1 953 if not tt_unit_name and _G.UnitName("target") == target_name then
jcallahan@1 954 tt_unit_name = target_name
jcallahan@1 955 tt_unit_id = "target"
jcallahan@1 956 end
jcallahan@1 957 local spell_flags = private.SPELL_FLAGS_BY_LABEL[spell_label]
jcallahan@28 958 local zone_name, area_id, x, y, map_level, instance_token = CurrentLocationData()
jcallahan@28 959
jcallahan@28 960 action_data.instance_token = instance_token
jcallahan@28 961 action_data.map_level = map_level
jcallahan@28 962 action_data.x = x
jcallahan@28 963 action_data.y = y
jcallahan@28 964 action_data.zone = ("%s:%d"):format(zone_name, area_id)
jcallahan@1 965
jcallahan@16 966 if tt_unit_name and not tt_item_name then
jcallahan@16 967 if bit.band(spell_flags, AF.NPC) == AF.NPC then
jcallahan@16 968 if not tt_unit_id or tt_unit_name ~= target_name then
jcallahan@16 969 return
jcallahan@16 970 end
jcallahan@16 971 action_data.type = AF.NPC
jcallahan@25 972 action_data.label = spell_label:lower()
jcallahan@25 973 action_data.unit_name = tt_unit_name
jcallahan@16 974 end
jcallahan@16 975 elseif bit.band(spell_flags, AF.ITEM) == AF.ITEM then
jcallahan@16 976 action_data.type = AF.ITEM
jcallahan@25 977 action_data.label = spell_label:lower()
jcallahan@16 978
jcallahan@16 979 if tt_item_name and tt_item_name == target_name then
jcallahan@28 980 action_data.identifier = ItemLinkToID(tt_item_link)
jcallahan@16 981 elseif target_name and target_name ~= "" then
jcallahan@16 982 local _, target_item_link = _G.GetItemInfo(target_name)
jcallahan@28 983 action_data.identifier = ItemLinkToID(target_item_link)
jcallahan@16 984 end
jcallahan@16 985 elseif not tt_item_name and not tt_unit_name then
jcallahan@17 986 action_data.name = target_name
jcallahan@17 987
jcallahan@1 988 if bit.band(spell_flags, AF.OBJECT) == AF.OBJECT then
jcallahan@17 989 if target_name == "" then
jcallahan@17 990 return
jcallahan@17 991 end
jcallahan@11 992 local identifier = ("%s:%s"):format(spell_label, target_name)
jcallahan@11 993 UpdateObjectLocation(identifier)
jcallahan@11 994
jcallahan@1 995 action_data.type = AF.OBJECT
jcallahan@11 996 action_data.identifier = identifier
jcallahan@1 997 elseif bit.band(spell_flags, AF.ZONE) == AF.ZONE then
jcallahan@17 998 action_data.type = AF.ZONE
jcallahan@25 999 action_data.label = spell_label:lower()
jcallahan@1 1000 end
jcallahan@1 1001 end
jcallahan@1 1002 private.tracked_line = spell_line
jcallahan@0 1003 end
jcallahan@0 1004
jcallahan@0 1005
jcallahan@1 1006 function WDP:UNIT_SPELLCAST_SUCCEEDED(event_name, unit_id, spell_name, spell_rank, spell_line, spell_id)
jcallahan@1 1007 if unit_id ~= "player" then
jcallahan@1 1008 return
jcallahan@1 1009 end
jcallahan@1 1010 private.tracked_line = nil
jcallahan@0 1011 end
jcallahan@0 1012
jcallahan@1 1013 function WDP:HandleSpellFailure(event_name, unit_id, spell_name, spell_rank, spell_line, spell_id)
jcallahan@1 1014 if unit_id ~= "player" then
jcallahan@1 1015 return
jcallahan@1 1016 end
jcallahan@0 1017
jcallahan@1 1018 if private.tracked_line == spell_line then
jcallahan@1 1019 private.tracked_line = nil
jcallahan@1 1020 end
jcallahan@0 1021 end