diff options
| author | Petr Mrázek | 2012-03-24 00:13:16 +0100 |
|---|---|---|
| committer | Petr Mrázek | 2012-03-24 00:13:16 +0100 |
| commit | addb5c87aa73fa08258923444a031e011f2e8a50 (patch) | |
| tree | 246dca11f301b840c4d5c438ee8c67248af4980f /plugins/Brushes.h | |
| parent | 078caf363f693a8f7744de85a0539de4f68346cc (diff) | |
| download | dfhack-addb5c87aa73fa08258923444a031e011f2e8a50.tar.gz dfhack-addb5c87aa73fa08258923444a031e011f2e8a50.tar.bz2 dfhack-addb5c87aa73fa08258923444a031e011f2e8a50.tar.xz | |
liquids vs liquidsgo: FIGHT!
liquidsgo WINS, renamed to liquids to not confuse users.
Diffstat (limited to 'plugins/Brushes.h')
| -rw-r--r-- | plugins/Brushes.h | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/plugins/Brushes.h b/plugins/Brushes.h new file mode 100644 index 00000000..73c3a05a --- /dev/null +++ b/plugins/Brushes.h @@ -0,0 +1,178 @@ +#pragma once + +typedef vector <df::coord> coord_vec; +class Brush +{ +public: + virtual ~Brush(){}; + virtual coord_vec points(MapExtras::MapCache & mc,DFHack::DFCoord start) = 0; +}; +/** + * generic 3D rectangle brush. you can specify the dimensions of + * the rectangle and optionally which tile is its 'center' + */ +class RectangleBrush : public Brush +{ +public: + RectangleBrush(int x, int y, int z = 1, int centerx = -1, int centery = -1, int centerz = -1) + { + if(centerx == -1) + cx_ = x/2; + else + cx_ = centerx; + if(centery == -1) + cy_ = y/2; + else + cy_ = centery; + if(centerz == -1) + cz_ = z/2; + else + cz_ = centerz; + x_ = x; + y_ = y; + z_ = z; + }; + coord_vec points(MapExtras::MapCache & mc, DFHack::DFCoord start) + { + coord_vec v; + DFHack::DFCoord iterstart(start.x - cx_, start.y - cy_, start.z - cz_); + DFHack::DFCoord iter = iterstart; + for(int xi = 0; xi < x_; xi++) + { + for(int yi = 0; yi < y_; yi++) + { + for(int zi = 0; zi < z_; zi++) + { + if(mc.testCoord(iter)) + v.push_back(iter); + iter.z++; + } + iter.z = iterstart.z; + iter.y++; + } + iter.y = iterstart.y; + iter.x ++; + } + return v; + }; + ~RectangleBrush(){}; +private: + int x_, y_, z_; + int cx_, cy_, cz_; +}; + +/** + * stupid block brush, legacy. use when you want to apply something to a whole DF map block. + */ +class BlockBrush : public Brush +{ +public: + BlockBrush(){}; + ~BlockBrush(){}; + coord_vec points(MapExtras::MapCache & mc, DFHack::DFCoord start) + { + coord_vec v; + DFHack::DFCoord blockc = start / 16; + DFHack::DFCoord iterc = blockc * 16; + if( !mc.testCoord(start) ) + return v; + auto starty = iterc.y; + for(int xi = 0; xi < 16; xi++) + { + for(int yi = 0; yi < 16; yi++) + { + v.push_back(iterc); + iterc.y++; + } + iterc.y = starty; + iterc.x ++; + } + return v; + }; +}; + +/** + * Column from a position through open space tiles + * example: create a column of magma + */ +class ColumnBrush : public Brush +{ +public: + ColumnBrush(){}; + ~ColumnBrush(){}; + coord_vec points(MapExtras::MapCache & mc, DFHack::DFCoord start) + { + coord_vec v; + bool juststarted = true; + while (mc.testCoord(start)) + { + df::tiletype tt = mc.tiletypeAt(start); + if(DFHack::LowPassable(tt) || juststarted && DFHack::HighPassable(tt)) + { + v.push_back(start); + juststarted = false; + start.z++; + } + else break; + } + return v; + }; +}; + +/** + * Flood-fill water tiles from cursor (for wclean) + * example: remove salt flag from a river + */ +class FloodBrush : public Brush +{ +public: + FloodBrush(Core *c){c_ = c;}; + ~FloodBrush(){}; + coord_vec points(MapExtras::MapCache & mc, DFHack::DFCoord start) + { + coord_vec v; + + std::stack<DFCoord> to_flood; + to_flood.push(start); + + std::set<DFCoord> seen; + + while (!to_flood.empty()) { + DFCoord xy = to_flood.top(); + to_flood.pop(); + + df::tile_designation des = mc.designationAt(xy); + + if (seen.find(xy) == seen.end() + && des.bits.flow_size + && des.bits.liquid_type == tile_liquid::Water) { + v.push_back(xy); + seen.insert(xy); + + maybeFlood(DFCoord(xy.x - 1, xy.y, xy.z), to_flood, mc); + maybeFlood(DFCoord(xy.x + 1, xy.y, xy.z), to_flood, mc); + maybeFlood(DFCoord(xy.x, xy.y - 1, xy.z), to_flood, mc); + maybeFlood(DFCoord(xy.x, xy.y + 1, xy.z), to_flood, mc); + + df::tiletype tt = mc.tiletypeAt(xy); + if (LowPassable(tt)) + { + maybeFlood(DFCoord(xy.x, xy.y, xy.z - 1), to_flood, mc); + } + if (HighPassable(tt)) + { + maybeFlood(DFCoord(xy.x, xy.y, xy.z + 1), to_flood, mc); + } + } + } + + return v; + } +private: + void maybeFlood(DFCoord c, std::stack<DFCoord> &to_flood, MapExtras::MapCache &mc) { + if (mc.testCoord(c)) { + to_flood.push(c); + } + } + Core *c_; +}; |
