Add loading screen, fix tree/foliage collision, jump buffering, and fence rotation

- Loading screen stays visible until all terrain tiles finish streaming;
  character spawns only after terrain is loaded and Z-snapped to ground
- Reduce tree trunk collision bounds (5% of canopy, capped at 5.0) and
  make all small/medium trees, bushes, lily pads, and foliage walkthrough
- Add jump input buffering (150ms) and coyote time (100ms) for responsive jumps
- Fix fence orientation by adding +180° heading rotation
- Increase terrain load radius from 1 to 2 (5x5 tile grid)
- Add hearthstone callback for single-player camera reset
This commit is contained in:
Kelsi 2026-02-04 13:29:27 -08:00
parent f7cd871895
commit 6ca9e9024a
9 changed files with 188 additions and 222 deletions

View file

@ -1101,11 +1101,12 @@ void GameHandler::handleCreatureQueryResponse(network::Packet& packet) {
// ============================================================
void GameHandler::startAutoAttack(uint64_t targetGuid) {
if (state != WorldState::IN_WORLD || !socket) return;
autoAttacking = true;
autoAttackTarget = targetGuid;
auto packet = AttackSwingPacket::build(targetGuid);
socket->send(packet);
if (state == WorldState::IN_WORLD && socket) {
auto packet = AttackSwingPacket::build(targetGuid);
socket->send(packet);
}
LOG_INFO("Starting auto-attack on 0x", std::hex, targetGuid, std::dec);
}
@ -1204,9 +1205,14 @@ void GameHandler::handleSpellHealLog(network::Packet& packet) {
// ============================================================
void GameHandler::castSpell(uint32_t spellId, uint64_t targetGuid) {
if (state != WorldState::IN_WORLD || !socket) return;
// Hearthstone (8690) — handle locally when no server connection (single-player)
if (spellId == 8690 && hearthstoneCallback) {
LOG_INFO("Hearthstone: teleporting home");
hearthstoneCallback();
return;
}
// Attack (6603) routes to auto-attack instead of cast
// Attack (6603) routes to auto-attack instead of cast (works without server)
if (spellId == 6603) {
uint64_t target = targetGuid != 0 ? targetGuid : this->targetGuid;
if (target != 0) {
@ -1219,6 +1225,8 @@ void GameHandler::castSpell(uint32_t spellId, uint64_t targetGuid) {
return;
}
if (state != WorldState::IN_WORLD || !socket) return;
if (casting) return; // Already casting
uint64_t target = targetGuid != 0 ? targetGuid : targetGuid;