Add damage flash toggle setting and fix map explored zone reveal

Persist damage_flash to settings.cfg; checkbox in Interface > Screen Effects.
Fix world map fog: trust server exploration mask unconditionally when present,
always reveal the current zone immediately regardless of server mask state.
This commit is contained in:
Kelsi 2026-03-12 03:21:49 -07:00
parent 40a98f2436
commit 6cf511aa7f
3 changed files with 22 additions and 5 deletions

View file

@ -74,6 +74,7 @@ private:
ImVec2 nameplateCtxPos_{}; // Screen position of nameplate right-click
uint32_t lastPlayerHp_ = 0; // Previous frame HP for damage flash detection
float damageFlashAlpha_ = 0.0f; // Screen edge flash intensity (fades to 0)
bool damageFlashEnabled_ = true;
float levelUpFlashAlpha_ = 0.0f; // Golden level-up burst effect (fades to 0)
uint32_t levelUpDisplayLevel_ = 0; // Level shown in level-up text

View file

@ -752,7 +752,6 @@ void WorldMap::updateExploration(const glm::vec3& playerRenderPos) {
return (serverExplorationMask[word] & (1u << (bitIndex % 32))) != 0;
};
bool markedAny = false;
if (hasServerExplorationMask) {
exploredZones.clear();
for (int i = 0; i < static_cast<int>(zones.size()); i++) {
@ -761,15 +760,19 @@ void WorldMap::updateExploration(const glm::vec3& playerRenderPos) {
for (uint32_t bit : z.exploreBits) {
if (isBitSet(bit)) {
exploredZones.insert(i);
markedAny = true;
break;
}
}
}
// Always trust the server mask when available — even if empty (unexplored character).
// Also reveal the zone the player is currently standing in so the map isn't pitch-black
// the moment they first enter a new zone (the server bit arrives on the next update).
int curZone = findZoneForPlayer(playerRenderPos);
if (curZone >= 0) exploredZones.insert(curZone);
return;
}
if (markedAny) return;
// Server mask unavailable or empty — fall back to locally-accumulated position tracking.
// Server mask unavailable — fall back to locally-accumulated position tracking.
// Add the zone the player is currently in to the local set and display that.
float wowX = playerRenderPos.y;
float wowY = playerRenderPos.x;

View file

@ -709,7 +709,7 @@ void GameScreen::render(game::GameHandler& gameHandler) {
}
// Detect HP drop (ignore transitions from 0 — entity just spawned or uninitialized)
if (lastPlayerHp_ > 0 && currentHp < lastPlayerHp_ && currentHp > 0)
if (damageFlashEnabled_ && lastPlayerHp_ > 0 && currentHp < lastPlayerHp_ && currentHp > 0)
damageFlashAlpha_ = 1.0f;
lastPlayerHp_ = currentHp;
@ -10626,6 +10626,16 @@ void GameScreen::renderSettingsWindow() {
ImGui::SameLine();
ImGui::TextDisabled("(ms indicator near minimap)");
ImGui::Spacing();
ImGui::SeparatorText("Screen Effects");
ImGui::Spacing();
if (ImGui::Checkbox("Damage Flash", &damageFlashEnabled_)) {
if (!damageFlashEnabled_) damageFlashAlpha_ = 0.0f;
saveSettings();
}
ImGui::SameLine();
ImGui::TextDisabled("(red vignette on taking damage)");
ImGui::EndChild();
ImGui::EndTabItem();
}
@ -12290,6 +12300,7 @@ void GameScreen::saveSettings() {
out << "show_left_bar=" << (pendingShowLeftBar ? 1 : 0) << "\n";
out << "right_bar_offset_y=" << pendingRightBarOffsetY << "\n";
out << "left_bar_offset_y=" << pendingLeftBarOffsetY << "\n";
out << "damage_flash=" << (damageFlashEnabled_ ? 1 : 0) << "\n";
// Audio
out << "sound_muted=" << (soundMuted_ ? 1 : 0) << "\n";
@ -12407,6 +12418,8 @@ void GameScreen::loadSettings() {
pendingRightBarOffsetY = std::clamp(std::stof(val), -400.0f, 400.0f);
} else if (key == "left_bar_offset_y") {
pendingLeftBarOffsetY = std::clamp(std::stof(val), -400.0f, 400.0f);
} else if (key == "damage_flash") {
damageFlashEnabled_ = (std::stoi(val) != 0);
}
// Audio
else if (key == "sound_muted") {