mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
Update opcode data and movement integration docs/code
This commit is contained in:
parent
86127f0ddf
commit
bd0ce17794
11 changed files with 41 additions and 15 deletions
1
.github/FUNDING.yml
vendored
Normal file
1
.github/FUNDING.yml
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
github: Kelsidavis
|
||||
|
|
@ -94,6 +94,7 @@
|
|||
"CMSG_BINDER_ACTIVATE": "0x1B5",
|
||||
"SMSG_LOG_XPGAIN": "0x1D0",
|
||||
"SMSG_MONSTER_MOVE": "0x0DD",
|
||||
"SMSG_COMPRESSED_MOVES": "0x06B",
|
||||
"CMSG_ATTACKSWING": "0x141",
|
||||
"CMSG_ATTACKSTOP": "0x142",
|
||||
"SMSG_ATTACKSTART": "0x143",
|
||||
|
|
|
|||
|
|
@ -93,7 +93,8 @@
|
|||
"CMSG_SET_ACTIVE_MOVER": "0x26A",
|
||||
"CMSG_BINDER_ACTIVATE": "0x1B5",
|
||||
"SMSG_LOG_XPGAIN": "0x1D0",
|
||||
"SMSG_MONSTER_MOVE": "0x0DD",
|
||||
"SMSG_MONSTER_MOVE": "0x2FB",
|
||||
"SMSG_COMPRESSED_MOVES": "0x06B",
|
||||
"CMSG_ATTACKSWING": "0x141",
|
||||
"CMSG_ATTACKSTOP": "0x142",
|
||||
"SMSG_ATTACKSTART": "0x143",
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
A native C++ World of Warcraft client with a custom OpenGL renderer.
|
||||
|
||||
[](https://github.com/sponsors/Kelsidavis)
|
||||
|
||||
[](https://youtu.be/Pd9JuYYxu0o)
|
||||
|
||||
[](https://youtu.be/J4NXegzqWSQ)
|
||||
|
|
|
|||
|
|
@ -105,6 +105,13 @@ public:
|
|||
|
||||
bool isEntityMoving() const { return isMoving_; }
|
||||
|
||||
// Returns the latest server-authoritative position: destination if moving, current if not.
|
||||
// Unlike getX/Y/Z (which only update via updateMovement), this always reflects the
|
||||
// last known server position regardless of distance culling.
|
||||
float getLatestX() const { return isMoving_ ? moveEndX_ : x; }
|
||||
float getLatestY() const { return isMoving_ ? moveEndY_ : y; }
|
||||
float getLatestZ() const { return isMoving_ ? moveEndZ_ : z; }
|
||||
|
||||
// Object type
|
||||
ObjectType getType() const { return type; }
|
||||
void setType(ObjectType t) { type = t; }
|
||||
|
|
|
|||
|
|
@ -1049,6 +1049,7 @@ private:
|
|||
|
||||
// ---- Creature movement handler ----
|
||||
void handleMonsterMove(network::Packet& packet);
|
||||
void handleCompressedMoves(network::Packet& packet);
|
||||
void handleMonsterMoveTransport(network::Packet& packet);
|
||||
|
||||
// ---- Other player movement (MSG_MOVE_* from server) ----
|
||||
|
|
|
|||
|
|
@ -157,6 +157,7 @@ enum class LogicalOpcode : uint16_t {
|
|||
|
||||
// ---- Creature Movement ----
|
||||
SMSG_MONSTER_MOVE,
|
||||
SMSG_COMPRESSED_MOVES, // Vanilla/Classic batch movement packet (0x6B)
|
||||
|
||||
// ---- Phase 2: Combat Core ----
|
||||
CMSG_ATTACKSWING,
|
||||
|
|
|
|||
|
|
@ -1450,7 +1450,11 @@ struct MonsterMoveData {
|
|||
|
||||
class MonsterMoveParser {
|
||||
public:
|
||||
// WotLK 3.3.5a format: PackedGUID + uint8 unk + float[3] + uint32 splineId + uint8 moveType + ...
|
||||
static bool parse(network::Packet& packet, MonsterMoveData& data);
|
||||
// Vanilla 1.12 format: PackedGUID + float[3] + uint32 timeInMs + uint8 moveType + ...
|
||||
// Used for Classic/TBC/Turtle WoW servers (no splineId, timeInMs before moveType)
|
||||
static bool parseVanilla(network::Packet& packet, MonsterMoveData& data);
|
||||
};
|
||||
|
||||
/** SMSG_ATTACKSTART data */
|
||||
|
|
|
|||
|
|
@ -3419,6 +3419,20 @@ void Application::spawnOnlineCreature(uint64_t guid, uint32_t displayId, float x
|
|||
}
|
||||
}
|
||||
|
||||
// Use the entity's latest server-authoritative position rather than the stale spawn
|
||||
// position. Movement packets (SMSG_MONSTER_MOVE) can arrive while a creature is still
|
||||
// queued in pendingCreatureSpawns_ and get silently dropped. getLatestX/Y/Z returns
|
||||
// the movement destination if the entity is mid-move, which is always up-to-date
|
||||
// regardless of distance culling (unlike getX/Y/Z which requires updateMovement).
|
||||
if (gameHandler) {
|
||||
if (auto entity = gameHandler->getEntityManager().getEntity(guid)) {
|
||||
x = entity->getLatestX();
|
||||
y = entity->getLatestY();
|
||||
z = entity->getLatestZ();
|
||||
orientation = entity->getOrientation();
|
||||
}
|
||||
}
|
||||
|
||||
// Convert canonical → render coordinates
|
||||
glm::vec3 renderPos = core::coords::canonicalToRender(glm::vec3(x, y, z));
|
||||
|
||||
|
|
|
|||
|
|
@ -126,6 +126,7 @@ static const OpcodeNameEntry kOpcodeNames[] = {
|
|||
{"CMSG_BINDER_ACTIVATE", LogicalOpcode::CMSG_BINDER_ACTIVATE},
|
||||
{"SMSG_LOG_XPGAIN", LogicalOpcode::SMSG_LOG_XPGAIN},
|
||||
{"SMSG_MONSTER_MOVE", LogicalOpcode::SMSG_MONSTER_MOVE},
|
||||
{"SMSG_COMPRESSED_MOVES", LogicalOpcode::SMSG_COMPRESSED_MOVES},
|
||||
{"CMSG_ATTACKSWING", LogicalOpcode::CMSG_ATTACKSWING},
|
||||
{"CMSG_ATTACKSTOP", LogicalOpcode::CMSG_ATTACKSTOP},
|
||||
{"SMSG_ATTACKSTART", LogicalOpcode::SMSG_ATTACKSTART},
|
||||
|
|
|
|||
|
|
@ -1175,22 +1175,15 @@ bool M2Renderer::loadModel(const pipeline::M2Model& model, uint32_t modelId) {
|
|||
}
|
||||
bgpu.texture = tex;
|
||||
bgpu.hasAlpha = (tex != 0 && tex != whiteTexture);
|
||||
bgpu.textureUnit = static_cast<uint8_t>(batch.textureUnit & 0x1);
|
||||
// textureCoordIndex is an index into a texture coord combo table, not directly
|
||||
// a UV set selector. Most batches have index=0 (UV set 0). We always use UV set 0
|
||||
// since we don't have the full combo table — dual-UV effects are rare edge cases.
|
||||
bgpu.textureUnit = 0;
|
||||
|
||||
// Resolve opacity: texture weight track × color animation alpha
|
||||
// Batches whose texture failed to load are hidden (avoid white shell artifacts)
|
||||
// Batch is hidden only when its named texture failed to load (avoids white shell artifacts).
|
||||
// Do NOT bake transparency/color animation tracks here — they animate over time and
|
||||
// baking the first keyframe value causes legitimate meshes to become invisible.
|
||||
bgpu.batchOpacity = texFailed ? 0.0f : 1.0f;
|
||||
// Texture weight track (via transparency lookup)
|
||||
if (batch.transparencyIndex < model.textureTransformLookup.size()) {
|
||||
uint16_t trackIdx = model.textureTransformLookup[batch.transparencyIndex];
|
||||
if (trackIdx < model.textureWeights.size()) {
|
||||
bgpu.batchOpacity *= model.textureWeights[trackIdx];
|
||||
}
|
||||
}
|
||||
// Color animation alpha (M2Color.alpha, indexed directly by colorIndex)
|
||||
if (batch.colorIndex < model.colorAlphas.size()) {
|
||||
bgpu.batchOpacity *= model.colorAlphas[batch.colorIndex];
|
||||
}
|
||||
|
||||
// Compute batch center and radius for glow sprite positioning
|
||||
if (bgpu.blendMode >= 3 && batch.indexCount > 0) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue