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:
Kelsi 2026-02-06 13:47:03 -08:00
parent bb4c2c25f7
commit 71c3d2ea77
21 changed files with 1092 additions and 149 deletions

View file

@ -192,6 +192,11 @@ private:
float introEndPitch = -5.0f;
float introStartDistance = 12.0f;
float introEndDistance = 10.0f;
// Idle camera: triggers intro pan after IDLE_TIMEOUT seconds of no input
float idleTimer_ = 0.0f;
bool idleOrbit_ = false; // true when current intro pan is an idle orbit (loops)
static constexpr float IDLE_TIMEOUT = 120.0f; // 2 minutes
};
} // namespace rendering

View file

@ -61,6 +61,9 @@ public:
void setInstancePosition(uint32_t instanceId, const glm::vec3& position);
void setInstanceRotation(uint32_t instanceId, const glm::vec3& rotation);
void moveInstanceTo(uint32_t instanceId, const glm::vec3& destination, float durationSeconds);
void startFadeIn(uint32_t instanceId, float durationSeconds);
const pipeline::M2Model* getModelData(uint32_t modelId) const;
void setActiveGeosets(uint32_t instanceId, const std::unordered_set<uint16_t>& geosets);
void setGroupTextureOverride(uint32_t instanceId, uint16_t geosetGroup, GLuint textureId);
void setInstanceVisible(uint32_t instanceId, bool visible);
@ -130,6 +133,18 @@ private:
// Weapon attachments (weapons parented to this instance's bones)
std::vector<WeaponAttachment> weaponAttachments;
// Opacity (for fade-in)
float opacity = 1.0f;
float fadeInTime = 0.0f; // elapsed fade time (seconds)
float fadeInDuration = 0.0f; // total fade duration (0 = no fade)
// Movement interpolation
bool isMoving = false;
glm::vec3 moveStart{0.0f};
glm::vec3 moveEnd{0.0f};
float moveDuration = 0.0f; // seconds
float moveElapsed = 0.0f;
// Override model matrix (used for weapon instances positioned by parent bone)
bool hasOverrideModelMatrix = false;
glm::mat4 overrideModelMatrix{1.0f};

View file

@ -123,6 +123,10 @@ public:
bool isMoving() const;
void triggerMeleeSwing();
// Selection circle for targeted entity
void setSelectionCircle(const glm::vec3& pos, float radius, const glm::vec3& color);
void clearSelectionCircle();
// CPU timing stats (milliseconds, last frame).
double getLastUpdateMs() const { return lastUpdateMs; }
double getLastRenderMs() const { return lastRenderMs; }
@ -224,6 +228,18 @@ private:
// Target facing
const glm::vec3* targetPosition = nullptr;
// Selection circle rendering
uint32_t selCircleVAO = 0;
uint32_t selCircleVBO = 0;
uint32_t selCircleShader = 0;
int selCircleVertCount = 0;
void initSelectionCircle();
void renderSelectionCircle(const glm::mat4& view, const glm::mat4& projection);
glm::vec3 selCirclePos{0.0f};
glm::vec3 selCircleColor{1.0f, 0.0f, 0.0f};
float selCircleRadius = 1.5f;
bool selCircleVisible = false;
// Footstep event tracking (animation-driven)
uint32_t footstepLastAnimationId = 0;
float footstepLastNormTime = 0.0f;