diff options
| author | Caldfir | 2012-04-20 13:42:32 -0700 |
|---|---|---|
| committer | Caldfir | 2012-04-20 13:42:32 -0700 |
| commit | d12be67bcf24c66c66b2e5a4946250da40b4156b (patch) | |
| tree | 18f059e5c119a9bad3d288741e71593e51be6b73 | |
| parent | e0b93a5e334f61060dc02212c079f2bfdf7a5471 (diff) | |
| download | stonesense-d12be67bcf24c66c66b2e5a4946250da40b4156b.tar.gz stonesense-d12be67bcf24c66c66b2e5a4946250da40b4156b.tar.bz2 stonesense-d12be67bcf24c66c66b2e5a4946250da40b4156b.tar.xz | |
Added a second stage hidden block test for each block-hiding mode.
| -rw-r--r-- | MapLoading.cpp | 125 | ||||
| -rw-r--r-- | UserInput.cpp | 2 | ||||
| -rw-r--r-- | commonTypes.h | 2 |
3 files changed, 114 insertions, 15 deletions
diff --git a/MapLoading.cpp b/MapLoading.cpp index 228c05e..91e4117 100644 --- a/MapLoading.cpp +++ b/MapLoading.cpp @@ -34,6 +34,11 @@ inline bool IDisFloor(int in){ return isFloorTerrain( (tiletype::tiletype) in );;
}
+inline bool IDhasNoFloor(int in){
+ //if not a custom type, do a lookup in dfHack's interface
+ return LowPassable( (tiletype::tiletype) in );;
+}
+
//big look up table
char rampblut[] =
// generated by blutmaker.py
@@ -132,9 +137,6 @@ bool isBlockOnVisibleEdgeOfSegment(WorldSegment* segment, Block* b) if(b->z == segment->z + segment->sizez - 2)
return true;
- if(!(segment->getBlock(b->x, b->y, b->z+1)))
- return true;
-
if (DisplayedRotation == 0 &&
(
b->x == segment->x + segment->sizex - 2
@@ -179,8 +181,35 @@ bool isBlockOnVisibleEdgeOfSegment(WorldSegment* segment, Block* b) return false;
}
-bool areNeighborsVisible(t_designation designations[16][16],int x,int y)
+bool areNeighborsVisible(WorldSegment* segment, Block* b)
{
+ Block* temp;
+
+ temp = segment->getBlock(b->x, b->y, b->z+1);
+ if(!temp || !(temp->designation.bits.hidden))
+ return true;
+
+ temp = segment->getBlock(b->x+1, b->y, b->z);
+ if(temp && !(temp->designation.bits.hidden))
+ return true;
+ temp = segment->getBlock(b->x-1, b->y, b->z);
+ if(temp && !(temp->designation.bits.hidden))
+ return true;
+ temp = segment->getBlock(b->x, b->y+1, b->z);
+ if(temp && !(temp->designation.bits.hidden))
+ return true;
+ temp = segment->getBlock(b->x, b->y-1, b->z);
+ if(temp && !(temp->designation.bits.hidden))
+ return true;
+return false;
+}
+
+bool areCellNeighborsVisible(t_designation designations[16][16],int x,int y)
+{
+ //don't do anything if this is the edge of the cell
+ if(x==0 || y==0 || x==15 || y==15)
+ return true;
+ //otherwise look at the neighbors and try to remove what we can
if(designations[x-1][y-1].bits.hidden == false)
return true;
if(designations[x-1][y].bits.hidden == false)
@@ -200,6 +229,35 @@ bool areNeighborsVisible(t_designation designations[16][16],int x,int y) return false;
}
+/**
+ * returns true iff the block is enclosed by other solid blocks, and is itself solid
+ */
+bool enclosed(WorldSegment* segment, Block* b)
+{
+ if(!IDisWall(b->tileType))
+ return false;
+
+ Block* temp;
+ temp = segment->getBlock(b->x, b->y, b->z+1);
+ if(!temp || IDhasNoFloor(temp->tileType))
+ return false;
+
+ temp = segment->getBlock(b->x+1, b->y, b->z);
+ if(temp && !IDisWall(temp->tileType))
+ return false;
+ temp = segment->getBlock(b->x-1, b->y, b->z);
+ if(temp && !IDisWall(temp->tileType))
+ return false;
+ temp = segment->getBlock(b->x, b->y+1, b->z);
+ if(temp && !IDisWall(temp->tileType))
+ return false;
+ temp = segment->getBlock(b->x, b->y-1, b->z);
+ if(temp && !IDisWall(temp->tileType))
+ return false;
+
+ return true;
+}
+
void ReadCellToSegment(DFHack::Core& DF, WorldSegment& segment, int CellX, int CellY, int CellZ,
uint32_t BoundrySX, uint32_t BoundrySY,
uint32_t BoundryEX, uint32_t BoundryEY,
@@ -366,12 +424,14 @@ void ReadCellToSegment(DFHack::Core& DF, WorldSegment& segment, int CellX, int C isHidden &= !config.show_hidden_blocks;
bool shouldBeIncluded = (!isOpenTerrain(b->tileType) || b->water.index || !trueBlock->designation[lx][ly].bits.outside) && !isHidden;
- //include hidden blocks as shaded black
- if(config.shade_hidden_blocks && isHidden && (isBlockOnVisibleEdgeOfSegment(&segment, b) || areNeighborsVisible(trueBlock->designation, lx, ly)))
- {
- b->building.info.type = (building_type::building_type) BUILDINGTYPE_BLACKBOX;
- shouldBeIncluded= true;
- }
+ //add back in blocks that are candidates for being shaded black (secondary check in beautify_Segment)
+ if( (!shouldBeIncluded)
+ && config.shade_hidden_blocks
+ && isHidden
+ && ( isBlockOnVisibleEdgeOfSegment(&segment, b)
+ || areCellNeighborsVisible(trueBlock->designation, lx, ly)
+ || (!segment.getBlock(b->x, b->y, b->z+1) )))
+ shouldBeIncluded = true;
if( shouldBeIncluded )
{
@@ -837,20 +897,59 @@ WorldSegment* ReadMapSegment(int x, int y, int z, int sizex, int sizey, int size return segment;
}
+/**
+ * checks to see if the block is a potentially viewable hidden block
+ * if so, put the black mask block overtop
+ * if not, makes block not visible
+ */
+void mask_block(WorldSegment * segment, Block* b)
+{
+ //include hidden blocks as shaded black, make remaining invisible
+ if( b->designation.bits.hidden )
+ {
+ if( isBlockOnVisibleEdgeOfSegment(segment, b)
+ || areNeighborsVisible(segment, b) )
+ b->building.info.type = (building_type::building_type) BUILDINGTYPE_BLACKBOX;
+ else b->visible = false;
+ }
+}
+
+/**
+ * checks to see if the block is a potentially viewable hidden block
+ * if not, makes block not visible
+ */
+void unhidden_block(WorldSegment * segment, Block* b)
+{
+ //make blocks that are impossible to see invisible
+ if( b->designation.bits.hidden
+ && (!isBlockOnVisibleEdgeOfSegment(segment, b))
+ && (enclosed(segment, b)) )
+ b->visible = false;
+}
+
void beautify_Segment(WorldSegment * segment)
{
if(!segment)
return;
clock_t start_time = clock();
//do misc beautification
+
uint32_t numblocks = segment->getNumBlocks();
for(uint32_t i=0; i < numblocks; i++){
Block* b = segment->getBlock(i);
- if(config.occlusion == 1)
- occlude_block(b);
- else if(config.occlusion == 2 && b->designation.bits.hidden)
+ //first check to see if this block is possible to be seen
+ if(config.shade_hidden_blocks && (!config.show_hidden_blocks))
+ mask_block(segment, b);
+ else
+ unhidden_block(segment, b);
+
+ if(!b->visible)
+ continue;
+
+ //next see if the block is behind something
+ if(config.occlusion)
occlude_block(b);
if(!b->visible)
diff --git a/UserInput.cpp b/UserInput.cpp index 55cb7ac..96c31fb 100644 --- a/UserInput.cpp +++ b/UserInput.cpp @@ -225,7 +225,7 @@ void doKeys(int Key) timeToReloadSegment = true;
}
if(Key == ALLEGRO_KEY_O){
- config.occlusion = (config.occlusion+1)%3;
+ config.occlusion = !config.occlusion;
timeToReloadSegment = true;
}
if(Key == ALLEGRO_KEY_M){
diff --git a/commonTypes.h b/commonTypes.h index 3af3a5c..40c7c7f 100644 --- a/commonTypes.h +++ b/commonTypes.h @@ -196,7 +196,7 @@ typedef struct bool fog_of_war;
- char occlusion;
+ bool occlusion;
bool block_count;
uint16_t bloodcutoff;
|
