diff options
| author | Alexander Gavrilov | 2012-04-14 14:12:59 +0400 |
|---|---|---|
| committer | Alexander Gavrilov | 2012-04-14 14:12:59 +0400 |
| commit | 7a34a89f53071a8368ec5bd064accb10354b6d56 (patch) | |
| tree | 1f5b9c622c9333d092d4ae7420296c35df3f3564 /plugins/burrows.cpp | |
| parent | 2f54a48e6391720c62a62cad9839f3d36a6e7385 (diff) | |
| download | dfhack-7a34a89f53071a8368ec5bd064accb10354b6d56.tar.gz dfhack-7a34a89f53071a8368ec5bd064accb10354b6d56.tar.bz2 dfhack-7a34a89f53071a8368ec5bd064accb10354b6d56.tar.xz | |
Add burrow subcommands to modify burrow unit and tile sets.
Diffstat (limited to 'plugins/burrows.cpp')
| -rw-r--r-- | plugins/burrows.cpp | 262 |
1 files changed, 253 insertions, 9 deletions
diff --git a/plugins/burrows.cpp b/plugins/burrows.cpp index a559573a..c973405e 100644 --- a/plugins/burrows.cpp +++ b/plugins/burrows.cpp @@ -8,6 +8,7 @@ #include "modules/Maps.h" #include "modules/MapCache.h" #include "modules/World.h" +#include "modules/Units.h" #include "TileTypes.h" #include "DataDefs.h" @@ -16,6 +17,7 @@ #include "df/unit.h" #include "df/burrow.h" #include "df/map_block.h" +#include "df/block_burrow.h" #include "df/job.h" #include "df/job_list_link.h" @@ -52,11 +54,28 @@ DFhackCExport command_result plugin_init (color_ostream &out, std::vector <Plugi " burrow disable options...\n" " Enable or disable features of the plugin.\n" " See below for a list and explanation.\n" + " burrow clear-units burrow burrow...\n" + " burrow clear-tiles burrow burrow...\n" + " Removes all units or tiles from the burrows.\n" + " burrow set-units target-burrow src-burrow...\n" + " burrow add-units target-burrow src-burrow...\n" + " burrow remove-units target-burrow src-burrow...\n" + " Adds or removes units in source burrows to/from the target\n" + " burrow. Set is equivalent to clear and add.\n" + " burrow set-tiles target-burrow src-burrow...\n" + " burrow add-tiles target-burrow src-burrow...\n" + " burrow remove-tiles target-burrow src-burrow...\n" + " Adds or removes tiles in source burrows to/from the target\n" + " burrow. In place of a source burrow it is possible to use\n" + " one of the following keywords:\n" + " ABOVE_GROUND, SUBTERRANEAN, INSIDE, OUTSIDE,\n" + " LIGHT, DARK, HIDDEN, REVEALED\n" "Implemented features:\n" " auto-grow\n" " When a wall inside a burrow with a name ending in '+' is dug\n" " out, the burrow is extended to newly-revealed adjacent walls.\n" - " Digging 1-wide corridors with the miner inside the burrow is SLOW.\n" + " This final '+' may be omitted in burrow name args of commands above.\n" + " Note: Digging 1-wide corridors with the miner inside the burrow is SLOW.\n" )); if (Core::getInstance().isMapLoaded()) @@ -201,11 +220,14 @@ static std::vector<int> grow_burrows; DFhackCExport command_result plugin_onupdate(color_ostream &out) { - if (!active || !auto_grow) + if (!active) return CR_OK; detect_burrow_renames(out); - detect_digging(out); + + if (auto_grow) + detect_digging(out); + return CR_OK; } @@ -213,24 +235,39 @@ DFhackCExport command_result plugin_onupdate(color_ostream &out) * Config and processing */ +static std::map<std::string,int> name_lookup; + static void parse_names() { auto &list = ui->burrows.list; grow_burrows.clear(); + name_lookup.clear(); for (size_t i = 0; i < list.size(); i++) { auto burrow = list[i]; - if (!burrow->name.empty() && burrow->name[burrow->name.size()-1] == '+') - grow_burrows.push_back(burrow->id); + std::string name = burrow->name; + + if (!name.empty()) + { + name_lookup[name] = burrow->id; + + if (name[name.size()-1] == '+') + { + grow_burrows.push_back(burrow->id); + name.resize(name.size()-1); + } + + if (!name.empty()) + name_lookup[name] = burrow->id; + } } } static void reset_tracking() { - name_burrow_id = -1; diggers.clear(); next_job_id_save = 0; } @@ -244,6 +281,8 @@ static void init_map(color_ostream &out) } parse_names(); + name_burrow_id = -1; + reset_tracking(); active = true; @@ -286,10 +325,7 @@ static void enable_auto_grow(color_ostream &out, bool enable) auto_grow = enable; if (enable) - { - parse_names(); reset_tracking(); - } } static void handle_burrow_rename(color_ostream &out, df::burrow *burrow) @@ -371,6 +407,137 @@ static void handle_dig_complete(color_ostream &out, df::job_type job, df::coord } } +static df::burrow *findByName(color_ostream &out, std::string name, bool silent = false) +{ + int id = -1; + if (name_lookup.count(name)) + id = name_lookup[name]; + auto rv = df::burrow::find(id); + if (!rv && !silent) + out.printerr("Burrow not found: '%s'\n", name.c_str()); + return rv; +} + +static void copyUnits(df::burrow *target, df::burrow *source, bool enable) +{ + if (source == target) + { + if (!enable) + Units::clearBurrowMembers(target); + + return; + } + + for (size_t i = 0; i < source->units.size(); i++) + { + auto unit = df::unit::find(source->units[i]); + + if (unit) + Units::setInBurrow(unit, target, enable); + } +} + +static void copyTiles(df::burrow *target, df::burrow *source, bool enable) +{ + if (source == target) + { + if (!enable) + Maps::clearBurrowTiles(target); + + return; + } + + std::vector<df::map_block*> pvec; + Maps::listBurrowBlocks(&pvec, source); + + for (size_t i = 0; i < pvec.size(); i++) + { + auto block = pvec[i]; + auto smask = Maps::getBlockBurrowMask(source, block); + if (!smask) + continue; + + auto tmask = Maps::getBlockBurrowMask(target, block, enable); + if (!tmask) + continue; + + if (enable) + { + for (int j = 0; j < 16; j++) + tmask->tile_bitmask[j] |= smask->tile_bitmask[j]; + } + else + { + for (int j = 0; j < 16; j++) + tmask->tile_bitmask[j] &= ~smask->tile_bitmask[j]; + + if (!tmask->has_assignments()) + Maps::deleteBlockBurrowMask(target, block, tmask); + } + } +} + +static void setTilesByDesignation(df::burrow *target, df::tile_designation d_mask, + df::tile_designation d_value, bool enable) +{ + auto &blocks = world->map.map_blocks; + + for (size_t i = 0; i < blocks.size(); i++) + { + auto block = blocks[i]; + df::block_burrow *mask = NULL; + + for (int x = 0; x < 16; x++) + { + for (int y = 0; y < 16; y++) + { + if ((block->designation[x][y].whole & d_mask.whole) != d_value.whole) + continue; + + if (!mask) + mask = Maps::getBlockBurrowMask(target, block, enable); + if (!mask) + goto next_block; + + mask->setassignment(x, y, enable); + } + } + + if (mask && !enable && !mask->has_assignments()) + Maps::deleteBlockBurrowMask(target, block, mask); + + next_block:; + } +} + +static bool setTilesByKeyword(df::burrow *target, std::string name, bool enable) +{ + df::tile_designation mask(0); + df::tile_designation value(0); + + if (name == "ABOVE_GROUND") + mask.bits.subterranean = true; + else if (name == "SUBTERRANEAN") + mask.bits.subterranean = value.bits.subterranean = true; + else if (name == "LIGHT") + mask.bits.light = value.bits.light = true; + else if (name == "DARK") + mask.bits.light = true; + else if (name == "OUTSIDE") + mask.bits.outside = value.bits.outside = true; + else if (name == "INSIDE") + mask.bits.outside = true; + else if (name == "HIDDEN") + mask.bits.hidden = value.bits.hidden = true; + else if (name == "REVEALED") + mask.bits.hidden = true; + else + return false; + + setTilesByDesignation(target, mask, value, enable); + return true; +} + static command_result burrow(color_ostream &out, vector <string> ¶meters) { CoreSuspender suspend; @@ -402,6 +569,83 @@ static command_result burrow(color_ostream &out, vector <string> ¶meters) return CR_WRONG_USAGE; } } + else if (cmd == "clear-units") + { + if (parameters.size() < 2) + return CR_WRONG_USAGE; + + for (int i = 1; i < parameters.size(); i++) + { + auto target = findByName(out, parameters[i]); + if (!target) + return CR_WRONG_USAGE; + + Units::clearBurrowMembers(target); + } + } + else if (cmd == "set-units" || cmd == "add-units" || cmd == "remove-units") + { + if (parameters.size() < 3) + return CR_WRONG_USAGE; + + auto target = findByName(out, parameters[1]); + if (!target) + return CR_WRONG_USAGE; + + if (cmd == "set-units") + Units::clearBurrowMembers(target); + + bool enable = (cmd != "remove-units"); + + for (int i = 2; i < parameters.size(); i++) + { + auto source = findByName(out, parameters[i]); + if (!source) + return CR_WRONG_USAGE; + + copyUnits(target, source, enable); + } + } + else if (cmd == "clear-tiles") + { + if (parameters.size() < 2) + return CR_WRONG_USAGE; + + for (int i = 1; i < parameters.size(); i++) + { + auto target = findByName(out, parameters[i]); + if (!target) + return CR_WRONG_USAGE; + + Maps::clearBurrowTiles(target); + } + } + else if (cmd == "set-tiles" || cmd == "add-tiles" || cmd == "remove-tiles") + { + if (parameters.size() < 3) + return CR_WRONG_USAGE; + + auto target = findByName(out, parameters[1]); + if (!target) + return CR_WRONG_USAGE; + + if (cmd == "set-tiles") + Maps::clearBurrowTiles(target); + + bool enable = (cmd != "remove-tiles"); + + for (int i = 2; i < parameters.size(); i++) + { + if (setTilesByKeyword(target, parameters[i], enable)) + continue; + + auto source = findByName(out, parameters[i]); + if (!source) + return CR_WRONG_USAGE; + + copyTiles(target, source, enable); + } + } else { if (!parameters.empty() && cmd != "?") |
