mirror of
https://codeberg.org/Duvelcorp/MetaHunt.git
synced 2026-09-22 07:36:58 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c35258e615 | |||
| b40f9c1095 | |||
| 1680c6fc51 | |||
| 05cfce240b | |||
| d49ed5abcc | |||
| ea01c9ef15 | |||
| 315f6bb4f1 |
@@ -14,6 +14,16 @@ You play the best class, now you have the best companion for it (and its not you
|
||||
- MetaHunt is fully compatible with QUIVER <3, and is not a replacement for it.
|
||||
- The addon purposely disable itself on all Capycraft/Ravencraft Realms, following the DDOS attacks they conducted on other servers.
|
||||
|
||||
|
||||
### Installation (READ THIS!) ⚠️⚠️⚠️
|
||||
|
||||
After you download the zip, you have a manual action to do because of Gitea behaviour.
|
||||
|
||||
When you unzip, you will find a "metahunt" root folder, you SHOULD rename it as exactly "MetaHunt", and then move that folder in your \Interface\AddOns\ directory. If you dont restore the capital letters in the folder name, the addon will be broken.
|
||||
|
||||
This is [a known issue from Gitea/Forgejo](https://codeberg.org/forgejo/forgejo/issues/800) when the system creates zip files, and there's nothing add-on devs can do to overcome it.
|
||||
|
||||
|
||||
## Twow Data
|
||||
|
||||
MetaHunt ships with large twow datastores, and notably:
|
||||
|
||||
@@ -30,8 +30,8 @@ MTH_FEED_TRACE = false
|
||||
|
||||
local function MTH_FEED_Trace(message)
|
||||
if not MTH_FEED_TRACE then return end
|
||||
if type(DEFAULT_CHAT_FRAME) == "table" and DEFAULT_CHAT_FRAME.AddMessage then
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cff88aaff[MTH-FeedTrack]|r " .. tostring(message))
|
||||
if MTH_DebugFrame and type(MTH_DebugFrame.AddInfo) == "function" then
|
||||
MTH_DebugFrame:AddInfo("[MTH-FeedTrack] " .. tostring(message))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
local MTH_LT_Frame = nil
|
||||
local MTH_LT_PendingPetCheck = false
|
||||
local MTH_LT_SuppressUntil = 0
|
||||
|
||||
local MTH_LT_HunterLines = {
|
||||
[1] = "You can now track beasts. Revolutionary: look for the things you intend to shoot.",
|
||||
@@ -293,6 +294,13 @@ local function MTH_LT_HandlePetState()
|
||||
store.pet = state
|
||||
return
|
||||
end
|
||||
-- Just after a loading screen the pet's real level/loyalty can arrive a beat
|
||||
-- late; record them as the baseline silently so we never announce progress
|
||||
-- that actually happened in an earlier session (e.g. a fresh install).
|
||||
if type(GetTime) == "function" and MTH_LT_SuppressUntil > 0 and GetTime() < MTH_LT_SuppressUntil then
|
||||
store.pet = state
|
||||
return
|
||||
end
|
||||
if state.level > (tonumber(pet.level) or 0) then
|
||||
local line = MTH_LT_NextLine(store, "petLine", MTH_LT_PetLines)
|
||||
if MTH_LT_MessageEnabled("petLevelUp", true) then MTH:Print(state.name .. " reached level " .. state.level .. ". " .. line) end
|
||||
@@ -368,6 +376,7 @@ function MTH_LevelTracker_Initialize()
|
||||
if event == "PLAYER_ENTERING_WORLD" then
|
||||
local level = type(UnitLevel) == "function" and tonumber(UnitLevel("player")) or nil
|
||||
if level then MTH_LT_Store().hunterLevel = level end
|
||||
if type(GetTime) == "function" then MTH_LT_SuppressUntil = GetTime() + 8 end
|
||||
MTH_LT_RequestPetCheck()
|
||||
elseif event == "PLAYER_LEVEL_UP" then
|
||||
MTH_LT_HandleHunterLevel(tonumber(arg1) or tonumber(UnitLevel("player")) or 1)
|
||||
|
||||
@@ -2138,16 +2138,45 @@ local function MTH_PETS_SelectPetIdBySnapshot(store, snapshot, previousPetId)
|
||||
if snapshot.signature and snapshot.signature ~= "" then
|
||||
local list = store.signatureIndex[snapshot.signature]
|
||||
if type(list) == "table" then
|
||||
local count = 0
|
||||
local candidateId = nil
|
||||
local liveIds = {}
|
||||
for _, listedId in pairs(list) do
|
||||
if listedId and store.activeById[listedId] then
|
||||
count = count + 1
|
||||
candidateId = listedId
|
||||
if listedId and store.activeById[tostring(listedId)] then
|
||||
table.insert(liveIds, tostring(listedId))
|
||||
end
|
||||
end
|
||||
if count == 1 then
|
||||
return candidateId
|
||||
local liveCount = table.getn(liveIds)
|
||||
if liveCount == 1 then
|
||||
return liveIds[1]
|
||||
elseif liveCount > 1 then
|
||||
-- Several records share this name+family (earlier fragmentation, or two
|
||||
-- pets with the same name). Reuse the best existing match instead of
|
||||
-- minting yet another empty shell that only worsens the fragmentation:
|
||||
-- require a level match, then prefer loyalty match and records that
|
||||
-- already carry tame/spellbook history, then most recently seen.
|
||||
local snapLevel = tonumber(snapshot.level)
|
||||
local snapLoyalty = tonumber(snapshot.loyaltyLevel)
|
||||
local bestId = nil
|
||||
local bestScore = -1
|
||||
local bestSeen = -1
|
||||
for i = 1, liveCount do
|
||||
local rowId = liveIds[i]
|
||||
local row = store.activeById[rowId]
|
||||
if type(row) == "table" and snapLevel and tonumber(row.level) == snapLevel then
|
||||
local score = 0
|
||||
if snapLoyalty and tonumber(row.loyaltyLevel) == snapLoyalty then score = score + 2 end
|
||||
if MTH_PETS_RowHasAnyTameMetadata(row) then score = score + 1 end
|
||||
if type(row.petSpellbook) == "table" then score = score + 1 end
|
||||
local seen = tonumber(row.lastSeen) or tonumber(row.lastUpdated) or 0
|
||||
if score > bestScore or (score == bestScore and seen > bestSeen) then
|
||||
bestScore = score
|
||||
bestSeen = seen
|
||||
bestId = rowId
|
||||
end
|
||||
end
|
||||
end
|
||||
if bestId then
|
||||
return bestId
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -2364,10 +2393,14 @@ local function MTH_PETS_RecordStableSlot(pets, slot, raw1, raw2, raw3, raw4, raw
|
||||
local snapshotGuid = snapshot and snapshot.guid or nil
|
||||
local signatureMatches = (existingSignature and snapshotSignature and existingSignature == snapshotSignature) and true or false
|
||||
local guidMatches = (existingGuid and snapshotGuid and existingGuid ~= "" and existingGuid == snapshotGuid) and true or false
|
||||
-- An empty shell must not lock the slot: a richer same-signature record may
|
||||
-- exist that we should re-adopt instead (self-heals earlier fragmentation).
|
||||
local existingHasData = MTH_PETS_RowHasAnyTameMetadata(existingRow)
|
||||
or type(existingRow.petSpellbook) == "table" or existingRow.petNumber ~= nil
|
||||
|
||||
if signatureMatches or guidMatches then
|
||||
if guidMatches or (signatureMatches and existingHasData) then
|
||||
petId = existingId
|
||||
else
|
||||
elseif not signatureMatches then
|
||||
MTH_PETS_LogConsistency("RecordStableSlot remapping stale slot=" .. tostring(slotNumber)
|
||||
.. " existingId=" .. tostring(existingId)
|
||||
.. " existingSignature='" .. tostring(existingSignature or "") .. "'"
|
||||
|
||||
@@ -2483,10 +2483,20 @@ function FOM_FlatFoodList()
|
||||
local isExceptionReject = false;
|
||||
local isLevelOverrideReject = not FOM_IsItemPetLevelCompatible(itemID, petLevel);
|
||||
local isQuarantineReject = FOM_IsQuarantined(itemID, petLevel, familyKey);
|
||||
-- A food whose known level is below the pet's minimum is refused by the
|
||||
-- server ("not high enough"); skip it up front so FOM never keeps
|
||||
-- re-feeding a too-low stack just to free a bag slot.
|
||||
local isLevelRuleReject = false;
|
||||
if (petLevel > 0 and tonumber(foodLevel) ~= nil and type(MTH_FEED_GetDerivedMinFoodLevel) == "function") then
|
||||
local minFoodLevel = MTH_FEED_GetDerivedMinFoodLevel(petLevel);
|
||||
if (minFoodLevel ~= nil and tonumber(foodLevel) < minFoodLevel) then
|
||||
isLevelRuleReject = true;
|
||||
end
|
||||
end
|
||||
if (isExceptionReject) then
|
||||
rejectedByException = rejectedByException + 1;
|
||||
end
|
||||
if (isLevelOverrideReject) then
|
||||
if (isLevelOverrideReject or isLevelRuleReject) then
|
||||
rejectedByLevelOverride = rejectedByLevelOverride + 1;
|
||||
end
|
||||
if (isQuarantineReject) then
|
||||
@@ -2500,7 +2510,7 @@ function FOM_FlatFoodList()
|
||||
unknownLevelCandidates = unknownLevelCandidates + 1;
|
||||
end
|
||||
|
||||
if (isCompatible and not isExceptionReject and not isLevelOverrideReject and not isQuarantineReject) then
|
||||
if (isCompatible and not isExceptionReject and not isLevelOverrideReject and not isQuarantineReject and not isLevelRuleReject) then
|
||||
compatibleCount = compatibleCount + 1;
|
||||
local foodQuality = tonumber(foodLevel);
|
||||
if (foodQuality == nil) then
|
||||
@@ -2511,7 +2521,7 @@ function FOM_FlatFoodList()
|
||||
end
|
||||
end
|
||||
table.insert(foodList, {bag=bagNum, slot=itemNum, link=itemLink, itemId=itemID, count=itemCount, quality=foodQuality, useful=isUseful, temp=FOM_IsTemporaryFood(itemLink), knownLevel=hasKnownLevel});
|
||||
elseif (isAbovePreferredLevel and not isExceptionReject and not isLevelOverrideReject and not isQuarantineReject) then
|
||||
elseif (isAbovePreferredLevel and not isExceptionReject and not isLevelOverrideReject and not isQuarantineReject and not isLevelRuleReject) then
|
||||
overflowCompatibleCount = overflowCompatibleCount + 1;
|
||||
local overflowQuality = tonumber(foodLevel);
|
||||
if (overflowQuality == nil) then
|
||||
|
||||
Reference in New Issue
Block a user