Merge remote-tracking branch 'suokko/check_jobs_on_mapcache_commit_1229' into develop

develop
lethosor 2018-06-21 15:03:51 -04:00
commit 854f467f56
5 changed files with 94 additions and 57 deletions

@ -52,6 +52,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
- `stockpiles`: ``loadstock`` sets usable and unusable weapon and armor settings
- `stocks`: Remove carried items from stockpile where they were picked up

@ -38,6 +38,8 @@ distribution.
#include "df/item.h"
#include "df/inclusion_type.h"
#include <bitset>
namespace df {
struct world_region_details;
}
@ -127,22 +129,22 @@ public:
/// Arbitrary tag field for flood fills etc.
int16_t &tag(df::coord2d p) {
if (!tags) init_tags();
return index_tile<int16_t&>(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<df::tiletype>(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<int16_t>(basemats->mat_type,p),
index_tile<int16_t>(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 +166,13 @@ public:
int16_t veinMaterialAt(df::coord2d p)
{
if (!basemats) init_tiles(true);
return index_tile<int16_t>(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<uint8_t>(basemats->veintype,p);
return (df::inclusion_type)index_tile(basemats->veintype,p);
}
/** Sets the vein material at the specified tile position.
@ -207,7 +209,7 @@ public:
{
if (!tiles) init_tiles();
if (tiles->con_info)
return index_tile<df::tiletype>(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 +218,8 @@ public:
if (!basemats) init_tiles(true);
if (tiles->con_info)
return t_matpair(
index_tile<int16_t>(tiles->con_info->mat_type,p),
index_tile<int16_t>(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,47 +234,50 @@ public:
{
if (!block) return tiletype::Void;
if (tiles)
return index_tile<df::tiletype>(tiles->raw_tiles,p);
return index_tile<df::tiletype>(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<uint16_t>(temp1,p);
return index_tile(temp1,p);
}
bool setTemp1At(df::coord2d p, uint16_t temp)
{
if(!valid) return false;
dirty_temperatures = true;
index_tile<uint16_t&>(temp1,p) = temp;
index_tile(temp1,p) = temp;
return true;
}
uint16_t temperature2At(df::coord2d p)
{
return index_tile<uint16_t>(temp2,p);
return index_tile(temp2,p);
}
bool setTemp2At(df::coord2d p, uint16_t temp)
{
if(!valid) return false;
dirty_temperatures = true;
index_tile<uint16_t&>(temp2,p) = temp;
index_tile(temp2,p) = temp;
return true;
}
df::tile_designation DesignationAt(df::coord2d p)
{
return index_tile<df::tile_designation>(designation,p);
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<df::tile_designation&>(designation,p) = des;
if(des.bits.dig && block)
index_tile(designation,p) = des;
if((des.bits.dig || des.bits.smooth) && block) {
block->flags.bits.designated = true;
setPriorityAt(p, priority);
}
return true;
}
@ -281,21 +286,21 @@ public:
df::tile_occupancy OccupancyAt(df::coord2d p)
{
return index_tile<df::tile_occupancy>(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<df::tile_occupancy&>(occupancy,p) = des;
index_tile(occupancy,p) = des;
return true;
}
bool getFlagAt(df::coord2d p, df::tile_designation::Mask mask) {
return (index_tile<df::tile_designation&>(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<df::tile_occupancy&>(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 +308,7 @@ public:
int itemCountAt(df::coord2d p)
{
if (!item_counts) init_item_counts();
return index_tile<int>(item_counts,p);
return index_tile(item_counts,p);
}
t_blockflags BlockFlags()
@ -316,7 +321,7 @@ public:
int biomeIndexAt(df::coord2d p);
int layerIndexAt(df::coord2d p) {
return index_tile<df::tile_designation&>(designation,p).bits.geolayer_index;
return index_tile(designation,p).bits.geolayer_index;
}
df::coord2d biomeRegionAt(df::coord2d p);
@ -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<DFCoord, Block *>::iterator p;
for(p = blocks.begin(); p != blocks.end(); p++)
{
p->second->Write();
}
return true;
}
bool WriteAll();
void trash()
{
std::map<DFCoord, Block *>::iterator p;

@ -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<class R, class T> inline R index_tile(T &v, df::coord2d p) {
template<class T> inline auto index_tile(T &v, df::coord2d p)
-> typename std::add_rvalue_reference<decltype(v[0][0])>::type
{
return v[p.x&15][p.y&15];
}

@ -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;
@ -232,7 +236,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<df::tile_designation&>(designation,p);
auto &val = index_tile(designation,p);
bool cur = (val.whole & mask) != 0;
if (cur != set)
{
@ -245,7 +249,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<df::tile_occupancy&>(occupancy,p);
auto &val = index_tile(occupancy,p);
bool cur = (val.whole & mask) != 0;
if (cur != set)
{
@ -1063,7 +1067,7 @@ int MapExtras::Block::biomeIndexAt(df::coord2d p)
if (!block)
return -1;
auto des = index_tile<df::tile_designation>(designation,p);
auto des = index_tile(designation,p);
uint8_t idx = des.bits.biome;
if (idx >= 9)
return -1;
@ -1141,12 +1145,12 @@ bool MapExtras::Block::addItemOnGround(df::item *item)
if (inserted)
{
int &count = index_tile<int&>(item_counts,item->pos);
int &count = index_tile(item_counts,item->pos);
if (count++ == 0)
{
index_tile<df::tile_occupancy&>(occupancy,item->pos).bits.item = true;
index_tile<df::tile_occupancy&>(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 +1170,13 @@ bool MapExtras::Block::removeItemOnGround(df::item *item)
vector_erase_at(block->items, idx);
int &count = index_tile<int&>(item_counts,item->pos);
int &count = index_tile(item_counts,item->pos);
if (--count == 0)
{
index_tile<df::tile_occupancy&>(occupancy,item->pos).bits.item = false;
index_tile(occupancy,item->pos).bits.item = false;
auto &occ = index_tile<df::tile_occupancy&>(block->occupancy,item->pos);
auto &occ = index_tile(block->occupancy,item->pos);
occ.bits.item = false;
@ -1250,6 +1254,38 @@ 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;
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);
}
std::map<DFCoord, Block *>::iterator p;
for(p = blocks.begin(); p != blocks.end(); p++)
{
p->second->Write();
}
return true;
}
MapExtras::Block *MapExtras::MapCache::BlockAt(DFCoord blockcoord)
{
if(!valid)

@ -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<df::tile_designation>(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<uint16_t>(block1->walkable, pos1);
auto tile2 = index_tile<uint16_t>(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<uint16_t>(block1->walkable,pos1) || !index_tile<uint16_t>(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<df::tile_occupancy>(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<df::tile_occupancy>(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<df::tile_occupancy>(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;