- player can now hire 1 (2v2) or 2 bots (3v3) gameplay in arenas.
- enemy team will have only bots
- the system should support also 2players vs 2 bots or 3 players vs 3 bots.
- not all arenas might be enabled. this is still WIP
- enemy team bots currently just wait at their spawn point - still WIP
The covenant renown LEVEL is already a renown-reputation handled by TC's
ReputationMgr and synced to the client by the standard reputation packets,
so the only covenant-specific gap was granting the per-level rewards.
- Add the RenownRewards.db2 store (Meta 0x30AFBCF8, ParentIndex=CovenantID)
and a DB2Manager (covenantId, level) -> rewards map (GetRenownRewards).
- Track the highest renown level whose rewards were granted, per covenant
(Player::m_renownRewardsGranted), persisted to a new character_covenant_renown
table and loaded at login, so each level's rewards are granted exactly once.
- Player::ReputationChanged now grants rewards for every renown level crossed
when a covenant renown reputation increases; a login catch-up
(UpdateAllRenownRewards, run in-world after SendInitialPacketsAfterAddToMap)
grants anything earned before this feature existed. UpdateRenownRewards is
guarded on IsInWorld() so nothing is granted mid-load.
- GrantRenownReward grants item / spell / title / mount via the existing
Player + CollectionMgr APIs. The cosmetic-collection fields RenownRewards
also carries (TransmogID/TransmogSetID/TransmogIllusionID, GarrFollowerID,
QuestID) are documented as follow-ups rather than half-implemented.
Adds the four DB2 stores the Contribution system is built on (TC had the *Meta hotfix
schemas but never loaded these tables): Contribution, CreatureXContribution,
ManagedWorldState, ManagedWorldStateInput.
Field layouts derived from the authoritative TC *Meta structs (DB2Metadata.h) cross-checked
against the 68275 WoWDBDefs layouts (Contribution 167173C3, ManagedWorldState A4E9EA9F,
ManagedWorldStateInput 16683306, CreatureXContribution 29D9C37F). All four have IndexField=-1
(ID first). ManagedWorldState carries the accumulate/deplete progress driver bound to
Current/Progress/Occurrences WorldState IDs; ManagedWorldStateInput carries the QuestID that
is the contribution turn-in cost.
- DB2Structure.h: 4 entry structs.
- DB2LoadInfo.h: 4 load infos (arrays expanded per element, signedness per Meta).
- DB2Stores.h/.cpp: storage globals + LOAD_DB2 registration.
- HotfixDatabase.h/.cpp: hotfix SELECT statements (+ locale for Contribution's two
localized strings) and enum entries.
- sql/updates/hotfixes/master/2026_07_07_00_hotfixes.sql: the five hotfix tables.
Builds clean (game.dll). Next: the ManagedWorldStateMgr runtime (P1) that ticks these
states, then Contribute (P2).
Completes the conduit collection into a Blizzlike acquisition flow: obtaining
a conduit item now adds it to the collection, so the GM ".conduit add" command
is demoted to an admin/test convenience.
- Add the SoulbindConduitItem.db2 (ItemID -> ConduitID) and
SoulbindConduitRankProperties.db2 (Rank <-> ItemLevel) stores (both Metas
already present in TC, hashes 0xEDC6BB40 / 0x6EFBF7C9).
- DB2Manager: build an ItemID -> ConduitID map (GetConduitForItem) and
GetConduitRankForItemLevel(), which picks the highest rank whose ItemLevel
does not exceed the acquired item's level (a higher-ilvl duplicate upgrades
the collection, as retail does).
- Player::TryCollectConduitFromItem() runs from StoreNewItem alongside the
existing transmog CollectionMgr::OnItemAdded hook (same addToCollection gate),
collecting the mapped conduit at the item-level-derived rank (falls back to
the conduit's lowest defined rank if no properties row qualifies).
Non-destructive: the conduit item is not consumed (retail may consume it, but
that is not verified offline, so items are never destroyed on assumption).
Unblocks covenant P2 by building the conduit sub-system the soulbind
gameplay hangs off of (all garrison-talent opcodes were Handle_NULL).
Data (Phase A): add the SoulbindConduit.db2 store (Meta 0x2632E47D
already present) so conduits can be validated by type/covenant/spec.
Collection (Phase B): the conduit collection is server-authoritative -
Player now tracks owned conduits (conduitId -> RankIndex) and socketed
conduits (GarrTalent node -> conduitId + treeId), both persisted to new
character_soulbind_conduits / character_soulbind_conduit_sockets tables
loaded at login. CollectConduit() grants at the data-driven lowest
RankIndex defined for the conduit (never assumes 0; refuses if there is
no rank row). The "conduit add" GM command is the interim grant trigger;
auto-collection from conduit items needs the item-to-conduit link (TODO).
Socketing (Phase C): CMSG_GARRISON_SOCKET_TALENT now decodes to
{ u32 GarrTalentID, u32 count, count x (SoulbindConduitID, Rank) } - the
pair mirrors this protocol's GarrisonTalentSocketData. The handler routes
to Player::SocketConduit, which validates the conduit exists, is owned,
and its covenant matches, then persists and casts the conduit's
SoulbindConduitRank->SpellID aura. ApplyConduitSpells/RemoveConduitSpells
gate on the active soulbind's tree, re-apply on login (mirrors
_LoadGlyphAuras) and swap on soulbind switch.
Server-authoritative: the client-sent rank is ignored (server uses its
own collection). The socket wire's leading id / pair order carry a
NEEDS-CONFIRM (sniff) flag, but the handler fails closed - an unowned or
invalid id simply no-ops, so a misread can never corrupt state or apply a
wrong spell.