mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-04-05 04:33:51 +00:00
docs: add why-comments to rendering, packets, and UI code
- charge_effect: explain inversesqrt guard (prevents NaN on stationary character) and dust accumulator rate (30 particles/sec * 16ms) - swim_effects: explain why insect pipeline disables depth test (screen-space sprites must render above water geometry) - packet_parsers_classic: explain spline waypoint cap (DoS prevention) and packed GUID compression format (non-zero bytes only, mask byte) - talent_screen: explain class ID to bitmask conversion (1-indexed WoW class IDs → power-of-2 mask for TalentTab.classMask matching) - auth_screen: explain login music volume reduction (80% so UI sounds remain audible over background track)
This commit is contained in:
parent
e8a4a7402f
commit
92369c1cec
5 changed files with 14 additions and 3 deletions
|
|
@ -282,6 +282,7 @@ bool ClassicPacketParsers::parseMovementBlock(network::Packet& packet, UpdateBlo
|
|||
/*uint32_t splineId =*/ packet.readUInt32();
|
||||
|
||||
uint32_t pointCount = packet.readUInt32();
|
||||
// Cap waypoints to prevent DoS from malformed packets allocating huge arrays
|
||||
if (pointCount > 256) return false;
|
||||
|
||||
// points + endPoint (no splineMode in Classic)
|
||||
|
|
@ -362,7 +363,9 @@ void ClassicPacketParsers::writeMovementPayload(network::Packet& packet, const M
|
|||
|
||||
// Transport data (Classic ONTRANSPORT = 0x02000000, no timestamp)
|
||||
if (wireFlags & ClassicMoveFlags::ONTRANSPORT) {
|
||||
// Packed transport GUID
|
||||
// Packed GUID compression: only transmit non-zero bytes of the 8-byte GUID.
|
||||
// The mask byte indicates which positions are present (bit N = byte N included).
|
||||
// This is the standard WoW packed GUID wire format across all expansions.
|
||||
uint8_t transMask = 0;
|
||||
uint8_t transGuidBytes[8];
|
||||
int transGuidByteCount = 0;
|
||||
|
|
|
|||
|
|
@ -474,11 +474,13 @@ void ChargeEffect::emit(const glm::vec3& position, const glm::vec3& direction) {
|
|||
// Spawn dust puffs at feet
|
||||
glm::vec3 horizDir = glm::vec3(direction.x, direction.y, 0.0f);
|
||||
float horizLenSq = glm::dot(horizDir, horizDir);
|
||||
// Skip dust when character is nearly stationary — prevents NaN from inversesqrt(0)
|
||||
if (horizLenSq < 1e-6f) return;
|
||||
float invHorizLen = glm::inversesqrt(horizLenSq);
|
||||
glm::vec3 backDir = -horizDir * invHorizLen;
|
||||
glm::vec3 sideDir = glm::vec3(-backDir.y, backDir.x, 0.0f);
|
||||
|
||||
// Accumulate ~0.48 per frame at 60fps (30 particles/sec * 16ms); emit when >= 1.0
|
||||
dustAccum_ += 30.0f * 0.016f;
|
||||
while (dustAccum_ >= 1.0f && dustPuffs_.size() < MAX_DUST) {
|
||||
dustAccum_ -= 1.0f;
|
||||
|
|
|
|||
|
|
@ -175,6 +175,8 @@ bool SwimEffects::initialize(VkContext* ctx, VkDescriptorSetLayout perFrameLayou
|
|||
return false;
|
||||
}
|
||||
|
||||
// Depth test disabled — insects are screen-space sprites that must always
|
||||
// render above the water surface regardless of scene geometry.
|
||||
insectPipeline = PipelineBuilder()
|
||||
.setShaders(vertStage, fragStage)
|
||||
.setVertexInput({binding}, attrs)
|
||||
|
|
|
|||
|
|
@ -216,7 +216,9 @@ void AuthScreen::render(auth::AuthHandler& authHandler) {
|
|||
if (music) {
|
||||
if (!loginMusicVolumeAdjusted_) {
|
||||
savedMusicVolume_ = music->getVolume();
|
||||
int loginVolume = (savedMusicVolume_ * 80) / 100; // reduce auth music by 20%
|
||||
// Reduce music to 80% during login so UI button clicks and error sounds
|
||||
// remain audible over the background track
|
||||
int loginVolume = (savedMusicVolume_ * 80) / 100;
|
||||
if (loginVolume < 0) loginVolume = 0;
|
||||
if (loginVolume > 100) loginVolume = 100;
|
||||
music->setVolume(loginVolume);
|
||||
|
|
|
|||
|
|
@ -76,7 +76,9 @@ void TalentScreen::renderTalentTrees(game::GameHandler& gameHandler) {
|
|||
return;
|
||||
}
|
||||
|
||||
// Get talent tabs for this class, sorted by orderIndex
|
||||
// Get talent tabs for this class, sorted by orderIndex.
|
||||
// WoW class IDs are 1-indexed (Warrior=1..Druid=11); convert to bitmask for
|
||||
// TalentTab.classMask matching (Warrior=0x1, Paladin=0x2, Hunter=0x4, etc.)
|
||||
uint32_t classMask = 1u << (playerClass - 1);
|
||||
std::vector<const game::GameHandler::TalentTabEntry*> classTabs;
|
||||
for (const auto& [tabId, tab] : gameHandler.getAllTalentTabs()) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue