mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
game: fix SMSG_SPELL_GO miss-entry consumption in WotLK and TBC parsers
Both SpellGoParser::parse (WotLK) and TbcPacketParsers::parseSpellGo
(TBC) read missCount but did not consume the per-miss (guid + missType)
entries that follow, leaving unread bytes in the packet and silently
corrupting any subsequent parsing of cast-flags–gated spell data.
- Add SpellGoMissEntry{targetGuid, missType} and missTargets vector
to SpellGoData
- WotLK parser now reads packed GUIDs + missType per miss entry
- TBC parser now reads full uint64 GUIDs + missType per miss entry
(9 bytes per entry, bounds-checked)
- handleSpellGo now shows MISS/DODGE/PARRY/BLOCK combat text
for each missed target when the local player cast the spell,
complementing the existing SMSG_SPELLLOGMISS path
- Remove unused foliageLikeModel variable in m2_renderer pass-2 loop
(fix unused-variable warning)
- Update smoke model comment in m2_renderer to reflect current state
This commit is contained in:
parent
06a628dae2
commit
6951b7803d
5 changed files with 42 additions and 4 deletions
|
|
@ -1766,6 +1766,11 @@ public:
|
|||
};
|
||||
|
||||
/** SMSG_SPELL_GO data (simplified) */
|
||||
struct SpellGoMissEntry {
|
||||
uint64_t targetGuid = 0;
|
||||
uint8_t missType = 0; // 0=MISS 1=DODGE 2=PARRY 3=BLOCK 4=EVADE 5=IMMUNE 6=DEFLECT 7=ABSORB 8=RESIST
|
||||
};
|
||||
|
||||
struct SpellGoData {
|
||||
uint64_t casterGuid = 0;
|
||||
uint64_t casterUnit = 0;
|
||||
|
|
@ -1773,8 +1778,9 @@ struct SpellGoData {
|
|||
uint32_t spellId = 0;
|
||||
uint32_t castFlags = 0;
|
||||
uint8_t hitCount = 0;
|
||||
std::vector<uint64_t> hitTargets;
|
||||
std::vector<uint64_t> hitTargets;
|
||||
uint8_t missCount = 0;
|
||||
std::vector<SpellGoMissEntry> missTargets;
|
||||
|
||||
bool isValid() const { return spellId != 0; }
|
||||
};
|
||||
|
|
|
|||
|
|
@ -12713,6 +12713,26 @@ void GameHandler::handleSpellGo(network::Packet& packet) {
|
|||
castTimeRemaining = 0.0f;
|
||||
}
|
||||
|
||||
// Show miss/dodge/parry/etc combat text when player's spells miss targets
|
||||
if (data.casterUnit == playerGuid && !data.missTargets.empty()) {
|
||||
static const CombatTextEntry::Type missTypes[] = {
|
||||
CombatTextEntry::MISS, // 0=MISS
|
||||
CombatTextEntry::DODGE, // 1=DODGE
|
||||
CombatTextEntry::PARRY, // 2=PARRY
|
||||
CombatTextEntry::BLOCK, // 3=BLOCK
|
||||
CombatTextEntry::MISS, // 4=EVADE → show as MISS
|
||||
CombatTextEntry::MISS, // 5=IMMUNE → show as MISS
|
||||
CombatTextEntry::MISS, // 6=DEFLECT
|
||||
CombatTextEntry::MISS, // 7=ABSORB
|
||||
CombatTextEntry::MISS, // 8=RESIST
|
||||
};
|
||||
// Show text for each miss (usually just 1 target per spell go)
|
||||
for (const auto& m : data.missTargets) {
|
||||
CombatTextEntry::Type ct = (m.missType < 9) ? missTypes[m.missType] : CombatTextEntry::MISS;
|
||||
addCombatText(ct, 0, 0, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Play impact sound when player is hit by any spell (from self or others)
|
||||
bool playerIsHit = false;
|
||||
for (const auto& tgt : data.hitTargets) {
|
||||
|
|
|
|||
|
|
@ -1051,6 +1051,13 @@ bool TbcPacketParsers::parseSpellGo(network::Packet& packet, SpellGoData& data)
|
|||
|
||||
if (packet.getReadPos() < packet.getSize()) {
|
||||
data.missCount = packet.readUInt8();
|
||||
data.missTargets.reserve(data.missCount);
|
||||
for (uint8_t i = 0; i < data.missCount && packet.getReadPos() + 9 <= packet.getSize(); ++i) {
|
||||
SpellGoMissEntry m;
|
||||
m.targetGuid = packet.readUInt64(); // full GUID in TBC
|
||||
m.missType = packet.readUInt8();
|
||||
data.missTargets.push_back(m);
|
||||
}
|
||||
}
|
||||
|
||||
LOG_DEBUG("[TBC] Spell go: spell=", data.spellId, " hits=", (int)data.hitCount,
|
||||
|
|
|
|||
|
|
@ -2987,7 +2987,13 @@ bool SpellGoParser::parse(network::Packet& packet, SpellGoData& data) {
|
|||
}
|
||||
|
||||
data.missCount = packet.readUInt8();
|
||||
// Skip miss details for now
|
||||
data.missTargets.reserve(data.missCount);
|
||||
for (uint8_t i = 0; i < data.missCount && packet.getReadPos() + 2 <= packet.getSize(); ++i) {
|
||||
SpellGoMissEntry m;
|
||||
m.targetGuid = UpdateObjectParser::readPackedGuid(packet); // packed GUID in WotLK
|
||||
m.missType = (packet.getReadPos() < packet.getSize()) ? packet.readUInt8() : 0;
|
||||
data.missTargets.push_back(m);
|
||||
}
|
||||
|
||||
LOG_DEBUG("Spell go: spell=", data.spellId, " hits=", (int)data.hitCount,
|
||||
" misses=", (int)data.missCount);
|
||||
|
|
|
|||
|
|
@ -1185,7 +1185,7 @@ bool M2Renderer::loadModel(const pipeline::M2Model& model, uint32_t modelId) {
|
|||
" tris, grid ", gpuModel.collision.gridCellsX, "x", gpuModel.collision.gridCellsY);
|
||||
}
|
||||
|
||||
// Flag smoke models for UV scroll animation (particle emitters not implemented)
|
||||
// Flag smoke models for UV scroll animation (in addition to particle emitters)
|
||||
{
|
||||
std::string smokeName = model.name;
|
||||
std::transform(smokeName.begin(), smokeName.end(), smokeName.begin(),
|
||||
|
|
@ -2709,7 +2709,6 @@ void M2Renderer::render(VkCommandBuffer cmd, VkDescriptorSet perFrameSet, const
|
|||
uint16_t targetLOD = desiredLOD;
|
||||
if (desiredLOD > 0 && !(model.availableLODs & (1u << desiredLOD))) targetLOD = 0;
|
||||
|
||||
const bool foliageLikeModel = model.isFoliageLike;
|
||||
const bool particleDominantEffect = model.isSpellEffect &&
|
||||
!model.particleEmitters.empty() && model.batches.size() <= 2;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue