mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-04-04 04:03:52 +00:00
fixin critical bugs, non critical bugs, sendmail implementation
This commit is contained in:
parent
b2710258dc
commit
888a78d775
15 changed files with 116 additions and 119 deletions
|
|
@ -814,26 +814,35 @@ public:
|
|||
float getTargetCastTimeRemaining() const { return spellHandler_ ? spellHandler_->getTargetCastTimeRemaining() : 0.0f; }
|
||||
bool isTargetCastInterruptible() const { return spellHandler_ ? spellHandler_->isTargetCastInterruptible() : true; }
|
||||
|
||||
// Talents
|
||||
uint8_t getActiveTalentSpec() const { return activeTalentSpec_; }
|
||||
uint8_t getUnspentTalentPoints() const { return unspentTalentPoints_[activeTalentSpec_]; }
|
||||
uint8_t getUnspentTalentPoints(uint8_t spec) const { return spec < 2 ? unspentTalentPoints_[spec] : 0; }
|
||||
const std::unordered_map<uint32_t, uint8_t>& getLearnedTalents() const { return learnedTalents_[activeTalentSpec_]; }
|
||||
// Talents — delegate to SpellHandler as canonical authority
|
||||
uint8_t getActiveTalentSpec() const { return spellHandler_ ? spellHandler_->getActiveTalentSpec() : 0; }
|
||||
uint8_t getUnspentTalentPoints() const { return spellHandler_ ? spellHandler_->getUnspentTalentPoints() : 0; }
|
||||
uint8_t getUnspentTalentPoints(uint8_t spec) const { return spellHandler_ ? spellHandler_->getUnspentTalentPoints(spec) : 0; }
|
||||
const std::unordered_map<uint32_t, uint8_t>& getLearnedTalents() const {
|
||||
if (spellHandler_) return spellHandler_->getLearnedTalents();
|
||||
static const std::unordered_map<uint32_t, uint8_t> empty;
|
||||
return empty;
|
||||
}
|
||||
const std::unordered_map<uint32_t, uint8_t>& getLearnedTalents(uint8_t spec) const {
|
||||
static std::unordered_map<uint32_t, uint8_t> empty;
|
||||
return spec < 2 ? learnedTalents_[spec] : empty;
|
||||
if (spellHandler_) return spellHandler_->getLearnedTalents(spec);
|
||||
static const std::unordered_map<uint32_t, uint8_t> empty;
|
||||
return empty;
|
||||
}
|
||||
|
||||
// Glyphs (WotLK): up to 6 glyph slots per spec (3 major + 3 minor)
|
||||
static constexpr uint8_t MAX_GLYPH_SLOTS = 6;
|
||||
const std::array<uint16_t, MAX_GLYPH_SLOTS>& getGlyphs() const { return learnedGlyphs_[activeTalentSpec_]; }
|
||||
const std::array<uint16_t, MAX_GLYPH_SLOTS>& getGlyphs() const {
|
||||
if (spellHandler_) return spellHandler_->getGlyphs();
|
||||
static const std::array<uint16_t, MAX_GLYPH_SLOTS> empty{};
|
||||
return empty;
|
||||
}
|
||||
const std::array<uint16_t, MAX_GLYPH_SLOTS>& getGlyphs(uint8_t spec) const {
|
||||
static std::array<uint16_t, MAX_GLYPH_SLOTS> empty{};
|
||||
return spec < 2 ? learnedGlyphs_[spec] : empty;
|
||||
if (spellHandler_) return spellHandler_->getGlyphs(spec);
|
||||
static const std::array<uint16_t, MAX_GLYPH_SLOTS> empty{};
|
||||
return empty;
|
||||
}
|
||||
uint8_t getTalentRank(uint32_t talentId) const {
|
||||
auto it = learnedTalents_[activeTalentSpec_].find(talentId);
|
||||
return (it != learnedTalents_[activeTalentSpec_].end()) ? it->second : 0;
|
||||
return spellHandler_ ? spellHandler_->getTalentRank(talentId) : 0;
|
||||
}
|
||||
void learnTalent(uint32_t talentId, uint32_t requestedRank);
|
||||
void switchTalentSpec(uint8_t newSpec);
|
||||
|
|
@ -1431,7 +1440,7 @@ public:
|
|||
|
||||
// Equipment Sets (aliased from handler_types.hpp)
|
||||
using EquipmentSetInfo = game::EquipmentSetInfo;
|
||||
const std::vector<EquipmentSetInfo>& getEquipmentSets() const { return equipmentSetInfo_; }
|
||||
const std::vector<EquipmentSetInfo>& getEquipmentSets() const;
|
||||
bool supportsEquipmentSets() const;
|
||||
void useEquipmentSet(uint32_t setId);
|
||||
void saveEquipmentSet(const std::string& name, const std::string& iconName = "INV_Misc_QuestionMark",
|
||||
|
|
|
|||
|
|
@ -347,6 +347,7 @@ private:
|
|||
void handleSetFactionAtWar(network::Packet& packet);
|
||||
void handleSetFactionVisible(network::Packet& packet);
|
||||
void handleGroupSetLeader(network::Packet& packet);
|
||||
void handleTalentsInfo(network::Packet& packet);
|
||||
|
||||
GameHandler& owner_;
|
||||
|
||||
|
|
|
|||
|
|
@ -162,8 +162,8 @@ public:
|
|||
void useItemInBag(int bagIndex, int slotIndex);
|
||||
void useItemById(uint32_t itemId);
|
||||
|
||||
// Equipment sets
|
||||
const std::vector<EquipmentSetInfo>& getEquipmentSets() const { return equipmentSetInfo_; }
|
||||
// Equipment sets — canonical data owned by InventoryHandler;
|
||||
// GameHandler::getEquipmentSets() delegates to inventoryHandler_.
|
||||
|
||||
// Pet spells
|
||||
void sendPetAction(uint32_t action, uint64_t targetGuid = 0);
|
||||
|
|
@ -186,6 +186,7 @@ public:
|
|||
// Cast state
|
||||
void stopCasting();
|
||||
void resetCastState();
|
||||
void resetTalentState();
|
||||
void clearUnitCaches();
|
||||
|
||||
// Aura duration
|
||||
|
|
@ -252,7 +253,6 @@ private:
|
|||
void handleUnlearnSpells(network::Packet& packet);
|
||||
void handleTalentsInfo(network::Packet& packet);
|
||||
void handleAchievementEarned(network::Packet& packet);
|
||||
void handleEquipmentSetList(network::Packet& packet);
|
||||
|
||||
friend class GameHandler;
|
||||
friend class InventoryHandler;
|
||||
|
|
@ -313,18 +313,6 @@ private:
|
|||
bool petUnlearnPending_ = false;
|
||||
uint64_t petUnlearnGuid_ = 0;
|
||||
uint32_t petUnlearnCost_ = 0;
|
||||
|
||||
// Equipment sets
|
||||
struct EquipmentSet {
|
||||
uint64_t setGuid = 0;
|
||||
uint32_t setId = 0;
|
||||
std::string name;
|
||||
std::string iconName;
|
||||
uint32_t ignoreSlotMask = 0;
|
||||
std::array<uint64_t, 19> itemGuids{};
|
||||
};
|
||||
std::vector<EquipmentSet> equipmentSets_;
|
||||
std::vector<EquipmentSetInfo> equipmentSetInfo_;
|
||||
};
|
||||
|
||||
} // namespace game
|
||||
|
|
|
|||
|
|
@ -2660,8 +2660,7 @@ void GameHandler::registerOpcodeHandlers() {
|
|||
// Clear cached talent data so the talent screen reflects the reset.
|
||||
dispatchTable_[Opcode::SMSG_TALENTS_INVOLUNTARILY_RESET] = [this](network::Packet& packet) {
|
||||
// Clear cached talent data so the talent screen reflects the reset.
|
||||
learnedTalents_[0].clear();
|
||||
learnedTalents_[1].clear();
|
||||
if (spellHandler_) spellHandler_->resetTalentState();
|
||||
addUIError("Your talents have been reset by the server.");
|
||||
addSystemChatMessage("Your talents have been reset by the server.");
|
||||
packet.skipAll();
|
||||
|
|
@ -4917,14 +4916,7 @@ void GameHandler::handleLoginVerifyWorld(network::Packet& packet) {
|
|||
|
||||
// Reset talent initialization so the first SMSG_TALENTS_INFO after login
|
||||
// correctly sets the active spec (static locals don't reset across logins).
|
||||
talentsInitialized_ = false;
|
||||
learnedTalents_[0].clear();
|
||||
learnedTalents_[1].clear();
|
||||
learnedGlyphs_[0].fill(0);
|
||||
learnedGlyphs_[1].fill(0);
|
||||
unspentTalentPoints_[0] = 0;
|
||||
unspentTalentPoints_[1] = 0;
|
||||
activeTalentSpec_ = 0;
|
||||
if (spellHandler_) spellHandler_->resetTalentState();
|
||||
|
||||
// Auto-join default chat channels only on first world entry.
|
||||
autoJoinDefaultChannels();
|
||||
|
|
@ -5069,6 +5061,12 @@ void GameHandler::sendRequestVehicleExit() {
|
|||
vehicleId_ = 0; // Optimistically clear; server will confirm via SMSG_PLAYER_VEHICLE_DATA(0)
|
||||
}
|
||||
|
||||
const std::vector<GameHandler::EquipmentSetInfo>& GameHandler::getEquipmentSets() const {
|
||||
if (inventoryHandler_) return inventoryHandler_->getEquipmentSets();
|
||||
static const std::vector<EquipmentSetInfo> empty;
|
||||
return empty;
|
||||
}
|
||||
|
||||
bool GameHandler::supportsEquipmentSets() const {
|
||||
return inventoryHandler_ && inventoryHandler_->supportsEquipmentSets();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -698,7 +698,7 @@ void InventoryHandler::handleLootResponse(network::Packet& packet) {
|
|||
const bool wotlkLoot = isActiveExpansion("wotlk");
|
||||
if (!LootResponseParser::parse(packet, currentLoot_, wotlkLoot)) return;
|
||||
const bool hasLoot = !currentLoot_.items.empty() || currentLoot_.gold > 0;
|
||||
if (!hasLoot && owner_.casting && owner_.currentCastSpellId != 0 && lastInteractedGoGuid_ != 0) {
|
||||
if (!hasLoot && owner_.isCasting() && owner_.getCurrentCastSpellId() != 0 && lastInteractedGoGuid_ != 0) {
|
||||
LOG_DEBUG("Ignoring empty SMSG_LOOT_RESPONSE during gather cast");
|
||||
return;
|
||||
}
|
||||
|
|
@ -1500,14 +1500,30 @@ void InventoryHandler::refreshMailList() {
|
|||
|
||||
void InventoryHandler::sendMail(const std::string& recipient, const std::string& subject,
|
||||
const std::string& body, uint64_t money, uint64_t cod) {
|
||||
if (owner_.state != WorldState::IN_WORLD || !owner_.socket || mailboxGuid_ == 0) return;
|
||||
std::vector<uint64_t> itemGuids;
|
||||
for (const auto& a : mailAttachments_) {
|
||||
if (a.occupied()) itemGuids.push_back(a.itemGuid);
|
||||
if (owner_.state != WorldState::IN_WORLD) {
|
||||
LOG_WARNING("sendMail: not in world");
|
||||
return;
|
||||
}
|
||||
auto packet = SendMailPacket::build(mailboxGuid_, recipient, subject, body, money, cod,
|
||||
itemGuids);
|
||||
if (!owner_.socket) {
|
||||
LOG_WARNING("sendMail: no socket");
|
||||
return;
|
||||
}
|
||||
if (mailboxGuid_ == 0) {
|
||||
LOG_WARNING("sendMail: mailboxGuid_ is 0 (mailbox closed?)");
|
||||
return;
|
||||
}
|
||||
// Collect attached item GUIDs
|
||||
std::vector<uint64_t> itemGuids;
|
||||
for (const auto& att : mailAttachments_) {
|
||||
if (att.occupied()) {
|
||||
itemGuids.push_back(att.itemGuid);
|
||||
}
|
||||
}
|
||||
auto packet = owner_.packetParsers_->buildSendMail(mailboxGuid_, recipient, subject, body, money, cod, itemGuids);
|
||||
LOG_INFO("sendMail: to='", recipient, "' subject='", subject, "' money=", money,
|
||||
" attachments=", itemGuids.size(), " mailboxGuid=", mailboxGuid_);
|
||||
owner_.socket->send(packet);
|
||||
clearMailAttachments();
|
||||
}
|
||||
|
||||
bool InventoryHandler::attachItemFromBackpack(int backpackIndex) {
|
||||
|
|
|
|||
|
|
@ -431,7 +431,7 @@ void MovementHandler::sendMovement(Opcode opcode) {
|
|||
const bool wasMoving = (movementInfo.flags & kMoveMask) != 0;
|
||||
|
||||
// Cancel any timed (non-channeled) cast the moment the player starts moving.
|
||||
if (owner_.casting && !owner_.castIsChannel) {
|
||||
if (owner_.isCasting() && !owner_.isChanneling()) {
|
||||
const bool isPositionalMove =
|
||||
opcode == Opcode::MSG_MOVE_START_FORWARD ||
|
||||
opcode == Opcode::MSG_MOVE_START_BACKWARD ||
|
||||
|
|
@ -798,7 +798,7 @@ void MovementHandler::dismount() {
|
|||
owner_.socket->send(pkt);
|
||||
LOG_INFO("Sent CMSG_CANCEL_AURA (mount spell ", savedMountAura, ") — Classic fallback");
|
||||
} else {
|
||||
for (const auto& a : owner_.playerAuras) {
|
||||
for (const auto& a : owner_.getPlayerAuras()) {
|
||||
if (!a.isEmpty() && a.maxDurationMs < 0 && a.casterGuid == owner_.playerGuid) {
|
||||
auto pkt = CancelAuraPacket::build(a.spellId);
|
||||
owner_.socket->send(pkt);
|
||||
|
|
@ -1808,6 +1808,9 @@ void MovementHandler::handleTeleportAck(network::Packet& packet) {
|
|||
movementInfo.orientation = core::coords::serverToCanonicalYaw(orientation);
|
||||
movementInfo.flags = 0;
|
||||
|
||||
// Clear cast bar on teleport — SpellHandler owns the casting_ flag
|
||||
if (owner_.spellHandler_) owner_.spellHandler_->resetCastState();
|
||||
|
||||
if (owner_.socket) {
|
||||
network::Packet ack(wireOpcode(Opcode::MSG_MOVE_TELEPORT_ACK));
|
||||
const bool legacyGuidAck =
|
||||
|
|
@ -1869,10 +1872,7 @@ void MovementHandler::handleNewWorld(network::Packet& packet) {
|
|||
owner_.clearHostileAttackers();
|
||||
owner_.stopAutoAttack();
|
||||
owner_.tabCycleStale = true;
|
||||
owner_.casting = false;
|
||||
owner_.castIsChannel = false;
|
||||
owner_.currentCastSpellId = 0;
|
||||
owner_.castTimeRemaining = 0.0f;
|
||||
owner_.resetCastState();
|
||||
owner_.craftQueueSpellId_ = 0;
|
||||
owner_.craftQueueRemaining_ = 0;
|
||||
owner_.queuedSpellId_ = 0;
|
||||
|
|
@ -1941,12 +1941,7 @@ void MovementHandler::handleNewWorld(network::Packet& packet) {
|
|||
owner_.areaTriggerCheckTimer_ = -5.0f;
|
||||
owner_.areaTriggerSuppressFirst_ = true;
|
||||
owner_.stopAutoAttack();
|
||||
owner_.casting = false;
|
||||
owner_.castIsChannel = false;
|
||||
owner_.currentCastSpellId = 0;
|
||||
owner_.pendingGameObjectInteractGuid_ = 0;
|
||||
owner_.lastInteractedGoGuid_ = 0;
|
||||
owner_.castTimeRemaining = 0.0f;
|
||||
owner_.resetCastState();
|
||||
owner_.craftQueueSpellId_ = 0;
|
||||
owner_.craftQueueRemaining_ = 0;
|
||||
owner_.queuedSpellId_ = 0;
|
||||
|
|
|
|||
|
|
@ -1221,7 +1221,6 @@ void SocialHandler::handleGroupDecline(network::Packet& packet) {
|
|||
|
||||
void SocialHandler::handleGroupList(network::Packet& packet) {
|
||||
const bool hasRoles = isActiveExpansion("wotlk");
|
||||
const uint32_t prevCount = partyData.memberCount;
|
||||
const uint8_t prevLootMethod = partyData.lootMethod;
|
||||
const bool wasInGroup = !partyData.isEmpty();
|
||||
partyData = GroupListData{};
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ void SpellHandler::registerOpcodes(DispatchTable& table) {
|
|||
table[Opcode::SMSG_ACHIEVEMENT_EARNED] = [this](network::Packet& packet) {
|
||||
handleAchievementEarned(packet);
|
||||
};
|
||||
table[Opcode::SMSG_EQUIPMENT_SET_LIST] = [this](network::Packet& packet) { handleEquipmentSetList(packet); };
|
||||
// SMSG_EQUIPMENT_SET_LIST — owned by InventoryHandler::registerOpcodes
|
||||
|
||||
// ---- Cast result / spell visuals / cooldowns / modifiers ----
|
||||
table[Opcode::SMSG_CAST_RESULT] = [this](network::Packet& p) { handleCastResult(p); };
|
||||
|
|
@ -1423,43 +1423,7 @@ void SpellHandler::handleAchievementEarned(network::Packet& packet) {
|
|||
owner_.addonEventCallback_("ACHIEVEMENT_EARNED", {std::to_string(achievementId)});
|
||||
}
|
||||
|
||||
void SpellHandler::handleEquipmentSetList(network::Packet& packet) {
|
||||
if (packet.getSize() - packet.getReadPos() < 4) return;
|
||||
uint32_t count = packet.readUInt32();
|
||||
if (count > 10) {
|
||||
LOG_WARNING("SMSG_EQUIPMENT_SET_LIST: unexpected count ", count, ", ignoring");
|
||||
packet.setReadPos(packet.getSize());
|
||||
return;
|
||||
}
|
||||
equipmentSets_.clear();
|
||||
equipmentSets_.reserve(count);
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
if (packet.getSize() - packet.getReadPos() < 16) break;
|
||||
EquipmentSet es;
|
||||
es.setGuid = packet.readUInt64();
|
||||
es.setId = packet.readUInt32();
|
||||
es.name = packet.readString();
|
||||
es.iconName = packet.readString();
|
||||
es.ignoreSlotMask = packet.readUInt32();
|
||||
for (int slot = 0; slot < 19; ++slot) {
|
||||
if (packet.getSize() - packet.getReadPos() < 8) break;
|
||||
es.itemGuids[slot] = packet.readUInt64();
|
||||
}
|
||||
equipmentSets_.push_back(std::move(es));
|
||||
}
|
||||
// Populate public-facing info
|
||||
equipmentSetInfo_.clear();
|
||||
equipmentSetInfo_.reserve(equipmentSets_.size());
|
||||
for (const auto& es : equipmentSets_) {
|
||||
EquipmentSetInfo info;
|
||||
info.setGuid = es.setGuid;
|
||||
info.setId = es.setId;
|
||||
info.name = es.name;
|
||||
info.iconName = es.iconName;
|
||||
equipmentSetInfo_.push_back(std::move(info));
|
||||
}
|
||||
LOG_INFO("SMSG_EQUIPMENT_SET_LIST: ", equipmentSets_.size(), " equipment sets received");
|
||||
}
|
||||
// SMSG_EQUIPMENT_SET_LIST — moved to InventoryHandler
|
||||
|
||||
// ============================================================
|
||||
// Pet spell methods (moved from GameHandler)
|
||||
|
|
@ -1645,6 +1609,17 @@ void SpellHandler::resetCastState() {
|
|||
owner_.lastInteractedGoGuid_ = 0;
|
||||
}
|
||||
|
||||
void SpellHandler::resetTalentState() {
|
||||
talentsInitialized_ = false;
|
||||
learnedTalents_[0].clear();
|
||||
learnedTalents_[1].clear();
|
||||
learnedGlyphs_[0].fill(0);
|
||||
learnedGlyphs_[1].fill(0);
|
||||
unspentTalentPoints_[0] = 0;
|
||||
unspentTalentPoints_[1] = 0;
|
||||
activeTalentSpec_ = 0;
|
||||
}
|
||||
|
||||
void SpellHandler::clearUnitCaches() {
|
||||
unitCastStates_.clear();
|
||||
unitAurasCache_.clear();
|
||||
|
|
|
|||
|
|
@ -226,10 +226,8 @@ bool CharacterRenderer::initialize(VkContext* ctx, VkDescriptorSetLayout perFram
|
|||
|
||||
// --- Load shaders ---
|
||||
rendering::VkShaderModule charVert, charFrag;
|
||||
charVert.loadFromFile(device, "assets/shaders/character.vert.spv");
|
||||
charFrag.loadFromFile(device, "assets/shaders/character.frag.spv");
|
||||
|
||||
if (!charVert.isValid() || !charFrag.isValid()) {
|
||||
if (!charVert.loadFromFile(device, "assets/shaders/character.vert.spv") ||
|
||||
!charFrag.loadFromFile(device, "assets/shaders/character.frag.spv")) {
|
||||
LOG_ERROR("Character: Missing required shaders, cannot initialize");
|
||||
return false;
|
||||
}
|
||||
|
|
@ -3287,10 +3285,8 @@ void CharacterRenderer::recreatePipelines() {
|
|||
|
||||
// --- Load shaders ---
|
||||
rendering::VkShaderModule charVert, charFrag;
|
||||
charVert.loadFromFile(device, "assets/shaders/character.vert.spv");
|
||||
charFrag.loadFromFile(device, "assets/shaders/character.frag.spv");
|
||||
|
||||
if (!charVert.isValid() || !charFrag.isValid()) {
|
||||
if (!charVert.loadFromFile(device, "assets/shaders/character.vert.spv") ||
|
||||
!charFrag.loadFromFile(device, "assets/shaders/character.frag.spv")) {
|
||||
LOG_ERROR("CharacterRenderer::recreatePipelines: missing required shaders");
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -273,9 +273,12 @@ void ChargeEffect::recreatePipelines() {
|
|||
// ---- Rebuild ribbon trail pipeline (TRIANGLE_STRIP) ----
|
||||
{
|
||||
VkShaderModule vertModule;
|
||||
vertModule.loadFromFile(device, "assets/shaders/charge_ribbon.vert.spv");
|
||||
VkShaderModule fragModule;
|
||||
fragModule.loadFromFile(device, "assets/shaders/charge_ribbon.frag.spv");
|
||||
if (!vertModule.loadFromFile(device, "assets/shaders/charge_ribbon.vert.spv") ||
|
||||
!fragModule.loadFromFile(device, "assets/shaders/charge_ribbon.frag.spv")) {
|
||||
LOG_ERROR("ChargeEffect::recreatePipelines: failed to load ribbon shader modules");
|
||||
return;
|
||||
}
|
||||
|
||||
VkPipelineShaderStageCreateInfo vertStage = vertModule.stageInfo(VK_SHADER_STAGE_VERTEX_BIT);
|
||||
VkPipelineShaderStageCreateInfo fragStage = fragModule.stageInfo(VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
|
|
@ -323,9 +326,12 @@ void ChargeEffect::recreatePipelines() {
|
|||
// ---- Rebuild dust puff pipeline (POINT_LIST) ----
|
||||
{
|
||||
VkShaderModule vertModule;
|
||||
vertModule.loadFromFile(device, "assets/shaders/charge_dust.vert.spv");
|
||||
VkShaderModule fragModule;
|
||||
fragModule.loadFromFile(device, "assets/shaders/charge_dust.frag.spv");
|
||||
if (!vertModule.loadFromFile(device, "assets/shaders/charge_dust.vert.spv") ||
|
||||
!fragModule.loadFromFile(device, "assets/shaders/charge_dust.frag.spv")) {
|
||||
LOG_ERROR("ChargeEffect::recreatePipelines: failed to load dust shader modules");
|
||||
return;
|
||||
}
|
||||
|
||||
VkPipelineShaderStageCreateInfo vertStage = vertModule.stageInfo(VK_SHADER_STAGE_VERTEX_BIT);
|
||||
VkPipelineShaderStageCreateInfo fragStage = fragModule.stageInfo(VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
|
|
|
|||
|
|
@ -158,9 +158,12 @@ void LensFlare::recreatePipelines() {
|
|||
}
|
||||
|
||||
VkShaderModule vertModule;
|
||||
vertModule.loadFromFile(device, "assets/shaders/lens_flare.vert.spv");
|
||||
VkShaderModule fragModule;
|
||||
fragModule.loadFromFile(device, "assets/shaders/lens_flare.frag.spv");
|
||||
if (!vertModule.loadFromFile(device, "assets/shaders/lens_flare.vert.spv") ||
|
||||
!fragModule.loadFromFile(device, "assets/shaders/lens_flare.frag.spv")) {
|
||||
LOG_ERROR("LensFlare::recreatePipelines: failed to load shader modules");
|
||||
return;
|
||||
}
|
||||
|
||||
VkPipelineShaderStageCreateInfo vertStage = vertModule.stageInfo(VK_SHADER_STAGE_VERTEX_BIT);
|
||||
VkPipelineShaderStageCreateInfo fragStage = fragModule.stageInfo(VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
|
|
|
|||
|
|
@ -277,9 +277,12 @@ void Lightning::recreatePipelines() {
|
|||
// ---- Rebuild bolt pipeline (LINE_STRIP) ----
|
||||
{
|
||||
VkShaderModule vertModule;
|
||||
vertModule.loadFromFile(device, "assets/shaders/lightning_bolt.vert.spv");
|
||||
VkShaderModule fragModule;
|
||||
fragModule.loadFromFile(device, "assets/shaders/lightning_bolt.frag.spv");
|
||||
if (!vertModule.loadFromFile(device, "assets/shaders/lightning_bolt.vert.spv") ||
|
||||
!fragModule.loadFromFile(device, "assets/shaders/lightning_bolt.frag.spv")) {
|
||||
LOG_ERROR("Lightning::recreatePipelines: failed to load bolt shader modules");
|
||||
return;
|
||||
}
|
||||
|
||||
VkPipelineShaderStageCreateInfo vertStage = vertModule.stageInfo(VK_SHADER_STAGE_VERTEX_BIT);
|
||||
VkPipelineShaderStageCreateInfo fragStage = fragModule.stageInfo(VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
|
|
@ -315,9 +318,12 @@ void Lightning::recreatePipelines() {
|
|||
// ---- Rebuild flash pipeline (TRIANGLE_STRIP) ----
|
||||
{
|
||||
VkShaderModule vertModule;
|
||||
vertModule.loadFromFile(device, "assets/shaders/lightning_flash.vert.spv");
|
||||
VkShaderModule fragModule;
|
||||
fragModule.loadFromFile(device, "assets/shaders/lightning_flash.frag.spv");
|
||||
if (!vertModule.loadFromFile(device, "assets/shaders/lightning_flash.vert.spv") ||
|
||||
!fragModule.loadFromFile(device, "assets/shaders/lightning_flash.frag.spv")) {
|
||||
LOG_ERROR("Lightning::recreatePipelines: failed to load flash shader modules");
|
||||
return;
|
||||
}
|
||||
|
||||
VkPipelineShaderStageCreateInfo vertStage = vertModule.stageInfo(VK_SHADER_STAGE_VERTEX_BIT);
|
||||
VkPipelineShaderStageCreateInfo fragStage = fragModule.stageInfo(VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
|
|
|
|||
|
|
@ -157,9 +157,12 @@ void MountDust::recreatePipelines() {
|
|||
}
|
||||
|
||||
VkShaderModule vertModule;
|
||||
vertModule.loadFromFile(device, "assets/shaders/mount_dust.vert.spv");
|
||||
VkShaderModule fragModule;
|
||||
fragModule.loadFromFile(device, "assets/shaders/mount_dust.frag.spv");
|
||||
if (!vertModule.loadFromFile(device, "assets/shaders/mount_dust.vert.spv") ||
|
||||
!fragModule.loadFromFile(device, "assets/shaders/mount_dust.frag.spv")) {
|
||||
LOG_ERROR("MountDust::recreatePipelines: failed to load shader modules");
|
||||
return;
|
||||
}
|
||||
|
||||
VkPipelineShaderStageCreateInfo vertStage = vertModule.stageInfo(VK_SHADER_STAGE_VERTEX_BIT);
|
||||
VkPipelineShaderStageCreateInfo fragStage = fragModule.stageInfo(VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
|
|
|
|||
|
|
@ -193,9 +193,12 @@ void QuestMarkerRenderer::recreatePipelines() {
|
|||
}
|
||||
|
||||
VkShaderModule vertModule;
|
||||
vertModule.loadFromFile(device, "assets/shaders/quest_marker.vert.spv");
|
||||
VkShaderModule fragModule;
|
||||
fragModule.loadFromFile(device, "assets/shaders/quest_marker.frag.spv");
|
||||
if (!vertModule.loadFromFile(device, "assets/shaders/quest_marker.vert.spv") ||
|
||||
!fragModule.loadFromFile(device, "assets/shaders/quest_marker.frag.spv")) {
|
||||
LOG_ERROR("QuestMarkerRenderer::recreatePipelines: failed to load shader modules");
|
||||
return;
|
||||
}
|
||||
|
||||
VkPipelineShaderStageCreateInfo vertStage = vertModule.stageInfo(VK_SHADER_STAGE_VERTEX_BIT);
|
||||
VkPipelineShaderStageCreateInfo fragStage = fragModule.stageInfo(VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||
|
|
|
|||
|
|
@ -3129,7 +3129,6 @@ bool WMORenderer::checkWallCollision(const glm::vec3& from, const glm::vec3& to,
|
|||
glm::vec3 moveDir = to - from;
|
||||
float moveDistSq = glm::dot(moveDir, moveDir);
|
||||
if (moveDistSq < 1e-6f) return false;
|
||||
float moveDist = std::sqrt(moveDistSq);
|
||||
|
||||
// Player collision parameters — WoW-style horizontal cylinder
|
||||
// Tighter radius when inside for more responsive indoor collision
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue