diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 65a550018..c26af9a8c 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -134,9 +134,10 @@ if (BUILD_SUPPORTED) DFHACK_PLUGIN(workNow workNow.cpp) #DFHACK_PLUGIN(dfstream dfstream.cpp LINK_LIBRARIES clsocket dfhack-tinythread) DFHACK_PLUGIN(autoSyndrome autoSyndrome.cpp) - DFHACK_PLUGIN(trueTransformation trueTransformation.cpp) + DFHACK_PLUGIN(syndromeTrigger syndromeTrigger.cpp) DFHACK_PLUGIN(infiniteSky infiniteSky.cpp) DFHACK_PLUGIN(createitem createitem.cpp) + DFHACK_PLUGIN(outsideOnly outsideOnly.cpp) endif() diff --git a/plugins/outsideOnly.cpp b/plugins/outsideOnly.cpp new file mode 100644 index 000000000..7707053ca --- /dev/null +++ b/plugins/outsideOnly.cpp @@ -0,0 +1,63 @@ + +#include "Console.h" +#include "Core.h" +#include "DataDefs.h" +#include "Export.h" +#include "PluginManager.h" + +#include "modules/Buildings.h" +#include "modules/EventManager.h" +#include "modules/Maps.h" + +#include "df/coord.h" +#include "df/building.h" +#include "df/building_def.h" +#include "df/map_block.h" +#include "df/tile_designation.h" + +#include + +using namespace DFHack; +using namespace std; + +DFHACK_PLUGIN("outsideOnly"); + +void buildingCreated(color_ostream& out, void* data); + +DFhackCExport command_result plugin_init ( color_ostream &out, std::vector &commands) +{ + EventManager::EventHandler handler(buildingCreated,1); + EventManager::registerListener(EventManager::EventType::BUILDING, handler, plugin_self); + return CR_OK; +} + +// This is called right before the plugin library is removed from memory. +DFhackCExport command_result plugin_shutdown ( color_ostream &out ) +{ + return CR_OK; +} + +void buildingCreated(color_ostream& out, void* data) { + int32_t id = (int32_t)data; + df::building* building = df::building::find(id); + if ( building == NULL ) + return; + + if ( building->getCustomType() < 0 ) + return; + string prefix("OUTSIDE_ONLY"); + df::building_def* def = df::global::world->raws.buildings.all[building->getCustomType()]; + if (def->code.compare(0, prefix.size(), prefix)) { + return; + } + + //now, just check if it was created inside, and if so, scuttle it + df::coord pos(building->centerx,building->centery,building->z); + + df::tile_designation* des = Maps::getTileDesignation(pos); + if ( des->bits.outside ) + return; + + Buildings::deconstruct(building); +} + diff --git a/plugins/trueTransformation.cpp b/plugins/syndromeTrigger.cpp similarity index 51% rename from plugins/trueTransformation.cpp rename to plugins/syndromeTrigger.cpp index 4527871d9..95a1a49cf 100644 --- a/plugins/trueTransformation.cpp +++ b/plugins/syndromeTrigger.cpp @@ -6,6 +6,7 @@ #include "PluginManager.h" #include "modules/EventManager.h" +#include "modules/Once.h" #include "df/caste_raw.h" #include "df/creature_raw.h" @@ -19,7 +20,7 @@ using namespace DFHack; using namespace std; -DFHACK_PLUGIN("trueTransformation"); +DFHACK_PLUGIN("syndromeTrigger"); void syndromeHandler(color_ostream& out, void* ptr); @@ -37,22 +38,73 @@ void syndromeHandler(color_ostream& out, void* ptr) { df::unit* unit = df::unit::find(data->unitId); if (!unit) { - out.print("%s, line %d: couldn't find unit.\n", __FILE__, __LINE__); + if ( DFHack::Once::doOnce("syndromeTrigger_no find unit" ) ) + out.print("%s, line %d: couldn't find unit.\n", __FILE__, __LINE__); return; } df::unit_syndrome* unit_syndrome = unit->syndromes.active[data->syndromeIndex]; + //out.print(" syndrome type %d\n", unit_syndrome->type); df::syndrome* syndrome = df::global::world->raws.syndromes.all[unit_syndrome->type]; - bool foundIt = false; + bool foundPermanent = false; + bool foundCommand = false; + string commandStr; + vector args; int32_t raceId = -1; df::creature_raw* creatureRaw = NULL; int32_t casteId = -1; for ( size_t a = 0; a < syndrome->syn_class.size(); a++ ) { - if ( *syndrome->syn_class[a] == "\\PERMANENT" ) { - foundIt = true; + std::string& clazz = *syndrome->syn_class[a]; + //out.print(" clazz %d = %s\n", a, clazz.c_str()); + if ( foundCommand ) { + if ( commandStr == "" ) { + commandStr = clazz; + continue; + } + stringstream bob; + if ( clazz == "\\LOCATION" ) { + bob << unit->pos.x; + args.push_back(bob.str()); + bob.str(""); + bob.clear(); + + bob << unit->pos.y; + args.push_back(bob.str()); + bob.str(""); + bob.clear(); + + bob << unit->pos.z; + args.push_back(bob.str()); + bob.str(""); + bob.clear(); + } else if ( clazz == "\\UNIT_ID" ) { + bob << unit->id; + args.push_back(bob.str()); + bob.str(""); + bob.clear(); + } else if ( clazz == "\\SYNDROME_ID" ) { + bob << unit_syndrome->type; + args.push_back(bob.str()); + bob.str(""); + bob.clear(); + } else { + args.push_back(clazz); + } + continue; + } + + if ( clazz == "\\COMMAND" ) { + foundCommand = true; + continue; + } + if ( clazz == "\\PERMANENT" ) { + foundPermanent = true; + continue; } - if ( foundIt && raceId == -1 ) { + if ( !foundPermanent ) + continue; + if ( raceId == -1 ) { //find the race with the name string& name = *syndrome->syn_class[a]; for ( size_t b = 0; b < df::global::world->raws.creatures.all.size(); b++ ) { @@ -65,7 +117,7 @@ void syndromeHandler(color_ostream& out, void* ptr) { } continue; } - if ( foundIt && raceId != -1 ) { + if ( raceId != -1 && casteId == -1 ) { string& name = *syndrome->syn_class[a]; for ( size_t b = 0; b < creatureRaw->caste.size(); b++ ) { df::caste_raw* caste = creatureRaw->caste[b]; @@ -74,10 +126,15 @@ void syndromeHandler(color_ostream& out, void* ptr) { casteId = b; break; } - break; + continue; } } - if ( !foundIt || raceId == -1 || casteId == -1 ) + + if ( commandStr != "" ) { + Core::getInstance().runCommand(out, commandStr, args); + } + + if ( !foundPermanent || raceId == -1 || casteId == -1 ) return; unit->enemy.normal_race = raceId;