feat: add [indoors]/[outdoors] macro conditionals via WMO detection

Add indoor/outdoor state macro conditionals using the renderer's WMO
interior detection. Essential for mount macros that need to select
ground mounts indoors vs flying mounts outdoors. The Renderer now
caches the insideWmo state in playerIndoors_ and exposes it via
isPlayerIndoors(). Updated /macrohelp to list the new conditionals.
This commit is contained in:
Kelsi 2026-03-20 06:29:33 -07:00
parent 114478271e
commit fa82d32a9f
3 changed files with 15 additions and 1 deletions

View file

@ -139,6 +139,7 @@ public:
QuestMarkerRenderer* getQuestMarkerRenderer() const { return questMarkerRenderer.get(); }
SkySystem* getSkySystem() const { return skySystem.get(); }
const std::string& getCurrentZoneName() const { return currentZoneName; }
bool isPlayerIndoors() const { return playerIndoors_; }
VkContext* getVkContext() const { return vkCtx; }
VkDescriptorSetLayout getPerFrameSetLayout() const { return perFrameSetLayout; }
VkRenderPass getShadowRenderPass() const { return shadowRenderPass; }
@ -356,6 +357,7 @@ private:
std::string currentZoneName;
bool inTavern_ = false;
bool inBlacksmith_ = false;
bool playerIndoors_ = false; // Cached WMO inside state for macro conditionals
float musicSwitchCooldown_ = 0.0f;
bool deferredWorldInitEnabled_ = true;
bool deferredWorldInitPending_ = false;

View file

@ -3476,6 +3476,7 @@ void Renderer::update(float deltaTime) {
uint32_t insideWmoId = 0;
const bool insideWmo = canQueryWmo &&
wmoRenderer->isInsideWMO(camPos.x, camPos.y, camPos.z, &insideWmoId);
playerIndoors_ = insideWmo;
// Ambient environmental sounds: fireplaces, water, birds, etc.
if (ambientSoundManager && camera && wmoRenderer && cameraController) {

View file

@ -5772,6 +5772,16 @@ static std::string evaluateMacroConditionals(const std::string& rawArg,
if (c == "pet") return gameHandler.hasPet();
if (c == "nopet") return !gameHandler.hasPet();
// indoors / outdoors — WMO interior detection (affects mount type selection)
if (c == "indoors" || c == "nooutdoors") {
auto* r = core::Application::getInstance().getRenderer();
return r && r->isPlayerIndoors();
}
if (c == "outdoors" || c == "noindoors") {
auto* r = core::Application::getInstance().getRenderer();
return !r || !r->isPlayerIndoors();
}
// group / nogroup — player is in a party or raid
if (c == "group" || c == "party") return gameHandler.isInGroup();
if (c == "nogroup") return !gameHandler.isInGroup();
@ -6131,7 +6141,8 @@ void GameScreen::sendChatMessage(game::GameHandler& gameHandler) {
"--- Macro Conditionals ---",
"Usage: /cast [cond1,cond2] Spell1; [cond3] Spell2; Default",
"State: [combat] [mounted] [swimming] [flying] [stealthed]",
" [channeling] [pet] [group] (prefix no- to negate)",
" [channeling] [pet] [group] [indoors] [outdoors]",
" (prefix no- to negate any condition)",
"Target: [harm] [help] [exists] [noexists] [dead] [nodead]",
" [target=focus] [target=pet] [target=player]",
"Form: [noform] [nostance] [form:0]",