From 8318213b975a8f132a8e7b9a16d6e42d99b11892 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Wed, 6 Jul 2011 12:26:45 +0200 Subject: [PATCH] Safe version of reveal (no hell) --- plugins/reveal.cpp | 70 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 62 insertions(+), 8 deletions(-) diff --git a/plugins/reveal.cpp b/plugins/reveal.cpp index 71a2a3a10..54db81916 100644 --- a/plugins/reveal.cpp +++ b/plugins/reveal.cpp @@ -11,6 +11,29 @@ using namespace DFHack; +/* + * Anything that might reveal Hell is unsafe. + */ +bool isSafe(uint32_t x, uint32_t y, uint32_t z, DFHack::Maps *Maps) +{ + DFHack::t_feature *local_feature = NULL; + DFHack::t_feature *global_feature = NULL; + // get features of block + // error -> obviously not safe to manipulate + if(!Maps->ReadFeatures(x,y,z,&local_feature,&global_feature)) + { + return false; + } + // Adamantine tubes and temples lead to Hell + if (local_feature && local_feature->type != DFHack::feature_Other) + return false; + // And Hell *is* Hell. + if (global_feature && global_feature->type == DFHack::feature_Underworld) + return false; + // otherwise it's safe. + return true; +} + struct hideblock { uint32_t x; @@ -22,7 +45,15 @@ struct hideblock // the saved data. we keep map size to check if things still match uint32_t x_max, y_max, z_max; std::vector hidesaved; -bool revealed = false; + +enum revealstate +{ + NOT_REVEALED, + REVEALED, + SAFE_REVEALED +}; + +revealstate revealed = NOT_REVEALED; DFhackCExport command_result reveal(DFHack::Core * c, std::vector & params); DFhackCExport command_result unreveal(DFHack::Core * c, std::vector & params); @@ -36,7 +67,7 @@ DFhackCExport const char * plugin_name ( void ) DFhackCExport command_result plugin_init ( Core * c, std::vector &commands) { commands.clear(); - commands.push_back(PluginCommand("reveal","Reveal the map.",reveal)); + commands.push_back(PluginCommand("reveal","Reveal the map. 'reveal safe' will keep hell hidden.",reveal)); commands.push_back(PluginCommand("unreveal","Revert the map to its previous state.",unreveal)); commands.push_back(PluginCommand("revealtoggle","Reveal/unreveal depending on state.",revealtoggle)); return CR_OK; @@ -45,7 +76,7 @@ DFhackCExport command_result plugin_init ( Core * c, std::vector DFhackCExport command_result plugin_onupdate ( Core * c ) { // if the map is revealed and we're in fortress mode, force the game to pause. - if(revealed) + if(revealed == REVEALED) { DFHack::World *World =c->getWorld(); t_gamemodes gm; @@ -66,11 +97,18 @@ DFhackCExport command_result plugin_shutdown ( Core * c ) DFhackCExport command_result reveal(DFHack::Core * c, std::vector & params) { DFHack::designations40d designations; - if(revealed) + bool no_hell = false; + if(params[0] == "safe") + { + no_hell = true; + } + + if(revealed != NOT_REVEALED) { dfout << "Map is already revealed or this is a different map." << std::endl; return CR_FAILURE; } + c->Suspend(); DFHack::Maps *Maps =c->getMaps(); DFHack::World *World =c->getWorld(); @@ -82,7 +120,6 @@ DFhackCExport command_result reveal(DFHack::Core * c, std::vector & c->Resume(); return CR_FAILURE; } - // init the map if(!Maps->Start()) { dfout << "Can't init map." << std::endl; @@ -90,6 +127,13 @@ DFhackCExport command_result reveal(DFHack::Core * c, std::vector & return CR_FAILURE; } + if(no_hell && !Maps->StartFeatures()) + { + dfout << "Unable to read local features; can't reveal map safely" << std::endl; + c->Resume(); + return CR_FAILURE; + } + Maps->getSize(x_max,y_max,z_max); hidesaved.reserve(x_max * y_max * z_max); for(uint32_t x = 0; x< x_max;x++) @@ -100,6 +144,9 @@ DFhackCExport command_result reveal(DFHack::Core * c, std::vector & { if(Maps->isValidBlock(x,y,z)) { + // in 'no-hell'/'safe' mode, don't reveal blocks with hell and adamantine + if (no_hell && !isSafe(x, y, z, Maps)) + continue; hideblock hb; hb.x = x; hb.y = y; @@ -119,8 +166,15 @@ DFhackCExport command_result reveal(DFHack::Core * c, std::vector & } } } - World->SetPauseState(true); - revealed = true; + if(no_hell) + { + revealed = SAFE_REVEALED; + } + else + { + revealed = REVEALED; + World->SetPauseState(true); + } c->Resume(); dfout << "Map revealed." << std::endl; dfout << "Unpausing can unleash the forces of hell, so it has beed temporarily disabled!" << std::endl; @@ -179,7 +233,7 @@ DFhackCExport command_result unreveal(DFHack::Core * c, std::vector } // give back memory. hidesaved.clear(); - revealed = false; + revealed = NOT_REVEALED; dfout << "Map hidden!" << std::endl; c->Resume(); return CR_OK;