From 3acc4108574332fab7978b0f11b5357e0a158f99 Mon Sep 17 00:00:00 2001 From: zilpin Date: Sun, 17 Oct 2010 00:21:18 -0400 Subject: [PATCH 1/7] Tile Types update, and new hellhole n deramp tools in playground --- .gitignore | 2 + library/include/dfhack/DFTileTypes.h | 1798 +++++++++++++++----------- tools/playground/CMakeLists.txt | 28 + tools/playground/deramp.cpp | 128 ++ tools/playground/hellhole.cpp | 426 ++++++ tools/playground/printtiletypes.cpp | 93 ++ 6 files changed, 1704 insertions(+), 771 deletions(-) create mode 100644 tools/playground/deramp.cpp create mode 100644 tools/playground/hellhole.cpp create mode 100644 tools/playground/printtiletypes.cpp diff --git a/.gitignore b/.gitignore index 356bf6399..3d1c650da 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,5 @@ dfhack/python/pydfhack/_pydfhack.so dfhack/python/PyDFHack.egg-info dfhack/python/build dfhack/python/dist + +/cmakeall.bat \ No newline at end of file diff --git a/library/include/dfhack/DFTileTypes.h b/library/include/dfhack/DFTileTypes.h index e3b660711..52c3fb4de 100644 --- a/library/include/dfhack/DFTileTypes.h +++ b/library/include/dfhack/DFTileTypes.h @@ -1,771 +1,1027 @@ -/* -www.sourceforge.net/projects/dfhack -Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any -damages arising from the use of this software. - -Permission is granted to anyone to use this software for any -purpose, including commercial applications, and to alter it and -redistribute it freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must -not claim that you wrote the original software. If you use this -software in a product, an acknowledgment in the product documentation -would be appreciated but is not required. - -2. Altered source versions must be plainly marked as such, and -must not be misrepresented as being the original software. - -3. This notice may not be removed or altered from any source -distribution. -*/ - -#ifndef TILETYPES_H_INCLUDED -#define TILETYPES_H_INCLUDED - -#include "DFPragma.h" - -namespace DFHack -{ - // tile class -- determines the general shape of the tile - enum TileClass - { - EMPTY,// empty - - WALL, - PILLAR, - FORTIFICATION, - - STAIR_UP, - STAIR_DOWN, - STAIR_UPDOWN, - - RAMP,// ramps have no direction - RAMP_TOP,// the top of a ramp. I assume it's used for path finding. - - FLOOR,// generic floor - TREE_DEAD, - TREE_OK, - SAPLING_DEAD, - SAPLING_OK, - SHRUB_DEAD, - SHRUB_OK, - BOULDER, - PEBBLES - }; - // material -- what material the tile is made of - enum TileMaterial - { - AIR,// empty - SOIL,// ordinary soil. material depends on geology - STONE,// ordinary layer stone. material depends on geology - FEATSTONE,// map feature stone. used for things like hell, the hell temple or adamantine tubes. material depends on local/global feature - OBSIDIAN,// cast obsidian - - VEIN,// vein stone. material depends on mineral veins present - ICE,// frozen water... not much to say. you can determine what was on the tile before it froze by looking into the 'ice vein' objects - GRASS,// grass (has 4 variants) - GRASS2,// grass (has 4 variants) - GRASS_DEAD,// dead grass (has 4 variants) - GRASS_DRY,// dry grass (has 4 variants) - DRIFTWOOD,// non-specified wood - normally on top of the local layer stone/soil. - HFS,// the stuff demon pits are made of - this makes them different from ordinary pits. - MAGMA,// material for semi-molten rock and 'magma flow' tiles - CAMPFIRE,// human armies make them when they siege. The original tile may be lost? - FIRE,// burning grass - ASHES,// what remains from a FIRE - CONSTRUCTED,// tile material depends on the construction present - CYAN_GLOW// the glowy stuff that disappears from the demon temple when you take the sword. - }; - // variants are used for tiles, where there are multiple variants of the same - like grass floors - enum TileVariant - { - VAR_1, - VAR_2, - VAR_3, - VAR_4 - }; - - struct TileRow - { - const char * name; - TileClass c; - TileMaterial m; - TileVariant v; - }; - - #define TILE_TYPE_ARRAY_LENGTH 520 - - const TileRow tileTypeTable[TILE_TYPE_ARRAY_LENGTH] = - { - // 0 - {"void",EMPTY, AIR, VAR_1}, - {"ramp top",RAMP_TOP, AIR, VAR_1}, - {"pool",FLOOR, SOIL, VAR_1}, - {0, EMPTY, AIR, VAR_1}, - {0, EMPTY, AIR, VAR_1}, - {0, EMPTY, AIR, VAR_1}, - {0, EMPTY, AIR, VAR_1}, - {0, EMPTY, AIR, VAR_1}, - {0, EMPTY, AIR, VAR_1}, - {0, EMPTY, AIR, VAR_1}, - - // 10 - {0, EMPTY, AIR, VAR_1}, - {0, EMPTY, AIR, VAR_1}, - {0, EMPTY, AIR, VAR_1}, - {0, EMPTY, AIR, VAR_1}, - {0, EMPTY, AIR, VAR_1}, - {0, EMPTY, AIR, VAR_1}, - {0, EMPTY, AIR, VAR_1}, - {0, EMPTY, AIR, VAR_1}, - {0, EMPTY, AIR, VAR_1}, - {"driftwood stack",FLOOR, DRIFTWOOD, VAR_1}, - - // 20 - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {"tree",TREE_OK, SOIL, VAR_1}, - {"ice stair up/down",STAIR_UPDOWN, ICE, VAR_1}, - {"ice stair down",STAIR_DOWN, ICE, VAR_1}, - {"ice stair up",STAIR_UP, ICE, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - - // 30 - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {"empty space",EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {"shrub",SHRUB_OK, SOIL, VAR_1}, - {"chasm",FLOOR, AIR, VAR_1}, - {"obsidian stair up/down",STAIR_UPDOWN, OBSIDIAN, VAR_1}, - {"obsidian stair down",STAIR_DOWN, OBSIDIAN, VAR_1}, - {"obsidian stair up",STAIR_UP, OBSIDIAN, VAR_1}, - {"soil stair up/down",STAIR_UPDOWN, SOIL, VAR_1}, - - // 40 - {"soil stair down",STAIR_DOWN, SOIL, VAR_1}, - {"soil stair up",STAIR_UP, SOIL, VAR_1}, - {"eerie pit",FLOOR, HFS, VAR_1}, - {"smooth stone floor",FLOOR, STONE, VAR_1}, - {"smooth obsidian floor",FLOOR, OBSIDIAN, VAR_1}, - {"smooth featstone? floor",FLOOR, FEATSTONE, VAR_1}, - {"smooth vein floor",FLOOR, VEIN, VAR_1}, - {"smooth ice floor",FLOOR, ICE, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {"grass stair up/down",STAIR_UPDOWN, GRASS, VAR_1}, - - // 50 - {"grass stair down",STAIR_DOWN, GRASS, VAR_1}, - {"grass stair up",STAIR_UP, GRASS, VAR_1}, - {"grass2 stair up/down",STAIR_UPDOWN, GRASS2, VAR_1}, - {"grass2 stair down",STAIR_DOWN, GRASS2, VAR_1}, - {"grass2 stair up",STAIR_UP, GRASS2, VAR_1}, - {"stone stair up/down",STAIR_UPDOWN, STONE, VAR_1}, - {"stone stair down",STAIR_DOWN, STONE, VAR_1}, - {"stone stair up",STAIR_UP, STONE, VAR_1}, - {"vein stair up/down",STAIR_UPDOWN, VEIN, VAR_1}, - {"vein stair down",STAIR_DOWN, VEIN, VAR_1}, - - // 60 - {"vein stair up",STAIR_UP, VEIN, VAR_1}, - {"featstone? stair up/down",STAIR_UPDOWN, FEATSTONE, VAR_1}, - {"featstone? stair down",STAIR_DOWN, FEATSTONE, VAR_1}, - {"featstone? stair up",STAIR_UP, FEATSTONE, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {"stone fortification",FORTIFICATION, STONE, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {"campfire",FLOOR, CAMPFIRE, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - - // 70 - {"fire",FLOOR, FIRE, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {"stone pillar",PILLAR, STONE, VAR_1}, - - //80 - {"obsidian pillar",PILLAR, OBSIDIAN, VAR_1}, - {"featstone? pillar",PILLAR, FEATSTONE, VAR_1}, - {"vein pillar",PILLAR, VEIN, VAR_1}, - {"ice pillar",PILLAR, ICE, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {"waterfall landing",FLOOR, SOIL, VAR_1}, // verify material - - // 90 - {"river source",FLOOR, SOIL, VAR_1}, // verify material - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - - // 100 - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - - // 110 - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - - // 120 - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - - // 130 - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - - // 140 - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - - // 150 - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - - // 160 - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - - // 170 - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {"cracked stone wall" ,WALL, STONE, VAR_1}, - {"damaged stone wall" ,WALL, STONE, VAR_1}, - {"worn stone wall" ,WALL, STONE, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - - // 180 - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - - // 190 - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - - // 200 - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - - // 210 - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {"stone wall" ,WALL, STONE, VAR_1}, - - // 220 - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - - // 230 - {0 ,EMPTY, AIR, VAR_1}, - {"sapling" ,SAPLING_OK, SOIL, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {"dry grass ramp" ,RAMP, GRASS_DRY, VAR_1}, - {"dead grass ramp" ,RAMP, GRASS_DEAD, VAR_1}, - {"grass ramp" ,RAMP, GRASS, VAR_1}, - {"grass ramp" ,RAMP, GRASS2, VAR_1}, - {"stone ramp" ,RAMP, STONE, VAR_1}, - {"obsidian ramp" ,RAMP, OBSIDIAN, VAR_1}, - {"featstone? ramp" ,RAMP, FEATSTONE, VAR_1}, - - // 240 - {"vein ramp" ,RAMP, VEIN, VAR_1}, - {"soil ramp" ,RAMP, SOIL, VAR_1}, - {"ashes" ,FLOOR, ASHES, VAR_1}, - {"ashes" ,FLOOR, ASHES, VAR_2}, - {"ashes" ,FLOOR, ASHES, VAR_3}, - {"ice ramp" ,RAMP, ICE, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - - // 250 - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {"ice floor" ,FLOOR, ICE, VAR_2}, - {"ice floor" ,FLOOR, ICE, VAR_3}, - - // 260 - {"ice floor" ,FLOOR, ICE, VAR_4}, - {"furrowed soil" ,FLOOR, SOIL, VAR_1}, - {"ice floor" ,FLOOR, ICE, VAR_1}, - {"semi-molten rock" ,WALL, MAGMA, VAR_1},// unminable magma wall - {"magma" ,FLOOR, MAGMA, VAR_1}, - {"soil wall" ,WALL, SOIL, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {"glowing floor" ,FLOOR, CYAN_GLOW, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {"smooth obsidian wall RD2",WALL,OBSIDIAN,VAR_1}, - - // 270 - {"smooth obsidian wall R2D",WALL,OBSIDIAN,VAR_1}, - {"smooth obsidian wall R2U",WALL,OBSIDIAN,VAR_1}, - {"smooth obsidian wall RU2",WALL,OBSIDIAN,VAR_1}, - {"smooth obsidian wall L2U",WALL,OBSIDIAN,VAR_1}, - {"smooth obsidian wall LU2",WALL,OBSIDIAN,VAR_1}, - {"smooth obsidian wall L2D",WALL,OBSIDIAN,VAR_1}, - {"smooth obsidian wall LD2",WALL,OBSIDIAN,VAR_1}, - {"smooth obsidian wall LRUD",WALL,OBSIDIAN,VAR_1}, - {"smooth obsidian wall RUD",WALL,OBSIDIAN,VAR_1}, - {"smooth obsidian wall LRD",WALL,OBSIDIAN,VAR_1}, - - // 280 - {"smooth obsidian wall LRU",WALL,OBSIDIAN,VAR_1}, - {"smooth obsidian wall LUD",WALL,OBSIDIAN,VAR_1}, - {"smooth obsidian wall RD",WALL,OBSIDIAN,VAR_1}, - {"smooth obsidian wall RU",WALL,OBSIDIAN,VAR_1}, - {"smooth obsidian wall LU",WALL,OBSIDIAN,VAR_1}, - {"smooth obsidian wall LD",WALL,OBSIDIAN,VAR_1}, - {"smooth obsidian wall UD",WALL,OBSIDIAN,VAR_1}, - {"smooth obsidian wall LR",WALL,OBSIDIAN,VAR_1}, - {"smooth featstone wall RD2",WALL,FEATSTONE,VAR_1}, - {"smooth featstone wall R2D",WALL,FEATSTONE,VAR_1}, - - // 290 - {"smooth featstone wall R2U",WALL,FEATSTONE,VAR_1}, - {"smooth featstone wall RU2",WALL,FEATSTONE,VAR_1}, - {"smooth featstone wall L2U",WALL,FEATSTONE,VAR_1}, - {"smooth featstone wall LU2",WALL,FEATSTONE,VAR_1}, - {"smooth featstone wall L2D",WALL,FEATSTONE,VAR_1}, - {"smooth featstone wall LD2",WALL,FEATSTONE,VAR_1}, - {"smooth featstone wall LRUD",WALL,FEATSTONE,VAR_1}, - {"smooth featstone wall RUD",WALL,FEATSTONE,VAR_1}, - {"smooth featstone wall LRD",WALL,FEATSTONE,VAR_1}, - {"smooth featstone wall LRU",WALL,FEATSTONE,VAR_1}, - - //300 - {"smooth featstone wall LUD",WALL,FEATSTONE,VAR_1}, - {"smooth featstone wall RD",WALL,FEATSTONE,VAR_1}, - {"smooth featstone wall RU",WALL,FEATSTONE,VAR_1}, - {"smooth featstone wall LU",WALL,FEATSTONE,VAR_1}, - {"smooth featstone wall LD",WALL,FEATSTONE,VAR_1}, - {"smooth featstone wall UD",WALL,FEATSTONE,VAR_1}, - {"smooth featstone wall LR",WALL,FEATSTONE,VAR_1}, - {"smooth stone wall RD2",WALL,STONE,VAR_1}, - {"smooth stone wall R2D",WALL,STONE,VAR_1}, - {"smooth stone wall R2U",WALL,STONE,VAR_1}, - - //310 - {"smooth stone wall RU2",WALL,STONE,VAR_1}, - {"smooth stone wall L2U",WALL,STONE,VAR_1}, - {"smooth stone wall LU2",WALL,STONE,VAR_1}, - {"smooth stone wall L2D",WALL,STONE,VAR_1}, - {"smooth stone wall LD2",WALL,STONE,VAR_1}, - {"smooth stone wall LRUD",WALL,STONE,VAR_1}, - {"smooth stone wall RUD",WALL,STONE,VAR_1}, - {"smooth stone wall LRD",WALL,STONE,VAR_1}, - {"smooth stone wall LRU",WALL,STONE,VAR_1}, - {"smooth stone wall LUD",WALL,STONE,VAR_1}, - - //320 - {"smooth stone wall RD",WALL,STONE,VAR_1}, - {"smooth stone wall RU",WALL,STONE,VAR_1}, - {"smooth stone wall LU",WALL,STONE,VAR_1}, - {"smooth stone wall LD",WALL,STONE,VAR_1}, - {"smooth stone wall UD",WALL,STONE,VAR_1}, - {"smooth stone wall LR",WALL,STONE,VAR_1}, - {"obsidian fortification",FORTIFICATION,OBSIDIAN,VAR_1}, - {"featstone? fortification",FORTIFICATION,FEATSTONE,VAR_1}, - {"cracked obsidian wall",WALL,OBSIDIAN,VAR_1}, - {"damaged obsidian wall",WALL,OBSIDIAN,VAR_1}, - - // 330 - {"worn obsidian wall",WALL,OBSIDIAN,VAR_1}, - {"obsidian wall",WALL,OBSIDIAN,VAR_1}, - /*MAPTILE_FEATSTONE_WALL_WORN1, - MAPTILE_FEATSTONE_WALL_WORN2, - MAPTILE_FEATSTONE_WALL_WORN3, - MAPTILE_FEATSTONE_WALL,*/ - {"cracked featstone wall",WALL,STONE,VAR_1}, - {"damaged featstone wall",WALL,STONE,VAR_1}, - {"worn featstone wall",WALL,STONE,VAR_1}, - {"featstone wall",WALL,STONE,VAR_1}, - {"stone floor",FLOOR,STONE,VAR_1}, - {"stone floor",FLOOR,STONE,VAR_2}, - {"stone floor",FLOOR,STONE,VAR_3}, - {"stone floor",FLOOR,STONE,VAR_4}, - - // 340 - {"obsidian floor",FLOOR,OBSIDIAN,VAR_1}, - {"obsidian floor",FLOOR,OBSIDIAN,VAR_2}, - {"obsidian floor",FLOOR,OBSIDIAN,VAR_3}, - {"obsidian floor",FLOOR,OBSIDIAN,VAR_4}, - {"featstone floor 1",FLOOR,FEATSTONE,VAR_1}, - {"featstone floor 2",FLOOR,FEATSTONE,VAR_2}, - {"featstone floor 3",FLOOR,FEATSTONE,VAR_3}, - {"featstone floor 4",FLOOR,FEATSTONE,VAR_4}, - {"grass 1",FLOOR,GRASS,VAR_1}, - {"grass 2",FLOOR,GRASS,VAR_2}, - - // 350 - {"grass 3",FLOOR,GRASS,VAR_3}, - {"grass 4",FLOOR,GRASS,VAR_4}, - {"soil floor",FLOOR,SOIL,VAR_1}, - {"soil floor",FLOOR,SOIL,VAR_2}, - {"soil floor",FLOOR,SOIL,VAR_3}, - {"soil floor",FLOOR,SOIL,VAR_4}, - {"wet soil floor",FLOOR,SOIL,VAR_1}, - {"wet soil floor",FLOOR,SOIL,VAR_2}, - {"wet soil floor",FLOOR,SOIL,VAR_3}, - {"wet soil floor",FLOOR,SOIL,VAR_4}, - - // 360 - {"ice fortification",FORTIFICATION,ICE,VAR_1}, - {"cracked ice wall",WALL,ICE,VAR_1}, - {"damaged ice wall",WALL,ICE,VAR_1}, - {"worn ice wall",WALL,ICE,VAR_1}, - {"ice wall",WALL,ICE,VAR_1}, - {"river N",FLOOR,SOIL,VAR_1}, - {"river S",FLOOR,SOIL,VAR_1}, - {"river E",FLOOR,SOIL,VAR_1}, - {"river W",FLOOR,SOIL,VAR_1}, - {"river NW",FLOOR,SOIL,VAR_1}, - - //370 - {"river NE",FLOOR,SOIL,VAR_1}, - {"river SW",FLOOR,SOIL,VAR_1}, - {"river SE",FLOOR,SOIL,VAR_1}, - {"stream bed N",FLOOR,SOIL,VAR_1}, - {"stream bed S",FLOOR,SOIL,VAR_1}, - {"stream bed E",FLOOR,SOIL,VAR_1}, - {"stream bed W",FLOOR,SOIL,VAR_1}, - {"stream bed NW",FLOOR,SOIL,VAR_1}, - {"stream bed NE",FLOOR,SOIL,VAR_1}, - {"stream bed SW",FLOOR,SOIL,VAR_1}, - - // 380 - {"stream bed SE",FLOOR,SOIL,VAR_1}, - {"stream top",FLOOR,SOIL,VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {"dry grass 1",FLOOR,GRASS_DRY,VAR_1}, - {"dry grass 2",FLOOR,GRASS_DRY,VAR_2}, - {"dry grass 3",FLOOR,GRASS_DRY,VAR_3}, - - // 390 - {"dry grass 4",FLOOR,GRASS_DRY,VAR_4}, - {"dead tree",TREE_DEAD,SOIL,VAR_1}, - {"dead sapling",SAPLING_DEAD,SOIL,VAR_1}, - {"dead shrub",SHRUB_DEAD,SOIL,VAR_1}, - {"dead grass 1",FLOOR,GRASS_DEAD,VAR_1}, - {"dead grass 2",FLOOR,GRASS_DEAD,VAR_2}, - {"dead grass 3",FLOOR,GRASS_DEAD,VAR_3}, - {"dead grass 4",FLOOR,GRASS_DEAD,VAR_4}, - {"grass B1",FLOOR,GRASS2,VAR_1}, - {"grass B2",FLOOR,GRASS2,VAR_2}, - - // 400 - {"grass B3",FLOOR,GRASS2,VAR_3}, - {"grass B4",FLOOR,GRASS2,VAR_4}, - {"boulder",BOULDER,STONE,VAR_1}, - {"obsidian boulder",BOULDER,OBSIDIAN,VAR_1}, - {"featstone? boulder",BOULDER,FEATSTONE,VAR_1}, - {"pebbles 1",PEBBLES,STONE,VAR_1}, - {"pebbles 2",PEBBLES,STONE,VAR_2}, - {"pebbles 3",PEBBLES,STONE,VAR_3}, - {"pebbles 4",PEBBLES,STONE,VAR_4}, - {"obsidian shards",PEBBLES,OBSIDIAN,VAR_1}, - - // 410 - {"obsidian shards",PEBBLES,OBSIDIAN,VAR_2}, - {"obsidian shards",PEBBLES,OBSIDIAN,VAR_3}, - {"obsidian shards",PEBBLES,OBSIDIAN,VAR_4}, - {"featstone? pebbles",PEBBLES,FEATSTONE,VAR_1}, - {"featstone? pebbles",PEBBLES,FEATSTONE,VAR_2}, - {"featstone? pebbles",PEBBLES,FEATSTONE,VAR_3}, - {"featstone? pebbles",PEBBLES,FEATSTONE,VAR_4}, - {"smooth vein wall",WALL,VEIN,VAR_1}, - {"smooth vein wall",WALL,VEIN,VAR_1}, - {"smooth vein wall",WALL,VEIN,VAR_1}, - - // 420 - {"smooth vein wall",WALL,VEIN,VAR_1}, - {"smooth vein wall",WALL,VEIN,VAR_1}, - {"smooth vein wall",WALL,VEIN,VAR_1}, - {"smooth vein wall",WALL,VEIN,VAR_1}, - {"smooth vein wall",WALL,VEIN,VAR_1}, - {"smooth vein wall",WALL,VEIN,VAR_1}, - {"smooth vein wall",WALL,VEIN,VAR_1}, - {"smooth vein wall",WALL,VEIN,VAR_1}, - {"smooth vein wall",WALL,VEIN,VAR_1}, - {"smooth vein wall",WALL,VEIN,VAR_1}, - - // 430 - {"smooth vein wall",WALL,VEIN,VAR_1}, - {"smooth vein wall",WALL,VEIN,VAR_1}, - {"smooth vein wall",WALL,VEIN,VAR_1}, - {"smooth vein wall",WALL,VEIN,VAR_1}, - {"smooth vein wall",WALL,VEIN,VAR_1}, - {"smooth vein wall",WALL,VEIN,VAR_1}, - {"vein fortification",FORTIFICATION,VEIN,VAR_1}, - {"cracked vein wall",WALL,VEIN,VAR_1}, - {"damaged vein wall",WALL,VEIN,VAR_1}, - {"worn vein wall",WALL,VEIN,VAR_1}, - - // 440 - {"vein wall",WALL,VEIN,VAR_1}, - {"vein floor",FLOOR,VEIN,VAR_1}, - {"vein floor",FLOOR,VEIN,VAR_2}, - {"vein floor",FLOOR,VEIN,VAR_3}, - {"vein floor",FLOOR,VEIN,VAR_4}, - {"vein boulder",BOULDER,VEIN,VAR_1}, - {"vein pebbles",PEBBLES,VEIN,VAR_1}, - {"vein pebbles",PEBBLES,VEIN,VAR_2}, - {"vein pebbles",PEBBLES,VEIN,VAR_3}, - {"vein pebbles",PEBBLES,VEIN,VAR_4}, - - // 450 - {"smooth ice wall",WALL,ICE,VAR_1}, - {"smooth ice wall",WALL,ICE,VAR_1}, - {"smooth ice wall",WALL,ICE,VAR_1}, - {"smooth ice wall",WALL,ICE,VAR_1}, - {"smooth ice wall",WALL,ICE,VAR_1}, - {"smooth ice wall",WALL,ICE,VAR_1}, - {"smooth ice wall",WALL,ICE,VAR_1}, - {"smooth ice wall",WALL,ICE,VAR_1}, - {"smooth ice wall",WALL,ICE,VAR_1}, - {"smooth ice wall",WALL,ICE,VAR_1}, - - // 460 - {"smooth ice wall",WALL,ICE,VAR_1}, - {"smooth ice wall",WALL,ICE,VAR_1}, - {"smooth ice wall",WALL,ICE,VAR_1}, - {"smooth ice wall",WALL,ICE,VAR_1}, - {"smooth ice wall",WALL,ICE,VAR_1}, - {"smooth ice wall",WALL,ICE,VAR_1}, - {"smooth ice wall",WALL,ICE,VAR_1}, - {"smooth ice wall",WALL,ICE,VAR_1}, - {"smooth ice wall",WALL,ICE,VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - - // 470 - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - - // 480 - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - - // 490 - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {0 ,EMPTY, AIR, VAR_1}, - {"constructed floor",FLOOR,CONSTRUCTED, VAR_1}, - {"constructed fortification",FORTIFICATION,CONSTRUCTED, VAR_1}, - {"constructed pillar",PILLAR,CONSTRUCTED, VAR_1}, - {"constructed wall",WALL,CONSTRUCTED, VAR_1}, - {"constructed wall",WALL,CONSTRUCTED, VAR_1}, - {"constructed wall",WALL,CONSTRUCTED, VAR_1}, - {"constructed wall",WALL,CONSTRUCTED, VAR_1}, - - // 500 - {"constructed wall",WALL,CONSTRUCTED, VAR_1}, - {"constructed wall",WALL,CONSTRUCTED, VAR_1}, - {"constructed wall",WALL,CONSTRUCTED, VAR_1}, - {"constructed wall",WALL,CONSTRUCTED, VAR_1}, - {"constructed wall",WALL,CONSTRUCTED, VAR_1}, - {"constructed wall",WALL,CONSTRUCTED, VAR_1}, - {"constructed wall",WALL,CONSTRUCTED, VAR_1}, - {"constructed wall",WALL,CONSTRUCTED, VAR_1}, - {"constructed wall",WALL,CONSTRUCTED, VAR_1}, - {"constructed wall",WALL,CONSTRUCTED, VAR_1}, - - // 510 - {"constructed wall",WALL,CONSTRUCTED, VAR_1}, - {"constructed wall",WALL,CONSTRUCTED, VAR_1}, - {"constructed wall",WALL,CONSTRUCTED, VAR_1}, - {"constructed wall",WALL,CONSTRUCTED, VAR_1}, - {"constructed wall",WALL,CONSTRUCTED, VAR_1}, - {"constructed stair up/down",STAIR_UPDOWN,CONSTRUCTED, VAR_1}, - {"constructed stair down",STAIR_DOWN,CONSTRUCTED, VAR_1}, - {"constructed stair up",STAIR_UP,CONSTRUCTED, VAR_1}, - {"constructed ramp",RAMP,CONSTRUCTED, VAR_1}, - {0 ,EMPTY, AIR, VAR_1} // end - }; - - inline - bool isWallTerrain(int in) - { - return tileTypeTable[in].c >= WALL && tileTypeTable[in].c <= FORTIFICATION ; - } - - inline - bool isFloorTerrain(int in) - { - return tileTypeTable[in].c >= FLOOR && tileTypeTable[in].c <= PEBBLES; - } - - inline - bool isRampTerrain(int in) - { - return tileTypeTable[in].c == RAMP; - } - - inline - bool isStairTerrain(int in) - { - return tileTypeTable[in].c >= STAIR_UP && tileTypeTable[in].c <= STAIR_UPDOWN; - } - - inline - bool isOpenTerrain(int in) - { - return tileTypeTable[in].c == EMPTY; - } - - inline - int getVegetationType(int in) - { - return tileTypeTable[in].c; - } -} - - - -#endif // TILETYPES_H_INCLUDED +/* +www.sourceforge.net/projects/dfhack +Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any +damages arising from the use of this software. + +Permission is granted to anyone to use this software for any +purpose, including commercial applications, and to alter it and +redistribute it freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must +not claim that you wrote the original software. If you use this +software in a product, an acknowledgment in the product documentation +would be appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and +must not be misrepresented as being the original software. + +3. This notice may not be removed or altered from any source +distribution. +*/ + +#ifndef TILETYPES_H_INCLUDED +#define TILETYPES_H_INCLUDED + +#include "DFPragma.h" + +namespace DFHack +{ + + // tile class -- determines the general shape of the tile + // enum and lookup table for string names created using X macros +#define TILECLASS_MACRO \ + X(EMPTY, "") \ + X(WALL, "") \ + X(PILLAR, "") \ + X(FORTIFICATION, "") \ + X(STAIR_UP, "") \ + X(STAIR_DOWN, "") \ + X(STAIR_UPDOWN, "") \ + X(RAMP, "ramps have no direction" ) \ + X(RAMP_TOP, "used for pathing?" ) \ + X(FLOOR, "") \ + X(TREE_DEAD, "") \ + X(TREE_OK, "") \ + X(SAPLING_DEAD, "") \ + X(SAPLING_OK, "") \ + X(SHRUB_DEAD, "") \ + X(SHRUB_OK, "") \ + X(BOULDER, "") \ + X(PEBBLES, "") +//end TILECLASS_MACRO + + //define tile class enum + #define X(name,comment) name, + enum TileClass { + tileclass_invalid=-1, + TILECLASS_MACRO + tileclass_count, + }; + #undef X + + //Visual Studio screams if you don't do this for the const char* arrays + #ifndef char_p + typedef char * char_p; + #endif + + //set tile class string lookup table (e.g. for printing to user) + #define X(name,comment) #name, + const char_p TileClassString[tileclass_count+1] = { + TILECLASS_MACRO + NULL + }; + #undef X + + +#define TILEMATERIAL_MACRO \ + X(AIR, "empty" ) \ + X(SOIL, "ordinary soil. material depends on geology" ) \ + X(STONE, "ordinary layer stone. material depends on geology" ) \ + X(FEATSTONE, "map special stone. used for things like hell, the hell temple or adamantine tubes. material depends on local/global special" ) \ + X(OBSIDIAN, "cast obsidian" ) \ + X(VEIN, "vein stone. material depends on mineral veins present" ) \ + X(ICE, "frozen water... not much to say. you can determine what was on the tile before it froze by looking into the 'ice vein' objects" ) \ + X(GRASS, "grass (has 4 variants)" ) \ + X(GRASS2, "grass (has 4 variants)" ) \ + X(GRASS_DEAD, "dead grass (has 4 variants)" ) \ + X(GRASS_DRY, "dry grass (has 4 variants)" ) \ + X(DRIFTWOOD, "non-specified wood - normally on top of the local layer stone/soil." ) \ + X(HFS, "the stuff demon pits are made of - this makes them different from ordinary pits." ) \ + X(MAGMA, "material for semi-molten rock and 'magma flow' tiles" ) \ + X(CAMPFIRE, "human armies make them when they siege. The original tile may be lost?" ) \ + X(FIRE, "burning grass" ) \ + X(ASHES, "what remains from a FIRE" ) \ + X(CONSTRUCTED,"tile material depends on the construction present" ) \ + X(CYAN_GLOW, "the glowy stuff that disappears from the demon temple when you take the sword." ) +//end TILEMATERIAL_MACRO + + // material enum + #define X(name,comment) name, + enum TileMaterial { + tilematerial_invalid=-1, + TILEMATERIAL_MACRO + tilematerial_count, + }; + #undef X + + //string lookup table (e.g. for printing to user) + #define X(name,comment) #name, + const char_p TileMaterialString[tilematerial_count+1] = { + TILEMATERIAL_MACRO + NULL + }; + #undef X + + + // Special specials of the tile. + // Not the best way to do this, but compatible with existing code. + // When the TileType class gets created, everything should be re-thought. +#define TILESPECIAL_MACRO \ + X(NORMAL, "Default for all type, nothing present" ) \ + X(SPECIAL, "General purpose, for any unique tile which can not otherwise be differenciated" ) \ + X(POOL, "Murky Pool, will gather water from rain" ) \ + X(STREAM, "Streams (and brooks too? maybe?)" ) \ + X(STREAM_TOP, "The walkable surface of a stream/brook" ) \ + X(RIVER_SOURCE, "Rivers Source, when it exists on a map" ) \ + X(RIVER, "Rivers, and their entering and exiting tiles" ) \ + X(WATERFALL, "Special case for Waterfall Landing. How's this used?" ) \ + X(ENDLESS, "Eerie Pit and Old Chasm/Endless Pit" ) \ + X(CRACKED, "Walls being dug" ) \ + X(DAMAGED, "Walls being dug" ) \ + X(WORN, "Walls being dug ??" ) \ + X(SMOOTH, "Walls and floors." ) +//end TILESPECIAL_MACRO + + //special enum + #define X(name,comment) TILE_##name, + enum TileSpecial { + tilespecial_invalid=-1, + TILESPECIAL_MACRO + tilespecial_count, + }; + #undef X + + //string lookup table (e.g. for printing to user) + #define X(name,comment) #name, + const char_p TileSpecialString[tilespecial_count+1] = { + TILESPECIAL_MACRO + NULL + }; + #undef X + + + // variants are used for tiles, where there are multiple variants of the same - like grass floors + enum TileVariant + { + tilevariant_invalid=-1, + VAR_1, //Yes, the value of VAR_1 is 0. It's legacy. Deal with it. + VAR_2, + VAR_3, + VAR_4, + }; + + + //Mainly walls and rivers + //Byte values are used because walls can have either 1 or 2 in any given direction. + const int TileDirectionCount = 4; + union TileDirection + { + uint32_t whole; + unsigned char b[TileDirectionCount]; + struct { + //Maybe should add 'up' and 'down' for Z-levels? + unsigned char north,south,west,east; + }; + + inline TileDirection() + { + whole = 0; + } + TileDirection( uint32_t whole_bits) + { + whole = whole_bits; + } + TileDirection( unsigned char North, unsigned char South, unsigned char West, unsigned char East ) + { + north=North; south=South; east=East; west=West; + } + TileDirection( const char *dir ) + { + //This one just made for fun. + //Supports N S E W + const char *p = dir; + unsigned char *l=NULL; + north=south=east=west=0; + if(!dir) return; + + for( ;*p;++p){ + switch(*p){ + case 'N': //North / Up + case 'n': + ++north; l=&north; break; + case 'S': //South / Down + case 's': + ++south; l=&south; break; + case 'E': //East / Right + case 'e': + ++east; l=&east; break; + case 'W': //West / Left + case 'w': + ++west; l=&west; break; + case '-': + case ' ': + //Explicitly ensure dash and space are ignored. + //Other characters/symbols may be assigned in the future. + break; + default: + if( l && '0' <= *p && '9' >= *p ) + *l += *p - '0'; + break; + } + } + } + + //may be useful for some situations + inline uint32_t sum() const { + return 0L + north + south + east + west; + } + + //Gives a string that represents the direction. + //This is a static string, overwritten with every call! + //Support values > 2 even though they should never happen. + //Copy string if it will be used. + inline char * getStr() const { + static char str[16]; + //type punning trick + *( (uint64_t *)str ) = *( (uint64_t *)"--------" ); + str[8]=0; +#define DIRECTION(x,i,c) \ + if(x){ \ + str[i]=c; \ + if(1==x) ; \ + else if(2==x) str[i+1]=c; \ + else str[i+1]='0'+x; \ + } + + DIRECTION(north,0,'N') + DIRECTION(south,2,'S') + DIRECTION(west,4,'W') + DIRECTION(east,6,'E') +#undef DIRECTION + return str; + } + + + }; + + struct TileRow + { + const char * name; + TileClass c; + TileMaterial m; + TileVariant v; + TileSpecial s; + TileDirection d; + }; + + #define TILE_TYPE_ARRAY_LENGTH 520 + + const TileRow tileTypeTable[TILE_TYPE_ARRAY_LENGTH] = + { + // 0 + {"void",EMPTY, AIR, VAR_1}, + {"ramp top",RAMP_TOP, AIR, VAR_1}, + {"pool",FLOOR, SOIL, VAR_1, TILE_POOL}, + {0, EMPTY, AIR, VAR_1}, + {0, EMPTY, AIR, VAR_1}, + {0, EMPTY, AIR, VAR_1}, + {0, EMPTY, AIR, VAR_1}, + {0, EMPTY, AIR, VAR_1}, + {0, EMPTY, AIR, VAR_1}, + {0, EMPTY, AIR, VAR_1}, + + // 10 + {0, EMPTY, AIR, VAR_1}, + {0, EMPTY, AIR, VAR_1}, + {0, EMPTY, AIR, VAR_1}, + {0, EMPTY, AIR, VAR_1}, + {0, EMPTY, AIR, VAR_1}, + {0, EMPTY, AIR, VAR_1}, + {0, EMPTY, AIR, VAR_1}, + {0, EMPTY, AIR, VAR_1}, + {0, EMPTY, AIR, VAR_1}, + {"driftwood stack",FLOOR, DRIFTWOOD, VAR_1}, + + // 20 + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {"tree",TREE_OK, SOIL, VAR_1}, + {"ice stair up/down",STAIR_UPDOWN, ICE, VAR_1}, + {"ice stair down",STAIR_DOWN, ICE, VAR_1}, + {"ice stair up",STAIR_UP, ICE, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + + // 30 + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {"empty space",EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {"shrub",SHRUB_OK, SOIL, VAR_1}, + {"chasm",FLOOR, AIR, VAR_1, TILE_ENDLESS }, + {"obsidian stair up/down",STAIR_UPDOWN, OBSIDIAN, VAR_1}, + {"obsidian stair down",STAIR_DOWN, OBSIDIAN, VAR_1}, + {"obsidian stair up",STAIR_UP, OBSIDIAN, VAR_1}, + {"soil stair up/down",STAIR_UPDOWN, SOIL, VAR_1}, + + // 40 + {"soil stair down",STAIR_DOWN, SOIL, VAR_1}, + {"soil stair up",STAIR_UP, SOIL, VAR_1}, + {"eerie pit",FLOOR, HFS, VAR_1, TILE_ENDLESS}, + {"smooth stone floor",FLOOR, STONE, VAR_1 , TILE_SMOOTH }, + {"smooth obsidian floor",FLOOR, OBSIDIAN, VAR_1 , TILE_SMOOTH }, + {"smooth featstone? floor",FLOOR, FEATSTONE, VAR_1 , TILE_SMOOTH }, + {"smooth vein floor",FLOOR, VEIN, VAR_1 , TILE_SMOOTH }, + {"smooth ice floor",FLOOR, ICE, VAR_1 , TILE_SMOOTH }, + {0 ,EMPTY, AIR, VAR_1}, + {"grass stair up/down",STAIR_UPDOWN, GRASS, VAR_1}, + + // 50 + {"grass stair down",STAIR_DOWN, GRASS, VAR_1}, + {"grass stair up",STAIR_UP, GRASS, VAR_1}, + {"grass2 stair up/down",STAIR_UPDOWN, GRASS2, VAR_1}, + {"grass2 stair down",STAIR_DOWN, GRASS2, VAR_1}, + {"grass2 stair up",STAIR_UP, GRASS2, VAR_1}, + {"stone stair up/down",STAIR_UPDOWN, STONE, VAR_1}, + {"stone stair down",STAIR_DOWN, STONE, VAR_1}, + {"stone stair up",STAIR_UP, STONE, VAR_1}, + {"vein stair up/down",STAIR_UPDOWN, VEIN, VAR_1}, + {"vein stair down",STAIR_DOWN, VEIN, VAR_1}, + + // 60 + {"vein stair up",STAIR_UP, VEIN, VAR_1}, + {"featstone? stair up/down",STAIR_UPDOWN, FEATSTONE, VAR_1}, + {"featstone? stair down",STAIR_DOWN, FEATSTONE, VAR_1}, + {"featstone? stair up",STAIR_UP, FEATSTONE, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {"stone fortification",FORTIFICATION, STONE, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {"campfire",FLOOR, CAMPFIRE, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + + // 70 + {"fire",FLOOR, FIRE, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {"stone pillar",PILLAR, STONE, VAR_1}, + + //80 + {"obsidian pillar",PILLAR, OBSIDIAN, VAR_1}, + {"featstone? pillar",PILLAR, FEATSTONE, VAR_1}, + {"vein pillar",PILLAR, VEIN, VAR_1}, + {"ice pillar",PILLAR, ICE, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {"waterfall landing",FLOOR, SOIL, VAR_1, TILE_WATERFALL }, // verify material + + // 90 + {"river source",FLOOR, SOIL, VAR_1, TILE_RIVER_SOURCE }, // verify material + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + + // 100 + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + + // 110 + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + + // 120 + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + + // 130 + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + + // 140 + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + + // 150 + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + + // 160 + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + + // 170 + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {"cracked stone wall" ,WALL, STONE, VAR_1, TILE_CRACKED }, + {"damaged stone wall" ,WALL, STONE, VAR_1, TILE_DAMAGED }, + {"worn stone wall" ,WALL, STONE, VAR_1, TILE_WORN }, + {0 ,EMPTY, AIR, VAR_1}, + + // 180 + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + + // 190 + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + + // 200 + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + + // 210 + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {"stone wall" ,WALL, STONE, VAR_1}, + + // 220 + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + + // 230 + {0 ,EMPTY, AIR, VAR_1}, + {"sapling" ,SAPLING_OK, SOIL, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {"dry grass ramp" ,RAMP, GRASS_DRY, VAR_1}, + {"dead grass ramp" ,RAMP, GRASS_DEAD, VAR_1}, + {"grass ramp" ,RAMP, GRASS, VAR_1}, + {"grass ramp" ,RAMP, GRASS2, VAR_1}, + {"stone ramp" ,RAMP, STONE, VAR_1}, + {"obsidian ramp" ,RAMP, OBSIDIAN, VAR_1}, + {"featstone? ramp" ,RAMP, FEATSTONE, VAR_1}, + + // 240 + {"vein ramp" ,RAMP, VEIN, VAR_1}, + {"soil ramp" ,RAMP, SOIL, VAR_1}, + {"ashes" ,FLOOR, ASHES, VAR_1}, + {"ashes" ,FLOOR, ASHES, VAR_2}, + {"ashes" ,FLOOR, ASHES, VAR_3}, + {"ice ramp" ,RAMP, ICE, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + + // 250 + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {"ice floor" ,FLOOR, ICE, VAR_2}, + {"ice floor" ,FLOOR, ICE, VAR_3}, + + // 260 + {"ice floor" ,FLOOR, ICE, VAR_4}, + {"furrowed soil" ,FLOOR, SOIL, VAR_1}, + {"ice floor" ,FLOOR, ICE, VAR_1}, + {"semi-molten rock" ,WALL, MAGMA, VAR_1},// unminable magma wall + {"magma" ,FLOOR, MAGMA, VAR_1}, + {"soil wall" ,WALL, SOIL, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {"glowing floor" ,FLOOR, CYAN_GLOW, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {"smooth obsidian wall RD2",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "--SS--E-" }, + + // 270 + {"smooth obsidian wall R2D",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "--S---EE" }, + {"smooth obsidian wall R2U",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "N-----EE" }, + {"smooth obsidian wall RU2",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "NN----E-" }, + {"smooth obsidian wall L2U",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "N---WW--" }, + {"smooth obsidian wall LU2",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "NN--W---" }, + {"smooth obsidian wall L2D",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "--S-WW--" }, + {"smooth obsidian wall LD2",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "--SSW---" }, + {"smooth obsidian wall LRUD",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH ,"N-S-W-E-" }, + {"smooth obsidian wall RUD",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "N-S---E-" }, + {"smooth obsidian wall LRD",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "--S-W-E-" }, + + // 280 + {"smooth obsidian wall LRU",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "N---W-E-" }, + {"smooth obsidian wall LUD",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "N-S-W---" }, + {"smooth obsidian wall RD",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "--S---E-" }, + {"smooth obsidian wall RU",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "N-----E-" }, + {"smooth obsidian wall LU",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "N---W---" }, + {"smooth obsidian wall LD",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "--S-W---" }, + {"smooth obsidian wall UD",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "N-S-----" }, + {"smooth obsidian wall LR",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "----W-E-" }, + {"smooth featstone wall RD2",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "--SS--E-" }, + {"smooth featstone wall R2D",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "--S---EE" }, + + // 290 + {"smooth featstone wall R2U",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "N-----EE" }, + {"smooth featstone wall RU2",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "NN----E-" }, + {"smooth featstone wall L2U",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "N---WW--" }, + {"smooth featstone wall LU2",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "NN--W---" }, + {"smooth featstone wall L2D",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "--S-WW--" }, + {"smooth featstone wall LD2",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "--SSW---" }, + {"smooth featstone wall LRUD",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH ,"N-S-W-E-" }, + {"smooth featstone wall RUD",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "N-S---E-" }, + {"smooth featstone wall LRD",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "--S-W-E-" }, + {"smooth featstone wall LRU",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "N---W-E-" }, + + //300 + {"smooth featstone wall LUD",WALL,FEATSTONE,VAR_1, TILE_SMOOTH , "N-S-W---" }, + {"smooth featstone wall RD",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "--S---E-" }, + {"smooth featstone wall RU",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "N-----E-" }, + {"smooth featstone wall LU",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "N---W---" }, + {"smooth featstone wall LD",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "--S-W---" }, + {"smooth featstone wall UD",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "N-S-----" }, + {"smooth featstone wall LR",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "----W-E-" }, + {"smooth stone wall RD2",WALL,STONE,VAR_1 , TILE_SMOOTH , "--SS--E-" }, + {"smooth stone wall R2D",WALL,STONE,VAR_1 , TILE_SMOOTH , "--S---EE" }, + {"smooth stone wall R2U",WALL,STONE,VAR_1 , TILE_SMOOTH , "N-----EE" }, + + //310 + {"smooth stone wall RU2",WALL,STONE,VAR_1 , TILE_SMOOTH , "NN----E-" }, + {"smooth stone wall L2U",WALL,STONE,VAR_1 , TILE_SMOOTH , "N---WW--" }, + {"smooth stone wall LU2",WALL,STONE,VAR_1 , TILE_SMOOTH , "NN--W---" }, + {"smooth stone wall L2D",WALL,STONE,VAR_1 , TILE_SMOOTH , "--S-WW--" }, + {"smooth stone wall LD2",WALL,STONE,VAR_1 , TILE_SMOOTH , "--SSW---" }, + {"smooth stone wall LRUD",WALL,STONE,VAR_1 , TILE_SMOOTH , "N-S-W-E-" }, + {"smooth stone wall RUD",WALL,STONE,VAR_1 , TILE_SMOOTH , "N-S---E-" }, + {"smooth stone wall LRD",WALL,STONE,VAR_1 , TILE_SMOOTH , "--S-W-E-" }, + {"smooth stone wall LRU",WALL,STONE,VAR_1 , TILE_SMOOTH , "N---W-E-" }, + {"smooth stone wall LUD",WALL,STONE,VAR_1 , TILE_SMOOTH , "N-S-W---" }, + + //320 + {"smooth stone wall RD",WALL,STONE,VAR_1 , TILE_SMOOTH , "--S---E-" }, + {"smooth stone wall RU",WALL,STONE,VAR_1 , TILE_SMOOTH , "N-----E-" }, + {"smooth stone wall LU",WALL,STONE,VAR_1 , TILE_SMOOTH , "N---W---" }, + {"smooth stone wall LD",WALL,STONE,VAR_1 , TILE_SMOOTH , "--S-W---" }, + {"smooth stone wall UD",WALL,STONE,VAR_1 , TILE_SMOOTH , "N-S-----" }, + {"smooth stone wall LR",WALL,STONE,VAR_1 , TILE_SMOOTH , "----W-E-" }, + {"obsidian fortification",FORTIFICATION,OBSIDIAN,VAR_1}, + {"featstone? fortification",FORTIFICATION,FEATSTONE,VAR_1}, + {"cracked obsidian wall",WALL,OBSIDIAN,VAR_1, TILE_CRACKED }, + {"damaged obsidian wall",WALL,OBSIDIAN,VAR_1, TILE_DAMAGED }, + + // 330 + {"worn obsidian wall",WALL,OBSIDIAN,VAR_1}, + {"obsidian wall",WALL,OBSIDIAN,VAR_1}, + /*MAPTILE_FEATSTONE_WALL_WORN1, + MAPTILE_FEATSTONE_WALL_WORN2, + MAPTILE_FEATSTONE_WALL_WORN3, + MAPTILE_FEATSTONE_WALL,*/ + {"cracked featstone wall",WALL,STONE,VAR_1, TILE_CRACKED }, + {"damaged featstone wall",WALL,STONE,VAR_1, TILE_DAMAGED }, + {"worn featstone wall",WALL,STONE,VAR_1, TILE_WORN }, + {"featstone wall",WALL,STONE,VAR_1}, + {"stone floor",FLOOR,STONE,VAR_1}, + {"stone floor",FLOOR,STONE,VAR_2}, + {"stone floor",FLOOR,STONE,VAR_3}, + {"stone floor",FLOOR,STONE,VAR_4}, + + // 340 + {"obsidian floor",FLOOR,OBSIDIAN,VAR_1}, + {"obsidian floor",FLOOR,OBSIDIAN,VAR_2}, + {"obsidian floor",FLOOR,OBSIDIAN,VAR_3}, + {"obsidian floor",FLOOR,OBSIDIAN,VAR_4}, + {"featstone floor 1",FLOOR,FEATSTONE,VAR_1}, + {"featstone floor 2",FLOOR,FEATSTONE,VAR_2}, + {"featstone floor 3",FLOOR,FEATSTONE,VAR_3}, + {"featstone floor 4",FLOOR,FEATSTONE,VAR_4}, + {"grass 1",FLOOR,GRASS,VAR_1}, + {"grass 2",FLOOR,GRASS,VAR_2}, + + // 350 + {"grass 3",FLOOR,GRASS,VAR_3}, + {"grass 4",FLOOR,GRASS,VAR_4}, + {"soil floor",FLOOR,SOIL,VAR_1}, + {"soil floor",FLOOR,SOIL,VAR_2}, + {"soil floor",FLOOR,SOIL,VAR_3}, + {"soil floor",FLOOR,SOIL,VAR_4}, + {"wet soil floor",FLOOR,SOIL,VAR_1}, + {"wet soil floor",FLOOR,SOIL,VAR_2}, + {"wet soil floor",FLOOR,SOIL,VAR_3}, + {"wet soil floor",FLOOR,SOIL,VAR_4}, + + // 360 + {"ice fortification",FORTIFICATION,ICE,VAR_1}, + {"cracked ice wall",WALL,ICE,VAR_1, TILE_CRACKED}, + {"damaged ice wall",WALL,ICE,VAR_1, TILE_DAMAGED}, + {"worn ice wall",WALL,ICE,VAR_1, TILE_WORN }, + {"ice wall",WALL,ICE,VAR_1}, + {"river N",FLOOR,SOIL,VAR_1, TILE_RIVER , "N" }, + {"river S",FLOOR,SOIL,VAR_1, TILE_RIVER , "S" }, + {"river E",FLOOR,SOIL,VAR_1, TILE_RIVER , "E" }, + {"river W",FLOOR,SOIL,VAR_1, TILE_RIVER , "W" }, + {"river NW",FLOOR,SOIL,VAR_1, TILE_RIVER, "NW"}, + + //370 + {"river NE",FLOOR,SOIL,VAR_1, TILE_RIVER , "NE" }, + {"river SW",FLOOR,SOIL,VAR_1, TILE_RIVER , "SW" }, + {"river SE",FLOOR,SOIL,VAR_1, TILE_RIVER , "SE" }, + {"stream bed N",FLOOR,SOIL,VAR_1, TILE_STREAM , "N" }, + {"stream bed S",FLOOR,SOIL,VAR_1, TILE_STREAM , "S" }, + {"stream bed E",FLOOR,SOIL,VAR_1, TILE_STREAM , "E" }, + {"stream bed W",FLOOR,SOIL,VAR_1, TILE_STREAM , "W" }, + {"stream bed NW",FLOOR,SOIL,VAR_1, TILE_STREAM, "NW" }, + {"stream bed NE",FLOOR,SOIL,VAR_1, TILE_STREAM, "NE" }, + {"stream bed SW",FLOOR,SOIL,VAR_1, TILE_STREAM, "SW" }, + + // 380 + {"stream bed SE",FLOOR,SOIL,VAR_1, TILE_STREAM, "SE" }, + {"stream top",FLOOR,SOIL,VAR_1, TILE_STREAM_TOP }, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {"dry grass 1",FLOOR,GRASS_DRY,VAR_1}, + {"dry grass 2",FLOOR,GRASS_DRY,VAR_2}, + {"dry grass 3",FLOOR,GRASS_DRY,VAR_3}, + + // 390 + {"dry grass 4",FLOOR,GRASS_DRY,VAR_4}, + {"dead tree",TREE_DEAD,SOIL,VAR_1}, + {"dead sapling",SAPLING_DEAD,SOIL,VAR_1}, + {"dead shrub",SHRUB_DEAD,SOIL,VAR_1}, + {"dead grass 1",FLOOR,GRASS_DEAD,VAR_1}, + {"dead grass 2",FLOOR,GRASS_DEAD,VAR_2}, + {"dead grass 3",FLOOR,GRASS_DEAD,VAR_3}, + {"dead grass 4",FLOOR,GRASS_DEAD,VAR_4}, + {"grass B1",FLOOR,GRASS2,VAR_1}, + {"grass B2",FLOOR,GRASS2,VAR_2}, + + // 400 + {"grass B3",FLOOR,GRASS2,VAR_3}, + {"grass B4",FLOOR,GRASS2,VAR_4}, + {"boulder",BOULDER,STONE,VAR_1}, + {"obsidian boulder",BOULDER,OBSIDIAN,VAR_1}, + {"featstone? boulder",BOULDER,FEATSTONE,VAR_1}, + {"pebbles 1",PEBBLES,STONE,VAR_1}, + {"pebbles 2",PEBBLES,STONE,VAR_2}, + {"pebbles 3",PEBBLES,STONE,VAR_3}, + {"pebbles 4",PEBBLES,STONE,VAR_4}, + {"obsidian shards",PEBBLES,OBSIDIAN,VAR_1}, + + // 410 + {"obsidian shards",PEBBLES,OBSIDIAN,VAR_2}, + {"obsidian shards",PEBBLES,OBSIDIAN,VAR_3}, + {"obsidian shards",PEBBLES,OBSIDIAN,VAR_4}, + {"featstone? pebbles",PEBBLES,FEATSTONE,VAR_1}, + {"featstone? pebbles",PEBBLES,FEATSTONE,VAR_2}, + {"featstone? pebbles",PEBBLES,FEATSTONE,VAR_3}, + {"featstone? pebbles",PEBBLES,FEATSTONE,VAR_4}, + {"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "--SS--E-"}, + {"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "--S---EE"}, + {"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "N-----EE" }, + + // 420 + {"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "NN----E-"}, + {"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "N---WW--"}, + {"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "NN--W---"}, + {"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "--S-WW--" }, + {"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "--SSW---"}, + {"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "N-S-W-E-"}, + {"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "N-S---E-"}, + {"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "--S-W-E-"}, + {"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "N---W-E-"}, + {"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "N-S-W---"}, + + // 430 + {"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "--S---E-"}, + {"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "N-----E-"}, + {"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "N---W---"}, + {"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "--S-W---"}, + {"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "N-S-----"}, + {"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "----W-E-"}, + {"vein fortification",FORTIFICATION,VEIN,VAR_1}, + {"cracked vein wall",WALL,VEIN,VAR_1, TILE_CRACKED }, + {"damaged vein wall",WALL,VEIN,VAR_1, TILE_DAMAGED }, + {"worn vein wall",WALL,VEIN,VAR_1 , TILE_WORN }, + + // 440 + {"vein wall",WALL,VEIN,VAR_1}, + {"vein floor",FLOOR,VEIN,VAR_1}, + {"vein floor",FLOOR,VEIN,VAR_2}, + {"vein floor",FLOOR,VEIN,VAR_3}, + {"vein floor",FLOOR,VEIN,VAR_4}, + {"vein boulder",BOULDER,VEIN,VAR_1}, + {"vein pebbles",PEBBLES,VEIN,VAR_1}, + {"vein pebbles",PEBBLES,VEIN,VAR_2}, + {"vein pebbles",PEBBLES,VEIN,VAR_3}, + {"vein pebbles",PEBBLES,VEIN,VAR_4}, + + // 450 + {"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "--SS--E-"}, + {"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "--S---EE" }, + {"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "N-----EE" }, + {"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "NN----E-"}, + {"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "N---WW--" }, + {"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "NN--W---" }, + {"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "--S-WW--" }, + {"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "--SSW---" }, + {"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "N-S-W-E-"}, + {"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "N-S---E-" }, + + // 460 + {"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "--S-W-E-" }, + {"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "N---W-E-" }, + {"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "N-S-W---"}, + {"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "--S---E-"}, + {"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "N-----E-" }, + {"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "N---W---" }, + {"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "--S-W---" }, + {"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "N-S-----" }, + {"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "----W-E-"}, + {0 ,EMPTY, AIR, VAR_1}, + + // 470 + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + + // 480 + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + + // 490 + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {0 ,EMPTY, AIR, VAR_1}, + {"constructed floor",FLOOR,CONSTRUCTED, VAR_1}, + {"constructed fortification",FORTIFICATION,CONSTRUCTED, VAR_1}, + {"constructed pillar",PILLAR,CONSTRUCTED, VAR_1}, + {"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "--SS--E-" }, + {"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "--S---EE" }, + {"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "N-----EE" }, + {"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "NN----E-" }, + + // 500 + {"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "N---WW--" }, + {"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "NN--W---" }, + {"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "--S-WW--" }, + {"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "--SSW---" }, + {"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "N-S-W-E-" }, + {"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "N-S---E-" }, + {"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "--S-W-E-" }, + {"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "N---W-E-" }, + {"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "N-S-W---" }, + {"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "--S---E-" }, + + // 510 + {"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "N-----E-" }, + {"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "N---W---" }, + {"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "--S-W---" }, + {"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "N-S-----" }, + {"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "----W-E-" }, + {"constructed stair up/down",STAIR_UPDOWN,CONSTRUCTED, VAR_1}, + {"constructed stair down",STAIR_DOWN,CONSTRUCTED, VAR_1}, + {"constructed stair up",STAIR_UP,CONSTRUCTED, VAR_1}, + {"constructed ramp",RAMP,CONSTRUCTED, VAR_1}, + {0 ,EMPTY, AIR, VAR_1} // end + }; + + inline + bool isWallTerrain(int in) + { + return tileTypeTable[in].c >= WALL && tileTypeTable[in].c <= FORTIFICATION ; + } + + inline + bool isFloorTerrain(int in) + { + return tileTypeTable[in].c >= FLOOR && tileTypeTable[in].c <= PEBBLES; + } + + inline + bool isRampTerrain(int in) + { + return tileTypeTable[in].c == RAMP; + } + + inline + bool isStairTerrain(int in) + { + return tileTypeTable[in].c >= STAIR_UP && tileTypeTable[in].c <= STAIR_UPDOWN; + } + + inline + bool isOpenTerrain(int in) + { + return tileTypeTable[in].c == EMPTY; + } + + inline + int getVegetationType(int in) + { + return tileTypeTable[in].c; + } + + //zilpin: for convenience, when you'll be using the tile information a lot. + inline const + TileRow * getTileTypeP(int in) + { + if( in<0 || in>=TILE_TYPE_ARRAY_LENGTH ) return NULL; + return ( const TileRow * ) &tileTypeTable[in]; + } + + //zilpin: Find the first tile entry which matches the given search criteria. + //All parameters are optional. + //To omit, use the 'invalid' enum for that type (e.g. tileclass_invalid, tilematerial_invalid, etc) + //For tile directions, pass NULL to omit. + //Returns matching index in tileTypeTable, or -1 if none found. + inline + int32_t findTileType( const TileClass tclass, const TileMaterial tmat, const TileVariant tvar, const TileSpecial tspecial, const TileDirection tdir ) + { + int32_t tt; + for(tt=0;tt-1 ) if( tclass != tileTypeTable[tt].c ) continue; + if( tmat>-1 ) if( tmat != tileTypeTable[tt].m ) continue; + if( tvar>-1 ) if( tvar != tileTypeTable[tt].v ) continue; + if( tspecial>-1 ) if( tspecial != tileTypeTable[tt].s ) continue; + if( tdir.whole ) if( tdir.whole != tileTypeTable[tt].d.whole ) continue; + //Match! + return tt; + } + return -1; + } + //Convenience version of the above, to pass strings as the direction + inline + int32_t findTileType( const TileClass tclass, const TileMaterial tmat, const TileVariant tvar, const TileSpecial tspecial, const char *tdirStr ) + { + if(tdirStr){ + TileDirection tdir(tdirStr); + return findTileType(tclass,tmat,tvar,tspecial, tdir ); + }else{ + return findTileType(tclass,tmat,tvar,tspecial, NULL ); + } + } + + + //zilpin: Find a tile type similar to the one given, but with a different class. + //Useful for tile-editing operations. + //If no match found, returns the sourceType + //Definitely needs improvement for wall directions, etc. + inline + int32_t findSimilarTileType( const int32_t sourceTileType, const TileClass tclass ){ + int32_t tt, maybe=0, match=0; + int value=0, matchv=0; + const TileRow *source = &tileTypeTable[sourceTileType]; + const char * sourcename = source->name; + const uint32_t sourcenameint = *((const uint32_t *)sourcename); + +#ifdef assert + assert( sourceTileType >=0 && sourceTileType < TILE_TYPE_ARRAY_LENGTH ); +#endif + + for(tt=0;tts != tileTypeTable[tt].s ) continue; + + maybe=tt; value=0; + //Material is high-value match + if( tileTypeTable[tt].m == source->m ) value|=8; + //Direction is medium value match + if( tileTypeTable[tt].d.whole == source->d.whole ) value|=4; + //Variant is low-value match + if( tileTypeTable[tt].v == source->v ) value|=1; + + //Check value against last match + if( value>matchv ){ + match=tt; + matchv=value; + } + } + } + if( match ) return match; + return sourceTileType; + } + + +} + + + +#endif // TILETYPES_H_INCLUDED diff --git a/tools/playground/CMakeLists.txt b/tools/playground/CMakeLists.txt index f21d9170c..291845660 100644 --- a/tools/playground/CMakeLists.txt +++ b/tools/playground/CMakeLists.txt @@ -67,6 +67,31 @@ TARGET_LINK_LIBRARIES(dfcopypaste dfhack) ADD_EXECUTABLE(dfpaths paths.cpp) TARGET_LINK_LIBRARIES(dfpaths dfhack) +# deramp +# Author: zilpin +# seeks entire map for 'remove ramp' designation, makes a floor, removes designation. +# intended use is to simulate old 'channel' functionality. +ADD_EXECUTABLE(dfderamp deramp.cpp) +TARGET_LINK_LIBRARIES(dfderamp dfhack) + + +# printtiletypes +# Author: zilpin +# Prints CSV dump of all tile type information. +# No DF process needed. Intended only for debugging and information purposes. +ADD_EXECUTABLE(dfprinttiletypes printtiletypes.cpp) +TARGET_LINK_LIBRARIES(dfprinttiletypes dfhack) + +# hellhole +# Author: zilpin +# Creates a bottomless hole to hell. +# Experimental version hard-codes values. +# Will have many options in the future. +ADD_EXECUTABLE(dfhellhole hellhole.cpp) +TARGET_LINK_LIBRARIES(dfhellhole dfhack) + + + # this needs the C bindings IF(BUILD_DFHACK_C_BINDINGS) # for trying out some 'stuff' @@ -83,6 +108,9 @@ dfmoodump dfdigger dfdigger2 dfcatsplosion +dfderamp +dfprinttiletypes +dfhellhole RUNTIME DESTINATION bin ) IF(UNIX) diff --git a/tools/playground/deramp.cpp b/tools/playground/deramp.cpp new file mode 100644 index 000000000..3cfbf5170 --- /dev/null +++ b/tools/playground/deramp.cpp @@ -0,0 +1,128 @@ +// De-ramp. All ramps marked for removal are replaced with given tile (presently, normal floor). + +#include +#include +#include +#include +#include +using namespace std; + +#include +#include + + +int main (void) +{ + uint32_t x_max,y_max,z_max; + uint32_t num_blocks = 0; + uint32_t bytes_read = 0; + DFHack::designations40d designations; + DFHack::tiletypes40d tiles; + DFHack::tiletypes40d tilesAbove; + + //DFHack::TileRow *ptile; + int32_t oldT, newT; + int16_t t; + + int dirty=0, count=0; + + DFHack::ContextManager DFMgr("Memory.xml"); + DFHack::Context *DF = DFMgr.getSingleContext(); + + //sanity check + assert( sizeof(designations) == (16*16*sizeof(DFHack::t_designation)) ); + + //Init + try + { + DF->Attach(); + } + catch (exception& e) + { + cerr << e.what() << endl; + #ifndef LINUX_BUILD + cin.ignore(); + #endif + return 1; + } + DFHack::Maps *Mapz = DF->getMaps(); + + // init the map + if(!Mapz->Start()) + { + cerr << "Can't init map." << endl; + #ifndef LINUX_BUILD + cin.ignore(); + #endif + return 1; + } + + Mapz->getSize(x_max,y_max,z_max); + + uint8_t zeroes [16][16] = {0}; + + // walk the map + for(uint32_t x = 0; x< x_max;x++) + { + for(uint32_t y = 0; y< y_max;y++) + { + for(uint32_t z = 0; z< z_max;z++) + { + if(Mapz->isValidBlock(x,y,z)) + { + dirty=0; + Mapz->ReadDesignations(x,y,z, &designations); + Mapz->ReadTileTypes(x,y,z, &tiles); + if(Mapz->isValidBlock(x,y,z+1)){ + Mapz->ReadTileTypes(x,y,z+1, &tilesAbove); + }else{ + memset(&tilesAbove,0,sizeof(tilesAbove)); + } + + for(uint32_t ty=0;ty<16;++ty){ + for(uint32_t tx=0;tx<16;++tx){ + //Only the remove ramp designation (ignore channel designation, etc) + oldT = tiles[tx][ty]; + if( DFHack::designation_default == designations[tx][ty].bits.dig + && DFHack::RAMP==DFHack::tileTypeTable[oldT].c + ){ + //Current tile is a ramp. + //Set current tile, as accurately as can be expected + newT = DFHack::findSimilarTileType(oldT,DFHack::FLOOR); + + //If no change, skip it (couldn't find a good tile type) + if( oldT == newT) continue; + //Set new tile type, clear designation + tiles[tx][ty] = newT; + designations[tx][ty].bits.dig = DFHack::designation_no; + + //Check the tile above this one, in case a downward slope needs to be removed. + if( DFHack::RAMP_TOP == DFHack::tileTypeTable[tilesAbove[tx][ty]].c ){ + tilesAbove[tx][ty] = 32; + } + + dirty=-1; + ++count; + } + } + } + //If anything was changed, write it all. + if(dirty){ + Mapz->WriteDesignations(x,y,z, &designations); + Mapz->WriteTileTypes(x,y,z, &tiles); + if(Mapz->isValidBlock(x,y,z+1)){ + Mapz->WriteTileTypes(x,y,z+1, &tilesAbove); + } + } + } + } + } + } + DF->Detach(); + cout << "Found and changed " << count << " tiles." << endl; + #ifndef LINUX_BUILD + cout << "Done. Press any key to continue" << endl; + cin.ignore(); + #endif + return 0; +} diff --git a/tools/playground/hellhole.cpp b/tools/playground/hellhole.cpp new file mode 100644 index 000000000..06d1847d3 --- /dev/null +++ b/tools/playground/hellhole.cpp @@ -0,0 +1,426 @@ +// Burn a hole straight to hell! + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +using namespace std; + +#include +#include +#include +using namespace DFHack; + + +#ifdef LINUX_BUILD +#include +void waitmsec (int delay) +{ + usleep(delay); +} +#else +#include +void waitmsec (int delay) +{ + Sleep(delay); +} +#endif + + + +int main (void) +{ + srand ( time(NULL) ); + + int64_t n; + uint32_t x_max,y_max,z_max; + + //The Tile Type to use for the walls lining the hole + //263 is semi-molten rock, 331 is obsidian + uint32_t whell=263, wmolten=263, wmagma=331, wcave=331; + //The Tile Type to use for the hole's floor at bottom of the map + //35 is chasm, 42 is eerie pit , 340 is obsidian floor + uint32_t floor=35, cap=340; + //Should tiles be revealed? + int reveal=0; + + + //Pattern to dig + unsigned char pattern[16][16] = {0,}; + + { + //Calculate a randomized circle. + //These values found through experimentation. + int radius=6; + int x=0, y=0; + + for(y=-radius; y<=radius; ++y){ + for(x=-radius; x<=radius; ++x){ + if(x*x+y*y <= radius*radius + (rand()&31) ){ + pattern[7+x][7+y]=1; + } + } + } + //Post-process to figure out where to put walls. + for(y=0;y<16;++y){ + for(x=0;x<16;++x){ + if( 1==pattern[x][y] ){ + //No hole at edges. + if( x<1 || x>14 || y<1 || y>14 ){ + pattern[x][y]=2; + } + }else if( 0==pattern[x][y] ){ + //check neighbors + if( x>0 && y>0 && 1==pattern[x-1][y-1] ){ pattern[x][y]=2; continue; } + if( x>0 && 1==pattern[x-1][y ] ){ pattern[x][y]=2; continue; } + if( y>0 && 1==pattern[x ][y-1] ){ pattern[x][y]=2; continue; } + if( x<15 && 1==pattern[x+1][y ] ){ pattern[x][y]=2; continue; } + if( x<15&& y>0 && 1==pattern[x+1][y-1] ){ pattern[x][y]=2; continue; } + if( x<15&& y<15&& 1==pattern[x+1][y+1] ){ pattern[x][y]=2; continue; } + if( y<15&& 1==pattern[x ][y+1] ){ pattern[x][y]=2; continue; } + if( x>0 && y<15&& 1==pattern[x-1][y+1] ){ pattern[x][y]=2; continue; } + } + } + } + //Final pass, makes sure that somewhere random gets a vertical pillar of rock which is safe + //to dig stairs down, to permit access to anywhere within the pit from the top. + for(x=0, y=0; 1!=pattern[x][y]; x=rand()&15, y=rand()&15 ){} + pattern[x][y]=3; + +#if 0 + cout << endl; + //Print the pattern (debugging) + for(y=0;y<16;++y){ + for(x=0;x<16;++x){ + printf("%d",pattern[x][y]); + } + cout << endl; + } + cout << endl; + cin.ignore(); + return 0; +#endif + + } + + + + DFHack::ContextManager DFMgr("Memory.xml"); + DFHack::Context *DF = DFMgr.getSingleContext(); + + + //Message of intent + cout << + "DF Hell Hole" << endl << + "This program will instantly dig a hole through hell, wherever your cursor is." << endl << + "This can not be undone! End program now if you don't want hellish fun." << endl + ; + cin.ignore(); + + //Init + try + { + DF->Attach(); + } + catch (exception& e) + { + cerr << e.what() << endl; + #ifndef LINUX_BUILD + cin.ignore(); + #endif + return 1; + } + + // init the map + DFHack::Maps *Mapz = DF->getMaps(); + if(!Mapz->Start()) + { + cerr << "Can't init map. Exiting." << endl; + #ifndef LINUX_BUILD + cin.ignore(); + #endif + return 1; + } + + Mapz->getSize(x_max,y_max,z_max); + + + //Get cursor + int32_t cursorX, cursorY, cursorZ; + DFHack::Position *Pos = DF->getPosition(); + Pos->getCursorCoords(cursorX,cursorY,cursorZ); + if(-30000==cursorX){ + cout << "No cursor position found. Exiting." << endl; + #ifndef LINUX_BUILD + cin.ignore(); + #endif + return 1; + } + + //Block coordinates + int32_t bx=cursorX/16, by=cursorY/16, bz=cursorZ; + //Tile coordinates within block + int32_t tx=cursorX%16, ty=cursorY%16, tz=cursorZ; + + + /* + //Access the DF interface to pause the game. + //Copied from the reveal tool. + DFHack::Gui *Gui =DF->getGui(); + cout << "Pausing..." << endl; + Gui->SetPauseState(true); + DF->Resume(); + waitmsec(1000); + DF->Suspend(); + */ + + + //Verify that every z-level at this location exists. + for(uint32_t z = 0; z<= bz ;z++){ + if( ! Mapz->isValidBlock(bx,by,z) ){ + cout << "This block does't exist yet!" << endl << "Designate the lowest level for digging to make DF allocate the block, then try again." << endl; + #ifndef LINUX_BUILD + cin.ignore(); + #endif + return 1; + } + } + + //Get all the map features. + vector global_features; + if(!Mapz->ReadGlobalFeatures(global_features)){ + cout << "Couldn't load global features! Probably a version problem." << endl; + #ifndef LINUX_BUILD + cin.ignore(); + #endif + return 1; + } + std::map > local_features; + if(!Mapz->ReadLocalFeatures(local_features)){ + cout << "Couldn't load local features! Probably a version problem." << endl; + #ifndef LINUX_BUILD + cin.ignore(); + #endif + return 1; + } + + //Get info on current tile, to determine how to generate the pit + mapblock40d topblock; + Mapz->ReadBlock40d( bx, by, bz , &topblock ); + //Related block info + planecoord pc; + pc.dim.x=bx; pc.dim.y=by; + mapblock40d block; + const TileRow * tp; + t_designation * d; + + //From top to bottom, dig this dude. + + //Top level, cap. + Mapz->ReadBlock40d( bx, by, bz , &block ); + for(uint32_t x=0;x<16;++x){ + for(uint32_t y=0;y<16;++y){ + if(pattern[x][y]){ + tp = getTileTypeP(block.tiletypes[x][y]); + d = &block.designation[x][y]; + //Only modify this level if it's 'empty' + if( EMPTY != tp->c && RAMP_TOP != tp->c && STAIR_DOWN != tp->c && DFHack::TILE_STREAM_TOP != tp->s) continue; + + //Need a floor for empty space. + if(reveal) d->bits.hidden = 0; //topblock.designation[x][y].bits.hidden; + //Always clear the dig designation. + d->bits.dig=designation_no; + //unlock fluids, so they fall down the pit. + d->bits.flow_forbid = d->bits.liquid_static=0; + block.blockflags.bits.liquid_1 = block.blockflags.bits.liquid_2 = 1; + //Remove aquifer, to prevent bugginess + d->bits.water_table=0; + //Set the tile. + block.tiletypes[x][y] = cap + rand()%4; + } + } + } + //Write the block. + Mapz->WriteBlockFlags(bx,by,bz, block.blockflags ); + Mapz->WriteDesignations(bx,by,bz, &block.designation ); + Mapz->WriteTileTypes(bx,by,bz, &block.tiletypes ); + Mapz->WriteDirtyBit(bx,by,bz,1); + + //All levels in between. + uint32_t t; + for(uint32_t z = bz-1; z>0 ; --z){ + cout << z << endl; + assert( Mapz->isValidBlock(bx,by,z) ); + if(!Mapz->ReadBlock40d( bx, by, z , &block )){ + cout << "Bad block! " << bx << "," << by << "," << z; + } + for(uint32_t x=0;x<16;++x){ + for(uint32_t y=0;y<16;++y){ + t=0; + tp = getTileTypeP(block.tiletypes[x][y]); + d = &block.designation[x][y]; + //Border or space? + switch(pattern[x][y]){ + case 0: + continue; + break; + case 1: + //Empty Space + t=32; + //d->bits.light = topblock.designation[x][y].bits.light; + //d->bits.skyview = topblock.designation[x][y].bits.skyview; + //d->bits.subterranean = topblock.designation[x][y].bits.subterranean; + + //Erase special markers + d->bits.feature_global = d->bits.feature_local = 0; + + break; + case 2: + //Border. + //First guess based on current material + switch( tp->m ){ + case OBSIDIAN: + t=wmagma; + break; + case MAGMA: + t=wmolten; + break; + case HFS: + t=whell; + break; + case VEIN: + t=440; //Solid vein block + break; + case FEATSTONE: + t=335; //Solid feature stone block + break; + default: + t=wcave; + } + + //If the tile already is a feature, or if it is a vein, we're done. + //Otherwise, adopt block features. + if( VEIN!=tp->m && !d->bits.feature_global && !d->bits.feature_local ){ + //Local Feature? + if( block.local_feature > -1 ){ + switch( n=local_features[pc][block.local_feature]->type ){ + case feature_Adamantine_Tube: + case feature_Underworld: + case feature_Hell_Temple: + //Whatever the feature is made of. "featstone wall" + d->bits.feature_local = 1; + t=335; + break; + default: + //something here. for debugging, it may be interesting to know. + if(n) cout << '(' << n << ')'; + } + } + //Global Feature? + else if(block.global_feature > -1 ){ + switch( n=global_features[block.global_feature].type ){ + case feature_Adamantine_Tube: + case feature_Underworld: + case feature_Hell_Temple: + //Whatever the feature is made of. "featstone wall" + d->bits.feature_global = 1; + t=335; + break; + default: + //something here. for debugging, it may be interesting to know. + if(n) cout << '[' << n << ']'; + } + } + } + + //Erase any liquids, as they cause problems. + d->bits.flow_size=0; + d->bits.liquid_character = liquid_fresh; + d->bits.liquid_type=liquid_water; + + break; + + case 3: + //Special wall, always sets to obsidian, to give a stairway + t=331; + + //Erase special markers + d->bits.feature_global = d->bits.feature_local = 0; + + //Erase any liquids, as they cause problems. + d->bits.flow_size=0; + d->bits.liquid_character = liquid_fresh; + d->bits.liquid_type=liquid_water; + break; + default: + cout << ".err,bad pattern."; + } + + //For all tiles. + if(reveal) d->bits.hidden = 0; //topblock.designation[x][y].bits.hidden; + //Always clear the dig designation. + d->bits.dig=designation_no; + //unlock fluids, so they fall down the pit. + d->bits.flow_forbid = d->bits.liquid_static=0; + block.blockflags.bits.liquid_1 = block.blockflags.bits.liquid_2 = 1; + //Remove aquifer, to prevent bugginess + d->bits.water_table=0; + //Set the tile. + block.tiletypes[x][y] = t; + } + } + + //Write the block. + Mapz->WriteBlockFlags(bx,by,z, block.blockflags ); + Mapz->WriteDesignations(bx,by,z, &block.designation ); + Mapz->WriteTileTypes(bx,by,z, &block.tiletypes ); + Mapz->WriteDirtyBit(bx,by,z,1); + } + + + //The bottom level is special. + Mapz->ReadBlock40d( bx, by, 0 , &block ); + for(uint32_t x=0;x<16;++x){ + for(uint32_t y=0;y<16;++y){ + //Only the portion below the empty space is handled. + if(pattern[x][y]){ + if( 1==pattern[x][y] ) t=floor; + else if( 3==pattern[x][y] ) t=331; + else continue; + + tp = getTileTypeP(block.tiletypes[x][y]); + d = &block.designation[x][y]; + + //For all tiles. + if(reveal) d->bits.hidden = 0; //topblock.designation[x][y].bits.hidden; + //Always clear the dig designation. + d->bits.dig=designation_no; + //unlock fluids, so they fall down the pit. + d->bits.flow_forbid = d->bits.liquid_static=0; + block.blockflags.bits.liquid_1 = block.blockflags.bits.liquid_2 = 1; + //Set the tile. + block.tiletypes[x][y] = floor; + } + } + } + //Write the block. + Mapz->WriteBlockFlags(bx,by,0, block.blockflags ); + Mapz->WriteDesignations(bx,by,0, &block.designation ); + Mapz->WriteTileTypes(bx,by,0, &block.tiletypes ); + Mapz->WriteDirtyBit(bx,by,0,1); + + + + DF->Detach(); + #ifndef LINUX_BUILD + cout << "Done. Press any key to continue" << endl; + cin.ignore(); + #endif + return 0; +} diff --git a/tools/playground/printtiletypes.cpp b/tools/playground/printtiletypes.cpp new file mode 100644 index 000000000..1016694c9 --- /dev/null +++ b/tools/playground/printtiletypes.cpp @@ -0,0 +1,93 @@ +// Prints all the Tile Types known by DFHack. +// File is both fixed-field and CSV parsable. + +#include +#include +#include +#include +#include +#include +#include +using namespace std; + +#include +#include + +using namespace DFHack; + +int main (int argc, char **argv) +{ + FILE *f=stdout; + const int Columns = 7; + const char * Headings[Columns] = {"TileTypeID","Class","Material","V","Special","Direction","Description"}; + size_t Size[ Columns ] = {}; + int i; + + //First, figure out column widths. + for(i=0;i(Size[1],strlen(TileClassString[i])); + fprintf(f,"%4i ; %s\n", i, TileClassString[i] ,0 ); + } + + //Materials + fprintf(f,"\nTile Type Materials:\n"); + for(i=0;i(Size[2],strlen(TileMaterialString[i])); + fprintf(f,"%4i ; %s\n", i, TileMaterialString[i] ,0 ); + } + + //Specials + fprintf(f,"\nTile Type Specials:\n"); + for(i=0;i(Size[4],strlen(TileSpecialString[i])); + fprintf(f,"%4i ; %s\n", i, TileSpecialString[i] ,0 ); + } + + /* - Not needed for now - + //Direction is tricky + for(i=0;i Date: Mon, 18 Oct 2010 15:38:12 -0400 Subject: [PATCH 2/7] better randomized holes and walls. better placement of walls and pillars. --- tools/playground/hellhole.cpp | 476 ++++++++++++++++++++++++++++------ 1 file changed, 397 insertions(+), 79 deletions(-) diff --git a/tools/playground/hellhole.cpp b/tools/playground/hellhole.cpp index 06d1847d3..16905a83a 100644 --- a/tools/playground/hellhole.cpp +++ b/tools/playground/hellhole.cpp @@ -32,11 +32,237 @@ void waitmsec (int delay) } #endif +#define minmax(MinV,V,MaxV) (max((MinV),min((MaxV),(V)))) + +//User interaction enums. +//Pit Type (these only have meaning within hellhole, btw) +#define PITTYPEMACRO \ + X(pitTypeChasm,"Bottomless Chasm" ) \ + X(pitTypeEerie,"Bottomless Eerie Pit" ) \ + X(pitTypeMagma,"Magma Pit (similar to volcanoe, no hell access)" ) +//end PITTYPEMACRO + +#define X(name,desc) name, +enum e_pitType { + pitTypeInvalid=-1, + PITTYPEMACRO + pitTypeCount, +}; +#undef X + + +#define X(name,desc) desc, +const char * pitTypeDesc[pitTypeCount+1] = +{ + PITTYPEMACRO + "" +}; +#undef X + + + + +int getyesno( const char * msg , int default_value ){ + const int bufferlen=4; + static char buf[bufferlen]; + memset(buf,0,bufferlen); + while(-1){ + if(msg) printf("\n%s (default=%s)\n:" , msg , (default_value?"yes":"no") ); + fflush(stdin); + fgets(buf,bufferlen,stdin); + switch(buf[0]){ + case 0: case 0x0d: case 0x0a: + return default_value; + case 'y': case 'Y': case 'T': case 't': case '1': + return -1; + case 'n': case 'N': case 'F': case 'f': case '0': + return 0; + } + } + return 0; +} + +int getint( const char * msg , int min, int max, int default_value ){ + const int bufferlen=16; + static char buf[bufferlen]; + int n=0; + memset(buf,0,bufferlen); + while(-1){ + if(msg) printf("\n%s (default=%d)\n:" , msg , default_value); + fflush(stdin); + fgets(buf,bufferlen,stdin); + if( !buf[0] || 0x0a==buf[0] || 0x0d==buf[0] ) return default_value; + if( sscanf(buf,"%d", &n) ){ + if(n>=min && n<=max ) return n; + } + } +} + + + +//Interactive, get pit type from user +#define X( e , desc ) printf("%2d) %s\n", (e), (desc) ); +e_pitType selectPitType(e_pitType default_value ){ + e_pitType r=pitTypeInvalid; + int c=-1; + while( -1 ){ + printf("Enter the type of hole to dig (if no entry, default everything):\n" ); + PITTYPEMACRO + printf(":"); + return (e_pitType)getint(NULL, 0, pitTypeCount-1, default_value ); + } +} +#undef X + + +void drawcircle(const int radius, unsigned char pattern[16][16], unsigned char v ){ + //Small circles get better randomness if handled manually + if( 1==radius ){ + pattern[7][7]=v; + if( (rand()&1) ) pattern[6][7]=v; + if( (rand()&1) ) pattern[8][7]=v; + if( (rand()&1) ) pattern[7][6]=v; + if( (rand()&1) ) pattern[7][8]=v; + + }else if( 2==radius ){ + pattern[7][7]=v; + pattern[7][5]=v; + pattern[7][6]=v; + pattern[7][8]=v; + pattern[7][9]=v; + pattern[6][7]=v; + pattern[8][7]=v; + pattern[9][7]=v; + pattern[6][6]=v; + pattern[6][8]=v; + pattern[8][6]=v; + pattern[8][8]=v; + pattern[5][7]=v; + + if( (rand()&1) ) pattern[6][5]=v; + if( (rand()&1) ) pattern[5][6]=v; + if( (rand()&1) ) pattern[8][5]=v; + if( (rand()&1) ) pattern[9][6]=v; + if( (rand()&1) ) pattern[6][9]=v; + if( (rand()&1) ) pattern[5][8]=v; + if( (rand()&1) ) pattern[8][9]=v; + if( (rand()&1) ) pattern[9][8]=v; + }else{ + //radius 3 or larger, simple circle calculation. + int x,y; + for(y=0-radius; y<=radius; ++y){ + for(x=0-radius; x<=radius; ++x){ + if(x*x+y*y <= radius*radius + (rand()&31-8) ){ + pattern[ minmax(0,7+x,15) ][ minmax(0,7+y,15) ]=v; + } + } + } + //Prevent boxy patterns with a quick modification on edges + if(rand()&1) pattern[ 7 ][ minmax(0,7+radius+1,15) ] = v; + if(rand()&1) pattern[ 7 ][ minmax(0,7-radius-1,15) ] = v; + if(rand()&1) pattern[ minmax(0,7+radius+1,15) ][ 7 ] = v; + if(rand()&1) pattern[ minmax(0,7-radius-1,15) ][ 7 ] = v; + } +} + +void settileat(unsigned char pattern[16][16], const unsigned char needle, const unsigned char v, const int index ) +{ + int ok=0; + int safety=256*256; + int y,x,i=0; + //Scan for sequential index + while( !ok && --safety ){ + for(y=0 ; !ok && y<16 ; ++y ){ + for(x=0 ; !ok && x<16 ; ++x ){ + if( needle==pattern[x][y] ){ + ++i; + if( index==i ){ + //Got it! + pattern[x][y]=v; + ok=-1; + } + } + } + } + } +} int main (void) { - srand ( time(NULL) ); + srand ( (unsigned int)time(NULL) ); + + //Message of intent + cout << + "DF Hell Hole" << endl << + "This program will instantly dig a bottomless hole through hell, wherever your cursor is." << endl << + "This can not be undone! End program now if you don't want hellish fun." << endl + ; + + //User selection of settings should have it own routine, a structure for settings, I know + //sloppy mess, but this is just a demo utility. + + //Pit Types. + e_pitType pittype = selectPitType(pitTypeInvalid); + + + //Hole Diameter + int holeradius=6; + if( pitTypeInvalid != pittype && pitTypeMagma != pittype ){ + holeradius = getint( "Enter hole radius, 0 to 8", 0, 8, holeradius ); + } + + //Wall thickness + int wallthickness=1; + if( pitTypeInvalid != pittype && pitTypeMagma != pittype ){ + wallthickness = getint( "Enter wall thickness, 0 to 8", 0, 8, wallthickness ); + } + + //Obsidian Pillars + int pillarwall=1; + if( pitTypeInvalid != pittype ){ + pillarwall = getint( "Number of Obsidian Pillars in wall, 0 to 255", 0, 255, pillarwall ); + } + int pillarchasm=1; + if( pitTypeInvalid != pittype ){ + pillarchasm = getint( "Number of Obsidian Pillars in hole, 0 to 255", 0, 255, pillarchasm ); + } + + //Open Hell? + int exposehell = 0; + if( pitTypeInvalid != pittype && pitTypeMagma != pittype && wallthickness ){ + exposehell=getyesno("Expose the pit to hell (no walls in hell)?",0); + } + + //Fill? + int fillmagma=0; + if( pitTypeInvalid != pittype ){ + fillmagma=getyesno("Fill with magma?",0); + } + int fillwater=0; + if( pitTypeInvalid != pittype && !fillmagma){ + fillwater=getyesno("Fill with water?",0); + } + + + //If skipped all settings, fix the pit type + if( pitTypeInvalid == pittype ) pittype = pitTypeChasm; + + + /////////////////////////////////////////////////////////////////////////////////////////////// + //Print settings. + //If a settings struct existed, this could be in a routine + printf("Using Settings:\n"); + printf("Pit Type......: %d = %s\n", pittype, pitTypeDesc[pittype]); + printf("Hole Radius...: %d\n", holeradius); + printf("Wall Thickness: %d\n", wallthickness); + printf("Pillars, Wall.: %d\n", pillarwall); + printf("Pillars, Hole.: %d\n", pillarchasm); + printf("Expose Hell...: %c\n", (exposehell?'Y':'N') ); + printf("Magma Fill....: %c\n", (fillmagma?'Y':'N') ); + printf("Water Fill....: %c\n", (fillwater?'Y':'N') ); + + int64_t n; uint32_t x_max,y_max,z_max; @@ -47,81 +273,100 @@ int main (void) //The Tile Type to use for the hole's floor at bottom of the map //35 is chasm, 42 is eerie pit , 340 is obsidian floor uint32_t floor=35, cap=340; + if( pitTypeEerie == pittype ) floor=42; + //Should tiles be revealed? - int reveal=0; + int reveal=1; //Pattern to dig - unsigned char pattern[16][16] = {0,}; + unsigned char pattern[16][16]; + + + for(int regen=1;regen; ){ + regen=0; + + memset(pattern,0,sizeof(pattern)); - { //Calculate a randomized circle. //These values found through experimentation. - int radius=6; - int x=0, y=0; + int x=0, y=0, n=0; - for(y=-radius; y<=radius; ++y){ - for(x=-radius; x<=radius; ++x){ - if(x*x+y*y <= radius*radius + (rand()&31) ){ - pattern[7+x][7+y]=1; - } - } + //Two concentric irregular circles + //Outer circle, solid. + if( wallthickness ){ + drawcircle(holeradius+wallthickness, pattern, 2); } - //Post-process to figure out where to put walls. - for(y=0;y<16;++y){ - for(x=0;x<16;++x){ - if( 1==pattern[x][y] ){ - //No hole at edges. - if( x<1 || x>14 || y<1 || y>14 ){ - pattern[x][y]=2; + //Inner circle, hole. + if( holeradius ){ + drawcircle(holeradius, pattern, 1); + } + + + //Post-process to be certain the wall totally encloses hole. + if(wallthickness){ + for(y=0;y<16;++y){ + for(x=0;x<16;++x){ + if( 1==pattern[x][y] ){ + //No hole at edges. + if( x<1 || x>14 || y<1 || y>14 ){ + pattern[x][y]=2; + } + }else if( 0==pattern[x][y] ){ + //check neighbors + if( x>0 && y>0 && 1==pattern[x-1][y-1] ){ pattern[x][y]=2; continue; } + if( x>0 && 1==pattern[x-1][y ] ){ pattern[x][y]=2; continue; } + if( y>0 && 1==pattern[x ][y-1] ){ pattern[x][y]=2; continue; } + if( x<15 && 1==pattern[x+1][y ] ){ pattern[x][y]=2; continue; } + if( x<15&& y>0 && 1==pattern[x+1][y-1] ){ pattern[x][y]=2; continue; } + if( x<15&& y<15&& 1==pattern[x+1][y+1] ){ pattern[x][y]=2; continue; } + if( y<15&& 1==pattern[x ][y+1] ){ pattern[x][y]=2; continue; } + if( x>0 && y<15&& 1==pattern[x-1][y+1] ){ pattern[x][y]=2; continue; } } - }else if( 0==pattern[x][y] ){ - //check neighbors - if( x>0 && y>0 && 1==pattern[x-1][y-1] ){ pattern[x][y]=2; continue; } - if( x>0 && 1==pattern[x-1][y ] ){ pattern[x][y]=2; continue; } - if( y>0 && 1==pattern[x ][y-1] ){ pattern[x][y]=2; continue; } - if( x<15 && 1==pattern[x+1][y ] ){ pattern[x][y]=2; continue; } - if( x<15&& y>0 && 1==pattern[x+1][y-1] ){ pattern[x][y]=2; continue; } - if( x<15&& y<15&& 1==pattern[x+1][y+1] ){ pattern[x][y]=2; continue; } - if( y<15&& 1==pattern[x ][y+1] ){ pattern[x][y]=2; continue; } - if( x>0 && y<15&& 1==pattern[x-1][y+1] ){ pattern[x][y]=2; continue; } } } } + //Final pass, makes sure that somewhere random gets a vertical pillar of rock which is safe //to dig stairs down, to permit access to anywhere within the pit from the top. - for(x=0, y=0; 1!=pattern[x][y]; x=rand()&15, y=rand()&15 ){} - pattern[x][y]=3; + for(n=pillarchasm; n ; --n){ + settileat( pattern , 1 , 3 , rand()&255 ); + } + for(n=pillarwall; n ; --n){ + settileat( pattern , 2 , 3 , rand()&255 ); + } -#if 0 - cout << endl; - //Print the pattern (debugging) + + //Note: + //At this point, the pattern holds: + //0 for all tiles which will be ignored. + //1 for all tiles set to empty pit space. + //2 for all normal walls. + //3 for the straight obsidian top-to-bottom wall. + + printf("\nPattern:\n"); + const char patternkey[] = ".cW!4567890123"; + + //Print the pattern for(y=0;y<16;++y){ for(x=0;x<16;++x){ - printf("%d",pattern[x][y]); + cout << patternkey[ pattern[x][y] ]; } cout << endl; } cout << endl; - cin.ignore(); - return 0; -#endif + regen = !getyesno("Acceptable Pattern?",1); } - + /////////////////////////////////////////////////////////////////////////////////////////////// + + //Connect to DF! DFHack::ContextManager DFMgr("Memory.xml"); DFHack::Context *DF = DFMgr.getSingleContext(); - //Message of intent - cout << - "DF Hell Hole" << endl << - "This program will instantly dig a hole through hell, wherever your cursor is." << endl << - "This can not be undone! End program now if you don't want hellish fun." << endl - ; - cin.ignore(); //Init try @@ -136,7 +381,7 @@ int main (void) #endif return 1; } - + // init the map DFHack::Maps *Mapz = DF->getMaps(); if(!Mapz->Start()) @@ -182,7 +427,7 @@ int main (void) //Verify that every z-level at this location exists. - for(uint32_t z = 0; z<= bz ;z++){ + for(int32_t z = 0; z<= bz ;z++){ if( ! Mapz->isValidBlock(bx,by,z) ){ cout << "This block does't exist yet!" << endl << "Designate the lowest level for digging to make DF allocate the block, then try again." << endl; #ifndef LINUX_BUILD @@ -252,21 +497,74 @@ int main (void) Mapz->WriteTileTypes(bx,by,bz, &block.tiletypes ); Mapz->WriteDirtyBit(bx,by,bz,1); + //Various behaviour flags. + int moltencount=0; + int solidcount=0; + int emptycount=0; + int hellcount=0; + int tpat; + //All levels in between. uint32_t t; - for(uint32_t z = bz-1; z>0 ; --z){ + for(int32_t z = bz-1; z>0 ; --z){ + moltencount=0; + solidcount=0; + emptycount=0; + hellcount=0; cout << z << endl; assert( Mapz->isValidBlock(bx,by,z) ); if(!Mapz->ReadBlock40d( bx, by, z , &block )){ cout << "Bad block! " << bx << "," << by << "," << z; } - for(uint32_t x=0;x<16;++x){ - for(uint32_t y=0;y<16;++y){ + for(int32_t x=0;x<16;++x){ + for(int32_t y=0;y<16;++y){ t=0; tp = getTileTypeP(block.tiletypes[x][y]); d = &block.designation[x][y]; + tpat=pattern[x][y]; + + //Manipulate behaviour based on settings and location + switch( tp->m ){ + case MAGMA: + ++moltencount; + //Making a fake volcanoe/magma pipe? + if( pitTypeMagma == pittype ){ + //Leave tile unchanged. + tpat=0; + } + break; + case OBSIDIAN: + case FEATSTONE: + case HFS: + //ignore, even though it is technically solid + break; + case VEIN: + default: + if( EMPTY != tp->c ){ + ++emptycount; + }else{ + ++solidcount; + } + } + + //Check hell status + if( + (block.local_feature > -1 && feature_Underworld==local_features[pc][block.local_feature]->type ) + || + (block.global_feature > -1 && feature_Underworld==global_features[block.global_feature].type ) + ){ + ++hellcount; + + //Are we leaving hell open? + if( exposehell ){ + //Leave tile unchanged. + tpat=0; + } + } + + //Border or space? - switch(pattern[x][y]){ + switch(tpat){ case 0: continue; break; @@ -280,6 +578,17 @@ int main (void) //Erase special markers d->bits.feature_global = d->bits.feature_local = 0; + //Water? Magma? + if(fillmagma || fillwater){ + d->bits.flow_size=7; + d->bits.liquid_character = liquid_fresh; + if(fillmagma){ + d->bits.liquid_type=liquid_magma; + }else{ + d->bits.liquid_type=liquid_water; + } + } + break; case 2: //Border. @@ -373,6 +682,7 @@ int main (void) d->bits.water_table=0; //Set the tile. block.tiletypes[x][y] = t; + } } @@ -381,40 +691,48 @@ int main (void) Mapz->WriteDesignations(bx,by,z, &block.designation ); Mapz->WriteTileTypes(bx,by,z, &block.tiletypes ); Mapz->WriteDirtyBit(bx,by,z,1); - } + //Making a fake volcanoe/magma pipe? + if( pitTypeMagma == pittype && !solidcount){ + //Nothing «solid», we're making a magma pipe, we're done. + z=0; + } - //The bottom level is special. - Mapz->ReadBlock40d( bx, by, 0 , &block ); - for(uint32_t x=0;x<16;++x){ - for(uint32_t y=0;y<16;++y){ - //Only the portion below the empty space is handled. - if(pattern[x][y]){ - if( 1==pattern[x][y] ) t=floor; - else if( 3==pattern[x][y] ) t=331; - else continue; + } - tp = getTileTypeP(block.tiletypes[x][y]); - d = &block.designation[x][y]; - //For all tiles. - if(reveal) d->bits.hidden = 0; //topblock.designation[x][y].bits.hidden; - //Always clear the dig designation. - d->bits.dig=designation_no; - //unlock fluids, so they fall down the pit. - d->bits.flow_forbid = d->bits.liquid_static=0; - block.blockflags.bits.liquid_1 = block.blockflags.bits.liquid_2 = 1; - //Set the tile. - block.tiletypes[x][y] = floor; + //The bottom level is special. + if( pitTypeMagma != pittype ) { + Mapz->ReadBlock40d( bx, by, 0 , &block ); + for(uint32_t x=0;x<16;++x){ + for(uint32_t y=0;y<16;++y){ + //Only the portion below the empty space is handled. + if(pattern[x][y]){ + if( 1==pattern[x][y] ) t=floor; + else if( 3==pattern[x][y] ) t=331; + else continue; + + tp = getTileTypeP(block.tiletypes[x][y]); + d = &block.designation[x][y]; + + //For all tiles. + if(reveal) d->bits.hidden = 0; //topblock.designation[x][y].bits.hidden; + //Always clear the dig designation. + d->bits.dig=designation_no; + //unlock fluids, so they fall down the pit. + d->bits.flow_forbid = d->bits.liquid_static=0; + block.blockflags.bits.liquid_1 = block.blockflags.bits.liquid_2 = 1; + //Set the tile. + block.tiletypes[x][y] = floor; + } } } + //Write the block. + Mapz->WriteBlockFlags(bx,by,0, block.blockflags ); + Mapz->WriteDesignations(bx,by,0, &block.designation ); + Mapz->WriteTileTypes(bx,by,0, &block.tiletypes ); + Mapz->WriteDirtyBit(bx,by,0,1); } - //Write the block. - Mapz->WriteBlockFlags(bx,by,0, block.blockflags ); - Mapz->WriteDesignations(bx,by,0, &block.designation ); - Mapz->WriteTileTypes(bx,by,0, &block.tiletypes ); - Mapz->WriteDirtyBit(bx,by,0,1); - DF->Detach(); From 92d046869448a5fc64c39a8fded264ccd74b8865 Mon Sep 17 00:00:00 2001 From: zilpin Date: Wed, 20 Oct 2010 12:31:16 -0400 Subject: [PATCH 3/7] added more information to probe. added pit-with-floor option to hellhole. bug fixes for the fake magma pipe in hellhole. --- library/include/dfhack/DFTileTypes.h | 1 + tools/playground/hellhole.cpp | 155 ++++++++++++++++++--------- tools/supported/probe.cpp | 70 +++++++++--- 3 files changed, 157 insertions(+), 69 deletions(-) diff --git a/library/include/dfhack/DFTileTypes.h b/library/include/dfhack/DFTileTypes.h index 52c3fb4de..affff0c7a 100644 --- a/library/include/dfhack/DFTileTypes.h +++ b/library/include/dfhack/DFTileTypes.h @@ -997,6 +997,7 @@ namespace DFHack if( tclass == tileTypeTable[tt].c ){ //shortcut null entries if(!tileTypeTable[tt].name) continue; + //Special flag match is absolutely mandatory! if( source->s != tileTypeTable[tt].s ) continue; diff --git a/tools/playground/hellhole.cpp b/tools/playground/hellhole.cpp index 16905a83a..e8fc9da17 100644 --- a/tools/playground/hellhole.cpp +++ b/tools/playground/hellhole.cpp @@ -39,6 +39,7 @@ void waitmsec (int delay) #define PITTYPEMACRO \ X(pitTypeChasm,"Bottomless Chasm" ) \ X(pitTypeEerie,"Bottomless Eerie Pit" ) \ + X(pitTypeFloor,"Pit with a floor" ) \ X(pitTypeMagma,"Magma Pit (similar to volcanoe, no hell access)" ) //end PITTYPEMACRO @@ -208,13 +209,13 @@ int main (void) //Hole Diameter int holeradius=6; - if( pitTypeInvalid != pittype && pitTypeMagma != pittype ){ + if( pitTypeInvalid != pittype ){ holeradius = getint( "Enter hole radius, 0 to 8", 0, 8, holeradius ); } //Wall thickness int wallthickness=1; - if( pitTypeInvalid != pittype && pitTypeMagma != pittype ){ + if( pitTypeInvalid != pittype ){ wallthickness = getint( "Enter wall thickness, 0 to 8", 0, 8, wallthickness ); } @@ -271,12 +272,19 @@ int main (void) //263 is semi-molten rock, 331 is obsidian uint32_t whell=263, wmolten=263, wmagma=331, wcave=331; //The Tile Type to use for the hole's floor at bottom of the map - //35 is chasm, 42 is eerie pit , 340 is obsidian floor + //35 is chasm, 42 is eerie pit , 340 is obsidian floor, 344 is featstone floor, 264 is 'magma flow' floor uint32_t floor=35, cap=340; - if( pitTypeEerie == pittype ) floor=42; + switch( pittype ){ + case pitTypeEerie: floor=42; break; + case pitTypeFloor: floor=344; break; + case pitTypeMagma: floor=264; break; + default: + floor=35; + } + //Should tiles be revealed? - int reveal=1; + int reveal=0; //Pattern to dig @@ -314,14 +322,14 @@ int main (void) } }else if( 0==pattern[x][y] ){ //check neighbors - if( x>0 && y>0 && 1==pattern[x-1][y-1] ){ pattern[x][y]=2; continue; } - if( x>0 && 1==pattern[x-1][y ] ){ pattern[x][y]=2; continue; } - if( y>0 && 1==pattern[x ][y-1] ){ pattern[x][y]=2; continue; } - if( x<15 && 1==pattern[x+1][y ] ){ pattern[x][y]=2; continue; } - if( x<15&& y>0 && 1==pattern[x+1][y-1] ){ pattern[x][y]=2; continue; } - if( x<15&& y<15&& 1==pattern[x+1][y+1] ){ pattern[x][y]=2; continue; } - if( y<15&& 1==pattern[x ][y+1] ){ pattern[x][y]=2; continue; } - if( x>0 && y<15&& 1==pattern[x-1][y+1] ){ pattern[x][y]=2; continue; } + if( x>0 && y>0 && 1==pattern[x-1][y-1] ){ pattern[x][y]=2; continue; } + if( x>0 && 1==pattern[x-1][y ] ){ pattern[x][y]=2; continue; } + if( y>0 && 1==pattern[x ][y-1] ){ pattern[x][y]=2; continue; } + if( x<15 && 1==pattern[x+1][y ] ){ pattern[x][y]=2; continue; } + if( x<15 && y>0 && 1==pattern[x+1][y-1] ){ pattern[x][y]=2; continue; } + if( x<15 && y<15 && 1==pattern[x+1][y+1] ){ pattern[x][y]=2; continue; } + if( y<15 && 1==pattern[x ][y+1] ){ pattern[x][y]=2; continue; } + if( x>0 && y<15 && 1==pattern[x-1][y+1] ){ pattern[x][y]=2; continue; } } } } @@ -465,39 +473,46 @@ int main (void) const TileRow * tp; t_designation * d; + ////////////////////////////////////// //From top to bottom, dig this dude. + ////////////////////////////////////// //Top level, cap. - Mapz->ReadBlock40d( bx, by, bz , &block ); - for(uint32_t x=0;x<16;++x){ - for(uint32_t y=0;y<16;++y){ - if(pattern[x][y]){ - tp = getTileTypeP(block.tiletypes[x][y]); - d = &block.designation[x][y]; - //Only modify this level if it's 'empty' - if( EMPTY != tp->c && RAMP_TOP != tp->c && STAIR_DOWN != tp->c && DFHack::TILE_STREAM_TOP != tp->s) continue; + //Might make this an option in the future + if(-1){ + Mapz->ReadBlock40d( bx, by, bz , &block ); + for(uint32_t x=0;x<16;++x){ + for(uint32_t y=0;y<16;++y){ + if(pattern[x][y]){ + tp = getTileTypeP(block.tiletypes[x][y]); + d = &block.designation[x][y]; + //Only modify this level if it's 'empty' + if( EMPTY != tp->c && RAMP_TOP != tp->c && STAIR_DOWN != tp->c && DFHack::TILE_STREAM_TOP != tp->s) continue; - //Need a floor for empty space. - if(reveal) d->bits.hidden = 0; //topblock.designation[x][y].bits.hidden; - //Always clear the dig designation. - d->bits.dig=designation_no; - //unlock fluids, so they fall down the pit. - d->bits.flow_forbid = d->bits.liquid_static=0; - block.blockflags.bits.liquid_1 = block.blockflags.bits.liquid_2 = 1; - //Remove aquifer, to prevent bugginess - d->bits.water_table=0; - //Set the tile. - block.tiletypes[x][y] = cap + rand()%4; + //Need a floor for empty space. + if(reveal) d->bits.hidden = 0; //topblock.designation[x][y].bits.hidden; + //Always clear the dig designation. + d->bits.dig=designation_no; + //unlock fluids, so they fall down the pit. + d->bits.flow_forbid = d->bits.liquid_static=0; + block.blockflags.bits.liquid_1 = block.blockflags.bits.liquid_2 = 1; + //Remove aquifer, to prevent bugginess + d->bits.water_table=0; + //Set the tile. + block.tiletypes[x][y] = cap + rand()%4; + } } } + //Write the block. + Mapz->WriteBlockFlags(bx,by,bz, block.blockflags ); + Mapz->WriteDesignations(bx,by,bz, &block.designation ); + Mapz->WriteTileTypes(bx,by,bz, &block.tiletypes ); + Mapz->WriteDirtyBit(bx,by,bz,1); } - //Write the block. - Mapz->WriteBlockFlags(bx,by,bz, block.blockflags ); - Mapz->WriteDesignations(bx,by,bz, &block.designation ); - Mapz->WriteTileTypes(bx,by,bz, &block.tiletypes ); - Mapz->WriteDirtyBit(bx,by,bz,1); + /////////////////////////////////////////////////////////////////////////////////////////////// //Various behaviour flags. + int magmacount=0; int moltencount=0; int solidcount=0; int emptycount=0; @@ -508,6 +523,7 @@ int main (void) uint32_t t; for(int32_t z = bz-1; z>0 ; --z){ moltencount=0; + magmacount=0; solidcount=0; emptycount=0; hellcount=0; @@ -527,18 +543,16 @@ int main (void) switch( tp->m ){ case MAGMA: ++moltencount; + case FEATSTONE: + case HFS: //Making a fake volcanoe/magma pipe? if( pitTypeMagma == pittype ){ //Leave tile unchanged. tpat=0; } break; - case OBSIDIAN: - case FEATSTONE: - case HFS: - //ignore, even though it is technically solid - break; case VEIN: + case OBSIDIAN: default: if( EMPTY != tp->c ){ ++emptycount; @@ -547,6 +561,15 @@ int main (void) } } + //No walls if magma found anywhere for a magma pipe + if( d->bits.flow_size && liquid_magma==d->bits.liquid_type ){ + ++magmacount; + if(pitTypeMagma == pittype){ + tpat=0; + } + } + + //Check hell status if( (block.local_feature > -1 && feature_Underworld==local_features[pc][block.local_feature]->type ) @@ -560,6 +583,15 @@ int main (void) //Leave tile unchanged. tpat=0; } + + //Never should have gotten here + if(pitTypeMagma == pittype){ + x=y=255; + z=0; + tpat=0; + continue; + } + } @@ -587,6 +619,11 @@ int main (void) }else{ d->bits.liquid_type=liquid_water; } + }else{ + //Otherwise, remove all liquids. + d->bits.flow_size=0; + d->bits.liquid_character = liquid_fresh; + d->bits.liquid_type=liquid_water; } break; @@ -615,9 +652,10 @@ int main (void) //If the tile already is a feature, or if it is a vein, we're done. //Otherwise, adopt block features. - if( VEIN!=tp->m && !d->bits.feature_global && !d->bits.feature_local ){ + //Adamantine (a local feature) trumps veins. + { //Local Feature? - if( block.local_feature > -1 ){ + if( block.local_feature > -1 && !d->bits.feature_global ){ switch( n=local_features[pc][block.local_feature]->type ){ case feature_Adamantine_Tube: case feature_Underworld: @@ -632,7 +670,7 @@ int main (void) } } //Global Feature? - else if(block.global_feature > -1 ){ + else if(block.global_feature > -1 && !d->bits.feature_local ){ switch( n=global_features[block.global_feature].type ){ case feature_Adamantine_Tube: case feature_Underworld: @@ -668,13 +706,17 @@ int main (void) d->bits.liquid_type=liquid_water; break; default: - cout << ".err,bad pattern."; + cout << ".error,bad pattern."; } //For all tiles. if(reveal) d->bits.hidden = 0; //topblock.designation[x][y].bits.hidden; //Always clear the dig designation. d->bits.dig=designation_no; + //Make it underground, because it is capped + d->bits.subterranean=1; + d->bits.light=0; + d->bits.skyview=0; //unlock fluids, so they fall down the pit. d->bits.flow_forbid = d->bits.liquid_static=0; block.blockflags.bits.liquid_1 = block.blockflags.bits.liquid_2 = 1; @@ -693,7 +735,7 @@ int main (void) Mapz->WriteDirtyBit(bx,by,z,1); //Making a fake volcanoe/magma pipe? - if( pitTypeMagma == pittype && !solidcount){ + if( pitTypeMagma == pittype && !solidcount && (moltencount || magmacount) ){ //Nothing «solid», we're making a magma pipe, we're done. z=0; } @@ -702,24 +744,31 @@ int main (void) //The bottom level is special. - if( pitTypeMagma != pittype ) { + if(-1){ Mapz->ReadBlock40d( bx, by, 0 , &block ); for(uint32_t x=0;x<16;++x){ for(uint32_t y=0;y<16;++y){ //Only the portion below the empty space is handled. - if(pattern[x][y]){ - if( 1==pattern[x][y] ) t=floor; - else if( 3==pattern[x][y] ) t=331; - else continue; + if(1==pattern[x][y]){ + //if( 1==pattern[x][y] ) t=floor; + //else if( 3==pattern[x][y] ) t=331; + //else continue; tp = getTileTypeP(block.tiletypes[x][y]); d = &block.designation[x][y]; + //Special handling for magma pipe. + //Need to be sure that solid blocks have a floor above them. + //Only solid blocks will have a floor drawn; empty blocks will be ignored. + if( pitTypeMagma == pittype ) { + if( EMPTY == tp->c || RAMP_TOP == tp->c || STAIR_DOWN == tp->c ) continue; + } + //For all tiles. if(reveal) d->bits.hidden = 0; //topblock.designation[x][y].bits.hidden; //Always clear the dig designation. d->bits.dig=designation_no; - //unlock fluids, so they fall down the pit. + //unlock fluids d->bits.flow_forbid = d->bits.liquid_static=0; block.blockflags.bits.liquid_1 = block.blockflags.bits.liquid_2 = 1; //Set the tile. diff --git a/tools/supported/probe.cpp b/tools/supported/probe.cpp index 57992f470..81a34b693 100644 --- a/tools/supported/probe.cpp +++ b/tools/supported/probe.cpp @@ -8,8 +8,8 @@ #include #include -#define DFHACK_WANT_MISCUTILS -#define DFHACK_WANT_TILETYPES +#define DFHACK_WANT_MISCUTILS 1 +#define DFHACK_WANT_TILETYPES 1 #include using namespace DFHack; @@ -18,6 +18,7 @@ int main (int numargs, const char ** args) DFHack::ContextManager DFMgr("Memory.xml"); DFHack::Context *DF = DFMgr.getSingleContext(); +BEGIN_PROBE: try { DF->Attach(); @@ -31,6 +32,7 @@ int main (int numargs, const char ** args) return 1; } + DFHack::Position *Pos = DF->getPosition(); DFHack::VersionInfo* mem = DF->getMemoryInfo(); DFHack::Maps *Maps = DF->getMaps(); @@ -57,6 +59,11 @@ int main (int numargs, const char ** args) Maps->Start(); + vector global_features; + std::map > local_features; + Maps->ReadLocalFeatures(local_features); + Maps->ReadGlobalFeatures(global_features); + int32_t cursorX, cursorY, cursorZ; Pos->getCursorCoords(cursorX,cursorY,cursorZ); if(cursorX != -30000) @@ -82,7 +89,15 @@ int main (int numargs, const char ** args) // tiletype std::cout <<"tiletype: " << tiletype; if(tileTypeTable[tiletype].name) - std::cout << " = " << tileTypeTable[tiletype].name; + std::cout << " = " << tileTypeTable[tiletype].name << std::endl; + + printf("%-10s: %4d %s\n","Class",tileTypeTable[tiletype].c,TileClassString[ tileTypeTable[tiletype].c ] , 0); + printf("%-10s: %4d %s\n","Material",tileTypeTable[tiletype].c,TileMaterialString[ tileTypeTable[tiletype].m ] , 0); + printf("%-10s: %4d %s\n","Special",tileTypeTable[tiletype].c,TileSpecialString[ tileTypeTable[tiletype].s ] , 0); + printf("%-10s: %4d\n","Variant",tileTypeTable[tiletype].v , 0); + printf("%-10s: %s\n","Direction",tileTypeTable[tiletype].d.getStr() , 0); + + std::cout << std::endl; std::cout <<"temperature1: " << tmpb1[tileX][tileY] << " U" << std::endl; std::cout <<"temperature2: " << tmpb2[tileX][tileY] << " U" << std::endl; @@ -109,24 +124,47 @@ int main (int numargs, const char ** args) std::cout << "smooth?" << std::endl; uint32_t designato = block.origin + designatus + (tileX * 16 + tileY) * sizeof(t_designation); printf("designation offset: 0x%x\n", designato); - if(des.light) - std::cout << "Light "; - else - std::cout << " "; - if(des.skyview) - std::cout << "SkyView "; - else - std::cout << " "; - if(des.subterranean) - std::cout << "Underground "; - else - std::cout << " "; + +#define PRINT_FLAG( X ) printf("%-16s= %c\n", #X , ( des.X ? 'Y' : ' ' ) ) + PRINT_FLAG( hidden ); + PRINT_FLAG( light ); + PRINT_FLAG( skyview ); + PRINT_FLAG( subterranean ); + PRINT_FLAG( water_table ); + //PRINT_FLAG( rained ); + + planecoord pc; + pc.dim.x=blockX; pc.dim.y=blockY; + + PRINT_FLAG( feature_local ); + if( des.feature_local ){ + printf("%-16s %4d (%2d) %s\n", "", + block.local_feature, + local_features[pc][block.local_feature]->type, + sa_feature[local_features[pc][block.local_feature]->type] + ); + } + + PRINT_FLAG( feature_global ); + if( des.feature_global ){ + printf("%-16s %4d (%2d) %s\n", "", + block.global_feature, + global_features[block.global_feature].type, + sa_feature[global_features[block.global_feature].type] + ); + } + +#undef PRINT_FLAG + std::cout << std::endl; } } + DF->Detach(); #ifndef LINUX_BUILD - std::cout << "Done. Press any key to continue" << std::endl; + //std::cout << "Done. Press any key to continue" << std::endl; + std::cout << "Press any key to refresh..." << std::endl; cin.ignore(); + goto BEGIN_PROBE; #endif return 0; } From 30b94dac8787d1e135c018089968b1a4a37be48e Mon Sep 17 00:00:00 2001 From: zilpin Date: Thu, 21 Oct 2010 17:25:24 -0400 Subject: [PATCH 4/7] lots of new features. need debugging. --- tools/playground/hellhole.cpp | 605 ++++++++++++++++++++++++---------- 1 file changed, 438 insertions(+), 167 deletions(-) diff --git a/tools/playground/hellhole.cpp b/tools/playground/hellhole.cpp index e8fc9da17..4767d4700 100644 --- a/tools/playground/hellhole.cpp +++ b/tools/playground/hellhole.cpp @@ -39,8 +39,12 @@ void waitmsec (int delay) #define PITTYPEMACRO \ X(pitTypeChasm,"Bottomless Chasm" ) \ X(pitTypeEerie,"Bottomless Eerie Pit" ) \ - X(pitTypeFloor,"Pit with a floor" ) \ - X(pitTypeMagma,"Magma Pit (similar to volcanoe, no hell access)" ) + X(pitTypeFloor,"Pit with floor" ) \ + X(pitTypeSolid,"Solid Pillar" ) \ + X(pitTypeOasis,"Oasis, with partial aquifer (no hell access)" ) \ + X(pitTypeOPool,"Oasis Pool, with partial aquifer (default 5 deep)" ) \ + X(pitTypeMagma,"Magma Pit (similar to volcano, no hell access)" ) \ + X(pitTypeMPool,"Magma Pool (default 5 z-levels)" ) //end PITTYPEMACRO #define X(name,desc) name, @@ -99,21 +103,35 @@ int getint( const char * msg , int min, int max, int default_value ){ } } +int getint( const char * msg , int min, int max ){ + const int bufferlen=16; + static char buf[bufferlen]; + int n=0; + memset(buf,0,bufferlen); + while(-1){ + if(msg) printf("\n%s \n:" , msg ); + fflush(stdin); + fgets(buf,bufferlen,stdin); + if( !buf[0] || 0x0a==buf[0] || 0x0d==buf[0] ) continue; + if( sscanf(buf,"%d", &n) ){ + if(n>=min && n<=max ) return n; + } + } +} + //Interactive, get pit type from user -#define X( e , desc ) printf("%2d) %s\n", (e), (desc) ); -e_pitType selectPitType(e_pitType default_value ){ - e_pitType r=pitTypeInvalid; - int c=-1; +e_pitType selectPitType(){ while( -1 ){ - printf("Enter the type of hole to dig (if no entry, default everything):\n" ); - PITTYPEMACRO + printf("Enter the type of hole to dig:\n" ); + for(int n=0;n=0, replace with v. +//Returns number of neighbors found. +int checkneighbors(unsigned char pattern[16][16], int x, int y, unsigned char n , char v ) +{ + int r=0; + if( x>0 && y>0 && n==pattern[x-1][y-1] ){ ++r; if(v>-1) pattern[x][y]=v; } + if( x>0 && n==pattern[x-1][y ] ){ ++r; if(v>-1) pattern[x][y]=v; } + if( y>0 && n==pattern[x ][y-1] ){ ++r; if(v>-1) pattern[x][y]=v; } + if( x<15 && n==pattern[x+1][y ] ){ ++r; if(v>-1) pattern[x][y]=v; } + if( x<15 && y>0 && n==pattern[x+1][y-1] ){ ++r; if(v>-1) pattern[x][y]=v; } + if( x<15 && y<15 && n==pattern[x+1][y+1] ){ ++r; if(v>-1) pattern[x][y]=v; } + if( y<15 && n==pattern[x ][y+1] ){ ++r; if(v>-1) pattern[x][y]=v; } + if( x>0 && y<15 && n==pattern[x-1][y+1] ){ ++r; if(v>-1) pattern[x][y]=v; } + return r; +} +//convenience +int checkneighbors(unsigned char pattern[16][16], int x, int y, unsigned char n ) +{ + return checkneighbors(pattern,x,y,n,-1); +} + void settileat(unsigned char pattern[16][16], const unsigned char needle, const unsigned char v, const int index ) { int ok=0; @@ -189,14 +229,37 @@ void settileat(unsigned char pattern[16][16], const unsigned char needle, const } +//Is a given feature present at the given tile? +int isfeature( + vector global_features, + std::map > local_features, + const mapblock40d &block, const planecoord &pc, const int x, const int y, const e_feature Feat +) +{ + //const TileRow * tp; + //tp = getTileTypeP(block.tiletypes[x][y]); + const t_designation * d; + d = &block.designation[x][y]; + + if( block.local_feature > -1 && d->bits.feature_local ){ + if( Feat==local_features[pc][block.local_feature]->type ) return Feat; + } + if( block.global_feature > -1 && d->bits.feature_global ){ + if( Feat==global_features[block.global_feature].type ) return Feat; + } + + return 0; +} + + int main (void) { srand ( (unsigned int)time(NULL) ); //Message of intent cout << - "DF Hell Hole" << endl << - "This program will instantly dig a bottomless hole through hell, wherever your cursor is." << endl << + "DF Hole" << endl << + "This tool will instantly dig a chasm, pit, pipe, etc through hell, wherever your cursor is." << endl << "This can not be undone! End program now if you don't want hellish fun." << endl ; @@ -204,69 +267,22 @@ int main (void) //sloppy mess, but this is just a demo utility. //Pit Types. - e_pitType pittype = selectPitType(pitTypeInvalid); - + e_pitType pittype = selectPitType(); - //Hole Diameter + //Here are all the settings. + //Default values are set here. + int pitdepth=0; + int roof=-1; int holeradius=6; - if( pitTypeInvalid != pittype ){ - holeradius = getint( "Enter hole radius, 0 to 8", 0, 8, holeradius ); - } - - //Wall thickness int wallthickness=1; - if( pitTypeInvalid != pittype ){ - wallthickness = getint( "Enter wall thickness, 0 to 8", 0, 8, wallthickness ); - } - - //Obsidian Pillars - int pillarwall=1; - if( pitTypeInvalid != pittype ){ - pillarwall = getint( "Number of Obsidian Pillars in wall, 0 to 255", 0, 255, pillarwall ); - } - int pillarchasm=1; - if( pitTypeInvalid != pittype ){ - pillarchasm = getint( "Number of Obsidian Pillars in hole, 0 to 255", 0, 255, pillarchasm ); - } - - //Open Hell? + int wallpillar=1; + int holepillar=1; int exposehell = 0; - if( pitTypeInvalid != pittype && pitTypeMagma != pittype && wallthickness ){ - exposehell=getyesno("Expose the pit to hell (no walls in hell)?",0); - } - - //Fill? int fillmagma=0; - if( pitTypeInvalid != pittype ){ - fillmagma=getyesno("Fill with magma?",0); - } int fillwater=0; - if( pitTypeInvalid != pittype && !fillmagma){ - fillwater=getyesno("Fill with water?",0); - } - - - //If skipped all settings, fix the pit type - if( pitTypeInvalid == pittype ) pittype = pitTypeChasm; - - - /////////////////////////////////////////////////////////////////////////////////////////////// - //Print settings. - //If a settings struct existed, this could be in a routine - printf("Using Settings:\n"); - printf("Pit Type......: %d = %s\n", pittype, pitTypeDesc[pittype]); - printf("Hole Radius...: %d\n", holeradius); - printf("Wall Thickness: %d\n", wallthickness); - printf("Pillars, Wall.: %d\n", pillarwall); - printf("Pillars, Hole.: %d\n", pillarchasm); - printf("Expose Hell...: %c\n", (exposehell?'Y':'N') ); - printf("Magma Fill....: %c\n", (fillmagma?'Y':'N') ); - printf("Water Fill....: %c\n", (fillwater?'Y':'N') ); - - - - int64_t n; - uint32_t x_max,y_max,z_max; + int stopatmagma=0; + int exposemagma=0; + int aquify=0; //The Tile Type to use for the walls lining the hole //263 is semi-molten rock, 331 is obsidian @@ -274,10 +290,47 @@ int main (void) //The Tile Type to use for the hole's floor at bottom of the map //35 is chasm, 42 is eerie pit , 340 is obsidian floor, 344 is featstone floor, 264 is 'magma flow' floor uint32_t floor=35, cap=340; + int floorvar=0; + + + //Modify default settings based on pit type. switch( pittype ){ - case pitTypeEerie: floor=42; break; - case pitTypeFloor: floor=344; break; - case pitTypeMagma: floor=264; break; + case pitTypeChasm: + floor=35; + break; + case pitTypeEerie: + floor=42; + break; + case pitTypeFloor: + floor=344; + floorvar=3; + break; + case pitTypeOasis: + stopatmagma=-1; + //fillwater=-1; + wallthickness=2; + aquify=-1; + floor=340; + floorvar=3; + break; + case pitTypeOPool: + //fillwater=-1; + wallthickness=2; + aquify=-1; + floor=340; + floorvar=3; + break; + case pitTypeMagma: + stopatmagma=-1; + exposemagma=-1; + fillmagma=-1; + floor=264; + break; + case pitTypeMPool: + fillmagma=-1; + floor=340; + floorvar=3; + break; default: floor=35; } @@ -287,6 +340,59 @@ int main (void) int reveal=0; + int accept = getyesno("Use default settings?",1); + + while( !accept ){ + + //Pit Depth + pitdepth = getint( "Enter pit depth (0 for bottom of map)", 0, INT_MAX, pitdepth ); + + //Hole Size + holeradius = getint( "Enter hole radius, 0 to 16", 0, 8, holeradius ); + + //Wall thickness + wallthickness = getint( "Enter wall thickness, 0 to 16", 0, 8, wallthickness ); + + //Obsidian Pillars + holepillar = getint( "Number of Obsidian Pillars in hole, 0 to 255", 0, 255, holepillar ); + wallpillar = getint( "Number of Obsidian Pillars in wall, 0 to 255", 0, 255, wallpillar ); + + //Open Hell? + exposehell=getyesno("Expose the pit to hell (no walls in hell)?",exposehell); + + //Stop when magma sea is hit? + stopatmagma=getyesno("Stop at magma sea?",stopatmagma); + + //Fill? + fillmagma=getyesno("Fill with magma?",fillmagma); + if(fillmagma) aquify=fillwater=0; + fillwater=getyesno("Fill with water?",fillwater); + aquify=getyesno("Aquifer?",aquify); + + + /////////////////////////////////////////////////////////////////////////////////////////////// + //Print settings. + //If a settings struct existed, this could be in a routine + printf("Using Settings:\n"); + printf("Pit Type......: %d = %s\n", pittype, pitTypeDesc[pittype]); + printf("Hole Radius...: %d\n", holeradius); + printf("Wall Thickness: %d\n", wallthickness); + printf("Pillars, Hole.: %d\n", holepillar); + printf("Pillars, Wall.: %d\n", wallpillar); + printf("Expose Hell...: %c\n", (exposehell?'Y':'N') ); + printf("Stop at Magma.: %c\n", (stopatmagma?'Y':'N') ); + printf("Magma Fill....: %c\n", (fillmagma?'Y':'N') ); + printf("Water Fill....: %c\n", (fillwater?'Y':'N') ); + printf("Aquifer.......: %c\n", (aquify?'Y':'N') ); + + accept = getyesno("Accept these settings?",1); + } + + + int64_t n; + uint32_t x_max,y_max,z_max; + + //Pattern to dig unsigned char pattern[16][16]; @@ -322,38 +428,33 @@ int main (void) } }else if( 0==pattern[x][y] ){ //check neighbors - if( x>0 && y>0 && 1==pattern[x-1][y-1] ){ pattern[x][y]=2; continue; } - if( x>0 && 1==pattern[x-1][y ] ){ pattern[x][y]=2; continue; } - if( y>0 && 1==pattern[x ][y-1] ){ pattern[x][y]=2; continue; } - if( x<15 && 1==pattern[x+1][y ] ){ pattern[x][y]=2; continue; } - if( x<15 && y>0 && 1==pattern[x+1][y-1] ){ pattern[x][y]=2; continue; } - if( x<15 && y<15 && 1==pattern[x+1][y+1] ){ pattern[x][y]=2; continue; } - if( y<15 && 1==pattern[x ][y+1] ){ pattern[x][y]=2; continue; } - if( x>0 && y<15 && 1==pattern[x-1][y+1] ){ pattern[x][y]=2; continue; } + checkneighbors( pattern , x,y, 1, 2); } } } } - //Final pass, makes sure that somewhere random gets a vertical pillar of rock which is safe + //Makes sure that somewhere random gets a vertical pillar of rock which is safe //to dig stairs down, to permit access to anywhere within the pit from the top. - for(n=pillarchasm; n ; --n){ + for(n=holepillar; n ; --n){ settileat( pattern , 1 , 3 , rand()&255 ); } - for(n=pillarwall; n ; --n){ + for(n=wallpillar; n ; --n){ settileat( pattern , 2 , 3 , rand()&255 ); } + //Note: //At this point, the pattern holds: //0 for all tiles which will be ignored. //1 for all tiles set to empty pit space. //2 for all normal walls. //3 for the straight obsidian top-to-bottom wall. + //4 is randomized between wall or floor (!not implemented!) printf("\nPattern:\n"); - const char patternkey[] = ".cW!4567890123"; + const char patternkey[] = ".cW!?567890123"; //Print the pattern for(y=0;y<16;++y){ @@ -367,9 +468,15 @@ int main (void) regen = !getyesno("Acceptable Pattern?",1); } + //Post-process settings to fix problems here + if(pitdepth<1) pitdepth=INT_MAX; + /////////////////////////////////////////////////////////////////////////////////////////////// + + cerr << "Loading memory map..." << endl; + //Connect to DF! DFHack::ContextManager DFMgr("Memory.xml"); DFHack::Context *DF = DFMgr.getSingleContext(); @@ -377,6 +484,7 @@ int main (void) //Init + cerr << "Attaching to DF..." << endl; try { DF->Attach(); @@ -435,9 +543,9 @@ int main (void) //Verify that every z-level at this location exists. - for(int32_t z = 0; z<= bz ;z++){ - if( ! Mapz->isValidBlock(bx,by,z) ){ - cout << "This block does't exist yet!" << endl << "Designate the lowest level for digging to make DF allocate the block, then try again." << endl; + for(int32_t Z = 0; Z<= bz ;Z++){ + if( ! Mapz->isValidBlock(bx,by,Z) ){ + cout << "This block does't exist! Exiting." << endl; #ifndef LINUX_BUILD cin.ignore(); #endif @@ -479,11 +587,12 @@ int main (void) //Top level, cap. //Might make this an option in the future - if(-1){ + //For now, no wall means no cap. + if(wallthickness){ Mapz->ReadBlock40d( bx, by, bz , &block ); for(uint32_t x=0;x<16;++x){ for(uint32_t y=0;y<16;++y){ - if(pattern[x][y]){ + if( (pattern[x][y]>1) || (roof && pattern[x][y]) ){ tp = getTileTypeP(block.tiletypes[x][y]); d = &block.designation[x][y]; //Only modify this level if it's 'empty' @@ -511,27 +620,32 @@ int main (void) } /////////////////////////////////////////////////////////////////////////////////////////////// - //Various behaviour flags. - int magmacount=0; - int moltencount=0; - int solidcount=0; - int emptycount=0; - int hellcount=0; - int tpat; - //All levels in between. - uint32_t t; - for(int32_t z = bz-1; z>0 ; --z){ - moltencount=0; - magmacount=0; - solidcount=0; - emptycount=0; - hellcount=0; + int done=0; + uint32_t t,v; + int32_t z = bz-1; + int32_t bottom = max(0,bz-pitdepth-1); + assert( bottom>=0 && bottom<=bz ); + for( ; !done && z>=bottom ; --z){ + int watercount=0; + int magmacount=0; + int moltencount=0; + int solidcount=0; + int veincount=0; + int emptycount=0; + int hellcount=0; + int templecount=0; + int adamcount=0; + int featcount=0; + int tpat; + cout << z << endl; assert( Mapz->isValidBlock(bx,by,z) ); if(!Mapz->ReadBlock40d( bx, by, z , &block )){ - cout << "Bad block! " << bx << "," << by << "," << z; + cout << "Bad block! " << bx << "," << by << "," << z << endl; } + + //Pre-process this z-level, to get some tile statistics. for(int32_t x=0;x<16;++x){ for(int32_t y=0;y<16;++y){ t=0; @@ -539,59 +653,145 @@ int main (void) d = &block.designation[x][y]; tpat=pattern[x][y]; - //Manipulate behaviour based on settings and location + //Tile type material categories switch( tp->m ){ case MAGMA: ++moltencount; - case FEATSTONE: - case HFS: - //Making a fake volcanoe/magma pipe? - if( pitTypeMagma == pittype ){ - //Leave tile unchanged. - tpat=0; - } break; case VEIN: + ++veincount; + break; + case FEATSTONE: + case HFS: case OBSIDIAN: default: - if( EMPTY != tp->c ){ + if( EMPTY == tp->c || RAMP_TOP == tp->c || STAIR_DOWN == tp->c ){ ++emptycount; }else{ ++solidcount; } } - //No walls if magma found anywhere for a magma pipe - if( d->bits.flow_size && liquid_magma==d->bits.liquid_type ){ - ++magmacount; - if(pitTypeMagma == pittype){ - tpat=0; + //Magma and water + if( d->bits.flow_size ){ + if(d->bits.liquid_type){ + ++magmacount; + }else{ + ++watercount; } } - //Check hell status - if( - (block.local_feature > -1 && feature_Underworld==local_features[pc][block.local_feature]->type ) - || - (block.global_feature > -1 && feature_Underworld==global_features[block.global_feature].type ) - ){ - ++hellcount; + //Check for Features + if( block.local_feature > -1 || block.global_feature > -1 ){ + //Count tiles which actually are in the feature. + //It is possible for a block to have a feature, but no tiles to be feature. + if( d->bits.feature_global || d->bits.feature_local ){ + //All features + ++featcount; + + if( d->bits.feature_global && d->bits.feature_local ){ + cout << "warn:tile is global and local at same time!" << endl; + } - //Are we leaving hell open? + n=0; + if( block.global_feature > -1 && d->bits.feature_global ){ + n=global_features[block.global_feature].type; + switch( n ){ + case feature_Other: + //no count + break; + case feature_Adamantine_Tube: + ++adamcount; + break; + case feature_Underworld: + ++hellcount; + break; + case feature_Hell_Temple: + ++templecount; + break; + default: + //something here. for debugging, it may be interesting to know. + if(n) cout << '(' << n << ')'; + } + } + + n=0; + if( block.local_feature > -1 && d->bits.feature_local ){ + n=local_features[pc][block.local_feature]->type; + switch( n ){ + case feature_Other: + //no count + break; + case feature_Adamantine_Tube: + ++adamcount; + break; + case feature_Underworld: + ++hellcount; + break; + case feature_Hell_Temple: + ++templecount; + break; + default: + //something here. for debugging, it may be interesting to know. + if(n) cout << '[' << n << ']'; + } + } + } + } + } + } + + + ///////////////////////////////////////////////////////////////////////////////////////////////// + //Some checks, based on settings and stats collected + //First check, are we at illegal depth? + if( hellcount && stopatmagma ){ + //Panic! + done=-1; + tpat=0; + cout << "error: illegal breach of hell!"; + } + + + ///////////////////////////////////////////////////////////////////////////////////////////////// + //Actually process the current z-level. + //These loops do the work. + for(int32_t x=0;!done && x<16;++x){ + for(int32_t y=0;!done && y<16;++y){ + t=0; + tp = getTileTypeP(block.tiletypes[x][y]); + d = &block.designation[x][y]; + tpat=pattern[x][y]; + + //Change behaviour based on settings and stats from this z-level + + //In hell? + if( tpat && isfeature(global_features, local_features,block,pc,x,y,feature_Underworld ) ){ if( exposehell ){ - //Leave tile unchanged. tpat=0; } + } - //Never should have gotten here - if(pitTypeMagma == pittype){ - x=y=255; - z=0; + //Expose magma? + if( tpat && exposemagma ){ + //Leave certain tiles unchanged. + switch( tp->m ){ + case MAGMA: + case VEIN: + case FEATSTONE: + case HFS: + tpat=0; + } + //Leave magma sea unchanged. + if( d->bits.flow_size && d->bits.liquid_type){ tpat=0; - continue; } + } + //Stop at magma? + if( tpat && stopatmagma ){ + //Processed normally, but tricky at end. } @@ -623,12 +823,12 @@ int main (void) //Otherwise, remove all liquids. d->bits.flow_size=0; d->bits.liquid_character = liquid_fresh; - d->bits.liquid_type=liquid_water; + d->bits.liquid_type = liquid_water; } break; case 2: - //Border. + //Wall. //First guess based on current material switch( tp->m ){ case OBSIDIAN: @@ -664,9 +864,6 @@ int main (void) d->bits.feature_local = 1; t=335; break; - default: - //something here. for debugging, it may be interesting to know. - if(n) cout << '(' << n << ')'; } } //Global Feature? @@ -679,9 +876,6 @@ int main (void) d->bits.feature_global = 1; t=335; break; - default: - //something here. for debugging, it may be interesting to know. - if(n) cout << '[' << n << ']'; } } } @@ -691,9 +885,25 @@ int main (void) d->bits.liquid_character = liquid_fresh; d->bits.liquid_type=liquid_water; + //Placing an aquifer? + if( aquify ){ + //Only normal stone types can be aquified + if( tp->m!=MAGMA && tp->m!=FEATSTONE && tp->m!=HFS ){ + //Only place next to the hole. + //If no hole, place in middle. + if( checkneighbors(pattern,x,y,1) || (7==x && 7==y) ){ + d->bits.water_table = 1; + t=265; //soil wall + } + } + } + break; case 3: + //No obsidian walls on bottom of map! + if(z<1) continue; + //Special wall, always sets to obsidian, to give a stairway t=331; @@ -735,45 +945,106 @@ int main (void) Mapz->WriteDirtyBit(bx,by,z,1); //Making a fake volcanoe/magma pipe? - if( pitTypeMagma == pittype && !solidcount && (moltencount || magmacount) ){ - //Nothing «solid», we're making a magma pipe, we're done. - z=0; + if( stopatmagma && (moltencount || magmacount) && (!exposemagma || !solidcount) ){ + //If not exposing magma, quit at the first sign of magma. + //If exposing magma, quite once magma is exposed. + done=-1; } } + //Re-process the last z-level handled above. + z++; + assert( z>=0 ); + + /////////////////////////////////////////////////////////////////////////////////////////////// //The bottom level is special. if(-1){ - Mapz->ReadBlock40d( bx, by, 0 , &block ); + Mapz->ReadBlock40d( bx, by, z , &block ); for(uint32_t x=0;x<16;++x){ for(uint32_t y=0;y<16;++y){ - //Only the portion below the empty space is handled. - if(1==pattern[x][y]){ - //if( 1==pattern[x][y] ) t=floor; - //else if( 3==pattern[x][y] ) t=331; - //else continue; - - tp = getTileTypeP(block.tiletypes[x][y]); - d = &block.designation[x][y]; + t=floor; + v=floorvar; + tp = getTileTypeP(block.tiletypes[x][y]); + d = &block.designation[x][y]; - //Special handling for magma pipe. - //Need to be sure that solid blocks have a floor above them. - //Only solid blocks will have a floor drawn; empty blocks will be ignored. - if( pitTypeMagma == pittype ) { - if( EMPTY == tp->c || RAMP_TOP == tp->c || STAIR_DOWN == tp->c ) continue; + if( exposehell ){ + //Leave hell tiles unchanged when exposing hell. + if( isfeature(global_features,local_features,block,pc,x,y,feature_Underworld) ){ + continue; } + } - //For all tiles. - if(reveal) d->bits.hidden = 0; //topblock.designation[x][y].bits.hidden; - //Always clear the dig designation. - d->bits.dig=designation_no; - //unlock fluids - d->bits.flow_forbid = d->bits.liquid_static=0; - block.blockflags.bits.liquid_1 = block.blockflags.bits.liquid_2 = 1; - //Set the tile. - block.tiletypes[x][y] = floor; + switch(pattern[x][y]){ + case 0: + continue; + break; + case 1: + //Empty becomes floor. + + //Base floor type on the z-level first, features, then tile type. + if(!z){ + //Bottom of map, use the floor specified, always. + break; + } + + if(exposemagma){ + //Only place floor where ground is already solid when exposing + if( EMPTY == tp->c || RAMP_TOP == tp->c || STAIR_DOWN == tp->c ){ + continue; + } + } + + if( d->bits.feature_global || d->bits.feature_global ){ + //Feature Floor! + t=344; + break; + } + + //Tile material check. + switch( tp->m ){ + case OBSIDIAN: + t=340; + v=3; + break; + case MAGMA: + v=0; + t=264; //magma flow + break; + case HFS: + //should only happen at bottom of map + break; + case VEIN: + t=441; //vein floor + v=3; + break; + case FEATSTONE: + t=344; + v=3; + break; + } + + break; + case 2: + case 3: + //Walls already drawn. + //Ignore. + continue; + break; } + + //For all tiles. + if(reveal) d->bits.hidden = 0; //topblock.designation[x][y].bits.hidden; + //Always clear the dig designation. + d->bits.dig=designation_no; + //unlock fluids + d->bits.flow_forbid = d->bits.liquid_static=0; + block.blockflags.bits.liquid_1 = block.blockflags.bits.liquid_2 = 1; + + //Set the tile. + block.tiletypes[x][y] = t + ( v ? rand()&v : 0 ) ; + } } //Write the block. From e2d776d23fa33f110786defeaf983dcfd295d878 Mon Sep 17 00:00:00 2001 From: zilpin Date: Thu, 21 Oct 2010 19:00:12 -0400 Subject: [PATCH 5/7] tested, working. many extensions, hellhole should probably be renamed. --- tools/playground/hellhole.cpp | 71 +++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 25 deletions(-) diff --git a/tools/playground/hellhole.cpp b/tools/playground/hellhole.cpp index 4767d4700..e42fe992c 100644 --- a/tools/playground/hellhole.cpp +++ b/tools/playground/hellhole.cpp @@ -41,8 +41,8 @@ void waitmsec (int delay) X(pitTypeEerie,"Bottomless Eerie Pit" ) \ X(pitTypeFloor,"Pit with floor" ) \ X(pitTypeSolid,"Solid Pillar" ) \ - X(pitTypeOasis,"Oasis, with partial aquifer (no hell access)" ) \ - X(pitTypeOPool,"Oasis Pool, with partial aquifer (default 5 deep)" ) \ + X(pitTypeOasis,"Oasis Pit (ends at magma, no hell access)" ) \ + X(pitTypeOPool,"Oasis Pool, with partial aquifer (default 5 z-levels)" ) \ X(pitTypeMagma,"Magma Pit (similar to volcano, no hell access)" ) \ X(pitTypeMPool,"Magma Pool (default 5 z-levels)" ) //end PITTYPEMACRO @@ -305,34 +305,43 @@ int main (void) floor=344; floorvar=3; break; + case pitTypeSolid: + holeradius=0; + wallthickness=7; + wallpillar=4; + break; case pitTypeOasis: stopatmagma=-1; - //fillwater=-1; + fillwater=-1; + holeradius=5; wallthickness=2; - aquify=-1; + //aquify=-1; floor=340; floorvar=3; break; case pitTypeOPool: - //fillwater=-1; + pitdepth=5; + fillwater=-1; + holeradius=5; wallthickness=2; - aquify=-1; + //aquify=-1; floor=340; floorvar=3; break; case pitTypeMagma: stopatmagma=-1; exposemagma=-1; + wallthickness=2; fillmagma=-1; floor=264; break; case pitTypeMPool: + pitdepth=5; + wallthickness=2; fillmagma=-1; floor=340; floorvar=3; break; - default: - floor=35; } @@ -362,12 +371,13 @@ int main (void) //Stop when magma sea is hit? stopatmagma=getyesno("Stop at magma sea?",stopatmagma); + exposemagma=getyesno("Expose magma sea (no walls)?",exposemagma); //Fill? fillmagma=getyesno("Fill with magma?",fillmagma); if(fillmagma) aquify=fillwater=0; fillwater=getyesno("Fill with water?",fillwater); - aquify=getyesno("Aquifer?",aquify); + //aquify=getyesno("Aquifer?",aquify); /////////////////////////////////////////////////////////////////////////////////////////////// @@ -375,12 +385,14 @@ int main (void) //If a settings struct existed, this could be in a routine printf("Using Settings:\n"); printf("Pit Type......: %d = %s\n", pittype, pitTypeDesc[pittype]); + printf("Depth.........: %d\n", pitdepth); printf("Hole Radius...: %d\n", holeradius); printf("Wall Thickness: %d\n", wallthickness); printf("Pillars, Hole.: %d\n", holepillar); printf("Pillars, Wall.: %d\n", wallpillar); printf("Expose Hell...: %c\n", (exposehell?'Y':'N') ); printf("Stop at Magma.: %c\n", (stopatmagma?'Y':'N') ); + printf("Expose Magma..: %c\n", (exposemagma?'Y':'N') ); printf("Magma Fill....: %c\n", (fillmagma?'Y':'N') ); printf("Water Fill....: %c\n", (fillwater?'Y':'N') ); printf("Aquifer.......: %c\n", (aquify?'Y':'N') ); @@ -582,7 +594,7 @@ int main (void) t_designation * d; ////////////////////////////////////// - //From top to bottom, dig this dude. + //From top to bottom, dig this thing. ////////////////////////////////////// //Top level, cap. @@ -646,8 +658,10 @@ int main (void) } //Pre-process this z-level, to get some tile statistics. - for(int32_t x=0;x<16;++x){ - for(int32_t y=0;y<16;++y){ + for(int32_t x=0;x<16;++x) + { + for(int32_t y=0;y<16;++y) + { t=0; tp = getTileTypeP(block.tiletypes[x][y]); d = &block.designation[x][y]; @@ -753,7 +767,7 @@ int main (void) cout << "error: illegal breach of hell!"; } - + ///////////////////////////////////////////////////////////////////////////////////////////////// //Actually process the current z-level. //These loops do the work. @@ -764,6 +778,11 @@ int main (void) d = &block.designation[x][y]; tpat=pattern[x][y]; + //Up front, remove aquifer, to prevent bugginess + //It may be added back if aquify is set. + d->bits.water_table=0; + + //Change behaviour based on settings and stats from this z-level //In hell? @@ -778,7 +797,6 @@ int main (void) //Leave certain tiles unchanged. switch( tp->m ){ case MAGMA: - case VEIN: case FEATSTONE: case HFS: tpat=0; @@ -807,8 +825,8 @@ int main (void) //d->bits.skyview = topblock.designation[x][y].bits.skyview; //d->bits.subterranean = topblock.designation[x][y].bits.subterranean; - //Erase special markers - d->bits.feature_global = d->bits.feature_local = 0; + //Erase special markers? + //d->bits.feature_global = d->bits.feature_local = 0; //Water? Magma? if(fillmagma || fillwater){ @@ -838,7 +856,7 @@ int main (void) t=wmolten; break; case HFS: - t=whell; + //t=whell; break; case VEIN: t=440; //Solid vein block @@ -861,6 +879,7 @@ int main (void) case feature_Underworld: case feature_Hell_Temple: //Whatever the feature is made of. "featstone wall" + d->bits.feature_global = 0; d->bits.feature_local = 1; t=335; break; @@ -902,7 +921,9 @@ int main (void) case 3: //No obsidian walls on bottom of map! - if(z<1) continue; + if(z<1 && (d->bits.feature_global || d->bits.feature_local) ) { + t=335; + } //Special wall, always sets to obsidian, to give a stairway t=331; @@ -930,8 +951,6 @@ int main (void) //unlock fluids, so they fall down the pit. d->bits.flow_forbid = d->bits.liquid_static=0; block.blockflags.bits.liquid_1 = block.blockflags.bits.liquid_2 = 1; - //Remove aquifer, to prevent bugginess - d->bits.water_table=0; //Set the tile. block.tiletypes[x][y] = t; @@ -961,7 +980,9 @@ int main (void) /////////////////////////////////////////////////////////////////////////////////////////////// //The bottom level is special. if(-1){ - Mapz->ReadBlock40d( bx, by, z , &block ); + if(!Mapz->ReadBlock40d( bx, by, z , &block )){ + cout << "Bad block! " << bx << "," << by << "," << z << endl; + } for(uint32_t x=0;x<16;++x){ for(uint32_t y=0;y<16;++y){ t=floor; @@ -1048,10 +1069,10 @@ int main (void) } } //Write the block. - Mapz->WriteBlockFlags(bx,by,0, block.blockflags ); - Mapz->WriteDesignations(bx,by,0, &block.designation ); - Mapz->WriteTileTypes(bx,by,0, &block.tiletypes ); - Mapz->WriteDirtyBit(bx,by,0,1); + Mapz->WriteBlockFlags(bx,by,z, block.blockflags ); + Mapz->WriteDesignations(bx,by,z, &block.designation ); + Mapz->WriteTileTypes(bx,by,z, &block.tiletypes ); + Mapz->WriteDirtyBit(bx,by,z,1); } From 36fb3a2c6ac3aa6f7f8c9289fc6b32aade659799 Mon Sep 17 00:00:00 2001 From: zilpin Date: Fri, 22 Oct 2010 10:44:33 -0400 Subject: [PATCH 6/7] some bug fixes. magma pit still bugged when placed over adamantine tube, but no longer leaks. --- tools/playground/hellhole.cpp | 100 +++++++++++++++++++++------------- 1 file changed, 63 insertions(+), 37 deletions(-) diff --git a/tools/playground/hellhole.cpp b/tools/playground/hellhole.cpp index e42fe992c..32c6f9b46 100644 --- a/tools/playground/hellhole.cpp +++ b/tools/playground/hellhole.cpp @@ -354,13 +354,13 @@ int main (void) while( !accept ){ //Pit Depth - pitdepth = getint( "Enter pit depth (0 for bottom of map)", 0, INT_MAX, pitdepth ); + pitdepth = getint( "Enter max depth (0 for bottom of map)", 0, INT_MAX, pitdepth ); //Hole Size - holeradius = getint( "Enter hole radius, 0 to 16", 0, 8, holeradius ); + holeradius = getint( "Enter hole radius, 0 to 16", 0, 16, holeradius ); //Wall thickness - wallthickness = getint( "Enter wall thickness, 0 to 16", 0, 8, wallthickness ); + wallthickness = getint( "Enter wall thickness, 0 to 16", 0, 16, wallthickness ); //Obsidian Pillars holepillar = getint( "Number of Obsidian Pillars in hole, 0 to 255", 0, 255, holepillar ); @@ -371,7 +371,7 @@ int main (void) //Stop when magma sea is hit? stopatmagma=getyesno("Stop at magma sea?",stopatmagma); - exposemagma=getyesno("Expose magma sea (no walls)?",exposemagma); + exposemagma=getyesno("Expose magma sea (no walls in magma)?",exposemagma); //Fill? fillmagma=getyesno("Fill with magma?",fillmagma); @@ -642,7 +642,7 @@ int main (void) int watercount=0; int magmacount=0; int moltencount=0; - int solidcount=0; + int rockcount=0; int veincount=0; int emptycount=0; int hellcount=0; @@ -669,6 +669,9 @@ int main (void) //Tile type material categories switch( tp->m ){ + case AIR: + ++emptycount; + break; case MAGMA: ++moltencount; break; @@ -678,12 +681,15 @@ int main (void) case FEATSTONE: case HFS: case OBSIDIAN: + //basicly, ignored. + break; default: if( EMPTY == tp->c || RAMP_TOP == tp->c || STAIR_DOWN == tp->c ){ ++emptycount; }else{ - ++solidcount; + ++rockcount; } + break; } //Magma and water @@ -757,14 +763,23 @@ int main (void) } + //If stopping at magma, and no no non-feature stone in this layer, and magma found, then we're either at + //or below the magma sea / molten rock. + if( stopatmagma && (moltencount || magmacount) && (!exposemagma || !rockcount) ){ + //If not exposing magma, quit at the first sign of magma. + //If exposing magma, quite once magma is exposed. + done=-1; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////// //Some checks, based on settings and stats collected //First check, are we at illegal depth? - if( hellcount && stopatmagma ){ + if( !done && hellcount && stopatmagma ){ //Panic! done=-1; tpat=0; - cout << "error: illegal breach of hell!"; + cout << "error: illegal breach of hell!" << endl; } @@ -786,20 +801,26 @@ int main (void) //Change behaviour based on settings and stats from this z-level //In hell? - if( tpat && isfeature(global_features, local_features,block,pc,x,y,feature_Underworld ) ){ + if( tpat && tpat!=3 && isfeature(global_features, local_features,block,pc,x,y,feature_Underworld ) ){ if( exposehell ){ tpat=0; } } //Expose magma? - if( tpat && exposemagma ){ + if( tpat && tpat!=3 && exposemagma ){ //Leave certain tiles unchanged. switch( tp->m ){ - case MAGMA: - case FEATSTONE: case HFS: + case FEATSTONE: + case MAGMA: tpat=0; + default: + break; + } + //Adamantine may be left unchanged... + if( isfeature(global_features, local_features,block,pc,x,y,feature_Adamantine_Tube ) ){ + tpat=0; } //Leave magma sea unchanged. if( d->bits.flow_size && d->bits.liquid_type){ @@ -807,9 +828,13 @@ int main (void) } } - //Stop at magma? - if( tpat && stopatmagma ){ - //Processed normally, but tricky at end. + + //For all situations... + //Special modification for walls, always for adamantine. + if( isfeature(global_features, local_features,block,pc,x,y,feature_Adamantine_Tube ) ){ + if( 2==pattern[x][y] || 3==pattern[x][y] ){ + tpat=2; + } } @@ -868,16 +893,20 @@ int main (void) t=wcave; } - //If the tile already is a feature, or if it is a vein, we're done. - //Otherwise, adopt block features. + //Adamantine (a local feature) trumps veins. { //Local Feature? - if( block.local_feature > -1 && !d->bits.feature_global ){ + if( block.local_feature > -1 ){ switch( n=local_features[pc][block.local_feature]->type ){ - case feature_Adamantine_Tube: case feature_Underworld: case feature_Hell_Temple: + //Only adopt these if there is no global feature present + if( block.global_feature >-1 ){ + break; + } + case feature_Adamantine_Tube: + //Always for adamantine, sometimes for others //Whatever the feature is made of. "featstone wall" d->bits.feature_global = 0; d->bits.feature_local = 1; @@ -905,6 +934,7 @@ int main (void) d->bits.liquid_type=liquid_water; //Placing an aquifer? + //(bugged, these aquifers don't generate water!) if( aquify ){ //Only normal stone types can be aquified if( tp->m!=MAGMA && tp->m!=FEATSTONE && tp->m!=HFS ){ @@ -912,7 +942,7 @@ int main (void) //If no hole, place in middle. if( checkneighbors(pattern,x,y,1) || (7==x && 7==y) ){ d->bits.water_table = 1; - t=265; //soil wall + //t=265; //soil wall } } } @@ -920,10 +950,10 @@ int main (void) break; case 3: - //No obsidian walls on bottom of map! - if(z<1 && (d->bits.feature_global || d->bits.feature_local) ) { - t=335; - } + ////No obsidian walls on bottom of map! + //if(z<1 && (d->bits.feature_global || d->bits.feature_local) ) { + // t=335; + //} //Special wall, always sets to obsidian, to give a stairway t=331; @@ -963,13 +993,6 @@ int main (void) Mapz->WriteTileTypes(bx,by,z, &block.tiletypes ); Mapz->WriteDirtyBit(bx,by,z,1); - //Making a fake volcanoe/magma pipe? - if( stopatmagma && (moltencount || magmacount) && (!exposemagma || !solidcount) ){ - //If not exposing magma, quit at the first sign of magma. - //If exposing magma, quite once magma is exposed. - done=-1; - } - } //Re-process the last z-level handled above. @@ -997,6 +1020,11 @@ int main (void) } } + //Does expose magma need anything at this level? + if( exposemagma && stopatmagma ){ + continue; + } + switch(pattern[x][y]){ case 0: continue; @@ -1010,12 +1038,10 @@ int main (void) break; } - if(exposemagma){ - //Only place floor where ground is already solid when exposing - if( EMPTY == tp->c || RAMP_TOP == tp->c || STAIR_DOWN == tp->c ){ - continue; - } - } + ////Only place floor where ground is already solid when exposing + //if( EMPTY == tp->c || RAMP_TOP == tp->c || STAIR_DOWN == tp->c ){ + // continue; + //} if( d->bits.feature_global || d->bits.feature_global ){ //Feature Floor! From 70cb93d9f4c510d8a3718e4e1455c984f81943a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Mon, 25 Oct 2010 04:39:14 +0200 Subject: [PATCH 7/7] Fixed includes, unified formatting. --- library/include/dfhack/DFTileTypes.h | 607 ++++---- tools/playground/deramp.cpp | 133 +- tools/playground/hellhole.cpp | 2058 ++++++++++++++------------ tools/playground/printtiletypes.cpp | 127 +- tools/supported/probe.cpp | 334 +++-- 5 files changed, 1722 insertions(+), 1537 deletions(-) diff --git a/library/include/dfhack/DFTileTypes.h b/library/include/dfhack/DFTileTypes.h index affff0c7a..8ccb89827 100644 --- a/library/include/dfhack/DFTileTypes.h +++ b/library/include/dfhack/DFTileTypes.h @@ -30,9 +30,9 @@ distribution. namespace DFHack { - // tile class -- determines the general shape of the tile - // enum and lookup table for string names created using X macros -#define TILECLASS_MACRO \ + // tile class -- determines the general shape of the tile + // enum and lookup table for string names created using X macros + #define TILECLASS_MACRO \ X(EMPTY, "") \ X(WALL, "") \ X(PILLAR, "") \ @@ -51,32 +51,32 @@ namespace DFHack X(SHRUB_OK, "") \ X(BOULDER, "") \ X(PEBBLES, "") -//end TILECLASS_MACRO - - //define tile class enum - #define X(name,comment) name, - enum TileClass { - tileclass_invalid=-1, - TILECLASS_MACRO - tileclass_count, - }; - #undef X - - //Visual Studio screams if you don't do this for the const char* arrays - #ifndef char_p - typedef char * char_p; - #endif - - //set tile class string lookup table (e.g. for printing to user) - #define X(name,comment) #name, - const char_p TileClassString[tileclass_count+1] = { - TILECLASS_MACRO - NULL - }; - #undef X - - -#define TILEMATERIAL_MACRO \ + //end TILECLASS_MACRO + + //define tile class enum + #define X(name,comment) name, + enum TileClass { + tileclass_invalid=-1, + TILECLASS_MACRO + tileclass_count, + }; + #undef X + + //Visual Studio screams if you don't do this for the const char* arrays + #ifndef char_p + typedef char * char_p; + #endif + + //set tile class string lookup table (e.g. for printing to user) + #define X(name,comment) #name, + const char_p TileClassString[tileclass_count+1] = { + TILECLASS_MACRO + 0 + }; + #undef X + + + #define TILEMATERIAL_MACRO \ X(AIR, "empty" ) \ X(SOIL, "ordinary soil. material depends on geology" ) \ X(STONE, "ordinary layer stone. material depends on geology" ) \ @@ -96,30 +96,30 @@ namespace DFHack X(ASHES, "what remains from a FIRE" ) \ X(CONSTRUCTED,"tile material depends on the construction present" ) \ X(CYAN_GLOW, "the glowy stuff that disappears from the demon temple when you take the sword." ) -//end TILEMATERIAL_MACRO + //end TILEMATERIAL_MACRO // material enum - #define X(name,comment) name, - enum TileMaterial { - tilematerial_invalid=-1, - TILEMATERIAL_MACRO - tilematerial_count, - }; - #undef X - - //string lookup table (e.g. for printing to user) - #define X(name,comment) #name, - const char_p TileMaterialString[tilematerial_count+1] = { - TILEMATERIAL_MACRO - NULL - }; - #undef X - - - // Special specials of the tile. - // Not the best way to do this, but compatible with existing code. - // When the TileType class gets created, everything should be re-thought. -#define TILESPECIAL_MACRO \ + #define X(name,comment) name, + enum TileMaterial { + tilematerial_invalid=-1, + TILEMATERIAL_MACRO + tilematerial_count, + }; + #undef X + + //string lookup table (e.g. for printing to user) + #define X(name,comment) #name, + const char_p TileMaterialString[tilematerial_count+1] = { + TILEMATERIAL_MACRO + 0 + }; + #undef X + + + // Special specials of the tile. + // Not the best way to do this, but compatible with existing code. + // When the TileType class gets created, everything should be re-thought. + #define TILESPECIAL_MACRO \ X(NORMAL, "Default for all type, nothing present" ) \ X(SPECIAL, "General purpose, for any unique tile which can not otherwise be differenciated" ) \ X(POOL, "Murky Pool, will gather water from rain" ) \ @@ -133,141 +133,146 @@ namespace DFHack X(DAMAGED, "Walls being dug" ) \ X(WORN, "Walls being dug ??" ) \ X(SMOOTH, "Walls and floors." ) -//end TILESPECIAL_MACRO - - //special enum - #define X(name,comment) TILE_##name, - enum TileSpecial { - tilespecial_invalid=-1, - TILESPECIAL_MACRO - tilespecial_count, - }; - #undef X - - //string lookup table (e.g. for printing to user) - #define X(name,comment) #name, - const char_p TileSpecialString[tilespecial_count+1] = { - TILESPECIAL_MACRO - NULL - }; - #undef X + //end TILESPECIAL_MACRO + + //special enum + #define X(name,comment) TILE_##name, + enum TileSpecial { + tilespecial_invalid=-1, + TILESPECIAL_MACRO + tilespecial_count, + }; + #undef X + + //string lookup table (e.g. for printing to user) + #define X(name,comment) #name, + const char_p TileSpecialString[tilespecial_count+1] = { + TILESPECIAL_MACRO + 0 + }; + #undef X // variants are used for tiles, where there are multiple variants of the same - like grass floors enum TileVariant { - tilevariant_invalid=-1, - VAR_1, //Yes, the value of VAR_1 is 0. It's legacy. Deal with it. + tilevariant_invalid=-1, + VAR_1, //Yes, the value of VAR_1 is 0. It's legacy. Deal with it. VAR_2, VAR_3, VAR_4, }; - //Mainly walls and rivers - //Byte values are used because walls can have either 1 or 2 in any given direction. - const int TileDirectionCount = 4; - union TileDirection - { - uint32_t whole; - unsigned char b[TileDirectionCount]; - struct { - //Maybe should add 'up' and 'down' for Z-levels? - unsigned char north,south,west,east; - }; - - inline TileDirection() - { - whole = 0; - } - TileDirection( uint32_t whole_bits) - { - whole = whole_bits; - } - TileDirection( unsigned char North, unsigned char South, unsigned char West, unsigned char East ) - { - north=North; south=South; east=East; west=West; - } - TileDirection( const char *dir ) - { - //This one just made for fun. - //Supports N S E W - const char *p = dir; - unsigned char *l=NULL; - north=south=east=west=0; - if(!dir) return; - - for( ;*p;++p){ - switch(*p){ - case 'N': //North / Up - case 'n': - ++north; l=&north; break; - case 'S': //South / Down - case 's': - ++south; l=&south; break; - case 'E': //East / Right - case 'e': - ++east; l=&east; break; - case 'W': //West / Left - case 'w': - ++west; l=&west; break; - case '-': - case ' ': - //Explicitly ensure dash and space are ignored. - //Other characters/symbols may be assigned in the future. - break; - default: - if( l && '0' <= *p && '9' >= *p ) - *l += *p - '0'; - break; - } - } - } - - //may be useful for some situations - inline uint32_t sum() const { - return 0L + north + south + east + west; - } - - //Gives a string that represents the direction. - //This is a static string, overwritten with every call! - //Support values > 2 even though they should never happen. - //Copy string if it will be used. - inline char * getStr() const { - static char str[16]; - //type punning trick - *( (uint64_t *)str ) = *( (uint64_t *)"--------" ); - str[8]=0; -#define DIRECTION(x,i,c) \ - if(x){ \ - str[i]=c; \ - if(1==x) ; \ - else if(2==x) str[i+1]=c; \ - else str[i+1]='0'+x; \ - } - - DIRECTION(north,0,'N') - DIRECTION(south,2,'S') - DIRECTION(west,4,'W') - DIRECTION(east,6,'E') -#undef DIRECTION - return str; - } - - - }; - + //Mainly walls and rivers + //Byte values are used because walls can have either 1 or 2 in any given direction. + const int TileDirectionCount = 4; + union TileDirection + { + uint32_t whole; + unsigned char b[TileDirectionCount]; + struct + { + //Maybe should add 'up' and 'down' for Z-levels? + unsigned char north,south,west,east; + }; + + inline TileDirection() + { + whole = 0; + } + TileDirection( uint32_t whole_bits) + { + whole = whole_bits; + } + TileDirection( unsigned char North, unsigned char South, unsigned char West, unsigned char East ) + { + north=North; south=South; east=East; west=West; + } + TileDirection( const char *dir ) + { + //This one just made for fun. + //Supports N S E W + const char *p = dir; + unsigned char *l=0; + north=south=east=west=0; + if(!dir) return; + + for( ;*p;++p) + { + switch(*p) + { + case 'N': //North / Up + case 'n': + ++north; l=&north; break; + case 'S': //South / Down + case 's': + ++south; l=&south; break; + case 'E': //East / Right + case 'e': + ++east; l=&east; break; + case 'W': //West / Left + case 'w': + ++west; l=&west; break; + case '-': + case ' ': + //Explicitly ensure dash and space are ignored. + //Other characters/symbols may be assigned in the future. + break; + default: + if( l && '0' <= *p && '9' >= *p ) + *l += *p - '0'; + break; + } + } + } + + //may be useful for some situations + inline uint32_t sum() const + { + return 0L + north + south + east + west; + } + + //Gives a string that represents the direction. + //This is a static string, overwritten with every call! + //Support values > 2 even though they should never happen. + //Copy string if it will be used. + inline char * getStr() const + { + static char str[16]; + //type punning trick + *( (uint64_t *)str ) = *( (uint64_t *)"--------" ); + str[8]=0; + #define DIRECTION(x,i,c) \ + if(x){ \ + str[i]=c; \ + if(1==x) ; \ + else if(2==x) str[i+1]=c; \ + else str[i+1]='0'+x; \ + } + + DIRECTION(north,0,'N') + DIRECTION(south,2,'S') + DIRECTION(west,4,'W') + DIRECTION(east,6,'E') + #undef DIRECTION + return str; + } + + + }; + struct TileRow { const char * name; TileClass c; TileMaterial m; TileVariant v; - TileSpecial s; - TileDirection d; + TileSpecial s; + TileDirection d; }; - - #define TILE_TYPE_ARRAY_LENGTH 520 + + #define TILE_TYPE_ARRAY_LENGTH 520 const TileRow tileTypeTable[TILE_TYPE_ARRAY_LENGTH] = { @@ -282,7 +287,7 @@ namespace DFHack {0, EMPTY, AIR, VAR_1}, {0, EMPTY, AIR, VAR_1}, {0, EMPTY, AIR, VAR_1}, - + // 10 {0, EMPTY, AIR, VAR_1}, {0, EMPTY, AIR, VAR_1}, @@ -294,7 +299,7 @@ namespace DFHack {0, EMPTY, AIR, VAR_1}, {0, EMPTY, AIR, VAR_1}, {"driftwood stack",FLOOR, DRIFTWOOD, VAR_1}, - + // 20 {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, @@ -306,7 +311,7 @@ namespace DFHack {"ice stair up",STAIR_UP, ICE, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, - + // 30 {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, @@ -318,7 +323,7 @@ namespace DFHack {"obsidian stair down",STAIR_DOWN, OBSIDIAN, VAR_1}, {"obsidian stair up",STAIR_UP, OBSIDIAN, VAR_1}, {"soil stair up/down",STAIR_UPDOWN, SOIL, VAR_1}, - + // 40 {"soil stair down",STAIR_DOWN, SOIL, VAR_1}, {"soil stair up",STAIR_UP, SOIL, VAR_1}, @@ -330,7 +335,7 @@ namespace DFHack {"smooth ice floor",FLOOR, ICE, VAR_1 , TILE_SMOOTH }, {0 ,EMPTY, AIR, VAR_1}, {"grass stair up/down",STAIR_UPDOWN, GRASS, VAR_1}, - + // 50 {"grass stair down",STAIR_DOWN, GRASS, VAR_1}, {"grass stair up",STAIR_UP, GRASS, VAR_1}, @@ -342,7 +347,7 @@ namespace DFHack {"stone stair up",STAIR_UP, STONE, VAR_1}, {"vein stair up/down",STAIR_UPDOWN, VEIN, VAR_1}, {"vein stair down",STAIR_DOWN, VEIN, VAR_1}, - + // 60 {"vein stair up",STAIR_UP, VEIN, VAR_1}, {"featstone? stair up/down",STAIR_UPDOWN, FEATSTONE, VAR_1}, @@ -354,7 +359,7 @@ namespace DFHack {"campfire",FLOOR, CAMPFIRE, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, - + // 70 {"fire",FLOOR, FIRE, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, @@ -366,7 +371,7 @@ namespace DFHack {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, {"stone pillar",PILLAR, STONE, VAR_1}, - + //80 {"obsidian pillar",PILLAR, OBSIDIAN, VAR_1}, {"featstone? pillar",PILLAR, FEATSTONE, VAR_1}, @@ -378,7 +383,7 @@ namespace DFHack {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, {"waterfall landing",FLOOR, SOIL, VAR_1, TILE_WATERFALL }, // verify material - + // 90 {"river source",FLOOR, SOIL, VAR_1, TILE_RIVER_SOURCE }, // verify material {0 ,EMPTY, AIR, VAR_1}, @@ -390,7 +395,7 @@ namespace DFHack {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, - + // 100 {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, @@ -402,7 +407,7 @@ namespace DFHack {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, - + // 110 {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, @@ -414,7 +419,7 @@ namespace DFHack {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, - + // 120 {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, @@ -426,7 +431,7 @@ namespace DFHack {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, - + // 130 {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, @@ -438,7 +443,7 @@ namespace DFHack {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, - + // 140 {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, @@ -450,7 +455,7 @@ namespace DFHack {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, - + // 150 {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, @@ -462,7 +467,7 @@ namespace DFHack {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, - + // 160 {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, @@ -474,7 +479,7 @@ namespace DFHack {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, - + // 170 {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, @@ -486,7 +491,7 @@ namespace DFHack {"damaged stone wall" ,WALL, STONE, VAR_1, TILE_DAMAGED }, {"worn stone wall" ,WALL, STONE, VAR_1, TILE_WORN }, {0 ,EMPTY, AIR, VAR_1}, - + // 180 {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, @@ -498,7 +503,7 @@ namespace DFHack {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, - + // 190 {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, @@ -510,7 +515,7 @@ namespace DFHack {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, - + // 200 {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, @@ -522,7 +527,7 @@ namespace DFHack {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, - + // 210 {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, @@ -534,7 +539,7 @@ namespace DFHack {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, {"stone wall" ,WALL, STONE, VAR_1}, - + // 220 {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, @@ -546,7 +551,7 @@ namespace DFHack {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, - + // 230 {0 ,EMPTY, AIR, VAR_1}, {"sapling" ,SAPLING_OK, SOIL, VAR_1}, @@ -558,7 +563,7 @@ namespace DFHack {"stone ramp" ,RAMP, STONE, VAR_1}, {"obsidian ramp" ,RAMP, OBSIDIAN, VAR_1}, {"featstone? ramp" ,RAMP, FEATSTONE, VAR_1}, - + // 240 {"vein ramp" ,RAMP, VEIN, VAR_1}, {"soil ramp" ,RAMP, SOIL, VAR_1}, @@ -570,7 +575,7 @@ namespace DFHack {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, - + // 250 {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, @@ -582,7 +587,7 @@ namespace DFHack {0 ,EMPTY, AIR, VAR_1}, {"ice floor" ,FLOOR, ICE, VAR_2}, {"ice floor" ,FLOOR, ICE, VAR_3}, - + // 260 {"ice floor" ,FLOOR, ICE, VAR_4}, {"furrowed soil" ,FLOOR, SOIL, VAR_1}, @@ -594,7 +599,7 @@ namespace DFHack {"glowing floor" ,FLOOR, CYAN_GLOW, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, {"smooth obsidian wall RD2",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "--SS--E-" }, - + // 270 {"smooth obsidian wall R2D",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "--S---EE" }, {"smooth obsidian wall R2U",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "N-----EE" }, @@ -606,7 +611,7 @@ namespace DFHack {"smooth obsidian wall LRUD",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH ,"N-S-W-E-" }, {"smooth obsidian wall RUD",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "N-S---E-" }, {"smooth obsidian wall LRD",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "--S-W-E-" }, - + // 280 {"smooth obsidian wall LRU",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "N---W-E-" }, {"smooth obsidian wall LUD",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "N-S-W---" }, @@ -618,7 +623,7 @@ namespace DFHack {"smooth obsidian wall LR",WALL,OBSIDIAN,VAR_1 , TILE_SMOOTH , "----W-E-" }, {"smooth featstone wall RD2",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "--SS--E-" }, {"smooth featstone wall R2D",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "--S---EE" }, - + // 290 {"smooth featstone wall R2U",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "N-----EE" }, {"smooth featstone wall RU2",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "NN----E-" }, @@ -630,7 +635,7 @@ namespace DFHack {"smooth featstone wall RUD",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "N-S---E-" }, {"smooth featstone wall LRD",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "--S-W-E-" }, {"smooth featstone wall LRU",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "N---W-E-" }, - + //300 {"smooth featstone wall LUD",WALL,FEATSTONE,VAR_1, TILE_SMOOTH , "N-S-W---" }, {"smooth featstone wall RD",WALL,FEATSTONE,VAR_1 , TILE_SMOOTH , "--S---E-" }, @@ -642,7 +647,7 @@ namespace DFHack {"smooth stone wall RD2",WALL,STONE,VAR_1 , TILE_SMOOTH , "--SS--E-" }, {"smooth stone wall R2D",WALL,STONE,VAR_1 , TILE_SMOOTH , "--S---EE" }, {"smooth stone wall R2U",WALL,STONE,VAR_1 , TILE_SMOOTH , "N-----EE" }, - + //310 {"smooth stone wall RU2",WALL,STONE,VAR_1 , TILE_SMOOTH , "NN----E-" }, {"smooth stone wall L2U",WALL,STONE,VAR_1 , TILE_SMOOTH , "N---WW--" }, @@ -654,7 +659,7 @@ namespace DFHack {"smooth stone wall LRD",WALL,STONE,VAR_1 , TILE_SMOOTH , "--S-W-E-" }, {"smooth stone wall LRU",WALL,STONE,VAR_1 , TILE_SMOOTH , "N---W-E-" }, {"smooth stone wall LUD",WALL,STONE,VAR_1 , TILE_SMOOTH , "N-S-W---" }, - + //320 {"smooth stone wall RD",WALL,STONE,VAR_1 , TILE_SMOOTH , "--S---E-" }, {"smooth stone wall RU",WALL,STONE,VAR_1 , TILE_SMOOTH , "N-----E-" }, @@ -666,7 +671,7 @@ namespace DFHack {"featstone? fortification",FORTIFICATION,FEATSTONE,VAR_1}, {"cracked obsidian wall",WALL,OBSIDIAN,VAR_1, TILE_CRACKED }, {"damaged obsidian wall",WALL,OBSIDIAN,VAR_1, TILE_DAMAGED }, - + // 330 {"worn obsidian wall",WALL,OBSIDIAN,VAR_1}, {"obsidian wall",WALL,OBSIDIAN,VAR_1}, @@ -682,7 +687,7 @@ namespace DFHack {"stone floor",FLOOR,STONE,VAR_2}, {"stone floor",FLOOR,STONE,VAR_3}, {"stone floor",FLOOR,STONE,VAR_4}, - + // 340 {"obsidian floor",FLOOR,OBSIDIAN,VAR_1}, {"obsidian floor",FLOOR,OBSIDIAN,VAR_2}, @@ -694,7 +699,7 @@ namespace DFHack {"featstone floor 4",FLOOR,FEATSTONE,VAR_4}, {"grass 1",FLOOR,GRASS,VAR_1}, {"grass 2",FLOOR,GRASS,VAR_2}, - + // 350 {"grass 3",FLOOR,GRASS,VAR_3}, {"grass 4",FLOOR,GRASS,VAR_4}, @@ -706,7 +711,7 @@ namespace DFHack {"wet soil floor",FLOOR,SOIL,VAR_2}, {"wet soil floor",FLOOR,SOIL,VAR_3}, {"wet soil floor",FLOOR,SOIL,VAR_4}, - + // 360 {"ice fortification",FORTIFICATION,ICE,VAR_1}, {"cracked ice wall",WALL,ICE,VAR_1, TILE_CRACKED}, @@ -718,7 +723,7 @@ namespace DFHack {"river E",FLOOR,SOIL,VAR_1, TILE_RIVER , "E" }, {"river W",FLOOR,SOIL,VAR_1, TILE_RIVER , "W" }, {"river NW",FLOOR,SOIL,VAR_1, TILE_RIVER, "NW"}, - + //370 {"river NE",FLOOR,SOIL,VAR_1, TILE_RIVER , "NE" }, {"river SW",FLOOR,SOIL,VAR_1, TILE_RIVER , "SW" }, @@ -730,7 +735,7 @@ namespace DFHack {"stream bed NW",FLOOR,SOIL,VAR_1, TILE_STREAM, "NW" }, {"stream bed NE",FLOOR,SOIL,VAR_1, TILE_STREAM, "NE" }, {"stream bed SW",FLOOR,SOIL,VAR_1, TILE_STREAM, "SW" }, - + // 380 {"stream bed SE",FLOOR,SOIL,VAR_1, TILE_STREAM, "SE" }, {"stream top",FLOOR,SOIL,VAR_1, TILE_STREAM_TOP }, @@ -742,7 +747,7 @@ namespace DFHack {"dry grass 1",FLOOR,GRASS_DRY,VAR_1}, {"dry grass 2",FLOOR,GRASS_DRY,VAR_2}, {"dry grass 3",FLOOR,GRASS_DRY,VAR_3}, - + // 390 {"dry grass 4",FLOOR,GRASS_DRY,VAR_4}, {"dead tree",TREE_DEAD,SOIL,VAR_1}, @@ -754,7 +759,7 @@ namespace DFHack {"dead grass 4",FLOOR,GRASS_DEAD,VAR_4}, {"grass B1",FLOOR,GRASS2,VAR_1}, {"grass B2",FLOOR,GRASS2,VAR_2}, - + // 400 {"grass B3",FLOOR,GRASS2,VAR_3}, {"grass B4",FLOOR,GRASS2,VAR_4}, @@ -766,7 +771,7 @@ namespace DFHack {"pebbles 3",PEBBLES,STONE,VAR_3}, {"pebbles 4",PEBBLES,STONE,VAR_4}, {"obsidian shards",PEBBLES,OBSIDIAN,VAR_1}, - + // 410 {"obsidian shards",PEBBLES,OBSIDIAN,VAR_2}, {"obsidian shards",PEBBLES,OBSIDIAN,VAR_3}, @@ -778,7 +783,7 @@ namespace DFHack {"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "--SS--E-"}, {"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "--S---EE"}, {"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "N-----EE" }, - + // 420 {"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "NN----E-"}, {"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "N---WW--"}, @@ -790,7 +795,7 @@ namespace DFHack {"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "--S-W-E-"}, {"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "N---W-E-"}, {"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "N-S-W---"}, - + // 430 {"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "--S---E-"}, {"smooth vein wall",WALL,VEIN,VAR_1 , TILE_SMOOTH , "N-----E-"}, @@ -802,7 +807,7 @@ namespace DFHack {"cracked vein wall",WALL,VEIN,VAR_1, TILE_CRACKED }, {"damaged vein wall",WALL,VEIN,VAR_1, TILE_DAMAGED }, {"worn vein wall",WALL,VEIN,VAR_1 , TILE_WORN }, - + // 440 {"vein wall",WALL,VEIN,VAR_1}, {"vein floor",FLOOR,VEIN,VAR_1}, @@ -814,7 +819,7 @@ namespace DFHack {"vein pebbles",PEBBLES,VEIN,VAR_2}, {"vein pebbles",PEBBLES,VEIN,VAR_3}, {"vein pebbles",PEBBLES,VEIN,VAR_4}, - + // 450 {"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "--SS--E-"}, {"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "--S---EE" }, @@ -826,7 +831,7 @@ namespace DFHack {"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "--SSW---" }, {"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "N-S-W-E-"}, {"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "N-S---E-" }, - + // 460 {"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "--S-W-E-" }, {"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "N---W-E-" }, @@ -838,7 +843,7 @@ namespace DFHack {"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "N-S-----" }, {"smooth ice wall",WALL,ICE,VAR_1 , TILE_SMOOTH , "----W-E-"}, {0 ,EMPTY, AIR, VAR_1}, - + // 470 {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, @@ -850,7 +855,7 @@ namespace DFHack {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, - + // 480 {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, @@ -862,7 +867,7 @@ namespace DFHack {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, - + // 490 {0 ,EMPTY, AIR, VAR_1}, {0 ,EMPTY, AIR, VAR_1}, @@ -874,7 +879,7 @@ namespace DFHack {"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "--S---EE" }, {"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "N-----EE" }, {"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "NN----E-" }, - + // 500 {"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "N---WW--" }, {"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "NN--W---" }, @@ -886,11 +891,11 @@ namespace DFHack {"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "N---W-E-" }, {"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "N-S-W---" }, {"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "--S---E-" }, - + // 510 {"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "N-----E-" }, {"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "N---W---" }, - {"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "--S-W---" }, + {"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "--S-W---" }, {"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "N-S-----" }, {"constructed wall",WALL,CONSTRUCTED, VAR_1 ,TILE_NORMAL, "----W-E-" }, {"constructed stair up/down",STAIR_UPDOWN,CONSTRUCTED, VAR_1}, @@ -899,7 +904,7 @@ namespace DFHack {"constructed ramp",RAMP,CONSTRUCTED, VAR_1}, {0 ,EMPTY, AIR, VAR_1} // end }; - + inline bool isWallTerrain(int in) { @@ -911,116 +916,114 @@ namespace DFHack { return tileTypeTable[in].c >= FLOOR && tileTypeTable[in].c <= PEBBLES; } - + inline bool isRampTerrain(int in) { return tileTypeTable[in].c == RAMP; } - + inline bool isStairTerrain(int in) { return tileTypeTable[in].c >= STAIR_UP && tileTypeTable[in].c <= STAIR_UPDOWN; } - + inline bool isOpenTerrain(int in) { return tileTypeTable[in].c == EMPTY; } - + inline int getVegetationType(int in) { return tileTypeTable[in].c; } - //zilpin: for convenience, when you'll be using the tile information a lot. + //zilpin: for convenience, when you'll be using the tile information a lot. inline const TileRow * getTileTypeP(int in) { - if( in<0 || in>=TILE_TYPE_ARRAY_LENGTH ) return NULL; + if( in<0 || in>=TILE_TYPE_ARRAY_LENGTH ) return 0; return ( const TileRow * ) &tileTypeTable[in]; } - //zilpin: Find the first tile entry which matches the given search criteria. - //All parameters are optional. - //To omit, use the 'invalid' enum for that type (e.g. tileclass_invalid, tilematerial_invalid, etc) - //For tile directions, pass NULL to omit. - //Returns matching index in tileTypeTable, or -1 if none found. - inline - int32_t findTileType( const TileClass tclass, const TileMaterial tmat, const TileVariant tvar, const TileSpecial tspecial, const TileDirection tdir ) - { - int32_t tt; - for(tt=0;tt-1 ) if( tclass != tileTypeTable[tt].c ) continue; - if( tmat>-1 ) if( tmat != tileTypeTable[tt].m ) continue; - if( tvar>-1 ) if( tvar != tileTypeTable[tt].v ) continue; - if( tspecial>-1 ) if( tspecial != tileTypeTable[tt].s ) continue; - if( tdir.whole ) if( tdir.whole != tileTypeTable[tt].d.whole ) continue; - //Match! - return tt; - } - return -1; - } - //Convenience version of the above, to pass strings as the direction - inline - int32_t findTileType( const TileClass tclass, const TileMaterial tmat, const TileVariant tvar, const TileSpecial tspecial, const char *tdirStr ) - { - if(tdirStr){ - TileDirection tdir(tdirStr); - return findTileType(tclass,tmat,tvar,tspecial, tdir ); - }else{ - return findTileType(tclass,tmat,tvar,tspecial, NULL ); - } - } - - - //zilpin: Find a tile type similar to the one given, but with a different class. - //Useful for tile-editing operations. - //If no match found, returns the sourceType - //Definitely needs improvement for wall directions, etc. - inline - int32_t findSimilarTileType( const int32_t sourceTileType, const TileClass tclass ){ - int32_t tt, maybe=0, match=0; - int value=0, matchv=0; - const TileRow *source = &tileTypeTable[sourceTileType]; - const char * sourcename = source->name; - const uint32_t sourcenameint = *((const uint32_t *)sourcename); - -#ifdef assert - assert( sourceTileType >=0 && sourceTileType < TILE_TYPE_ARRAY_LENGTH ); -#endif - - for(tt=0;tts != tileTypeTable[tt].s ) continue; - - maybe=tt; value=0; - //Material is high-value match - if( tileTypeTable[tt].m == source->m ) value|=8; - //Direction is medium value match - if( tileTypeTable[tt].d.whole == source->d.whole ) value|=4; - //Variant is low-value match - if( tileTypeTable[tt].v == source->v ) value|=1; - - //Check value against last match - if( value>matchv ){ - match=tt; - matchv=value; - } - } - } - if( match ) return match; - return sourceTileType; - } + //zilpin: Find the first tile entry which matches the given search criteria. + //All parameters are optional. + //To omit, use the 'invalid' enum for that type (e.g. tileclass_invalid, tilematerial_invalid, etc) + //For tile directions, pass NULL to omit. + //Returns matching index in tileTypeTable, or -1 if none found. + inline + int32_t findTileType( const TileClass tclass, const TileMaterial tmat, const TileVariant tvar, const TileSpecial tspecial, const TileDirection tdir ) + { + int32_t tt; + for(tt=0;tt-1 ) if( tclass != tileTypeTable[tt].c ) continue; + if( tmat>-1 ) if( tmat != tileTypeTable[tt].m ) continue; + if( tvar>-1 ) if( tvar != tileTypeTable[tt].v ) continue; + if( tspecial>-1 ) if( tspecial != tileTypeTable[tt].s ) continue; + if( tdir.whole ) if( tdir.whole != tileTypeTable[tt].d.whole ) continue; + //Match! + return tt; + } + return -1; + } + //Convenience version of the above, to pass strings as the direction + inline + int32_t findTileType( const TileClass tclass, const TileMaterial tmat, const TileVariant tvar, const TileSpecial tspecial, const char *tdirStr ) + { + if(tdirStr){ + TileDirection tdir(tdirStr); + return findTileType(tclass,tmat,tvar,tspecial, tdir ); + }else{ + return findTileType(tclass,tmat,tvar,tspecial, 0 ); + } + } + + //zilpin: Find a tile type similar to the one given, but with a different class. + //Useful for tile-editing operations. + //If no match found, returns the sourceType + //Definitely needs improvement for wall directions, etc. + inline + int32_t findSimilarTileType( const int32_t sourceTileType, const TileClass tclass ){ + int32_t tt, maybe=0, match=0; + int value=0, matchv=0; + const TileRow *source = &tileTypeTable[sourceTileType]; + const char * sourcename = source->name; + const uint32_t sourcenameint = *((const uint32_t *)sourcename); + + #ifdef assert + assert( sourceTileType >=0 && sourceTileType < TILE_TYPE_ARRAY_LENGTH ); + #endif + + for(tt=0;tts != tileTypeTable[tt].s ) continue; + + maybe=tt; value=0; + //Material is high-value match + if( tileTypeTable[tt].m == source->m ) value|=8; + //Direction is medium value match + if( tileTypeTable[tt].d.whole == source->d.whole ) value|=4; + //Variant is low-value match + if( tileTypeTable[tt].v == source->v ) value|=1; + + //Check value against last match + if( value>matchv ){ + match=tt; + matchv=value; + } + } + } + if( match ) return match; + return sourceTileType; + } } diff --git a/tools/playground/deramp.cpp b/tools/playground/deramp.cpp index 3cfbf5170..894cc1082 100644 --- a/tools/playground/deramp.cpp +++ b/tools/playground/deramp.cpp @@ -5,6 +5,7 @@ #include #include #include +#include using namespace std; #include @@ -20,20 +21,20 @@ int main (void) DFHack::tiletypes40d tiles; DFHack::tiletypes40d tilesAbove; - //DFHack::TileRow *ptile; - int32_t oldT, newT; - int16_t t; + //DFHack::TileRow *ptile; + int32_t oldT, newT; + int16_t t; + + int dirty=0, count=0; - int dirty=0, count=0; - DFHack::ContextManager DFMgr("Memory.xml"); DFHack::Context *DF = DFMgr.getSingleContext(); - //sanity check - assert( sizeof(designations) == (16*16*sizeof(DFHack::t_designation)) ); + //sanity check + assert( sizeof(designations) == (16*16*sizeof(DFHack::t_designation)) ); - //Init - try + //Init + try { DF->Attach(); } @@ -46,9 +47,9 @@ int main (void) return 1; } DFHack::Maps *Mapz = DF->getMaps(); - + // init the map - if(!Mapz->Start()) + if (!Mapz->Start()) { cerr << "Can't init map." << endl; #ifndef LINUX_BUILD @@ -56,73 +57,81 @@ int main (void) #endif return 1; } - + Mapz->getSize(x_max,y_max,z_max); uint8_t zeroes [16][16] = {0}; // walk the map - for(uint32_t x = 0; x< x_max;x++) + for (uint32_t x = 0; x< x_max;x++) { - for(uint32_t y = 0; y< y_max;y++) + for (uint32_t y = 0; y< y_max;y++) { - for(uint32_t z = 0; z< z_max;z++) + for (uint32_t z = 0; z< z_max;z++) { - if(Mapz->isValidBlock(x,y,z)) + if (Mapz->isValidBlock(x,y,z)) { - dirty=0; + dirty=0; Mapz->ReadDesignations(x,y,z, &designations); - Mapz->ReadTileTypes(x,y,z, &tiles); - if(Mapz->isValidBlock(x,y,z+1)){ - Mapz->ReadTileTypes(x,y,z+1, &tilesAbove); - }else{ - memset(&tilesAbove,0,sizeof(tilesAbove)); - } - - for(uint32_t ty=0;ty<16;++ty){ - for(uint32_t tx=0;tx<16;++tx){ - //Only the remove ramp designation (ignore channel designation, etc) - oldT = tiles[tx][ty]; - if( DFHack::designation_default == designations[tx][ty].bits.dig - && DFHack::RAMP==DFHack::tileTypeTable[oldT].c - ){ - //Current tile is a ramp. - //Set current tile, as accurately as can be expected - newT = DFHack::findSimilarTileType(oldT,DFHack::FLOOR); - - //If no change, skip it (couldn't find a good tile type) - if( oldT == newT) continue; - //Set new tile type, clear designation - tiles[tx][ty] = newT; - designations[tx][ty].bits.dig = DFHack::designation_no; - - //Check the tile above this one, in case a downward slope needs to be removed. - if( DFHack::RAMP_TOP == DFHack::tileTypeTable[tilesAbove[tx][ty]].c ){ - tilesAbove[tx][ty] = 32; - } - - dirty=-1; - ++count; - } - } - } - //If anything was changed, write it all. - if(dirty){ - Mapz->WriteDesignations(x,y,z, &designations); - Mapz->WriteTileTypes(x,y,z, &tiles); - if(Mapz->isValidBlock(x,y,z+1)){ - Mapz->WriteTileTypes(x,y,z+1, &tilesAbove); - } - } + Mapz->ReadTileTypes(x,y,z, &tiles); + if (Mapz->isValidBlock(x,y,z+1)) + { + Mapz->ReadTileTypes(x,y,z+1, &tilesAbove); + } + else + { + memset(&tilesAbove,0,sizeof(tilesAbove)); + } + + for (uint32_t ty=0;ty<16;++ty) + { + for (uint32_t tx=0;tx<16;++tx) + { + //Only the remove ramp designation (ignore channel designation, etc) + oldT = tiles[tx][ty]; + if ( DFHack::designation_default == designations[tx][ty].bits.dig + && DFHack::RAMP==DFHack::tileTypeTable[oldT].c) + { + //Current tile is a ramp. + //Set current tile, as accurately as can be expected + newT = DFHack::findSimilarTileType(oldT,DFHack::FLOOR); + + //If no change, skip it (couldn't find a good tile type) + if ( oldT == newT) continue; + //Set new tile type, clear designation + tiles[tx][ty] = newT; + designations[tx][ty].bits.dig = DFHack::designation_no; + + //Check the tile above this one, in case a downward slope needs to be removed. + if ( DFHack::RAMP_TOP == DFHack::tileTypeTable[tilesAbove[tx][ty]].c ) + { + tilesAbove[tx][ty] = 32; + } + + dirty=-1; + ++count; + } + } + } + //If anything was changed, write it all. + if (dirty) + { + Mapz->WriteDesignations(x,y,z, &designations); + Mapz->WriteTileTypes(x,y,z, &tiles); + if (Mapz->isValidBlock(x,y,z+1)) + { + Mapz->WriteTileTypes(x,y,z+1, &tilesAbove); + } + } } } } } DF->Detach(); - cout << "Found and changed " << count << " tiles." << endl; - #ifndef LINUX_BUILD + cout << "Found and changed " << count << " tiles." << endl; +#ifndef LINUX_BUILD cout << "Done. Press any key to continue" << endl; cin.ignore(); - #endif +#endif return 0; } diff --git a/tools/playground/hellhole.cpp b/tools/playground/hellhole.cpp index 32c6f9b46..a57b815a1 100644 --- a/tools/playground/hellhole.cpp +++ b/tools/playground/hellhole.cpp @@ -10,6 +10,9 @@ #include #include #include +#include +#include +#include using namespace std; #include @@ -37,21 +40,22 @@ void waitmsec (int delay) //User interaction enums. //Pit Type (these only have meaning within hellhole, btw) #define PITTYPEMACRO \ - X(pitTypeChasm,"Bottomless Chasm" ) \ - X(pitTypeEerie,"Bottomless Eerie Pit" ) \ - X(pitTypeFloor,"Pit with floor" ) \ - X(pitTypeSolid,"Solid Pillar" ) \ - X(pitTypeOasis,"Oasis Pit (ends at magma, no hell access)" ) \ - X(pitTypeOPool,"Oasis Pool, with partial aquifer (default 5 z-levels)" ) \ - X(pitTypeMagma,"Magma Pit (similar to volcano, no hell access)" ) \ - X(pitTypeMPool,"Magma Pool (default 5 z-levels)" ) + X(pitTypeChasm,"Bottomless Chasm" ) \ + X(pitTypeEerie,"Bottomless Eerie Pit" ) \ + X(pitTypeFloor,"Pit with floor" ) \ + X(pitTypeSolid,"Solid Pillar" ) \ + X(pitTypeOasis,"Oasis Pit (ends at magma, no hell access)" ) \ + X(pitTypeOPool,"Oasis Pool, with partial aquifer (default 5 z-levels)" ) \ + X(pitTypeMagma,"Magma Pit (similar to volcano, no hell access)" ) \ + X(pitTypeMPool,"Magma Pool (default 5 z-levels)" ) //end PITTYPEMACRO #define X(name,desc) name, -enum e_pitType { - pitTypeInvalid=-1, - PITTYPEMACRO - pitTypeCount, +enum e_pitType +{ + pitTypeInvalid=-1, + PITTYPEMACRO + pitTypeCount, }; #undef X @@ -59,129 +63,175 @@ enum e_pitType { #define X(name,desc) desc, const char * pitTypeDesc[pitTypeCount+1] = { - PITTYPEMACRO - "" + PITTYPEMACRO + "" }; #undef X -int getyesno( const char * msg , int default_value ){ - const int bufferlen=4; - static char buf[bufferlen]; - memset(buf,0,bufferlen); - while(-1){ - if(msg) printf("\n%s (default=%s)\n:" , msg , (default_value?"yes":"no") ); - fflush(stdin); - fgets(buf,bufferlen,stdin); - switch(buf[0]){ - case 0: case 0x0d: case 0x0a: - return default_value; - case 'y': case 'Y': case 'T': case 't': case '1': - return -1; - case 'n': case 'N': case 'F': case 'f': case '0': - return 0; - } - } - return 0; +int getyesno( const char * msg , int default_value ) +{ + const int bufferlen=4; + static char buf[bufferlen]; + memset(buf,0,bufferlen); + while (-1) + { + if (msg) printf("\n%s (default=%s)\n:" , msg , (default_value?"yes":"no") ); + fflush(stdin); + fgets(buf,bufferlen,stdin); + switch (buf[0]) + { + case 0: + case 0x0d: + case 0x0a: + return default_value; + case 'y': + case 'Y': + case 'T': + case 't': + case '1': + return -1; + case 'n': + case 'N': + case 'F': + case 'f': + case '0': + return 0; + } + } + return 0; } -int getint( const char * msg , int min, int max, int default_value ){ - const int bufferlen=16; - static char buf[bufferlen]; - int n=0; - memset(buf,0,bufferlen); - while(-1){ - if(msg) printf("\n%s (default=%d)\n:" , msg , default_value); - fflush(stdin); - fgets(buf,bufferlen,stdin); - if( !buf[0] || 0x0a==buf[0] || 0x0d==buf[0] ) return default_value; - if( sscanf(buf,"%d", &n) ){ - if(n>=min && n<=max ) return n; - } - } +int getint( const char * msg , int min, int max, int default_value ) { + const int bufferlen=16; + static char buf[bufferlen]; + int n=0; + memset(buf,0,bufferlen); + while (-1) + { + if (msg) printf("\n%s (default=%d)\n:" , msg , default_value); + fflush(stdin); + fgets(buf,bufferlen,stdin); + if ( !buf[0] || 0x0a==buf[0] || 0x0d==buf[0] ) + { + return default_value; + } + if ( sscanf(buf,"%d", &n) ) + { + if (n>=min && n<=max ) + { + return n; + } + } + } } -int getint( const char * msg , int min, int max ){ - const int bufferlen=16; - static char buf[bufferlen]; - int n=0; - memset(buf,0,bufferlen); - while(-1){ - if(msg) printf("\n%s \n:" , msg ); - fflush(stdin); - fgets(buf,bufferlen,stdin); - if( !buf[0] || 0x0a==buf[0] || 0x0d==buf[0] ) continue; - if( sscanf(buf,"%d", &n) ){ - if(n>=min && n<=max ) return n; - } - } +int getint( const char * msg , int min, int max ) +{ + const int bufferlen=16; + static char buf[bufferlen]; + int n=0; + memset(buf,0,bufferlen); + while (-1) + { + if (msg) + { + printf("\n%s \n:" , msg ); + } + fflush(stdin); + fgets(buf,bufferlen,stdin); + + if ( !buf[0] || 0x0a==buf[0] || 0x0d==buf[0] ) + { + continue; + } + if ( sscanf(buf,"%d", &n) ) + { + if (n>=min && n<=max ) + { + return n; + } + } + } } //Interactive, get pit type from user -e_pitType selectPitType(){ - while( -1 ){ - printf("Enter the type of hole to dig:\n" ); - for(int n=0;n0 && y>0 && n==pattern[x-1][y-1] ){ ++r; if(v>-1) pattern[x][y]=v; } - if( x>0 && n==pattern[x-1][y ] ){ ++r; if(v>-1) pattern[x][y]=v; } - if( y>0 && n==pattern[x ][y-1] ){ ++r; if(v>-1) pattern[x][y]=v; } - if( x<15 && n==pattern[x+1][y ] ){ ++r; if(v>-1) pattern[x][y]=v; } - if( x<15 && y>0 && n==pattern[x+1][y-1] ){ ++r; if(v>-1) pattern[x][y]=v; } - if( x<15 && y<15 && n==pattern[x+1][y+1] ){ ++r; if(v>-1) pattern[x][y]=v; } - if( y<15 && n==pattern[x ][y+1] ){ ++r; if(v>-1) pattern[x][y]=v; } - if( x>0 && y<15 && n==pattern[x-1][y+1] ){ ++r; if(v>-1) pattern[x][y]=v; } - return r; + int r=0; + if ( x>0 && y>0 && n==pattern[x-1][y-1] ) + { + ++r; + if (v>-1) pattern[x][y]=v; + } + if ( x>0 && n==pattern[x-1][y ] ) + { + ++r; + if (v>-1) pattern[x][y]=v; + } + if ( y>0 && n==pattern[x ][y-1] ) + { + ++r; + if (v>-1) pattern[x][y]=v; + } + if ( x<15 && n==pattern[x+1][y ] ) + { + ++r; + if (v>-1) pattern[x][y]=v; + } + if ( x<15 && y>0 && n==pattern[x+1][y-1] ) + { + ++r; + if (v>-1) pattern[x][y]=v; + } + if ( x<15 && y<15 && n==pattern[x+1][y+1] ) + { + ++r; + if (v>-1) pattern[x][y]=v; + } + if ( y<15 && n==pattern[x ][y+1] ) + { + ++r; + if (v>-1) pattern[x][y]=v; + } + if ( x>0 && y<15 && n==pattern[x-1][y+1] ) + { + ++r; + if (v>-1) pattern[x][y]=v; + } + return r; } //convenience int checkneighbors(unsigned char pattern[16][16], int x, int y, unsigned char n ) { - return checkneighbors(pattern,x,y,n,-1); + return checkneighbors(pattern,x,y,n,-1); } void settileat(unsigned char pattern[16][16], const unsigned char needle, const unsigned char v, const int index ) { - int ok=0; - int safety=256*256; - int y,x,i=0; - //Scan for sequential index - while( !ok && --safety ){ - for(y=0 ; !ok && y<16 ; ++y ){ - for(x=0 ; !ok && x<16 ; ++x ){ - if( needle==pattern[x][y] ){ - ++i; - if( index==i ){ - //Got it! - pattern[x][y]=v; - ok=-1; - } - } - } - } - } + int ok=0; + int safety=256*256; + int y,x,i=0; + //Scan for sequential index + while ( !ok && --safety ) + { + for (y=0 ; !ok && y<16 ; ++y ) + { + for (x=0 ; !ok && x<16 ; ++x ) + { + if ( needle==pattern[x][y] ) + { + ++i; + if ( index==i ) + { + //Got it! + pattern[x][y]=v; + ok=-1; + } + } + } + } + } } +//FIXME: good candidate for adding to dfhack. Maybe the Maps should have those cached so they can be queried? //Is a given feature present at the given tile? int isfeature( - vector global_features, - std::map > local_features, - const mapblock40d &block, const planecoord &pc, const int x, const int y, const e_feature Feat + vector global_features, + std::map > local_features, + const mapblock40d &block, const planecoord &pc, const int x, const int y, const e_feature Feat ) { - //const TileRow * tp; - //tp = getTileTypeP(block.tiletypes[x][y]); - const t_designation * d; - d = &block.designation[x][y]; - - if( block.local_feature > -1 && d->bits.feature_local ){ - if( Feat==local_features[pc][block.local_feature]->type ) return Feat; - } - if( block.global_feature > -1 && d->bits.feature_global ){ - if( Feat==global_features[block.global_feature].type ) return Feat; - } - - return 0; -} + //const TileRow * tp; + //tp = getTileTypeP(block.tiletypes[x][y]); + const t_designation * d; + d = &block.designation[x][y]; + if ( block.local_feature > -1 && d->bits.feature_local ) { + if ( Feat==local_features[pc][block.local_feature]->type ) return Feat; + } + if ( block.global_feature > -1 && d->bits.feature_global ) { + if ( Feat==global_features[block.global_feature].type ) return Feat; + } + return 0; +} + +// FIXME: use block cache, break into manageable bits int main (void) { - srand ( (unsigned int)time(NULL) ); - - //Message of intent - cout << - "DF Hole" << endl << - "This tool will instantly dig a chasm, pit, pipe, etc through hell, wherever your cursor is." << endl << - "This can not be undone! End program now if you don't want hellish fun." << endl - ; - - //User selection of settings should have it own routine, a structure for settings, I know - //sloppy mess, but this is just a demo utility. - - //Pit Types. - e_pitType pittype = selectPitType(); - - //Here are all the settings. - //Default values are set here. - int pitdepth=0; - int roof=-1; - int holeradius=6; - int wallthickness=1; - int wallpillar=1; - int holepillar=1; - int exposehell = 0; - int fillmagma=0; - int fillwater=0; - int stopatmagma=0; - int exposemagma=0; - int aquify=0; - - //The Tile Type to use for the walls lining the hole - //263 is semi-molten rock, 331 is obsidian - uint32_t whell=263, wmolten=263, wmagma=331, wcave=331; - //The Tile Type to use for the hole's floor at bottom of the map - //35 is chasm, 42 is eerie pit , 340 is obsidian floor, 344 is featstone floor, 264 is 'magma flow' floor - uint32_t floor=35, cap=340; - int floorvar=0; - - - //Modify default settings based on pit type. - switch( pittype ){ - case pitTypeChasm: - floor=35; - break; - case pitTypeEerie: - floor=42; - break; - case pitTypeFloor: - floor=344; - floorvar=3; - break; - case pitTypeSolid: - holeradius=0; - wallthickness=7; - wallpillar=4; - break; - case pitTypeOasis: - stopatmagma=-1; - fillwater=-1; - holeradius=5; - wallthickness=2; - //aquify=-1; - floor=340; - floorvar=3; - break; - case pitTypeOPool: - pitdepth=5; - fillwater=-1; - holeradius=5; - wallthickness=2; - //aquify=-1; - floor=340; - floorvar=3; - break; - case pitTypeMagma: - stopatmagma=-1; - exposemagma=-1; - wallthickness=2; - fillmagma=-1; - floor=264; - break; - case pitTypeMPool: - pitdepth=5; - wallthickness=2; - fillmagma=-1; - floor=340; - floorvar=3; - break; - } - - - //Should tiles be revealed? - int reveal=0; - - - int accept = getyesno("Use default settings?",1); - - while( !accept ){ - - //Pit Depth - pitdepth = getint( "Enter max depth (0 for bottom of map)", 0, INT_MAX, pitdepth ); - - //Hole Size - holeradius = getint( "Enter hole radius, 0 to 16", 0, 16, holeradius ); - - //Wall thickness - wallthickness = getint( "Enter wall thickness, 0 to 16", 0, 16, wallthickness ); - - //Obsidian Pillars - holepillar = getint( "Number of Obsidian Pillars in hole, 0 to 255", 0, 255, holepillar ); - wallpillar = getint( "Number of Obsidian Pillars in wall, 0 to 255", 0, 255, wallpillar ); - - //Open Hell? - exposehell=getyesno("Expose the pit to hell (no walls in hell)?",exposehell); - - //Stop when magma sea is hit? - stopatmagma=getyesno("Stop at magma sea?",stopatmagma); - exposemagma=getyesno("Expose magma sea (no walls in magma)?",exposemagma); - - //Fill? - fillmagma=getyesno("Fill with magma?",fillmagma); - if(fillmagma) aquify=fillwater=0; - fillwater=getyesno("Fill with water?",fillwater); - //aquify=getyesno("Aquifer?",aquify); - - - /////////////////////////////////////////////////////////////////////////////////////////////// - //Print settings. - //If a settings struct existed, this could be in a routine - printf("Using Settings:\n"); - printf("Pit Type......: %d = %s\n", pittype, pitTypeDesc[pittype]); - printf("Depth.........: %d\n", pitdepth); - printf("Hole Radius...: %d\n", holeradius); - printf("Wall Thickness: %d\n", wallthickness); - printf("Pillars, Hole.: %d\n", holepillar); - printf("Pillars, Wall.: %d\n", wallpillar); - printf("Expose Hell...: %c\n", (exposehell?'Y':'N') ); - printf("Stop at Magma.: %c\n", (stopatmagma?'Y':'N') ); - printf("Expose Magma..: %c\n", (exposemagma?'Y':'N') ); - printf("Magma Fill....: %c\n", (fillmagma?'Y':'N') ); - printf("Water Fill....: %c\n", (fillwater?'Y':'N') ); - printf("Aquifer.......: %c\n", (aquify?'Y':'N') ); - - accept = getyesno("Accept these settings?",1); - } - - - int64_t n; - uint32_t x_max,y_max,z_max; - - - //Pattern to dig - unsigned char pattern[16][16]; - - - for(int regen=1;regen; ){ - regen=0; - - memset(pattern,0,sizeof(pattern)); + srand ( (unsigned int)time(NULL) ); + + //Message of intent + cout << + "DF Hole" << endl << + "This tool will instantly dig a chasm, pit, pipe, etc through hell, wherever your cursor is." << endl << + "This can not be undone! End program now if you don't want hellish fun." << endl + ; + + //User selection of settings should have it own routine, a structure for settings, I know + //sloppy mess, but this is just a demo utility. + + //Pit Types. + e_pitType pittype = selectPitType(); + + //Here are all the settings. + //Default values are set here. + int pitdepth=0; + int roof=-1; + int holeradius=6; + int wallthickness=1; + int wallpillar=1; + int holepillar=1; + int exposehell = 0; + int fillmagma=0; + int fillwater=0; + int stopatmagma=0; + int exposemagma=0; + int aquify=0; + + //The Tile Type to use for the walls lining the hole + //263 is semi-molten rock, 331 is obsidian + uint32_t whell=263, wmolten=263, wmagma=331, wcave=331; + //The Tile Type to use for the hole's floor at bottom of the map + //35 is chasm, 42 is eerie pit , 340 is obsidian floor, 344 is featstone floor, 264 is 'magma flow' floor + uint32_t floor=35, cap=340; + int floorvar=0; + + + //Modify default settings based on pit type. + switch ( pittype ) + { + case pitTypeChasm: + floor=35; + break; + case pitTypeEerie: + floor=42; + break; + case pitTypeFloor: + floor=344; + floorvar=3; + break; + case pitTypeSolid: + holeradius=0; + wallthickness=7; + wallpillar=4; + break; + case pitTypeOasis: + stopatmagma=-1; + fillwater=-1; + holeradius=5; + wallthickness=2; + //aquify=-1; + floor=340; + floorvar=3; + break; + case pitTypeOPool: + pitdepth=5; + fillwater=-1; + holeradius=5; + wallthickness=2; + //aquify=-1; + floor=340; + floorvar=3; + break; + case pitTypeMagma: + stopatmagma=-1; + exposemagma=-1; + wallthickness=2; + fillmagma=-1; + floor=264; + break; + case pitTypeMPool: + pitdepth=5; + wallthickness=2; + fillmagma=-1; + floor=340; + floorvar=3; + break; + } - //Calculate a randomized circle. - //These values found through experimentation. - int x=0, y=0, n=0; - //Two concentric irregular circles - //Outer circle, solid. - if( wallthickness ){ - drawcircle(holeradius+wallthickness, pattern, 2); - } - //Inner circle, hole. - if( holeradius ){ - drawcircle(holeradius, pattern, 1); - } + //Should tiles be revealed? + int reveal=0; - //Post-process to be certain the wall totally encloses hole. - if(wallthickness){ - for(y=0;y<16;++y){ - for(x=0;x<16;++x){ - if( 1==pattern[x][y] ){ - //No hole at edges. - if( x<1 || x>14 || y<1 || y>14 ){ - pattern[x][y]=2; - } - }else if( 0==pattern[x][y] ){ - //check neighbors - checkneighbors( pattern , x,y, 1, 2); - } - } - } - } + int accept = getyesno("Use default settings?",1); - //Makes sure that somewhere random gets a vertical pillar of rock which is safe - //to dig stairs down, to permit access to anywhere within the pit from the top. - for(n=holepillar; n ; --n){ - settileat( pattern , 1 , 3 , rand()&255 ); - } - for(n=wallpillar; n ; --n){ - settileat( pattern , 2 , 3 , rand()&255 ); - } + while ( !accept ) + { + //Pit Depth + pitdepth = getint( "Enter max depth (0 for bottom of map)", 0, INT_MAX, pitdepth ); + + //Hole Size + holeradius = getint( "Enter hole radius, 0 to 16", 0, 16, holeradius ); + + //Wall thickness + wallthickness = getint( "Enter wall thickness, 0 to 16", 0, 16, wallthickness ); + + //Obsidian Pillars + holepillar = getint( "Number of Obsidian Pillars in hole, 0 to 255", 0, 255, holepillar ); + wallpillar = getint( "Number of Obsidian Pillars in wall, 0 to 255", 0, 255, wallpillar ); + + //Open Hell? + exposehell=getyesno("Expose the pit to hell (no walls in hell)?",exposehell); + + //Stop when magma sea is hit? + stopatmagma=getyesno("Stop at magma sea?",stopatmagma); + exposemagma=getyesno("Expose magma sea (no walls in magma)?",exposemagma); + + //Fill? + fillmagma=getyesno("Fill with magma?",fillmagma); + if (fillmagma) aquify=fillwater=0; + fillwater=getyesno("Fill with water?",fillwater); + //aquify=getyesno("Aquifer?",aquify); + + + /////////////////////////////////////////////////////////////////////////////////////////////// + //Print settings. + //If a settings struct existed, this could be in a routine + printf("Using Settings:\n"); + printf("Pit Type......: %d = %s\n", pittype, pitTypeDesc[pittype]); + printf("Depth.........: %d\n", pitdepth); + printf("Hole Radius...: %d\n", holeradius); + printf("Wall Thickness: %d\n", wallthickness); + printf("Pillars, Hole.: %d\n", holepillar); + printf("Pillars, Wall.: %d\n", wallpillar); + printf("Expose Hell...: %c\n", (exposehell?'Y':'N') ); + printf("Stop at Magma.: %c\n", (stopatmagma?'Y':'N') ); + printf("Expose Magma..: %c\n", (exposemagma?'Y':'N') ); + printf("Magma Fill....: %c\n", (fillmagma?'Y':'N') ); + printf("Water Fill....: %c\n", (fillwater?'Y':'N') ); + printf("Aquifer.......: %c\n", (aquify?'Y':'N') ); + + accept = getyesno("Accept these settings?",1); + } + int64_t n; + uint32_t x_max,y_max,z_max; - //Note: - //At this point, the pattern holds: - //0 for all tiles which will be ignored. - //1 for all tiles set to empty pit space. - //2 for all normal walls. - //3 for the straight obsidian top-to-bottom wall. - //4 is randomized between wall or floor (!not implemented!) - printf("\nPattern:\n"); - const char patternkey[] = ".cW!?567890123"; + //Pattern to dig + unsigned char pattern[16][16]; - //Print the pattern - for(y=0;y<16;++y){ - for(x=0;x<16;++x){ - cout << patternkey[ pattern[x][y] ]; - } - cout << endl; - } - cout << endl; - regen = !getyesno("Acceptable Pattern?",1); - } + for (int regen=1;regen; ) + { + regen=0; + + memset(pattern,0,sizeof(pattern)); + + //Calculate a randomized circle. + //These values found through experimentation. + int x=0, y=0, n=0; + + //Two concentric irregular circles + //Outer circle, solid. + if ( wallthickness ) + { + drawcircle(holeradius+wallthickness, pattern, 2); + } + //Inner circle, hole. + if ( holeradius ) + { + drawcircle(holeradius, pattern, 1); + } + + + //Post-process to be certain the wall totally encloses hole. + if (wallthickness) + { + for (y=0;y<16;++y) + { + for (x=0;x<16;++x) + { + if ( 1==pattern[x][y] ) + { + //No hole at edges. + if ( x<1 || x>14 || y<1 || y>14 ) + { + pattern[x][y]=2; + } + } + else if ( 0==pattern[x][y] ) + { + //check neighbors + checkneighbors( pattern , x,y, 1, 2); + } + } + } + } + + //Makes sure that somewhere random gets a vertical pillar of rock which is safe + //to dig stairs down, to permit access to anywhere within the pit from the top. + for (n=holepillar; n ; --n) + { + settileat( pattern , 1 , 3 , rand()&255 ); + } + for (n=wallpillar; n ; --n) + { + settileat( pattern , 2 , 3 , rand()&255 ); + } + + //Note: + //At this point, the pattern holds: + //0 for all tiles which will be ignored. + //1 for all tiles set to empty pit space. + //2 for all normal walls. + //3 for the straight obsidian top-to-bottom wall. + //4 is randomized between wall or floor (!not implemented!) + + printf("\nPattern:\n"); + const char patternkey[] = ".cW!?567890123"; + + //Print the pattern + for (y=0;y<16;++y) + { + for (x=0;x<16;++x) + { + cout << patternkey[ pattern[x][y] ]; + } + cout << endl; + } + cout << endl; + + regen = !getyesno("Acceptable Pattern?",1); + } - //Post-process settings to fix problems here - if(pitdepth<1) pitdepth=INT_MAX; + //Post-process settings to fix problems here + if (pitdepth<1) + { + pitdepth=INT_MAX; + } - /////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////// cerr << "Loading memory map..." << endl; - //Connect to DF! + //Connect to DF! DFHack::ContextManager DFMgr("Memory.xml"); DFHack::Context *DF = DFMgr.getSingleContext(); - //Init + //Init cerr << "Attaching to DF..." << endl; - try + try { DF->Attach(); } @@ -508,11 +612,11 @@ int main (void) cin.ignore(); #endif return 1; - } - + } + // init the map - DFHack::Maps *Mapz = DF->getMaps(); - if(!Mapz->Start()) + DFHack::Maps *Mapz = DF->getMaps(); + if (!Mapz->Start()) { cerr << "Can't init map. Exiting." << endl; #ifndef LINUX_BUILD @@ -520,592 +624,656 @@ int main (void) #endif return 1; } - + Mapz->getSize(x_max,y_max,z_max); - //Get cursor + //Get cursor int32_t cursorX, cursorY, cursorZ; DFHack::Position *Pos = DF->getPosition(); Pos->getCursorCoords(cursorX,cursorY,cursorZ); - if(-30000==cursorX){ - cout << "No cursor position found. Exiting." << endl; + if (-30000==cursorX) + { + cout << "No cursor position found. Exiting." << endl; #ifndef LINUX_BUILD cin.ignore(); #endif return 1; - } + } - //Block coordinates + //Block coordinates int32_t bx=cursorX/16, by=cursorY/16, bz=cursorZ; - //Tile coordinates within block + //Tile coordinates within block int32_t tx=cursorX%16, ty=cursorY%16, tz=cursorZ; - - /* - //Access the DF interface to pause the game. - //Copied from the reveal tool. + /* + //Access the DF interface to pause the game. + //Copied from the reveal tool. DFHack::Gui *Gui =DF->getGui(); cout << "Pausing..." << endl; Gui->SetPauseState(true); DF->Resume(); waitmsec(1000); DF->Suspend(); - */ - + */ - //Verify that every z-level at this location exists. - for(int32_t Z = 0; Z<= bz ;Z++){ - if( ! Mapz->isValidBlock(bx,by,Z) ){ - cout << "This block does't exist! Exiting." << endl; - #ifndef LINUX_BUILD - cin.ignore(); - #endif - return 1; - } - } + //Verify that every z-level at this location exists. + for (int32_t Z = 0; Z<= bz ;Z++) + { + if ( ! Mapz->isValidBlock(bx,by,Z) ) + { + cout << "This block does't exist! Exiting." << endl; + #ifndef LINUX_BUILD + cin.ignore(); + #endif + return 1; + } + } - //Get all the map features. + //Get all the map features. vector global_features; - if(!Mapz->ReadGlobalFeatures(global_features)){ - cout << "Couldn't load global features! Probably a version problem." << endl; - #ifndef LINUX_BUILD - cin.ignore(); - #endif - return 1; - } + if (!Mapz->ReadGlobalFeatures(global_features)) + { + cout << "Couldn't load global features! Probably a version problem." << endl; + #ifndef LINUX_BUILD + cin.ignore(); + #endif + return 1; + } + std::map > local_features; - if(!Mapz->ReadLocalFeatures(local_features)){ - cout << "Couldn't load local features! Probably a version problem." << endl; - #ifndef LINUX_BUILD - cin.ignore(); - #endif - return 1; - } - - //Get info on current tile, to determine how to generate the pit - mapblock40d topblock; - Mapz->ReadBlock40d( bx, by, bz , &topblock ); - //Related block info - planecoord pc; - pc.dim.x=bx; pc.dim.y=by; - mapblock40d block; - const TileRow * tp; - t_designation * d; - - ////////////////////////////////////// - //From top to bottom, dig this thing. - ////////////////////////////////////// - - //Top level, cap. - //Might make this an option in the future - //For now, no wall means no cap. - if(wallthickness){ - Mapz->ReadBlock40d( bx, by, bz , &block ); - for(uint32_t x=0;x<16;++x){ - for(uint32_t y=0;y<16;++y){ - if( (pattern[x][y]>1) || (roof && pattern[x][y]) ){ - tp = getTileTypeP(block.tiletypes[x][y]); - d = &block.designation[x][y]; - //Only modify this level if it's 'empty' - if( EMPTY != tp->c && RAMP_TOP != tp->c && STAIR_DOWN != tp->c && DFHack::TILE_STREAM_TOP != tp->s) continue; - - //Need a floor for empty space. - if(reveal) d->bits.hidden = 0; //topblock.designation[x][y].bits.hidden; - //Always clear the dig designation. - d->bits.dig=designation_no; - //unlock fluids, so they fall down the pit. - d->bits.flow_forbid = d->bits.liquid_static=0; - block.blockflags.bits.liquid_1 = block.blockflags.bits.liquid_2 = 1; - //Remove aquifer, to prevent bugginess - d->bits.water_table=0; - //Set the tile. - block.tiletypes[x][y] = cap + rand()%4; - } - } - } - //Write the block. - Mapz->WriteBlockFlags(bx,by,bz, block.blockflags ); - Mapz->WriteDesignations(bx,by,bz, &block.designation ); - Mapz->WriteTileTypes(bx,by,bz, &block.tiletypes ); - Mapz->WriteDirtyBit(bx,by,bz,1); - } - - /////////////////////////////////////////////////////////////////////////////////////////////// - //All levels in between. - int done=0; - uint32_t t,v; - int32_t z = bz-1; - int32_t bottom = max(0,bz-pitdepth-1); - assert( bottom>=0 && bottom<=bz ); - for( ; !done && z>=bottom ; --z){ - int watercount=0; - int magmacount=0; - int moltencount=0; - int rockcount=0; - int veincount=0; - int emptycount=0; - int hellcount=0; - int templecount=0; - int adamcount=0; - int featcount=0; - int tpat; - - cout << z << endl; - assert( Mapz->isValidBlock(bx,by,z) ); - if(!Mapz->ReadBlock40d( bx, by, z , &block )){ - cout << "Bad block! " << bx << "," << by << "," << z << endl; - } - - //Pre-process this z-level, to get some tile statistics. - for(int32_t x=0;x<16;++x) - { - for(int32_t y=0;y<16;++y) - { - t=0; - tp = getTileTypeP(block.tiletypes[x][y]); - d = &block.designation[x][y]; - tpat=pattern[x][y]; - - //Tile type material categories - switch( tp->m ){ - case AIR: - ++emptycount; - break; - case MAGMA: - ++moltencount; - break; - case VEIN: - ++veincount; - break; - case FEATSTONE: - case HFS: - case OBSIDIAN: - //basicly, ignored. - break; - default: - if( EMPTY == tp->c || RAMP_TOP == tp->c || STAIR_DOWN == tp->c ){ - ++emptycount; - }else{ - ++rockcount; - } - break; - } - - //Magma and water - if( d->bits.flow_size ){ - if(d->bits.liquid_type){ - ++magmacount; - }else{ - ++watercount; - } - } - - - //Check for Features - if( block.local_feature > -1 || block.global_feature > -1 ){ - //Count tiles which actually are in the feature. - //It is possible for a block to have a feature, but no tiles to be feature. - if( d->bits.feature_global || d->bits.feature_local ){ - //All features - ++featcount; - - if( d->bits.feature_global && d->bits.feature_local ){ - cout << "warn:tile is global and local at same time!" << endl; - } - - n=0; - if( block.global_feature > -1 && d->bits.feature_global ){ - n=global_features[block.global_feature].type; - switch( n ){ - case feature_Other: - //no count - break; - case feature_Adamantine_Tube: - ++adamcount; - break; - case feature_Underworld: - ++hellcount; - break; - case feature_Hell_Temple: - ++templecount; - break; - default: - //something here. for debugging, it may be interesting to know. - if(n) cout << '(' << n << ')'; - } - } - - n=0; - if( block.local_feature > -1 && d->bits.feature_local ){ - n=local_features[pc][block.local_feature]->type; - switch( n ){ - case feature_Other: - //no count - break; - case feature_Adamantine_Tube: - ++adamcount; - break; - case feature_Underworld: - ++hellcount; - break; - case feature_Hell_Temple: - ++templecount; - break; - default: - //something here. for debugging, it may be interesting to know. - if(n) cout << '[' << n << ']'; - } - } - } - } - } - } - - - //If stopping at magma, and no no non-feature stone in this layer, and magma found, then we're either at - //or below the magma sea / molten rock. - if( stopatmagma && (moltencount || magmacount) && (!exposemagma || !rockcount) ){ - //If not exposing magma, quit at the first sign of magma. - //If exposing magma, quite once magma is exposed. - done=-1; - } - - - ///////////////////////////////////////////////////////////////////////////////////////////////// - //Some checks, based on settings and stats collected - //First check, are we at illegal depth? - if( !done && hellcount && stopatmagma ){ - //Panic! - done=-1; - tpat=0; - cout << "error: illegal breach of hell!" << endl; - } - - - ///////////////////////////////////////////////////////////////////////////////////////////////// - //Actually process the current z-level. - //These loops do the work. - for(int32_t x=0;!done && x<16;++x){ - for(int32_t y=0;!done && y<16;++y){ - t=0; - tp = getTileTypeP(block.tiletypes[x][y]); - d = &block.designation[x][y]; - tpat=pattern[x][y]; - - //Up front, remove aquifer, to prevent bugginess - //It may be added back if aquify is set. - d->bits.water_table=0; - - - //Change behaviour based on settings and stats from this z-level - - //In hell? - if( tpat && tpat!=3 && isfeature(global_features, local_features,block,pc,x,y,feature_Underworld ) ){ - if( exposehell ){ - tpat=0; - } - } - - //Expose magma? - if( tpat && tpat!=3 && exposemagma ){ - //Leave certain tiles unchanged. - switch( tp->m ){ - case HFS: - case FEATSTONE: - case MAGMA: - tpat=0; - default: - break; - } - //Adamantine may be left unchanged... - if( isfeature(global_features, local_features,block,pc,x,y,feature_Adamantine_Tube ) ){ - tpat=0; - } - //Leave magma sea unchanged. - if( d->bits.flow_size && d->bits.liquid_type){ - tpat=0; - } - } - - - //For all situations... - //Special modification for walls, always for adamantine. - if( isfeature(global_features, local_features,block,pc,x,y,feature_Adamantine_Tube ) ){ - if( 2==pattern[x][y] || 3==pattern[x][y] ){ - tpat=2; - } - } - - - //Border or space? - switch(tpat){ - case 0: - continue; - break; - case 1: - //Empty Space - t=32; - //d->bits.light = topblock.designation[x][y].bits.light; - //d->bits.skyview = topblock.designation[x][y].bits.skyview; - //d->bits.subterranean = topblock.designation[x][y].bits.subterranean; - - //Erase special markers? - //d->bits.feature_global = d->bits.feature_local = 0; - - //Water? Magma? - if(fillmagma || fillwater){ - d->bits.flow_size=7; - d->bits.liquid_character = liquid_fresh; - if(fillmagma){ - d->bits.liquid_type=liquid_magma; - }else{ - d->bits.liquid_type=liquid_water; - } - }else{ - //Otherwise, remove all liquids. - d->bits.flow_size=0; - d->bits.liquid_character = liquid_fresh; - d->bits.liquid_type = liquid_water; - } - - break; - case 2: - //Wall. - //First guess based on current material - switch( tp->m ){ - case OBSIDIAN: - t=wmagma; - break; - case MAGMA: - t=wmolten; - break; - case HFS: - //t=whell; - break; - case VEIN: - t=440; //Solid vein block - break; - case FEATSTONE: - t=335; //Solid feature stone block - break; - default: - t=wcave; - } - - - //Adamantine (a local feature) trumps veins. - { - //Local Feature? - if( block.local_feature > -1 ){ - switch( n=local_features[pc][block.local_feature]->type ){ - case feature_Underworld: - case feature_Hell_Temple: - //Only adopt these if there is no global feature present - if( block.global_feature >-1 ){ - break; - } - case feature_Adamantine_Tube: - //Always for adamantine, sometimes for others - //Whatever the feature is made of. "featstone wall" - d->bits.feature_global = 0; - d->bits.feature_local = 1; - t=335; - break; - } - } - //Global Feature? - else if(block.global_feature > -1 && !d->bits.feature_local ){ - switch( n=global_features[block.global_feature].type ){ - case feature_Adamantine_Tube: - case feature_Underworld: - case feature_Hell_Temple: - //Whatever the feature is made of. "featstone wall" - d->bits.feature_global = 1; - t=335; - break; - } - } - } - - //Erase any liquids, as they cause problems. - d->bits.flow_size=0; - d->bits.liquid_character = liquid_fresh; - d->bits.liquid_type=liquid_water; - - //Placing an aquifer? - //(bugged, these aquifers don't generate water!) - if( aquify ){ - //Only normal stone types can be aquified - if( tp->m!=MAGMA && tp->m!=FEATSTONE && tp->m!=HFS ){ - //Only place next to the hole. - //If no hole, place in middle. - if( checkneighbors(pattern,x,y,1) || (7==x && 7==y) ){ - d->bits.water_table = 1; - //t=265; //soil wall - } - } - } - - break; - - case 3: - ////No obsidian walls on bottom of map! - //if(z<1 && (d->bits.feature_global || d->bits.feature_local) ) { - // t=335; - //} - - //Special wall, always sets to obsidian, to give a stairway - t=331; - - //Erase special markers - d->bits.feature_global = d->bits.feature_local = 0; - - //Erase any liquids, as they cause problems. - d->bits.flow_size=0; - d->bits.liquid_character = liquid_fresh; - d->bits.liquid_type=liquid_water; - break; - default: - cout << ".error,bad pattern."; - } - - //For all tiles. - if(reveal) d->bits.hidden = 0; //topblock.designation[x][y].bits.hidden; - //Always clear the dig designation. - d->bits.dig=designation_no; - //Make it underground, because it is capped - d->bits.subterranean=1; - d->bits.light=0; - d->bits.skyview=0; - //unlock fluids, so they fall down the pit. - d->bits.flow_forbid = d->bits.liquid_static=0; - block.blockflags.bits.liquid_1 = block.blockflags.bits.liquid_2 = 1; - //Set the tile. - block.tiletypes[x][y] = t; - - } - } - - //Write the block. - Mapz->WriteBlockFlags(bx,by,z, block.blockflags ); - Mapz->WriteDesignations(bx,by,z, &block.designation ); - Mapz->WriteTileTypes(bx,by,z, &block.tiletypes ); - Mapz->WriteDirtyBit(bx,by,z,1); - - } - - //Re-process the last z-level handled above. - z++; - assert( z>=0 ); - - - /////////////////////////////////////////////////////////////////////////////////////////////// - //The bottom level is special. - if(-1){ - if(!Mapz->ReadBlock40d( bx, by, z , &block )){ - cout << "Bad block! " << bx << "," << by << "," << z << endl; - } - for(uint32_t x=0;x<16;++x){ - for(uint32_t y=0;y<16;++y){ - t=floor; - v=floorvar; - tp = getTileTypeP(block.tiletypes[x][y]); - d = &block.designation[x][y]; - - if( exposehell ){ - //Leave hell tiles unchanged when exposing hell. - if( isfeature(global_features,local_features,block,pc,x,y,feature_Underworld) ){ - continue; - } - } - - //Does expose magma need anything at this level? - if( exposemagma && stopatmagma ){ - continue; - } - - switch(pattern[x][y]){ - case 0: - continue; - break; - case 1: - //Empty becomes floor. - - //Base floor type on the z-level first, features, then tile type. - if(!z){ - //Bottom of map, use the floor specified, always. - break; - } - - ////Only place floor where ground is already solid when exposing - //if( EMPTY == tp->c || RAMP_TOP == tp->c || STAIR_DOWN == tp->c ){ - // continue; - //} - - if( d->bits.feature_global || d->bits.feature_global ){ - //Feature Floor! - t=344; - break; - } - - //Tile material check. - switch( tp->m ){ - case OBSIDIAN: - t=340; - v=3; - break; - case MAGMA: - v=0; - t=264; //magma flow - break; - case HFS: - //should only happen at bottom of map - break; - case VEIN: - t=441; //vein floor - v=3; - break; - case FEATSTONE: - t=344; - v=3; - break; - } - - break; - case 2: - case 3: - //Walls already drawn. - //Ignore. - continue; - break; - } - - //For all tiles. - if(reveal) d->bits.hidden = 0; //topblock.designation[x][y].bits.hidden; - //Always clear the dig designation. - d->bits.dig=designation_no; - //unlock fluids - d->bits.flow_forbid = d->bits.liquid_static=0; - block.blockflags.bits.liquid_1 = block.blockflags.bits.liquid_2 = 1; - - //Set the tile. - block.tiletypes[x][y] = t + ( v ? rand()&v : 0 ) ; - - } - } - //Write the block. - Mapz->WriteBlockFlags(bx,by,z, block.blockflags ); - Mapz->WriteDesignations(bx,by,z, &block.designation ); - Mapz->WriteTileTypes(bx,by,z, &block.tiletypes ); - Mapz->WriteDirtyBit(bx,by,z,1); - } + if (!Mapz->ReadLocalFeatures(local_features)) + { + cout << "Couldn't load local features! Probably a version problem." << endl; + #ifndef LINUX_BUILD + cin.ignore(); + #endif + return 1; + } + //Get info on current tile, to determine how to generate the pit + mapblock40d topblock; + Mapz->ReadBlock40d( bx, by, bz , &topblock ); + //Related block info + planecoord pc; + pc.dim.x=bx; + pc.dim.y=by; + mapblock40d block; + const TileRow * tp; + t_designation * d; + + ////////////////////////////////////// + //From top to bottom, dig this thing. + ////////////////////////////////////// + + //Top level, cap. + //Might make this an option in the future + //For now, no wall means no cap. + if (wallthickness) + { + Mapz->ReadBlock40d( bx, by, bz , &block ); + for (uint32_t x=0;x<16;++x) + { + for (uint32_t y=0;y<16;++y) + { + if ( (pattern[x][y]>1) || (roof && pattern[x][y]) ) + { + tp = getTileTypeP(block.tiletypes[x][y]); + d = &block.designation[x][y]; + //Only modify this level if it's 'empty' + if ( EMPTY != tp->c && RAMP_TOP != tp->c && STAIR_DOWN != tp->c && DFHack::TILE_STREAM_TOP != tp->s) + { + continue; + } + + //Need a floor for empty space. + if (reveal) + { + d->bits.hidden = 0; //topblock.designation[x][y].bits.hidden; + } + //Always clear the dig designation. + d->bits.dig = designation_no; + //unlock fluids, so they fall down the pit. + d->bits.flow_forbid = d->bits.liquid_static=0; + block.blockflags.bits.liquid_1 = block.blockflags.bits.liquid_2 = 1; + //Remove aquifer, to prevent bugginess + d->bits.water_table=0; + //Set the tile. + block.tiletypes[x][y] = cap + rand()%4; + } + } + } + //Write the block. + Mapz->WriteBlockFlags(bx,by,bz, block.blockflags ); + Mapz->WriteDesignations(bx,by,bz, &block.designation ); + Mapz->WriteTileTypes(bx,by,bz, &block.tiletypes ); + Mapz->WriteDirtyBit(bx,by,bz,1); + } + + /////////////////////////////////////////////////////////////////////////////////////////////// + //All levels in between. + int done=0; + uint32_t t,v; + int32_t z = bz-1; + int32_t bottom = max(0,bz-pitdepth-1); + assert( bottom>=0 && bottom<=bz ); + for ( ; !done && z>=bottom ; --z) + { + int watercount=0; + int magmacount=0; + int moltencount=0; + int rockcount=0; + int veincount=0; + int emptycount=0; + int hellcount=0; + int templecount=0; + int adamcount=0; + int featcount=0; + int tpat; + + cout << z << endl; + assert( Mapz->isValidBlock(bx,by,z) ); + if (!Mapz->ReadBlock40d( bx, by, z , &block )) + { + cout << "Bad block! " << bx << "," << by << "," << z << endl; + } + + //Pre-process this z-level, to get some tile statistics. + for (int32_t x=0;x<16;++x) + { + for (int32_t y=0;y<16;++y) + { + t=0; + tp = getTileTypeP(block.tiletypes[x][y]); + d = &block.designation[x][y]; + tpat=pattern[x][y]; + + //Tile type material categories + switch ( tp->m ) + { + case AIR: + ++emptycount; + break; + case MAGMA: + ++moltencount; + break; + case VEIN: + ++veincount; + break; + case FEATSTONE: + case HFS: + case OBSIDIAN: + //basicly, ignored. + break; + default: + if ( EMPTY == tp->c || RAMP_TOP == tp->c || STAIR_DOWN == tp->c ) + { + ++emptycount; + } + else + { + ++rockcount; + } + break; + } + + //Magma and water + if ( d->bits.flow_size ) + { + if (d->bits.liquid_type) + { + ++magmacount; + } + else + { + ++watercount; + } + } + + + //Check for Features + if ( block.local_feature > -1 || block.global_feature > -1 ) + { + //Count tiles which actually are in the feature. + //It is possible for a block to have a feature, but no tiles to be feature. + if ( d->bits.feature_global || d->bits.feature_local ) + { + //All features + ++featcount; + + if ( d->bits.feature_global && d->bits.feature_local ) + { + cout << "warn:tile is global and local at same time!" << endl; + } + + n=0; + if ( block.global_feature > -1 && d->bits.feature_global ) + { + n=global_features[block.global_feature].type; + switch ( n ) + { + case feature_Other: + //no count + break; + case feature_Adamantine_Tube: + ++adamcount; + break; + case feature_Underworld: + ++hellcount; + break; + case feature_Hell_Temple: + ++templecount; + break; + default: + //something here. for debugging, it may be interesting to know. + if (n) cout << '(' << n << ')'; + } + } + + n=0; + if ( block.local_feature > -1 && d->bits.feature_local ) + { + n=local_features[pc][block.local_feature]->type; + switch ( n ) + { + case feature_Other: + //no count + break; + case feature_Adamantine_Tube: + ++adamcount; + break; + case feature_Underworld: + ++hellcount; + break; + case feature_Hell_Temple: + ++templecount; + break; + default: + //something here. for debugging, it may be interesting to know. + if (n) cout << '[' << n << ']'; + } + } + } + } + } + } + + + //If stopping at magma, and no no non-feature stone in this layer, and magma found, then we're either at + //or below the magma sea / molten rock. + if ( stopatmagma && (moltencount || magmacount) && (!exposemagma || !rockcount) ) + { + //If not exposing magma, quit at the first sign of magma. + //If exposing magma, quite once magma is exposed. + done=-1; + } + + + ///////////////////////////////////////////////////////////////////////////////////////////////// + //Some checks, based on settings and stats collected + //First check, are we at illegal depth? + if ( !done && hellcount && stopatmagma ) + { + //Panic! + done=-1; + tpat=0; + cout << "error: illegal breach of hell!" << endl; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////// + //Actually process the current z-level. + //These loops do the work. + for (int32_t x=0;!done && x<16;++x) + { + for (int32_t y=0;!done && y<16;++y) + { + t=0; + tp = getTileTypeP(block.tiletypes[x][y]); + d = &block.designation[x][y]; + tpat=pattern[x][y]; + + //Up front, remove aquifer, to prevent bugginess + //It may be added back if aquify is set. + d->bits.water_table=0; + + //Change behaviour based on settings and stats from this z-level + + //In hell? + if ( tpat && tpat!=3 && isfeature(global_features, local_features,block,pc,x,y,feature_Underworld ) ) + { + if ( exposehell ) + { + tpat=0; + } + } + + //Expose magma? + if ( tpat && tpat!=3 && exposemagma ) + { + //Leave certain tiles unchanged. + switch ( tp->m ) + { + case HFS: + case FEATSTONE: + case MAGMA: + tpat=0; + default: + break; + } + //Adamantine may be left unchanged... + if ( isfeature(global_features, local_features,block,pc,x,y,feature_Adamantine_Tube ) ) + { + tpat=0; + } + //Leave magma sea unchanged. + if ( d->bits.flow_size && d->bits.liquid_type) + { + tpat=0; + } + } + + + //For all situations... + //Special modification for walls, always for adamantine. + if ( isfeature(global_features, local_features,block,pc,x,y,feature_Adamantine_Tube ) ) + { + if ( 2==pattern[x][y] || 3==pattern[x][y] ) + { + tpat=2; + } + } + + + //Border or space? + switch (tpat) + { + case 0: + continue; + break; + case 1: + //Empty Space + t=32; + //d->bits.light = topblock.designation[x][y].bits.light; + //d->bits.skyview = topblock.designation[x][y].bits.skyview; + //d->bits.subterranean = topblock.designation[x][y].bits.subterranean; + + //Erase special markers? + //d->bits.feature_global = d->bits.feature_local = 0; + + //Water? Magma? + if (fillmagma || fillwater) + { + d->bits.flow_size=7; + d->bits.liquid_character = liquid_fresh; + if (fillmagma) + { + d->bits.liquid_type=liquid_magma; + } + else + { + d->bits.liquid_type=liquid_water; + } + } + else + { + //Otherwise, remove all liquids. + d->bits.flow_size=0; + d->bits.liquid_character = liquid_fresh; + d->bits.liquid_type = liquid_water; + } + + break; + case 2: + //Wall. + //First guess based on current material + switch ( tp->m ) + { + case OBSIDIAN: + t=wmagma; + break; + case MAGMA: + t=wmolten; + break; + case HFS: + //t=whell; + break; + case VEIN: + t=440; //Solid vein block + break; + case FEATSTONE: + t=335; //Solid feature stone block + break; + default: + t=wcave; + } + //Adamantine (a local feature) trumps veins. + { + //Local Feature? + if ( block.local_feature > -1 ) + { + switch ( n=local_features[pc][block.local_feature]->type ) + { + case feature_Underworld: + case feature_Hell_Temple: + //Only adopt these if there is no global feature present + if ( block.global_feature >-1 ) + { + break; + } + case feature_Adamantine_Tube: + //Always for adamantine, sometimes for others + //Whatever the feature is made of. "featstone wall" + d->bits.feature_global = 0; + d->bits.feature_local = 1; + t=335; + break; + } + } + //Global Feature? + else if (block.global_feature > -1 && !d->bits.feature_local ) + { + switch ( n=global_features[block.global_feature].type ) + { + case feature_Adamantine_Tube: + case feature_Underworld: + case feature_Hell_Temple: + //Whatever the feature is made of. "featstone wall" + d->bits.feature_global = 1; + t=335; + break; + } + } + } + + //Erase any liquids, as they cause problems. + d->bits.flow_size=0; + d->bits.liquid_character = liquid_fresh; + d->bits.liquid_type=liquid_water; + + //Placing an aquifer? + //(bugged, these aquifers don't generate water!) + if ( aquify ) + { + //Only normal stone types can be aquified + if ( tp->m!=MAGMA && tp->m!=FEATSTONE && tp->m!=HFS ) + { + //Only place next to the hole. + //If no hole, place in middle. + if ( checkneighbors(pattern,x,y,1) || (7==x && 7==y) ) + { + d->bits.water_table = 1; + //t=265; //soil wall + } + } + } + break; + case 3: + ////No obsidian walls on bottom of map! + //if(z<1 && (d->bits.feature_global || d->bits.feature_local) ) { + // t=335; + //} + + //Special wall, always sets to obsidian, to give a stairway + t=331; + + //Erase special markers + d->bits.feature_global = d->bits.feature_local = 0; + + //Erase any liquids, as they cause problems. + d->bits.flow_size=0; + d->bits.liquid_character = liquid_fresh; + d->bits.liquid_type=liquid_water; + break; + default: + cout << ".error,bad pattern."; + } + + //For all tiles. + if (reveal) + { + d->bits.hidden = 0; //topblock.designation[x][y].bits.hidden; + } + //Always clear the dig designation. + d->bits.dig=designation_no; + //Make it underground, because it is capped + d->bits.subterranean=1; + d->bits.light=0; + d->bits.skyview=0; + //unlock fluids, so they fall down the pit. + d->bits.flow_forbid = d->bits.liquid_static=0; + block.blockflags.bits.liquid_1 = block.blockflags.bits.liquid_2 = 1; + //Set the tile. + block.tiletypes[x][y] = t; + + } + } + + //Write the block. + Mapz->WriteBlockFlags(bx,by,z, block.blockflags ); + Mapz->WriteDesignations(bx,by,z, &block.designation ); + Mapz->WriteTileTypes(bx,by,z, &block.tiletypes ); + Mapz->WriteDirtyBit(bx,by,z,1); + + } + + //Re-process the last z-level handled above. + z++; + assert( z>=0 ); + + + /////////////////////////////////////////////////////////////////////////////////////////////// + //The bottom level is special. + if (-1) + { + if (!Mapz->ReadBlock40d( bx, by, z , &block )) + { + cout << "Bad block! " << bx << "," << by << "," << z << endl; + } + for (uint32_t x=0;x<16;++x) + { + for (uint32_t y=0;y<16;++y) + { + t=floor; + v=floorvar; + tp = getTileTypeP(block.tiletypes[x][y]); + d = &block.designation[x][y]; + + if ( exposehell ) + { + //Leave hell tiles unchanged when exposing hell. + if ( isfeature(global_features,local_features,block,pc,x,y,feature_Underworld) ) + { + continue; + } + } + + //Does expose magma need anything at this level? + if ( exposemagma && stopatmagma ) + { + continue; + } + + switch (pattern[x][y]) + { + case 0: + continue; + break; + case 1: + //Empty becomes floor. + + //Base floor type on the z-level first, features, then tile type. + if (!z) { + //Bottom of map, use the floor specified, always. + break; + } + + ////Only place floor where ground is already solid when exposing + //if( EMPTY == tp->c || RAMP_TOP == tp->c || STAIR_DOWN == tp->c ){ + // continue; + //} + + if ( d->bits.feature_global || d->bits.feature_global ) { + //Feature Floor! + t=344; + break; + } + + //Tile material check. + switch ( tp->m ) + { + case OBSIDIAN: + t=340; + v=3; + break; + case MAGMA: + v=0; + t=264; //magma flow + break; + case HFS: + //should only happen at bottom of map + break; + case VEIN: + t=441; //vein floor + v=3; + break; + case FEATSTONE: + t=344; + v=3; + break; + } + + break; + case 2: + case 3: + //Walls already drawn. + //Ignore. + continue; + break; + } + + //For all tiles. + if (reveal) d->bits.hidden = 0; //topblock.designation[x][y].bits.hidden; + //Always clear the dig designation. + d->bits.dig=designation_no; + //unlock fluids + d->bits.flow_forbid = d->bits.liquid_static=0; + block.blockflags.bits.liquid_1 = block.blockflags.bits.liquid_2 = 1; + + //Set the tile. + block.tiletypes[x][y] = t + ( v ? rand()&v : 0 ); + } + } + //Write the block. + Mapz->WriteBlockFlags(bx,by,z, block.blockflags ); + Mapz->WriteDesignations(bx,by,z, &block.designation ); + Mapz->WriteTileTypes(bx,by,z, &block.tiletypes ); + Mapz->WriteDirtyBit(bx,by,z,1); + } DF->Detach(); - #ifndef LINUX_BUILD +#ifndef LINUX_BUILD cout << "Done. Press any key to continue" << endl; cin.ignore(); - #endif +#endif return 0; } diff --git a/tools/playground/printtiletypes.cpp b/tools/playground/printtiletypes.cpp index 1016694c9..b9e9d75ce 100644 --- a/tools/playground/printtiletypes.cpp +++ b/tools/playground/printtiletypes.cpp @@ -17,77 +17,84 @@ using namespace DFHack; int main (int argc, char **argv) { - FILE *f=stdout; - const int Columns = 7; - const char * Headings[Columns] = {"TileTypeID","Class","Material","V","Special","Direction","Description"}; - size_t Size[ Columns ] = {}; - int i; + FILE *f=stdout; + const int Columns = 7; + const char * Headings[Columns] = {"TileTypeID","Class","Material","V","Special","Direction","Description"}; + size_t Size[ Columns ] = {}; + int i; - //First, figure out column widths. - for(i=0;i(Size[1],strlen(TileClassString[i])); - fprintf(f,"%4i ; %s\n", i, TileClassString[i] ,0 ); - } + //Classes + fprintf(f,"\nTile Type Classes:\n"); + for(i=0;i(Size[1],strlen(TileClassString[i])); + fprintf(f,"%4i ; %s\n", i, TileClassString[i] ,0 ); + } - //Materials - fprintf(f,"\nTile Type Materials:\n"); - for(i=0;i(Size[2],strlen(TileMaterialString[i])); - fprintf(f,"%4i ; %s\n", i, TileMaterialString[i] ,0 ); - } + //Materials + fprintf(f,"\nTile Type Materials:\n"); + for(i=0;i(Size[2],strlen(TileMaterialString[i])); + fprintf(f,"%4i ; %s\n", i, TileMaterialString[i] ,0 ); + } - //Specials - fprintf(f,"\nTile Type Specials:\n"); - for(i=0;i(Size[4],strlen(TileSpecialString[i])); - fprintf(f,"%4i ; %s\n", i, TileSpecialString[i] ,0 ); - } + //Specials + fprintf(f,"\nTile Type Specials:\n"); + for(i=0;i(Size[4],strlen(TileSpecialString[i])); + fprintf(f,"%4i ; %s\n", i, TileSpecialString[i] ,0 ); + } - /* - Not needed for now - - //Direction is tricky - for(i=0;i -#include -#include -#include -#include -#include -#include - -#define DFHACK_WANT_MISCUTILS 1 -#define DFHACK_WANT_TILETYPES 1 -#include - -using namespace DFHack; -int main (int numargs, const char ** args) -{ - DFHack::ContextManager DFMgr("Memory.xml"); - DFHack::Context *DF = DFMgr.getSingleContext(); - -BEGIN_PROBE: - try - { - DF->Attach(); - } - catch (std::exception& e) - { - std::cerr << e.what() << std::endl; - #ifndef LINUX_BUILD - cin.ignore(); - #endif - return 1; - } - - - DFHack::Position *Pos = DF->getPosition(); - DFHack::VersionInfo* mem = DF->getMemoryInfo(); - DFHack::Maps *Maps = DF->getMaps(); - DFHack::Process * p = DF->getProcess(); - OffsetGroup *mapsg = mem->getGroup("Maps"); - OffsetGroup *mapblockg = mapsg->getGroup("block"); - OffsetGroup *localfeatg = mapsg->getGroup("features")->getGroup("local"); - - uint32_t region_x_offset = mapsg->getAddress("region_x"); - uint32_t region_y_offset = mapsg->getAddress("region_y"); - uint32_t region_z_offset = mapsg->getAddress("region_z"); - - uint32_t designatus = mapblockg->getOffset("designation"); - uint32_t block_feature1 = mapblockg->getOffset("feature_local"); - uint32_t block_feature2 = mapblockg->getOffset("feature_global"); - - uint32_t feature1_start_ptr = localfeatg->getAddress("start_ptr"); - int32_t regionX, regionY, regionZ; - - // read position of the region inside DF world - p->readDWord (region_x_offset, (uint32_t &)regionX); - p->readDWord (region_y_offset, (uint32_t &)regionY); - p->readDWord (region_z_offset, (uint32_t &)regionZ); - - Maps->Start(); - +// Just show some position data + +#include +#include +#include +#include +#include +#include +#include + +#define DFHACK_WANT_MISCUTILS 1 +#define DFHACK_WANT_TILETYPES 1 +#include + +using namespace DFHack; +int main (int numargs, const char ** args) +{ + DFHack::ContextManager DFMgr("Memory.xml"); + DFHack::Context *DF = DFMgr.getSingleContext(); + + BEGIN_PROBE: + try + { + DF->Attach(); + } + catch (std::exception& e) + { + std::cerr << e.what() << std::endl; + #ifndef LINUX_BUILD + cin.ignore(); + #endif + return 1; + } + + + DFHack::Position *Pos = DF->getPosition(); + DFHack::VersionInfo* mem = DF->getMemoryInfo(); + DFHack::Maps *Maps = DF->getMaps(); + DFHack::Process * p = DF->getProcess(); + OffsetGroup *mapsg = mem->getGroup("Maps"); + OffsetGroup *mapblockg = mapsg->getGroup("block"); + OffsetGroup *localfeatg = mapsg->getGroup("features")->getGroup("local"); + + uint32_t region_x_offset = mapsg->getAddress("region_x"); + uint32_t region_y_offset = mapsg->getAddress("region_y"); + uint32_t region_z_offset = mapsg->getAddress("region_z"); + + uint32_t designatus = mapblockg->getOffset("designation"); + uint32_t block_feature1 = mapblockg->getOffset("feature_local"); + uint32_t block_feature2 = mapblockg->getOffset("feature_global"); + + uint32_t feature1_start_ptr = localfeatg->getAddress("start_ptr"); + int32_t regionX, regionY, regionZ; + + // read position of the region inside DF world + p->readDWord (region_x_offset, (uint32_t &)regionX); + p->readDWord (region_y_offset, (uint32_t &)regionY); + p->readDWord (region_z_offset, (uint32_t &)regionZ); + + Maps->Start(); + vector global_features; std::map > local_features; - Maps->ReadLocalFeatures(local_features); - Maps->ReadGlobalFeatures(global_features); - - int32_t cursorX, cursorY, cursorZ; - Pos->getCursorCoords(cursorX,cursorY,cursorZ); - if(cursorX != -30000) - { - uint32_t blockX = cursorX / 16; - uint32_t tileX = cursorX % 16; - uint32_t blockY = cursorY / 16; - uint32_t tileY = cursorY % 16; - t_temperatures tmpb1, tmpb2; - mapblock40d block; - if(Maps->ReadBlock40d(blockX,blockY,cursorZ,&block)) - { - Maps->ReadTemperatures(blockX,blockY,cursorZ,&tmpb1, &tmpb2); - printf("block addr: 0x%x\n", block.origin); - int16_t tiletype = block.tiletypes[tileX][tileY]; - naked_designation &des = block.designation[tileX][tileY].bits; - uint32_t &desw = block.designation[tileX][tileY].whole; - print_bits(block.designation[tileX][tileY].whole,std::cout); - std::cout << endl; - print_bits(block.occupancy[tileX][tileY].whole,std::cout); - std::cout << endl; - - // tiletype - std::cout <<"tiletype: " << tiletype; - if(tileTypeTable[tiletype].name) - std::cout << " = " << tileTypeTable[tiletype].name << std::endl; - - printf("%-10s: %4d %s\n","Class",tileTypeTable[tiletype].c,TileClassString[ tileTypeTable[tiletype].c ] , 0); - printf("%-10s: %4d %s\n","Material",tileTypeTable[tiletype].c,TileMaterialString[ tileTypeTable[tiletype].m ] , 0); - printf("%-10s: %4d %s\n","Special",tileTypeTable[tiletype].c,TileSpecialString[ tileTypeTable[tiletype].s ] , 0); - printf("%-10s: %4d\n","Variant",tileTypeTable[tiletype].v , 0); - printf("%-10s: %s\n","Direction",tileTypeTable[tiletype].d.getStr() , 0); - - - std::cout << std::endl; - std::cout <<"temperature1: " << tmpb1[tileX][tileY] << " U" << std::endl; - std::cout <<"temperature2: " << tmpb2[tileX][tileY] << " U" << std::endl; - - // biome, geolayer - std::cout << "biome: " << des.biome << std::endl; - std::cout << "geolayer: " << des.geolayer_index << std::endl; - - // liquids - if(des.flow_size) - { - if(des.liquid_type == DFHack::liquid_magma) - std::cout <<"magma: "; - else std::cout <<"water: "; - std::cout << des.flow_size << std::endl; - } - if(des.flow_forbid) - std::cout << "flow forbid" << std::endl; - if(des.pile) - std::cout << "stockpile?" << std::endl; - if(des.rained) - std::cout << "rained?" << std::endl; - if(des.smooth) - std::cout << "smooth?" << std::endl; - uint32_t designato = block.origin + designatus + (tileX * 16 + tileY) * sizeof(t_designation); - printf("designation offset: 0x%x\n", designato); - -#define PRINT_FLAG( X ) printf("%-16s= %c\n", #X , ( des.X ? 'Y' : ' ' ) ) - PRINT_FLAG( hidden ); - PRINT_FLAG( light ); - PRINT_FLAG( skyview ); - PRINT_FLAG( subterranean ); - PRINT_FLAG( water_table ); - //PRINT_FLAG( rained ); - - planecoord pc; - pc.dim.x=blockX; pc.dim.y=blockY; - - PRINT_FLAG( feature_local ); - if( des.feature_local ){ - printf("%-16s %4d (%2d) %s\n", "", - block.local_feature, - local_features[pc][block.local_feature]->type, - sa_feature[local_features[pc][block.local_feature]->type] - ); - } - - PRINT_FLAG( feature_global ); - if( des.feature_global ){ - printf("%-16s %4d (%2d) %s\n", "", - block.global_feature, - global_features[block.global_feature].type, - sa_feature[global_features[block.global_feature].type] - ); - } - -#undef PRINT_FLAG - - std::cout << std::endl; - } - } - DF->Detach(); - #ifndef LINUX_BUILD - //std::cout << "Done. Press any key to continue" << std::endl; - std::cout << "Press any key to refresh..." << std::endl; - cin.ignore(); - goto BEGIN_PROBE; - #endif - return 0; -} + Maps->ReadLocalFeatures(local_features); + Maps->ReadGlobalFeatures(global_features); + + int32_t cursorX, cursorY, cursorZ; + Pos->getCursorCoords(cursorX,cursorY,cursorZ); + if(cursorX != -30000) + { + uint32_t blockX = cursorX / 16; + uint32_t tileX = cursorX % 16; + uint32_t blockY = cursorY / 16; + uint32_t tileY = cursorY % 16; + t_temperatures tmpb1, tmpb2; + mapblock40d block; + if(Maps->ReadBlock40d(blockX,blockY,cursorZ,&block)) + { + Maps->ReadTemperatures(blockX,blockY,cursorZ,&tmpb1, &tmpb2); + printf("block addr: 0x%x\n", block.origin); + int16_t tiletype = block.tiletypes[tileX][tileY]; + naked_designation &des = block.designation[tileX][tileY].bits; + uint32_t &desw = block.designation[tileX][tileY].whole; + print_bits(block.designation[tileX][tileY].whole,std::cout); + std::cout << endl; + print_bits(block.occupancy[tileX][tileY].whole,std::cout); + std::cout << endl; + + // tiletype + std::cout <<"tiletype: " << tiletype; + if(tileTypeTable[tiletype].name) + std::cout << " = " << tileTypeTable[tiletype].name << std::endl; + + printf("%-10s: %4d %s\n","Class",tileTypeTable[tiletype].c,TileClassString[ tileTypeTable[tiletype].c ] , 0); + printf("%-10s: %4d %s\n","Material",tileTypeTable[tiletype].c,TileMaterialString[ tileTypeTable[tiletype].m ] , 0); + printf("%-10s: %4d %s\n","Special",tileTypeTable[tiletype].c,TileSpecialString[ tileTypeTable[tiletype].s ] , 0); + printf("%-10s: %4d\n","Variant",tileTypeTable[tiletype].v , 0); + printf("%-10s: %s\n","Direction",tileTypeTable[tiletype].d.getStr() , 0); + + + std::cout << std::endl; + std::cout <<"temperature1: " << tmpb1[tileX][tileY] << " U" << std::endl; + std::cout <<"temperature2: " << tmpb2[tileX][tileY] << " U" << std::endl; + + // biome, geolayer + std::cout << "biome: " << des.biome << std::endl; + std::cout << "geolayer: " << des.geolayer_index << std::endl; + + // liquids + if(des.flow_size) + { + if(des.liquid_type == DFHack::liquid_magma) + std::cout <<"magma: "; + else std::cout <<"water: "; + std::cout << des.flow_size << std::endl; + } + if(des.flow_forbid) + std::cout << "flow forbid" << std::endl; + if(des.pile) + std::cout << "stockpile?" << std::endl; + if(des.rained) + std::cout << "rained?" << std::endl; + if(des.smooth) + std::cout << "smooth?" << std::endl; + uint32_t designato = block.origin + designatus + (tileX * 16 + tileY) * sizeof(t_designation); + printf("designation offset: 0x%x\n", designato); + + #define PRINT_FLAG( X ) printf("%-16s= %c\n", #X , ( des.X ? 'Y' : ' ' ) ) + PRINT_FLAG( hidden ); + PRINT_FLAG( light ); + PRINT_FLAG( skyview ); + PRINT_FLAG( subterranean ); + PRINT_FLAG( water_table ); + //PRINT_FLAG( rained ); + + planecoord pc; + pc.dim.x=blockX; pc.dim.y=blockY; + + PRINT_FLAG( feature_local ); + if( des.feature_local ) + { + printf("%-16s %4d (%2d) %s\n", "", + block.local_feature, + local_features[pc][block.local_feature]->type, + sa_feature[local_features[pc][block.local_feature]->type] + ); + } + + PRINT_FLAG( feature_global ); + if( des.feature_global ){ + printf("%-16s %4d (%2d) %s\n", "", + block.global_feature, + global_features[block.global_feature].type, + sa_feature[global_features[block.global_feature].type] + ); + } + #undef PRINT_FLAG + std::cout << std::endl; + } + } + DF->Detach(); + #ifndef LINUX_BUILD + std::cout << "Press any key to refresh..." << std::endl; + cin.ignore(); + goto BEGIN_PROBE; + #endif + return 0; +}