mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-24 16:10:14 +00:00
Restructure inventory UI, add vendor selling, camera intro on all spawns, and quest log
Split inventory into bags-only (B key) and character screen (C key). Vendor window auto-opens bags with sell prices on hover and right-click to sell. Add camera intro pan on all login/spawn/teleport/hearthstone events and idle orbit after 2 minutes. Add quest log UI, SMSG_MONSTER_MOVE handling, deferred creature spawn queue, and creature fade-in/movement interpolation for online mode.
This commit is contained in:
parent
bb4c2c25f7
commit
71c3d2ea77
21 changed files with 1092 additions and 149 deletions
|
|
@ -575,11 +575,23 @@ network::Packet MovementPacket::build(Opcode opcode, const MovementInfo& info, u
|
|||
packet.writeBytes(reinterpret_cast<const uint8_t*>(&info.jumpXYSpeed), sizeof(float));
|
||||
}
|
||||
|
||||
static int mvLog = 10;
|
||||
// Detailed hex dump for debugging
|
||||
static int mvLog = 5;
|
||||
if (mvLog-- > 0) {
|
||||
LOG_INFO("Movement pkt: opcode=0x", std::hex, static_cast<uint16_t>(opcode), std::dec,
|
||||
" size=", packet.getSize(), " flags=0x", std::hex, info.flags, std::dec,
|
||||
" pos=(", info.x, ",", info.y, ",", info.z, ")");
|
||||
const auto& raw = packet.getData();
|
||||
std::string hex;
|
||||
for (size_t i = 0; i < raw.size(); i++) {
|
||||
char b[4]; snprintf(b, sizeof(b), "%02x ", raw[i]);
|
||||
hex += b;
|
||||
}
|
||||
LOG_INFO("MOVEPKT opcode=0x", std::hex, static_cast<uint16_t>(opcode), std::dec,
|
||||
" guid=0x", std::hex, playerGuid, std::dec,
|
||||
" payload=", raw.size(), " bytes",
|
||||
" flags=0x", std::hex, info.flags, std::dec,
|
||||
" flags2=0x", std::hex, info.flags2, std::dec,
|
||||
" pos=(", info.x, ",", info.y, ",", info.z, ",", info.orientation, ")",
|
||||
" fallTime=", info.fallTime);
|
||||
LOG_INFO("MOVEPKT hex: ", hex);
|
||||
}
|
||||
|
||||
return packet;
|
||||
|
|
@ -1288,7 +1300,7 @@ bool ItemQueryResponseParser::parse(network::Packet& packet, ItemQueryResponseDa
|
|||
packet.readUInt32(); // Flags
|
||||
packet.readUInt32(); // Flags2
|
||||
packet.readUInt32(); // BuyPrice
|
||||
packet.readUInt32(); // SellPrice
|
||||
data.sellPrice = packet.readUInt32(); // SellPrice
|
||||
|
||||
data.inventoryType = packet.readUInt32();
|
||||
|
||||
|
|
@ -1339,6 +1351,118 @@ bool ItemQueryResponseParser::parse(network::Packet& packet, ItemQueryResponseDa
|
|||
return true;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// Creature Movement
|
||||
// ============================================================
|
||||
|
||||
bool MonsterMoveParser::parse(network::Packet& packet, MonsterMoveData& data) {
|
||||
// PackedGuid
|
||||
data.guid = UpdateObjectParser::readPackedGuid(packet);
|
||||
if (data.guid == 0) return false;
|
||||
|
||||
// uint8 unk (toggle for MOVEMENTFLAG2_UNK7)
|
||||
if (packet.getReadPos() >= packet.getSize()) return false;
|
||||
packet.readUInt8();
|
||||
|
||||
// Current position (server coords: float x, y, z)
|
||||
if (packet.getReadPos() + 12 > packet.getSize()) return false;
|
||||
data.x = packet.readFloat();
|
||||
data.y = packet.readFloat();
|
||||
data.z = packet.readFloat();
|
||||
|
||||
// uint32 splineId
|
||||
if (packet.getReadPos() + 4 > packet.getSize()) return false;
|
||||
packet.readUInt32();
|
||||
|
||||
// uint8 moveType
|
||||
if (packet.getReadPos() >= packet.getSize()) return false;
|
||||
data.moveType = packet.readUInt8();
|
||||
|
||||
if (data.moveType == 1) {
|
||||
// Stop - no more required data
|
||||
data.destX = data.x;
|
||||
data.destY = data.y;
|
||||
data.destZ = data.z;
|
||||
data.hasDest = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Read facing data based on move type
|
||||
if (data.moveType == 2) {
|
||||
// FacingSpot: float x, y, z
|
||||
if (packet.getReadPos() + 12 > packet.getSize()) return false;
|
||||
packet.readFloat(); packet.readFloat(); packet.readFloat();
|
||||
} else if (data.moveType == 3) {
|
||||
// FacingTarget: uint64 guid
|
||||
if (packet.getReadPos() + 8 > packet.getSize()) return false;
|
||||
data.facingTarget = packet.readUInt64();
|
||||
} else if (data.moveType == 4) {
|
||||
// FacingAngle: float angle
|
||||
if (packet.getReadPos() + 4 > packet.getSize()) return false;
|
||||
data.facingAngle = packet.readFloat();
|
||||
}
|
||||
|
||||
// uint32 splineFlags
|
||||
if (packet.getReadPos() + 4 > packet.getSize()) return false;
|
||||
data.splineFlags = packet.readUInt32();
|
||||
|
||||
// Check for animation flag (0x00000100)
|
||||
if (data.splineFlags & 0x00000100) {
|
||||
if (packet.getReadPos() + 8 > packet.getSize()) return false;
|
||||
packet.readUInt32(); // animId
|
||||
packet.readUInt32(); // effectStartTime
|
||||
}
|
||||
|
||||
// uint32 duration
|
||||
if (packet.getReadPos() + 4 > packet.getSize()) return false;
|
||||
data.duration = packet.readUInt32();
|
||||
|
||||
// Check for parabolic flag (0x00000200)
|
||||
if (data.splineFlags & 0x00000200) {
|
||||
if (packet.getReadPos() + 8 > packet.getSize()) return false;
|
||||
packet.readFloat(); // vertAccel
|
||||
packet.readUInt32(); // effectStartTime
|
||||
}
|
||||
|
||||
// uint32 pointCount
|
||||
if (packet.getReadPos() + 4 > packet.getSize()) return false;
|
||||
uint32_t pointCount = packet.readUInt32();
|
||||
|
||||
if (pointCount == 0) return true;
|
||||
|
||||
// Read destination point(s)
|
||||
// If UncompressedPath flag (0x00040000): all points are full float x,y,z
|
||||
// Otherwise: first is packed destination, rest are packed deltas
|
||||
bool uncompressed = (data.splineFlags & 0x00040000) != 0;
|
||||
|
||||
if (uncompressed) {
|
||||
// Read last point as destination
|
||||
// Skip to last point: each point is 12 bytes
|
||||
for (uint32_t i = 0; i < pointCount - 1; i++) {
|
||||
if (packet.getReadPos() + 12 > packet.getSize()) return true;
|
||||
packet.readFloat(); packet.readFloat(); packet.readFloat();
|
||||
}
|
||||
if (packet.getReadPos() + 12 > packet.getSize()) return true;
|
||||
data.destX = packet.readFloat();
|
||||
data.destY = packet.readFloat();
|
||||
data.destZ = packet.readFloat();
|
||||
data.hasDest = true;
|
||||
} else {
|
||||
// Compressed: first 3 floats are the destination (final point)
|
||||
if (packet.getReadPos() + 12 > packet.getSize()) return true;
|
||||
data.destX = packet.readFloat();
|
||||
data.destY = packet.readFloat();
|
||||
data.destZ = packet.readFloat();
|
||||
data.hasDest = true;
|
||||
}
|
||||
|
||||
LOG_DEBUG("MonsterMove: guid=0x", std::hex, data.guid, std::dec,
|
||||
" type=", (int)data.moveType, " dur=", data.duration, "ms",
|
||||
" dest=(", data.destX, ",", data.destY, ",", data.destZ, ")");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// Phase 2: Combat Core
|
||||
// ============================================================
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue