From 6a151353e370c9cec5ac981cc79f4dfe7964cddc Mon Sep 17 00:00:00 2001 From: Pauli Date: Mon, 18 Jun 2018 15:49:27 +0300 Subject: [PATCH 1/4] Use automatic return type for index_tile --- library/include/modules/MapCache.h | 46 +++++++++++++++--------------- library/include/modules/Maps.h | 4 ++- library/modules/MapCache.cpp | 18 ++++++------ library/modules/Maps.cpp | 14 ++++----- 4 files changed, 42 insertions(+), 40 deletions(-) diff --git a/library/include/modules/MapCache.h b/library/include/modules/MapCache.h index 36625719b..10f5d49d8 100644 --- a/library/include/modules/MapCache.h +++ b/library/include/modules/MapCache.h @@ -127,22 +127,22 @@ public: /// Arbitrary tag field for flood fills etc. int16_t &tag(df::coord2d p) { if (!tags) init_tags(); - return index_tile(tags, p); + return index_tile(tags, p); } /// Base layer tile type (i.e. layer stone, veins, feature stone) df::tiletype baseTiletypeAt(df::coord2d p) { if (!tiles) init_tiles(); - return index_tile(tiles->base_tiles,p); + return index_tile(tiles->base_tiles,p); } /// Base layer material (i.e. layer stone, veins, feature stone) t_matpair baseMaterialAt(df::coord2d p) { if (!basemats) init_tiles(true); return t_matpair( - index_tile(basemats->mat_type,p), - index_tile(basemats->mat_index,p) + index_tile(basemats->mat_type,p), + index_tile(basemats->mat_index,p) ); } /// Check if the base layer tile is a vein @@ -164,13 +164,13 @@ public: int16_t veinMaterialAt(df::coord2d p) { if (!basemats) init_tiles(true); - return index_tile(basemats->veinmat,p); + return index_tile(basemats->veinmat,p); } /// Vein type at pos (even if there is no vein tile) df::inclusion_type veinTypeAt(df::coord2d p) { if (!basemats) init_tiles(true); - return (df::inclusion_type)index_tile(basemats->veintype,p); + return (df::inclusion_type)index_tile(basemats->veintype,p); } /** Sets the vein material at the specified tile position. @@ -207,7 +207,7 @@ public: { if (!tiles) init_tiles(); if (tiles->con_info) - return index_tile(tiles->con_info->tiles,p); + return index_tile(tiles->con_info->tiles,p); return baseTiletypeAt(p); } /// Static layer material (i.e. base + constructions) @@ -216,8 +216,8 @@ public: if (!basemats) init_tiles(true); if (tiles->con_info) return t_matpair( - index_tile(tiles->con_info->mat_type,p), - index_tile(tiles->con_info->mat_index,p) + index_tile(tiles->con_info->mat_type,p), + index_tile(tiles->con_info->mat_index,p) ); return baseMaterialAt(p); } @@ -232,45 +232,45 @@ public: { if (!block) return tiletype::Void; if (tiles) - return index_tile(tiles->raw_tiles,p); - return index_tile(block->tiletype,p); + return index_tile(tiles->raw_tiles,p); + return index_tile(block->tiletype,p); } bool setTiletypeAt(df::coord2d, df::tiletype tt, bool force = false); uint16_t temperature1At(df::coord2d p) { - return index_tile(temp1,p); + return index_tile(temp1,p); } bool setTemp1At(df::coord2d p, uint16_t temp) { if(!valid) return false; dirty_temperatures = true; - index_tile(temp1,p) = temp; + index_tile(temp1,p) = temp; return true; } uint16_t temperature2At(df::coord2d p) { - return index_tile(temp2,p); + return index_tile(temp2,p); } bool setTemp2At(df::coord2d p, uint16_t temp) { if(!valid) return false; dirty_temperatures = true; - index_tile(temp2,p) = temp; + index_tile(temp2,p) = temp; return true; } df::tile_designation DesignationAt(df::coord2d p) { - return index_tile(designation,p); + return index_tile(designation,p); } bool setDesignationAt(df::coord2d p, df::tile_designation des) { if(!valid) return false; dirty_designations = true; //printf("setting block %d/%d/%d , %d %d\n",x,y,z, p.x, p.y); - index_tile(designation,p) = des; + index_tile(designation,p) = des; if(des.bits.dig && block) block->flags.bits.designated = true; return true; @@ -281,21 +281,21 @@ public: df::tile_occupancy OccupancyAt(df::coord2d p) { - return index_tile(occupancy,p); + return index_tile(occupancy,p); } bool setOccupancyAt(df::coord2d p, df::tile_occupancy des) { if(!valid) return false; dirty_occupancies = true; - index_tile(occupancy,p) = des; + index_tile(occupancy,p) = des; return true; } bool getFlagAt(df::coord2d p, df::tile_designation::Mask mask) { - return (index_tile(designation,p).whole & mask) != 0; + return (index_tile(designation,p).whole & mask) != 0; } bool getFlagAt(df::coord2d p, df::tile_occupancy::Mask mask) { - return (index_tile(occupancy,p).whole & mask) != 0; + return (index_tile(occupancy,p).whole & mask) != 0; } bool setFlagAt(df::coord2d p, df::tile_designation::Mask mask, bool set); bool setFlagAt(df::coord2d p, df::tile_occupancy::Mask mask, bool set); @@ -303,7 +303,7 @@ public: int itemCountAt(df::coord2d p) { if (!item_counts) init_item_counts(); - return index_tile(item_counts,p); + return index_tile(item_counts,p); } t_blockflags BlockFlags() @@ -316,7 +316,7 @@ public: int biomeIndexAt(df::coord2d p); int layerIndexAt(df::coord2d p) { - return index_tile(designation,p).bits.geolayer_index; + return index_tile(designation,p).bits.geolayer_index; } df::coord2d biomeRegionAt(df::coord2d p); diff --git a/library/include/modules/Maps.h b/library/include/modules/Maps.h index 6b6e62f0a..0c41bf7f6 100644 --- a/library/include/modules/Maps.h +++ b/library/include/modules/Maps.h @@ -167,7 +167,9 @@ typedef uint16_t t_temperatures [16][16]; /** * Index a tile array by a 2D coordinate, clipping it to mod 16 */ -template inline R index_tile(T &v, df::coord2d p) { +template inline auto index_tile(T &v, df::coord2d p) + -> typename std::add_rvalue_reference::type +{ return v[p.x&15][p.y&15]; } diff --git a/library/modules/MapCache.cpp b/library/modules/MapCache.cpp index c0a2e4bed..8ec0ca7b9 100644 --- a/library/modules/MapCache.cpp +++ b/library/modules/MapCache.cpp @@ -232,7 +232,7 @@ MapExtras::Block::BasematInfo::BasematInfo() bool MapExtras::Block::setFlagAt(df::coord2d p, df::tile_designation::Mask mask, bool set) { if(!valid) return false; - auto &val = index_tile(designation,p); + auto &val = index_tile(designation,p); bool cur = (val.whole & mask) != 0; if (cur != set) { @@ -245,7 +245,7 @@ bool MapExtras::Block::setFlagAt(df::coord2d p, df::tile_designation::Mask mask, bool MapExtras::Block::setFlagAt(df::coord2d p, df::tile_occupancy::Mask mask, bool set) { if(!valid) return false; - auto &val = index_tile(occupancy,p); + auto &val = index_tile(occupancy,p); bool cur = (val.whole & mask) != 0; if (cur != set) { @@ -1063,7 +1063,7 @@ int MapExtras::Block::biomeIndexAt(df::coord2d p) if (!block) return -1; - auto des = index_tile(designation,p); + auto des = index_tile(designation,p); uint8_t idx = des.bits.biome; if (idx >= 9) return -1; @@ -1141,12 +1141,12 @@ bool MapExtras::Block::addItemOnGround(df::item *item) if (inserted) { - int &count = index_tile(item_counts,item->pos); + int &count = index_tile(item_counts,item->pos); if (count++ == 0) { - index_tile(occupancy,item->pos).bits.item = true; - index_tile(block->occupancy,item->pos).bits.item = true; + index_tile(occupancy,item->pos).bits.item = true; + index_tile(block->occupancy,item->pos).bits.item = true; } } @@ -1166,13 +1166,13 @@ bool MapExtras::Block::removeItemOnGround(df::item *item) vector_erase_at(block->items, idx); - int &count = index_tile(item_counts,item->pos); + int &count = index_tile(item_counts,item->pos); if (--count == 0) { - index_tile(occupancy,item->pos).bits.item = false; + index_tile(occupancy,item->pos).bits.item = false; - auto &occ = index_tile(block->occupancy,item->pos); + auto &occ = index_tile(block->occupancy,item->pos); occ.bits.item = false; diff --git a/library/modules/Maps.cpp b/library/modules/Maps.cpp index 20255dbe3..54f314db8 100644 --- a/library/modules/Maps.cpp +++ b/library/modules/Maps.cpp @@ -504,7 +504,7 @@ df::coord2d Maps::getBlockTileBiomeRgn(df::map_block *block, df::coord2d pos) if (!block || !world->world_data) return df::coord2d(); - auto des = index_tile(block->designation,pos); + auto des = index_tile(block->designation,pos); unsigned idx = des.bits.biome; if (idx < 9) { @@ -579,8 +579,8 @@ bool Maps::canWalkBetween(df::coord pos1, df::coord pos2) if (!block1 || !block2) return false; - auto tile1 = index_tile(block1->walkable, pos1); - auto tile2 = index_tile(block2->walkable, pos2); + auto tile1 = index_tile(block1->walkable, pos1); + auto tile2 = index_tile(block2->walkable, pos2); return tile1 && tile1 == tile2; } @@ -607,7 +607,7 @@ bool Maps::canStepBetween(df::coord pos1, df::coord pos2) if ( !block1 || !block2 ) return false; - if ( !index_tile(block1->walkable,pos1) || !index_tile(block2->walkable,pos2) ) { + if ( !index_tile(block1->walkable,pos1) || !index_tile(block2->walkable,pos2) ) { return false; } @@ -626,7 +626,7 @@ bool Maps::canStepBetween(df::coord pos1, df::coord pos2) if ( dx == 0 && dy == 0 ) { //check for forbidden hatches and floors and such - df::tile_building_occ upOcc = index_tile(block2->occupancy,pos2).bits.building; + df::tile_building_occ upOcc = index_tile(block2->occupancy,pos2).bits.building; if ( upOcc == tile_building_occ::Impassable || upOcc == tile_building_occ::Obstacle || upOcc == tile_building_occ::Floored ) return false; @@ -659,7 +659,7 @@ bool Maps::canStepBetween(df::coord pos1, df::coord pos2) return false; //unusable ramp //there has to be an unforbidden hatch above the ramp - if ( index_tile(block2->occupancy,pos2).bits.building != tile_building_occ::Dynamic ) + if ( index_tile(block2->occupancy,pos2).bits.building != tile_building_occ::Dynamic ) return false; //note that forbidden hatches have Floored occupancy. unforbidden ones have dynamic occupancy df::building* building = Buildings::findAtTile(pos2); @@ -703,7 +703,7 @@ bool Maps::canStepBetween(df::coord pos1, df::coord pos2) if ( !blockUp ) return false; - df::tile_building_occ occupancy = index_tile(blockUp->occupancy,up).bits.building; + df::tile_building_occ occupancy = index_tile(blockUp->occupancy,up).bits.building; if ( occupancy == tile_building_occ::Obstacle || occupancy == tile_building_occ::Floored || occupancy == tile_building_occ::Impassable ) return false; return true; From 1b5ec7ce693542f61718020ef434687b0a5e9f4e Mon Sep 17 00:00:00 2001 From: Pauli Date: Mon, 18 Jun 2018 15:53:13 +0300 Subject: [PATCH 2/4] Update jobs when committing MapCache changes The map_block->designation.{dig,smooth} are reset to zeros when a job posting is created for the designation. The job is then used to override the designation state in the map_block. To make the new designation set propogate to jobs the job structure would require updating. The update would be possible a complex operation. The simple alternative is to remove the job and let df create a new job in the next tick. Fixes #1229 --- library/include/modules/MapCache.h | 30 ++++++++++++------------- library/modules/MapCache.cpp | 35 +++++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 17 deletions(-) diff --git a/library/include/modules/MapCache.h b/library/include/modules/MapCache.h index 10f5d49d8..73a91d972 100644 --- a/library/include/modules/MapCache.h +++ b/library/include/modules/MapCache.h @@ -38,6 +38,8 @@ distribution. #include "df/item.h" #include "df/inclusion_type.h" +#include + namespace df { struct world_region_details; } @@ -265,14 +267,17 @@ public: { return index_tile(designation,p); } - bool setDesignationAt(df::coord2d p, df::tile_designation des) + bool setDesignationAt(df::coord2d p, df::tile_designation des, int32_t priority = 4000) { if(!valid) return false; dirty_designations = true; + designated_tiles[(p.x&15) + (p.y&15)*16] = true; //printf("setting block %d/%d/%d , %d %d\n",x,y,z, p.x, p.y); index_tile(designation,p) = des; - if(des.bits.dig && block) + if((des.bits.dig || des.bits.smooth) && block) { block->flags.bits.designated = true; + setPriorityAt(p, priority); + } return true; } @@ -342,13 +347,15 @@ private: void init(); - bool valid; + bool valid:1; bool dirty_designations:1; bool dirty_tiles:1; bool dirty_veins:1; bool dirty_temperatures:1; bool dirty_occupancies:1; + std::bitset<16*16> designated_tiles; + DFCoord bcoord; // Custom tags for floodfill @@ -548,13 +555,11 @@ class DFHACK_EXPORT MapCache return b ? b->DesignationAt(tilecoord) : df::tile_designation(); } // priority is optional, only set if >= 0 - bool setDesignationAt (DFCoord tilecoord, df::tile_designation des, int32_t priority = -1) + bool setDesignationAt (DFCoord tilecoord, df::tile_designation des, int32_t priority = 4000) { if (Block *b = BlockAtTile(tilecoord)) { - if (!b->setDesignationAt(tilecoord, des)) - return false; - if (priority >= 0 && b->setPriorityAt(tilecoord, priority)) + if (!b->setDesignationAt(tilecoord, des, priority)) return false; return true; } @@ -599,15 +604,8 @@ class DFHACK_EXPORT MapCache return b ? b->removeItemOnGround(item) : false; } - bool WriteAll() - { - std::map::iterator p; - for(p = blocks.begin(); p != blocks.end(); p++) - { - p->second->Write(); - } - return true; - } + bool WriteAll(); + void trash() { std::map::iterator p; diff --git a/library/modules/MapCache.cpp b/library/modules/MapCache.cpp index 8ec0ca7b9..ec9f69385 100644 --- a/library/modules/MapCache.cpp +++ b/library/modules/MapCache.cpp @@ -45,6 +45,7 @@ using namespace std; #include "modules/Buildings.h" #include "modules/MapCache.h" #include "modules/Maps.h" +#include "modules/Job.h" #include "modules/Materials.h" #include "df/block_burrow.h" @@ -57,6 +58,7 @@ using namespace std; #include "df/burrow.h" #include "df/feature_init.h" #include "df/flow_info.h" +#include "df/job.h" #include "df/plant.h" #include "df/plant_tree_info.h" #include "df/plant_tree_tile.h" @@ -91,7 +93,9 @@ const BiomeInfo MapCache::biome_stub = { #define COPY(a,b) memcpy(&a,&b,sizeof(a)) -MapExtras::Block::Block(MapCache *parent, DFCoord _bcoord) : parent(parent) +MapExtras::Block::Block(MapCache *parent, DFCoord _bcoord) : + parent(parent), + designated_tiles{} { dirty_designations = false; dirty_tiles = false; @@ -1250,6 +1254,35 @@ MapExtras::MapCache::MapCache() } } +bool MapExtras::MapCache::WriteAll() +{ + auto world = df::global::world; + df::job_list_link* job_link = world->jobs.list.next; + df::job_list_link* next = nullptr; + for (;job_link;job_link = next) { + next = job_link->next; + df::job* job = job_link->item; + df::coord pos = job->pos; + df::coord blockpos(pos.x>>4,pos.y>>4,pos.z); + auto iter = blocks.find(blockpos); + if (iter == blocks.end()) + continue; + df::coord2d bpos(pos.x - (blockpos.x<<4),pos.y - (blockpos.y<<4)); + auto block = iter->second; + if (!block->designated_tiles.test(bpos.x+bpos.y*16)) + continue; + // Remove designation job. DF will create a new one in the next tick + // processing. + Job::removeJob(job); + } + std::map::iterator p; + for(p = blocks.begin(); p != blocks.end(); p++) + { + p->second->Write(); + } + return true; +} + MapExtras::Block *MapExtras::MapCache::BlockAt(DFCoord blockcoord) { if(!valid) From 7c9462028221df452ff264bcd9095cc608c242a1 Mon Sep 17 00:00:00 2001 From: Pauli Date: Mon, 18 Jun 2018 16:42:29 +0300 Subject: [PATCH 3/4] Add changelog entry for designation fix --- docs/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog.txt b/docs/changelog.txt index ca7d50538..727980577 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -48,6 +48,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: - `ban-cooking`: fixed errors introduced by kitchen structure changes in 0.44.10-r1 - `remove-stress`: fixed an error when running on soul-less units (e.g. with ``-all``) - `revflood`: stopped revealing tiles adjacent to tiles above open space inappropriately +- `dig`: Fix "Inappropriate dig square" announcements if digging job has been posted ## Misc Improvements - Added script name to messages produced by ``qerror()`` in Lua scripts From bcf9387ce968c7358ef7788c1f5e46ea8064bc2d Mon Sep 17 00:00:00 2001 From: Pauli Date: Mon, 18 Jun 2018 19:50:35 +0300 Subject: [PATCH 4/4] Only remove jobs that were created from a designation --- library/modules/MapCache.cpp | 3 +++ library/xml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/library/modules/MapCache.cpp b/library/modules/MapCache.cpp index ec9f69385..d5c2e6c81 100644 --- a/library/modules/MapCache.cpp +++ b/library/modules/MapCache.cpp @@ -1271,6 +1271,9 @@ bool MapExtras::MapCache::WriteAll() auto block = iter->second; if (!block->designated_tiles.test(bpos.x+bpos.y*16)) continue; + bool is_designed = ENUM_ATTR(job_type,is_designation,job->job_type); + if (!is_designed) + continue; // Remove designation job. DF will create a new one in the next tick // processing. Job::removeJob(job); diff --git a/library/xml b/library/xml index c3025feb8..e8c309ec0 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit c3025feb80c6f8e7441ea5dcf4f463a9cf89cbbd +Subproject commit e8c309ec0ff7ec1b6d1db3945094cf79ce72d4b6