mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-04-17 09:33:51 +00:00
Transport hell
This commit is contained in:
parent
2e923311d0
commit
f3f3b62880
12 changed files with 912 additions and 126 deletions
|
|
@ -462,8 +462,8 @@ public:
|
|||
void setCreatureDespawnCallback(CreatureDespawnCallback cb) { creatureDespawnCallback_ = std::move(cb); }
|
||||
|
||||
// GameObject spawn callback (online mode - triggered when gameobject enters view)
|
||||
// Parameters: guid, displayId, x, y, z (canonical), orientation
|
||||
using GameObjectSpawnCallback = std::function<void(uint64_t guid, uint32_t displayId, float x, float y, float z, float orientation)>;
|
||||
// Parameters: guid, entry, displayId, x, y, z (canonical), orientation
|
||||
using GameObjectSpawnCallback = std::function<void(uint64_t guid, uint32_t entry, uint32_t displayId, float x, float y, float z, float orientation)>;
|
||||
void setGameObjectSpawnCallback(GameObjectSpawnCallback cb) { gameObjectSpawnCallback_ = std::move(cb); }
|
||||
|
||||
// GameObject despawn callback (online mode - triggered when gameobject leaves view)
|
||||
|
|
@ -483,10 +483,25 @@ public:
|
|||
using TransportMoveCallback = std::function<void(uint64_t guid, float x, float y, float z, float orientation)>;
|
||||
void setTransportMoveCallback(TransportMoveCallback cb) { transportMoveCallback_ = std::move(cb); }
|
||||
|
||||
// Transport spawn callback (online mode - triggered when transport GameObject is first detected)
|
||||
// Parameters: guid, entry, displayId, x, y, z (canonical), orientation
|
||||
using TransportSpawnCallback = std::function<void(uint64_t guid, uint32_t entry, uint32_t displayId, float x, float y, float z, float orientation)>;
|
||||
void setTransportSpawnCallback(TransportSpawnCallback cb) { transportSpawnCallback_ = std::move(cb); }
|
||||
|
||||
// Notify that a transport has been spawned (called after WMO instance creation)
|
||||
void notifyTransportSpawned(uint64_t guid, uint32_t entry, uint32_t displayId, float x, float y, float z, float orientation) {
|
||||
if (transportSpawnCallback_) {
|
||||
transportSpawnCallback_(guid, entry, displayId, x, y, z, orientation);
|
||||
}
|
||||
}
|
||||
|
||||
// Transport state for player-on-transport
|
||||
bool isOnTransport() const { return playerTransportGuid_ != 0; }
|
||||
uint64_t getPlayerTransportGuid() const { return playerTransportGuid_; }
|
||||
glm::vec3 getPlayerTransportOffset() const { return playerTransportOffset_; }
|
||||
|
||||
// Check if a GUID is a known transport
|
||||
bool isTransportGuid(uint64_t guid) const { return transportGuids_.count(guid) > 0; }
|
||||
glm::vec3 getComposedWorldPosition(); // Compose transport transform * local offset
|
||||
TransportManager* getTransportManager() { return transportManager_.get(); }
|
||||
void setPlayerOnTransport(uint64_t transportGuid, const glm::vec3& localOffset) {
|
||||
|
|
@ -792,6 +807,7 @@ private:
|
|||
|
||||
// ---- Creature movement handler ----
|
||||
void handleMonsterMove(network::Packet& packet);
|
||||
void handleMonsterMoveTransport(network::Packet& packet);
|
||||
|
||||
// ---- Phase 5 handlers ----
|
||||
void handleLootResponse(network::Packet& packet);
|
||||
|
|
@ -979,6 +995,7 @@ private:
|
|||
CreatureDespawnCallback creatureDespawnCallback_;
|
||||
CreatureMoveCallback creatureMoveCallback_;
|
||||
TransportMoveCallback transportMoveCallback_;
|
||||
TransportSpawnCallback transportSpawnCallback_;
|
||||
GameObjectSpawnCallback gameObjectSpawnCallback_;
|
||||
GameObjectDespawnCallback gameObjectDespawnCallback_;
|
||||
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ enum class Opcode : uint16_t {
|
|||
// ---- Entity/Object updates ----
|
||||
SMSG_UPDATE_OBJECT = 0x0A9,
|
||||
SMSG_COMPRESSED_UPDATE_OBJECT = 0x1F6,
|
||||
SMSG_MONSTER_MOVE_TRANSPORT = 0x2AE,
|
||||
SMSG_DESTROY_OBJECT = 0x0AA,
|
||||
|
||||
// ---- Chat ----
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
|
||||
|
|
@ -10,22 +11,29 @@ namespace wowee::rendering {
|
|||
class WMORenderer;
|
||||
}
|
||||
|
||||
namespace wowee::pipeline {
|
||||
class AssetManager;
|
||||
}
|
||||
|
||||
namespace wowee::game {
|
||||
|
||||
struct TimedPoint {
|
||||
uint32_t tMs; // Time in milliseconds from DBC
|
||||
glm::vec3 pos; // Position at this time
|
||||
};
|
||||
|
||||
struct TransportPath {
|
||||
uint32_t pathId;
|
||||
std::vector<glm::vec3> waypoints; // Position keyframes
|
||||
std::vector<glm::quat> rotations; // Optional rotation keyframes
|
||||
bool looping;
|
||||
float speed; // units/sec (default 18.0f like taxi)
|
||||
std::vector<TimedPoint> points; // Time-indexed waypoints (includes duplicate first point at end for wrap)
|
||||
bool looping; // Set to false after adding explicit wrap point
|
||||
uint32_t durationMs; // Total loop duration in ms (includes wrap segment if added)
|
||||
};
|
||||
|
||||
struct ActiveTransport {
|
||||
uint64_t guid; // Entity GUID
|
||||
uint32_t wmoInstanceId; // WMO renderer instance ID
|
||||
uint32_t pathId; // Current path
|
||||
size_t currentSegment; // Current waypoint index
|
||||
float segmentProgress; // Distance along segment
|
||||
glm::vec3 basePosition; // Spawn position (base offset for path)
|
||||
glm::vec3 position; // Current world position
|
||||
glm::quat rotation; // Current world rotation
|
||||
glm::mat4 transform; // Cached world transform
|
||||
|
|
@ -39,6 +47,17 @@ struct ActiveTransport {
|
|||
glm::vec3 deckMin;
|
||||
glm::vec3 deckMax;
|
||||
bool hasDeckBounds;
|
||||
|
||||
// Time-based animation (deterministic, no drift)
|
||||
uint32_t localClockMs; // Local path time in milliseconds
|
||||
bool hasServerClock; // Whether we've synced with server time
|
||||
int32_t serverClockOffsetMs; // Offset: serverClock - localNow
|
||||
bool useClientAnimation; // Use client-side path animation
|
||||
float serverYaw; // Server-authoritative yaw (radians)
|
||||
bool hasServerYaw; // Whether we've received server yaw
|
||||
|
||||
float lastServerUpdate; // Time of last server movement update
|
||||
int serverUpdateCount; // Number of server updates received
|
||||
};
|
||||
|
||||
class TransportManager {
|
||||
|
|
@ -49,7 +68,7 @@ public:
|
|||
void setWMORenderer(rendering::WMORenderer* renderer) { wmoRenderer_ = renderer; }
|
||||
|
||||
void update(float deltaTime);
|
||||
void registerTransport(uint64_t guid, uint32_t wmoInstanceId, uint32_t pathId);
|
||||
void registerTransport(uint64_t guid, uint32_t wmoInstanceId, uint32_t pathId, const glm::vec3& spawnWorldPos);
|
||||
void unregisterTransport(uint64_t guid);
|
||||
|
||||
ActiveTransport* getTransport(uint64_t guid);
|
||||
|
|
@ -59,15 +78,30 @@ public:
|
|||
void loadPathFromNodes(uint32_t pathId, const std::vector<glm::vec3>& waypoints, bool looping = true, float speed = 18.0f);
|
||||
void setDeckBounds(uint64_t guid, const glm::vec3& min, const glm::vec3& max);
|
||||
|
||||
// Load transport paths from TransportAnimation.dbc
|
||||
bool loadTransportAnimationDBC(pipeline::AssetManager* assetMgr);
|
||||
|
||||
// Check if a path exists for a given GameObject entry
|
||||
bool hasPathForEntry(uint32_t entry) const;
|
||||
|
||||
// Update server-controlled transport position/rotation directly (bypasses path movement)
|
||||
void updateServerTransport(uint64_t guid, const glm::vec3& position, float orientation);
|
||||
|
||||
// Enable/disable client-side animation for transports without server updates
|
||||
void setClientSideAnimation(bool enabled) { clientSideAnimation_ = enabled; }
|
||||
bool isClientSideAnimation() const { return clientSideAnimation_; }
|
||||
|
||||
private:
|
||||
void updateTransportMovement(ActiveTransport& transport, float deltaTime);
|
||||
glm::vec3 interpolatePath(const TransportPath& path, size_t segmentIdx, float t);
|
||||
glm::quat calculateOrientation(const TransportPath& path, size_t segmentIdx, float t);
|
||||
glm::vec3 evalTimedCatmullRom(const TransportPath& path, uint32_t pathTimeMs);
|
||||
glm::quat orientationFromTangent(const TransportPath& path, uint32_t pathTimeMs);
|
||||
void updateTransformMatrices(ActiveTransport& transport);
|
||||
|
||||
std::unordered_map<uint64_t, ActiveTransport> transports_;
|
||||
std::unordered_map<uint32_t, TransportPath> paths_;
|
||||
std::unordered_map<uint32_t, TransportPath> paths_; // Indexed by transportEntry (pathId from TransportAnimation.dbc)
|
||||
rendering::WMORenderer* wmoRenderer_ = nullptr;
|
||||
bool clientSideAnimation_ = true; // Enable client animation - smooth movement, synced with server updates
|
||||
float elapsedTime_ = 0.0f; // Total elapsed time (seconds)
|
||||
};
|
||||
|
||||
} // namespace wowee::game
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue