comparison Main.lua @ 584:be7931f9225c tip

Updated more extensively for Midnight's changes. Works for merchant recording in instances now.
author MMOSimca
date Sun, 05 Oct 2025 23:33:00 -0400
parents 4a51fdc1e2e4
children
comparison
equal deleted inserted replaced
583:4a51fdc1e2e4 584:be7931f9225c
112 CHAT_MSG_LOOT = true, 112 CHAT_MSG_LOOT = true,
113 CHAT_MSG_MONSTER_SAY = "RecordQuote", 113 CHAT_MSG_MONSTER_SAY = "RecordQuote",
114 CHAT_MSG_MONSTER_WHISPER = "RecordQuote", 114 CHAT_MSG_MONSTER_WHISPER = "RecordQuote",
115 CHAT_MSG_MONSTER_YELL = "RecordQuote", 115 CHAT_MSG_MONSTER_YELL = "RecordQuote",
116 CHAT_MSG_SYSTEM = true, 116 CHAT_MSG_SYSTEM = true,
117 COMBAT_LOG_EVENT_UNFILTERED = true,
118 COMBAT_TEXT_UPDATE = true,
119 WORLD_CURSOR_TOOLTIP_UPDATE = true, 117 WORLD_CURSOR_TOOLTIP_UPDATE = true,
120 GARRISON_MISSION_NPC_CLOSED = "ResumeChatLootRecording", 118 GARRISON_MISSION_NPC_CLOSED = "ResumeChatLootRecording",
121 GARRISON_MISSION_NPC_OPENED = "StopChatLootRecording", 119 GARRISON_MISSION_NPC_OPENED = "StopChatLootRecording",
122 GARRISON_SHIPYARD_NPC_CLOSED = "ResumeChatLootRecording", 120 GARRISON_SHIPYARD_NPC_CLOSED = "ResumeChatLootRecording",
123 GARRISON_SHIPYARD_NPC_OPENED = "StopChatLootRecording", 121 GARRISON_SHIPYARD_NPC_OPENED = "StopChatLootRecording",
154 --TRADE_SKILL_SHOW = true, 152 --TRADE_SKILL_SHOW = true,
155 --TRAINER_CLOSED = true, 153 --TRAINER_CLOSED = true,
156 --TRAINER_SHOW = true, 154 --TRAINER_SHOW = true,
157 UNIT_PET = true, 155 UNIT_PET = true,
158 UNIT_QUEST_LOG_CHANGED = true, 156 UNIT_QUEST_LOG_CHANGED = true,
159 UNIT_SPELLCAST_FAILED = "HandleSpellFailure",
160 UNIT_SPELLCAST_FAILED_QUIET = "HandleSpellFailure",
161 UNIT_SPELLCAST_INTERRUPTED = "HandleSpellFailure",
162 UNIT_SPELLCAST_SENT = true,
163 UNIT_SPELLCAST_SUCCEEDED = true,
164 PLAYER_INTERACTION_MANAGER_FRAME_SHOW = true, 157 PLAYER_INTERACTION_MANAGER_FRAME_SHOW = true,
165 } 158 }
166 159
167 160
168 -- VARIABLES ---------------------------------------------------------- 161 -- VARIABLES ----------------------------------------------------------
974 return 967 return
975 end 968 end
976 HandleItemUse(_G.C_Container.GetContainerItemLink(bag_index, slot_index), bag_index, slot_index) 969 HandleItemUse(_G.C_Container.GetContainerItemLink(bag_index, slot_index), bag_index, slot_index)
977 end) 970 end)
978 971
979 _G.hooksecurefunc("UseItemByName", function(identifier, target_unit) 972 _G.hooksecurefunc(C_Item, "UseItemByName", function(identifier, target_unit)
980 if target_unit then 973 if target_unit then
981 return 974 return
982 end 975 end
983 local _, item_link = _G.GetItemInfo(identifier) 976 local _, item_link = _G.GetItemInfo(identifier)
984 HandleItemUse(item_link) 977 HandleItemUse(item_link)
1206 current_target_id = unit_idnum 1199 current_target_id = unit_idnum
1207 1200
1208 local npc = NPCEntry(unit_idnum) 1201 local npc = NPCEntry(unit_idnum)
1209 local _, class_token = _G.UnitClass("target") 1202 local _, class_token = _G.UnitClass("target")
1210 npc.class = class_token 1203 npc.class = class_token
1211 npc.faction = UnitFactionStanding("target") 1204
1205 -- Can't do this in instances now, at least using the current method of putting a unit on a tooltip
1206 if not III() then
1207 npc.faction = UnitFactionStanding("target")
1208 end
1209
1212 npc.genders = npc.genders or {} 1210 npc.genders = npc.genders or {}
1213 npc.genders[private.GENDER_NAMES[_G.UnitSex("target")] or "UNDEFINED"] = true 1211 npc.genders[private.GENDER_NAMES[_G.UnitSex("target")] or "UNDEFINED"] = true
1214 npc.is_pvp = _G.UnitIsPVP("target") and true or nil 1212 npc.is_pvp = _G.UnitIsPVP("target") and true or nil
1215 npc.reaction = ("%s:%s:%s"):format(_G.UnitLevel("player"), _G.UnitFactionGroup("player"), private.REACTION_NAMES[_G.UnitReaction("player", "target")]) 1213 npc.reaction = ("%s:%s:%s"):format(_G.UnitLevel("player"), _G.UnitFactionGroup("player"), private.REACTION_NAMES[_G.UnitReaction("player", "target")])
1216 1214
1793 break 1791 break
1794 end 1792 end
1795 end 1793 end
1796 end 1794 end
1797 end 1795 end
1798
1799
1800 do
1801 local FLAGS_NPC = bit.bor(_G.COMBATLOG_OBJECT_TYPE_GUARDIAN, _G.COMBATLOG_OBJECT_CONTROL_NPC)
1802 local FLAGS_NPC_CONTROL = bit.bor(_G.COMBATLOG_OBJECT_AFFILIATION_OUTSIDER, _G.COMBATLOG_OBJECT_CONTROL_NPC)
1803
1804 local function RecordNPCSpell(sub_event, source_guid, source_name, source_flags, dest_guid, dest_name, dest_flags, spell_id)
1805 if not spell_id or private.BLACKLISTED_SPELLS[spell_id] then
1806 return
1807 end
1808 local source_type, source_id = ParseGUID(source_guid)
1809
1810 if not source_id or not UnitTypeIsNPC(source_type) then
1811 return
1812 end
1813
1814 if bit.band(FLAGS_NPC_CONTROL, source_flags) == FLAGS_NPC_CONTROL and bit.band(FLAGS_NPC, source_flags) ~= 0 then
1815 local encounter_data = NPCEntry(source_id):EncounterData(InstanceDifficultyToken())
1816 encounter_data.spells = encounter_data.spells or {}
1817 encounter_data.spells[spell_id] = (encounter_data.spells[spell_id] or 0) + 1
1818 end
1819 end
1820
1821 local HEAL_BATTLE_PETS_SPELL_ID = 125801
1822
1823 local previous_combat_event = {}
1824
1825 local COMBAT_LOG_FUNCS = {
1826 SPELL_AURA_APPLIED = RecordNPCSpell,
1827 SPELL_CAST_START = RecordNPCSpell,
1828 SPELL_CAST_SUCCESS = function(sub_event, source_guid, source_name, source_flags, dest_guid, dest_name, dest_flags, spell_id)
1829 if spell_id == HEAL_BATTLE_PETS_SPELL_ID then
1830 local unit_type, unit_idnum = ParseGUID(source_guid)
1831
1832 if unit_idnum and UnitTypeIsNPC(unit_type) then
1833 NPCEntry(unit_idnum).stable_master = true
1834 end
1835 end
1836 RecordNPCSpell(sub_event, source_guid, source_name, source_flags, dest_guid, dest_name, dest_flags, spell_id)
1837 end,
1838 UNIT_DIED = function(sub_event, source_guid, source_name, source_flags, dest_guid, dest_name, dest_flags, spell_id)
1839 local unit_type, unit_idnum = ParseGUID(dest_guid)
1840
1841 if not unit_idnum or not UnitTypeIsNPC(unit_type) then
1842 --Debug("%s: %s is not an NPC, or has no ID.", sub_event, dest_name or _G.UNKNOWN) -- we really don't need to know this
1843 ClearKilledNPC()
1844 private.harvesting = nil
1845 return
1846 end
1847
1848 if source_guid == "" then
1849 source_guid = nil
1850 end
1851 local killer_guid = source_guid or previous_combat_event.source_guid
1852 local killer_name = source_name or previous_combat_event.source_name
1853
1854 if not previous_combat_event.party_damage then
1855 --Debug("%s: %s was killed by %s (not group member or pet).", sub_event, dest_name or _G.UNKNOWN, killer_name or _G.UNKNOWN) -- broken in Patch 5.4
1856 table.wipe(previous_combat_event)
1857 ClearKilledNPC()
1858 else
1859 --Debug("%s: %s was killed by %s.", sub_event, dest_name or _G.UNKNOWN, killer_name or _G.UNKNOWN) -- broken in Patch 5.4
1860 end
1861 killed_npc_id = unit_idnum
1862 C_Timer.After(0.1, ClearKilledNPC)
1863 end,
1864 }
1865
1866
1867 local NON_DAMAGE_EVENTS = {
1868 SPELL_AURA_APPLIED = true,
1869 SPELL_AURA_REMOVED = true,
1870 SPELL_AURA_REMOVED_DOSE = true,
1871 SPELL_CAST_FAILED = true,
1872 SWING_MISSED = true,
1873 }
1874
1875 local DAMAGE_EVENTS = {
1876 RANGE_DAMAGE = true,
1877 SPELL_BUILDING_DAMAGE = true,
1878 SPELL_DAMAGE = true,
1879 SPELL_PERIODIC_DAMAGE = true,
1880 SWING_DAMAGE = true,
1881 }
1882
1883
1884 function WDP:COMBAT_LOG_EVENT_UNFILTERED(event_name, time_stamp, sub_event, hide_caster, source_guid, source_name, source_flags, source_raid_flags, dest_guid, dest_name, dest_flags, dest_raid_flags, spell_id, ...)
1885 time_stamp, sub_event, hide_caster, source_guid, source_name, source_flags, source_raid_flags, dest_guid, dest_name, dest_flags, dest_raid_flags, spell_id = CombatLogGetCurrentEventInfo()
1886
1887 local combat_log_func = COMBAT_LOG_FUNCS[sub_event]
1888
1889 if not combat_log_func then
1890 if DAMAGE_EVENTS[sub_event] then
1891 table.wipe(previous_combat_event)
1892 previous_combat_event.source_name = source_name
1893
1894 if source_guid ~= dest_guid and (in_instance or group_member_guids[source_guid] or group_pet_guids[source_guid]) then
1895 previous_combat_event.party_damage = true
1896 end
1897 end
1898 return
1899 end
1900 combat_log_func(sub_event, source_guid, source_name, source_flags, dest_guid, dest_name, dest_flags, spell_id)
1901
1902 if NON_DAMAGE_EVENTS[sub_event] then
1903 table.wipe(previous_combat_event)
1904 end
1905 end
1906
1907
1908 local DIPLOMACY_SPELL_ID = 20599
1909 local MR_POP_RANK1_SPELL_ID = 78634
1910 local MR_POP_RANK2_SPELL_ID = 78635
1911 local TRADING_PACT_SPELL_ID = 170200
1912
1913
1914 function WDP:COMBAT_TEXT_UPDATE(event_name, message_type, faction_name, amount)
1915 if message_type ~= "FACTION" or not killed_npc_id then
1916 return
1917 end
1918 UpdateFactionData()
1919
1920 if not faction_name or not faction_standings[faction_name] then
1921 return
1922 end
1923 local npc = NPCEntry(killed_npc_id)
1924 ClearKilledNPC()
1925
1926 if not npc then
1927 private.harvesting = nil
1928 return
1929 end
1930 npc.harvested = private.harvesting
1931 private.harvesting = nil
1932
1933 local modifier = 1
1934
1935 -- Check for modifiers from known spells
1936 if _G.IsSpellKnown(DIPLOMACY_SPELL_ID) then
1937 modifier = modifier + 0.1
1938 end
1939 if _G.IsSpellKnown(MR_POP_RANK2_SPELL_ID) then
1940 modifier = modifier + 0.1
1941 elseif _G.IsSpellKnown(MR_POP_RANK1_SPELL_ID) then
1942 modifier = modifier + 0.05
1943 end
1944 if _G.IsSpellKnown(TRADING_PACT_SPELL_ID) then
1945 modifier = modifier + 0.2
1946 end
1947
1948 -- Determine faction ID
1949 local faction_ID
1950 for pseudo_faction_name, faction_data_table in pairs(private.FACTION_DATA) do
1951 if faction_data_table[3] and faction_data_table[3].currentStanding and faction_name == faction_data_table[3].currentStanding then
1952 -- Check ignore flag
1953 if faction_data_table[2] then
1954 return
1955 end
1956 faction_ID = faction_data_table[1]
1957 break
1958 end
1959 end
1960 if faction_ID and faction_ID > 0 then
1961 -- Check for modifiers from Commendations (applied directly to the faction, account-wide)
1962 local factionReturn = _G.C_Reputation.GetFactionDataByID(faction_ID)
1963 if factionReturn and factionReturn.hasBonusRepGain then
1964 modifier = modifier + 1
1965 end
1966 end
1967
1968 -- Check for modifiers from buffs
1969 for buff_name, buff_data_table in pairs(private.REP_BUFFS) do
1970 if _G.UnitBuff("player", buff_name) then
1971 local modded_faction = buff_data_table.faction
1972
1973 if not modded_faction or faction_name == modded_faction then
1974 if buff_data_table.ignore then
1975 -- Some buffs from tabards convert all rep of other factions into rep for a specific faction.
1976 -- We can't know what faction the rep was orginally from, so we must ignore the data entirely in these cases.
1977 return
1978 else
1979 modifier = modifier + buff_data_table.modifier
1980 end
1981 end
1982 end
1983 end
1984
1985 npc.reputations = npc.reputations or {}
1986 npc.reputations[("%s:%s"):format(faction_name, faction_standings[faction_name])] = math.floor(amount / modifier)
1987 end
1988 end -- do-block
1989 1796
1990 1797
1991 function WDP:WORLD_CURSOR_TOOLTIP_UPDATE(event_name, is_shown) 1798 function WDP:WORLD_CURSOR_TOOLTIP_UPDATE(event_name, is_shown)
1992 if current_action.fishing_target or _G.Minimap:IsMouseOver() then 1799 if current_action.fishing_target or _G.Minimap:IsMouseOver() then
1993 return 1800 return
2415 local unit_type, unit_idnum = ParseGUID(_G.UnitGUID("npc")) 2222 local unit_type, unit_idnum = ParseGUID(_G.UnitGUID("npc"))
2416 2223
2417 if not unit_idnum or not UnitTypeIsNPC(unit_type) then 2224 if not unit_idnum or not UnitTypeIsNPC(unit_type) then
2418 return 2225 return
2419 end 2226 end
2420 local _, faction_standing = UnitFactionStanding("npc") 2227
2421 merchant_standing = faction_standing 2228 -- Can't do this in instances now, at least not by tooltip unit scanning
2229 if not III() then
2230 local _, faction_standing = UnitFactionStanding("npc")
2231 merchant_standing = faction_standing
2232 end
2233
2422 current_merchant = NPCEntry(unit_idnum) 2234 current_merchant = NPCEntry(unit_idnum)
2423 current_merchant.sells = current_merchant.sells or {} 2235 current_merchant.sells = current_merchant.sells or {}
2424 end 2236 end
2425 local current_filters = _G.GetMerchantFilter() 2237 local current_filters = _G.GetMerchantFilter()
2426 _G.SetMerchantFilter(_G.LE_LOOT_FILTER_ALL) 2238 _G.SetMerchantFilter(_G.LE_LOOT_FILTER_ALL)
2427 _G.MerchantFrame_Update() 2239 _G.MerchantFrame_Update()
2428 2240
2429 local num_items = _G.GetMerchantNumItems() 2241 local num_items = _G.GetMerchantNumItems()
2430 2242
2431 for item_index = 1, num_items do 2243 for item_index = 1, num_items do
2432 local _, _, copper_price, stack_size, num_available, _, extended_cost = _G.GetMerchantItemInfo(item_index) 2244 local _, _, copper_price, stack_size, num_available, _, extended_cost = _G.C_MerchantFrame.GetItemInfo(item_index)
2245 local itemInfoTable = _G.C_MerchantFrame.GetItemInfo(item_index)
2433 local item_id = ItemLinkToID(_G.GetMerchantItemLink(item_index)) 2246 local item_id = ItemLinkToID(_G.GetMerchantItemLink(item_index))
2434 2247
2435 DatamineTT:ClearLines() 2248 DatamineTT:ClearLines()
2436 DatamineTT:SetMerchantItem(item_index) 2249 DatamineTT:SetMerchantItem(item_index)
2437 2250
2440 item_id = ItemLinkToID(item_link) 2253 item_id = ItemLinkToID(item_link)
2441 -- GetMerchantItemLink() still ocassionally fails as of Patch 6.0.2. It fails so badly that debug functions cause considerable slowdown. 2254 -- GetMerchantItemLink() still ocassionally fails as of Patch 6.0.2. It fails so badly that debug functions cause considerable slowdown.
2442 end 2255 end
2443 2256
2444 if item_id and item_id > 0 then 2257 if item_id and item_id > 0 then
2445 local price_string = ActualCopperCost(copper_price, merchant_standing) 2258 local price_string = ActualCopperCost(itemInfoTable.price, merchant_standing)
2446 2259
2447 local num_lines = DatamineTT:NumLines() 2260 local num_lines = DatamineTT:NumLines()
2448 2261
2449 for line_index = 1, num_lines do 2262 for line_index = 1, num_lines do
2450 local current_line = _G["WDPDatamineTTTextLeft" .. line_index] 2263 local current_line = _G["WDPDatamineTTTextLeft" .. line_index]
2473 DBEntry("items", item_id).req_quest = ("%s"):format(quest_name:gsub("(.+): ", ""), quest_name) 2286 DBEntry("items", item_id).req_quest = ("%s"):format(quest_name:gsub("(.+): ", ""), quest_name)
2474 break 2287 break
2475 end 2288 end
2476 end 2289 end
2477 2290
2478 if extended_cost then 2291 if itemInfoTable.hasExtendedCost then
2479 local battleground_rating = 0 2292 local battleground_rating = 0
2480 local personal_rating = 0 2293 local personal_rating = 0
2481 local required_season_amount 2294 local required_season_amount
2482 2295
2483 for line_index = 1, num_lines do 2296 for line_index = 1, num_lines do
2531 2344
2532 for currency_index = 1, #currency_list do 2345 for currency_index = 1, #currency_list do
2533 price_string = ("%s:%s"):format(price_string, currency_list[currency_index]) 2346 price_string = ("%s:%s"):format(price_string, currency_list[currency_index])
2534 end 2347 end
2535 end 2348 end
2536 current_merchant.sells[item_id] = ("%s:%s:[%s]"):format(num_available, stack_size, price_string) 2349 current_merchant.sells[item_id] = ("%s:%s:[%s]"):format(itemInfoTable.numAvailable, itemInfoTable.stackCount, price_string)
2537 end 2350 end
2538 end 2351 end
2539 2352
2540 if _G.CanMerchantRepair() then 2353 if _G.CanMerchantRepair() then
2541 current_merchant.can_repair = true 2354 current_merchant.can_repair = true