allow adding purely decorative tiles in the editor without requiring mixing, leaving that up to the user
This commit is contained in:
parent
f38702ee81
commit
7ad3935dc6
7 changed files with 90 additions and 36 deletions
|
@ -100,6 +100,9 @@ void EditorChangeTile(const Vec2i &pos, int tileIndex, const Vec2i &lock_pos)
|
|||
|
||||
// Change the flags
|
||||
CMapField &mf = *Map.Field(pos);
|
||||
if (mf.isDecorative()) {
|
||||
return;
|
||||
}
|
||||
int tile = tileIndex;
|
||||
if (TileToolRandom) {
|
||||
int n = 0;
|
||||
|
@ -143,6 +146,10 @@ static void EditorChangeSurrounding(const Vec2i &pos, const Vec2i &lock_pos)
|
|||
return;
|
||||
}
|
||||
|
||||
if (mf.isDecorative()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const unsigned int quad = QuadFromTile(pos);
|
||||
const unsigned int TH_QUAD_M = 0xFFFF0000; // Top half quad mask
|
||||
const unsigned int BH_QUAD_M = 0x0000FFFF; // Bottom half quad mask
|
||||
|
@ -158,45 +165,53 @@ static void EditorChangeSurrounding(const Vec2i &pos, const Vec2i &lock_pos)
|
|||
if (pos.y) {
|
||||
const Vec2i offset(0, -1);
|
||||
// Insert into the bottom the new tile.
|
||||
unsigned q2 = QuadFromTile(pos + offset);
|
||||
unsigned u = (q2 & TH_QUAD_M) | ((quad >> 16) & BH_QUAD_M);
|
||||
if (u != q2 && (pos + offset) != lock_pos) {
|
||||
did_change = true;
|
||||
int tile = Map.Tileset->tileFromQuad(u & BH_QUAD_M, u);
|
||||
EditorChangeTile(pos + offset, tile, lock_pos);
|
||||
if (!(Map.Field(pos + offset)->isDecorative())) {
|
||||
unsigned q2 = QuadFromTile(pos + offset);
|
||||
unsigned u = (q2 & TH_QUAD_M) | ((quad >> 16) & BH_QUAD_M);
|
||||
if (u != q2 && (pos + offset) != lock_pos) {
|
||||
did_change = true;
|
||||
int tile = Map.Tileset->tileFromQuad(u & BH_QUAD_M, u);
|
||||
EditorChangeTile(pos + offset, tile, lock_pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pos.y < Map.Info.MapHeight - 1) {
|
||||
const Vec2i offset(0, 1);
|
||||
// Insert into the top the new tile.
|
||||
unsigned q2 = QuadFromTile(pos + offset);
|
||||
unsigned u = (q2 & BH_QUAD_M) | ((quad << 16) & TH_QUAD_M);
|
||||
if (u != q2 && (pos + offset) != lock_pos) {
|
||||
did_change = true;
|
||||
int tile = Map.Tileset->tileFromQuad(u & TH_QUAD_M, u);
|
||||
EditorChangeTile(pos + offset, tile, lock_pos);
|
||||
if (!(Map.Field(pos + offset)->isDecorative())) {
|
||||
unsigned q2 = QuadFromTile(pos + offset);
|
||||
unsigned u = (q2 & BH_QUAD_M) | ((quad << 16) & TH_QUAD_M);
|
||||
if (u != q2 && (pos + offset) != lock_pos) {
|
||||
did_change = true;
|
||||
int tile = Map.Tileset->tileFromQuad(u & TH_QUAD_M, u);
|
||||
EditorChangeTile(pos + offset, tile, lock_pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pos.x) {
|
||||
const Vec2i offset(-1, 0);
|
||||
// Insert into the left the new tile.
|
||||
unsigned q2 = QuadFromTile(pos + offset);
|
||||
unsigned u = (q2 & LH_QUAD_M) | ((quad >> 8) & RH_QUAD_M);
|
||||
if (u != q2 && (pos + offset) != lock_pos) {
|
||||
did_change = true;
|
||||
int tile = Map.Tileset->tileFromQuad(u & RH_QUAD_M, u);
|
||||
EditorChangeTile(pos + offset, tile, lock_pos);
|
||||
if (!(Map.Field(pos + offset)->isDecorative())) {
|
||||
unsigned q2 = QuadFromTile(pos + offset);
|
||||
unsigned u = (q2 & LH_QUAD_M) | ((quad >> 8) & RH_QUAD_M);
|
||||
if (u != q2 && (pos + offset) != lock_pos) {
|
||||
did_change = true;
|
||||
int tile = Map.Tileset->tileFromQuad(u & RH_QUAD_M, u);
|
||||
EditorChangeTile(pos + offset, tile, lock_pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pos.x < Map.Info.MapWidth - 1) {
|
||||
const Vec2i offset(1, 0);
|
||||
// Insert into the right the new tile.
|
||||
unsigned q2 = QuadFromTile(pos + offset);
|
||||
unsigned u = (q2 & RH_QUAD_M) | ((quad << 8) & LH_QUAD_M);
|
||||
if (u != q2 && (pos + offset) != lock_pos) {
|
||||
did_change = true;
|
||||
int tile = Map.Tileset->tileFromQuad(u & LH_QUAD_M, u);
|
||||
EditorChangeTile(pos + offset, tile, lock_pos);
|
||||
if (!(Map.Field(pos + offset)->isDecorative())) {
|
||||
unsigned q2 = QuadFromTile(pos + offset);
|
||||
unsigned u = (q2 & RH_QUAD_M) | ((quad << 8) & LH_QUAD_M);
|
||||
if (u != q2 && (pos + offset) != lock_pos) {
|
||||
did_change = true;
|
||||
int tile = Map.Tileset->tileFromQuad(u & LH_QUAD_M, u);
|
||||
EditorChangeTile(pos + offset, tile, lock_pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -210,6 +210,9 @@ public:
|
|||
/// Returns true, if coast on the map tile field
|
||||
bool RockOnMap() const;
|
||||
|
||||
/// Returns true if the field should not need mixing with the surroundings
|
||||
bool isDecorative() const;
|
||||
|
||||
bool isAWall() const;
|
||||
bool isHuman() const;
|
||||
bool isAHumanWall() const;
|
||||
|
@ -227,7 +230,7 @@ private:
|
|||
#endif
|
||||
unsigned short tile; /// graphic tile number
|
||||
public:
|
||||
unsigned short Flags; /// field flags
|
||||
unsigned int Flags; /// field flags
|
||||
private:
|
||||
unsigned char cost; /// unit cost to move in this tile
|
||||
public:
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
----------------------------------------------------------------------------*/
|
||||
|
||||
#include "vec2i.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
struct lua_State;
|
||||
|
@ -61,6 +62,8 @@ struct lua_State;
|
|||
#define MapFieldSeaUnit 0x4000 /// Water unit on field
|
||||
#define MapFieldBuilding 0x8000 /// Building on field
|
||||
|
||||
#define MapFieldDecorative 0x10000 /// A field that needs no mixing with the surroundings, for the editor
|
||||
|
||||
/**
|
||||
** These are used for lookup tiles types
|
||||
** mainly used for the FOW implementation of the seen woods/rocks
|
||||
|
@ -110,7 +113,7 @@ public:
|
|||
|
||||
public:
|
||||
unsigned short tile; /// graphical pos
|
||||
unsigned short flag; /// Flag
|
||||
unsigned int flag; /// Flag
|
||||
CTileInfo tileinfo; /// Tile descriptions
|
||||
};
|
||||
|
||||
|
@ -164,6 +167,7 @@ public:
|
|||
|
||||
void parse(lua_State *l);
|
||||
void buildTable(lua_State *l);
|
||||
int parseTilesetTileFlags(lua_State *l, int *back, int *j);
|
||||
|
||||
private:
|
||||
unsigned int getOrAddSolidTileIndexByName(const std::string &name);
|
||||
|
|
|
@ -233,6 +233,12 @@ bool CMapField::RockOnMap() const
|
|||
return CheckMask(MapFieldRocks);
|
||||
}
|
||||
|
||||
/// Returns true if the field should not need mixing with the surroundings
|
||||
bool CMapField::isDecorative() const
|
||||
{
|
||||
return CheckMask(MapFieldDecorative);
|
||||
}
|
||||
|
||||
bool CMapField::isAWall() const
|
||||
{
|
||||
return Flags & MapFieldWall;
|
||||
|
|
|
@ -468,8 +468,11 @@ static int CclSetTileFlags(lua_State *l)
|
|||
int j = 0;
|
||||
int flags = 0;
|
||||
|
||||
ParseTilesetTileFlags(l, &flags, &j);
|
||||
unsigned char newBase = Map.Tileset->parseTilesetTileFlags(l, &flags, &j);
|
||||
Map.Tileset->tiles[tilenumber].flag = flags;
|
||||
if (newBase) {
|
||||
Map.Tileset->tiles[tilenumber].tileinfo.BaseTerrain = newBase;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "tileset.h"
|
||||
|
||||
#include "script.h"
|
||||
#include <cstring>
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Functions
|
||||
|
@ -61,7 +62,8 @@ static bool ModifyFlag(const char *flagName, unsigned int *flag)
|
|||
{"air-unit", MapFieldAirUnit},
|
||||
{"sea-unit", MapFieldSeaUnit},
|
||||
{"building", MapFieldBuilding},
|
||||
{"human", MapFieldHuman}
|
||||
{"human", MapFieldHuman},
|
||||
{"decorative", MapFieldDecorative}
|
||||
};
|
||||
|
||||
for (unsigned int i = 0; i != sizeof(flags) / sizeof(*flags); ++i) {
|
||||
|
@ -98,8 +100,10 @@ static bool ModifyFlag(const char *flagName, unsigned int *flag)
|
|||
** @param back pointer for the flags (return).
|
||||
** @param j pointer for the location in the array. in and out
|
||||
**
|
||||
** @return index for basename, if the name this tile should be available as a different basename, or 0
|
||||
**
|
||||
*/
|
||||
void ParseTilesetTileFlags(lua_State *l, int *back, int *j)
|
||||
int CTileset::parseTilesetTileFlags(lua_State *l, int *back, int *j)
|
||||
{
|
||||
unsigned int flags = 3;
|
||||
|
||||
|
@ -114,12 +118,18 @@ void ParseTilesetTileFlags(lua_State *l, int *back, int *j)
|
|||
const char *value = LuaToString(l, -1);
|
||||
lua_pop(l, 1);
|
||||
|
||||
// Flags are only needed for the editor
|
||||
// Flags are mostly needed for the editor
|
||||
if (ModifyFlag(value, &flags) == false) {
|
||||
LuaError(l, "solid: unsupported tag: %s" _C_ value);
|
||||
}
|
||||
}
|
||||
*back = flags;
|
||||
|
||||
if (flags & MapFieldDecorative) {
|
||||
return getOrAddSolidTileIndexByName(std::to_string(solidTerrainTypes.size()));
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -190,7 +200,10 @@ void CTileset::parseSolid(lua_State *l)
|
|||
++j;
|
||||
|
||||
int f = 0;
|
||||
ParseTilesetTileFlags(l, &f, &j);
|
||||
if (parseTilesetTileFlags(l, &f, &j)) {
|
||||
LuaError(l, "cannot set a custom basename in the main set of flags");
|
||||
}
|
||||
|
||||
// Vector: the tiles.
|
||||
lua_rawgeti(l, -1, j + 1);
|
||||
if (!lua_istable(l, -1)) {
|
||||
|
@ -204,10 +217,13 @@ void CTileset::parseSolid(lua_State *l)
|
|||
if (lua_istable(l, -1)) {
|
||||
int k = 0;
|
||||
int tile_flag = 0;
|
||||
ParseTilesetTileFlags(l, &tile_flag, &k);
|
||||
unsigned char new_basename = parseTilesetTileFlags(l, &tile_flag, &k);
|
||||
--j;
|
||||
lua_pop(l, 1);
|
||||
tiles[index + j].flag = tile_flag;
|
||||
if (new_basename) {
|
||||
tiles[index + j].tileinfo.BaseTerrain = new_basename;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
const int pud = LuaToNumber(l, -1);
|
||||
|
@ -248,7 +264,9 @@ void CTileset::parseMixed(lua_State *l)
|
|||
++j;
|
||||
|
||||
int f = 0;
|
||||
ParseTilesetTileFlags(l, &f, &j);
|
||||
if (parseTilesetTileFlags(l, &f, &j)) {
|
||||
LuaError(l, "cannot set a custom basename in the main set of flags");
|
||||
}
|
||||
|
||||
for (; j < args; ++j) {
|
||||
lua_rawgeti(l, -1, j + 1);
|
||||
|
|
|
@ -656,11 +656,16 @@ unsigned CTileset::getQuadFromTile(unsigned int tile) const
|
|||
|
||||
void CTileset::fillSolidTiles(std::vector<unsigned int> *solidTiles) const
|
||||
{
|
||||
for (size_t i = 16; i < tiles.size(); i += 16) {
|
||||
const CTileInfo &info = tiles[i].tileinfo;
|
||||
std::vector<int> seen_types;
|
||||
seen_types.resize(solidTerrainTypes.size(), 0);
|
||||
|
||||
for (size_t i = 16; i < tiles.size(); i++) {
|
||||
const CTileInfo &info = tiles[i].tileinfo;
|
||||
if (info.BaseTerrain && info.MixTerrain == 0) {
|
||||
solidTiles->push_back(tiles[i].tile);
|
||||
if (seen_types[info.BaseTerrain] == 0) {
|
||||
seen_types[info.BaseTerrain] = 1;
|
||||
solidTiles->push_back(tiles[i].tile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue