Add CTileset::getTileNumber and fillSolidTiles
cleanup editloop.cpp Use loop.
This commit is contained in:
parent
c348a93f61
commit
2773438529
5 changed files with 301 additions and 355 deletions
src
|
@ -174,74 +174,26 @@ static EditorSliderListener *editorSliderListener;
|
|||
-- Edit
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
** Get tile number.
|
||||
**
|
||||
** @param basic Basic tile number
|
||||
** @param random Return random tile
|
||||
** @param filler Get a decorated tile.
|
||||
**
|
||||
** @return Tile number used in pud.
|
||||
**
|
||||
** @todo FIXME: Solid tiles are here still hardcoded.
|
||||
*/
|
||||
static int GetTileNumber(int basic, int random, int filler)
|
||||
{
|
||||
int tile = basic;
|
||||
if (random) {
|
||||
int i, n;
|
||||
for (n = i = 0; i < 16; ++i) {
|
||||
if (!Map.Tileset->Table[tile + i]) {
|
||||
if (!filler) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
++n;
|
||||
}
|
||||
}
|
||||
n = MyRand() % n;
|
||||
i = -1;
|
||||
do {
|
||||
while (++i < 16 && !Map.Tileset->Table[tile + i]) {
|
||||
}
|
||||
} while (i < 16 && n--);
|
||||
Assert(i != 16);
|
||||
return tile + i;
|
||||
}
|
||||
if (filler) {
|
||||
int i = 0;
|
||||
for (; i < 16 && Map.Tileset->Table[tile + i]; ++i) {
|
||||
}
|
||||
for (; i < 16 && !Map.Tileset->Table[tile + i]; ++i) {
|
||||
}
|
||||
if (i != 16) {
|
||||
return tile + i;
|
||||
}
|
||||
}
|
||||
return tile;
|
||||
}
|
||||
|
||||
/**
|
||||
** Edit tile.
|
||||
**
|
||||
** @param pos map tile coordinate.
|
||||
** @param tile Tile type to edit.
|
||||
*/
|
||||
void EditTile(const Vec2i &pos, int tile)
|
||||
static void EditTile(const Vec2i &pos, int tile)
|
||||
{
|
||||
Assert(Map.Info.IsPointOnMap(pos));
|
||||
|
||||
ChangeTile(pos, GetTileNumber(tile, TileToolRandom, TileToolDecoration));
|
||||
int tileIndex = Map.Tileset->findTileIndexByTile(tile);
|
||||
|
||||
ChangeTile(pos, Map.Tileset->getTileNumber(tileIndex, TileToolRandom, TileToolDecoration));
|
||||
|
||||
//
|
||||
// Change the flags
|
||||
//
|
||||
CMapField *mf = Map.Field(pos);
|
||||
mf->Flags &= ~(MapFieldHuman | MapFieldLandAllowed | MapFieldCoastAllowed |
|
||||
MapFieldWaterAllowed | MapFieldNoBuilding | MapFieldUnpassable |
|
||||
MapFieldWall | MapFieldRocks | MapFieldForest);
|
||||
|
||||
mf->Flags |= Map.Tileset->FlagsTable[GetTileNumber(tile, 0, 0)];
|
||||
CMapField &mf = *Map.Field(pos);
|
||||
mf.Flags &= ~(MapFieldHuman | MapFieldLandAllowed | MapFieldCoastAllowed |
|
||||
MapFieldWaterAllowed | MapFieldNoBuilding | MapFieldUnpassable |
|
||||
MapFieldWall | MapFieldRocks | MapFieldForest);
|
||||
mf.Flags |= Map.Tileset->FlagsTable[tileIndex];
|
||||
|
||||
UI.Minimap.UpdateSeenXY(pos);
|
||||
UI.Minimap.UpdateXY(pos);
|
||||
|
@ -281,7 +233,7 @@ static void EditTilesInternal(const Vec2i &pos, int tile, int size)
|
|||
** @param tile Tile type to edit.
|
||||
** @param size Size of rectangle
|
||||
*/
|
||||
void EditTiles(const Vec2i &pos, int tile, int size)
|
||||
static void EditTiles(const Vec2i &pos, int tile, int size)
|
||||
{
|
||||
EditTilesInternal(pos, tile, size);
|
||||
|
||||
|
@ -717,7 +669,6 @@ static void DrawTileIcon(unsigned tilenum, unsigned x, unsigned y, unsigned flag
|
|||
*/
|
||||
static void DrawTileIcons()
|
||||
{
|
||||
int i;
|
||||
CLabel label(GetGameFont());
|
||||
int x = UI.InfoPanel.X + 46;
|
||||
int y = UI.InfoPanel.Y + 4 + IconHeight + 11;
|
||||
|
@ -745,8 +696,7 @@ static void DrawTileIcons()
|
|||
//MenuButtonG->DrawFrame(MBUTTON_GEM_SQUARE + (TileToolDecoration ? 2 : 0), x + 40, y - 3);
|
||||
y += 20;
|
||||
|
||||
unsigned int tile;
|
||||
i = Editor.TileIndex;
|
||||
int i = Editor.TileIndex;
|
||||
Assert(Editor.TileIndex != -1);
|
||||
y = UI.ButtonPanel.Y + 24;
|
||||
while (y < UI.ButtonPanel.Y + ButtonPanelHeight - PixelTileSize.y) {
|
||||
|
@ -758,9 +708,9 @@ static void DrawTileIcons()
|
|||
if (i >= (int) Editor.ShownTileTypes.size()) {
|
||||
break;
|
||||
}
|
||||
tile = Editor.ShownTileTypes[i];
|
||||
unsigned int tile = Editor.ShownTileTypes[i];
|
||||
|
||||
Map.TileGraphic->DrawFrameClip(Map.Tileset->Table[tile], x, y);
|
||||
Map.TileGraphic->DrawFrameClip(tile, x, y);
|
||||
Video.DrawRectangleClip(ColorGray, x, y, PixelTileSize.x, PixelTileSize.y);
|
||||
|
||||
if (i == Editor.SelectedTileIndex) {
|
||||
|
@ -906,7 +856,7 @@ static void DrawMapCursor()
|
|||
const PixelPos screenPos = UI.MouseViewport->TilePosToScreen_TopLeft(tilePos);
|
||||
|
||||
if (Editor.State == EditorEditTile && Editor.SelectedTileIndex != -1) {
|
||||
const unsigned short frame = Map.Tileset->Table[Editor.ShownTileTypes[Editor.SelectedTileIndex]];
|
||||
const unsigned short tile = Editor.ShownTileTypes[Editor.SelectedTileIndex];
|
||||
PushClipping();
|
||||
UI.MouseViewport->SetClipping();
|
||||
|
||||
|
@ -921,7 +871,7 @@ static void DrawMapCursor()
|
|||
if (screenPosIt.x >= UI.MouseViewport->GetBottomRightPos().x) {
|
||||
break;
|
||||
}
|
||||
Map.TileGraphic->DrawFrameClip(frame, screenPosIt.x, screenPosIt.y);
|
||||
Map.TileGraphic->DrawFrameClip(tile, screenPosIt.x, screenPosIt.y);
|
||||
}
|
||||
}
|
||||
Video.DrawRectangleClip(ColorWhite, screenPos.x, screenPos.y, PixelTileSize.x * TileCursorSize, PixelTileSize.y * TileCursorSize);
|
||||
|
@ -1514,17 +1464,126 @@ static void EditorCallbackKeyRepeated(unsigned key, unsigned)
|
|||
}
|
||||
}
|
||||
|
||||
static bool EditorCallbackMouse_EditUnitArea(const PixelPos &screenPos)
|
||||
{
|
||||
Assert(Editor.State == EditorEditUnit || Editor.State == EditorSetStartLocation);
|
||||
|
||||
// Scrollbar
|
||||
if (UI.ButtonPanel.X + 4 < CursorScreenPos.x
|
||||
&& CursorScreenPos.x < UI.ButtonPanel.X + 176 - 4
|
||||
&& UI.ButtonPanel.Y + 4 < CursorScreenPos.y
|
||||
&& CursorScreenPos.y < UI.ButtonPanel.Y + 24) {
|
||||
return true;
|
||||
}
|
||||
int bx = UI.InfoPanel.X + 8;
|
||||
int by = UI.InfoPanel.Y + 4 + IconHeight + 10;
|
||||
for (int i = 0; i < PlayerMax; ++i) {
|
||||
if (i == PlayerMax / 2) {
|
||||
bx = UI.InfoPanel.X + 8;
|
||||
by += 20;
|
||||
}
|
||||
if (bx < screenPos.x && screenPos.x < bx + 20 && by < screenPos.y && screenPos.y < by + 20) {
|
||||
if (Map.Info.PlayerType[i] != PlayerNobody) {
|
||||
char buf[256];
|
||||
snprintf(buf, sizeof(buf), "Select player #%d", i);
|
||||
UI.StatusLine.Set(buf);
|
||||
} else {
|
||||
UI.StatusLine.Clear();
|
||||
}
|
||||
Editor.CursorPlayer = i;
|
||||
#if 0
|
||||
ButtonUnderCursor = i + 100;
|
||||
CursorOn = CursorOnButton;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
bx += 20;
|
||||
}
|
||||
|
||||
int i = Editor.UnitIndex;
|
||||
by = UI.ButtonPanel.Y + 24;
|
||||
while (by < UI.ButtonPanel.Y + ButtonPanelHeight - IconHeight) {
|
||||
if (i >= (int)Editor.ShownUnitTypes.size()) {
|
||||
break;
|
||||
}
|
||||
bx = UI.ButtonPanel.X + 10;
|
||||
while (bx < UI.ButtonPanel.X + ButtonPanelWidth - IconWidth) {
|
||||
if (i >= (int)Editor.ShownUnitTypes.size()) {
|
||||
break;
|
||||
}
|
||||
if (bx < screenPos.x && screenPos.x < bx + IconWidth
|
||||
&& by < screenPos.y && screenPos.y < by + IconHeight) {
|
||||
char buf[256];
|
||||
snprintf(buf, sizeof(buf), "%s \"%s\"",
|
||||
Editor.ShownUnitTypes[i]->Ident.c_str(),
|
||||
Editor.ShownUnitTypes[i]->Name.c_str());
|
||||
UI.StatusLine.Set(buf);
|
||||
Editor.CursorUnitIndex = i;
|
||||
#if 0
|
||||
ButtonUnderCursor = i + 100;
|
||||
CursorOn = CursorOnButton;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
bx += IconWidth + 8;
|
||||
i++;
|
||||
}
|
||||
by += IconHeight + 2;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool EditorCallbackMouse_EditTileArea(const PixelPos &screenPos)
|
||||
{
|
||||
int bx = UI.InfoPanel.X + 4;
|
||||
int by = UI.InfoPanel.Y + 4 + IconHeight + 10;
|
||||
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
if (bx < screenPos.x && screenPos.x < bx + 100 && by < screenPos.y && screenPos.y < by + 18) {
|
||||
ButtonUnderCursor = i + 300;
|
||||
CursorOn = CursorOnButton;
|
||||
return true;
|
||||
}
|
||||
by += 20;
|
||||
}
|
||||
|
||||
int i = Editor.TileIndex;
|
||||
by = UI.ButtonPanel.Y + 24;
|
||||
while (by < UI.ButtonPanel.Y + ButtonPanelHeight - PixelTileSize.y) {
|
||||
if (i >= (int)Editor.ShownTileTypes.size()) {
|
||||
break;
|
||||
}
|
||||
bx = UI.ButtonPanel.X + 10;
|
||||
while (bx < UI.ButtonPanel.X + ButtonPanelWidth - PixelTileSize.x) {
|
||||
if (i >= (int)Editor.ShownTileTypes.size()) {
|
||||
break;
|
||||
}
|
||||
if (bx < screenPos.x && screenPos.x < bx + PixelTileSize.x
|
||||
&& by < screenPos.y && screenPos.y < by + PixelTileSize.y) {
|
||||
const int tile = Editor.ShownTileTypes[i];
|
||||
const int tileindex = Map.Tileset->findTileIndexByTile(tile);
|
||||
const int base = Map.Tileset->Tiles[tileindex].BaseTerrain;
|
||||
UI.StatusLine.Set(Map.Tileset->SolidTerrainTypes[base].TerrainName);
|
||||
Editor.CursorTileIndex = i;
|
||||
return true;
|
||||
}
|
||||
bx += PixelTileSize.x + 8;
|
||||
i++;
|
||||
}
|
||||
by += PixelTileSize.y + 2;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
** Callback for input movement of the cursor.
|
||||
**
|
||||
** @param x Screen X position.
|
||||
** @param y Screen Y position.
|
||||
** @param pos Screen position.
|
||||
*/
|
||||
static void EditorCallbackMouse(const PixelPos &pos)
|
||||
{
|
||||
static int LastMapX;
|
||||
static int LastMapY;
|
||||
char buf[256];
|
||||
|
||||
PixelPos restrictPos = pos;
|
||||
HandleCursorMove(&restrictPos.x, &restrictPos.y); // Reduce to screen
|
||||
|
@ -1642,109 +1701,17 @@ static void EditorCallbackMouse(const PixelPos &pos)
|
|||
if (UI.Minimap.Contains(screenPos)) {
|
||||
CursorOn = CursorOnMinimap;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle edit unit area
|
||||
//
|
||||
if (Editor.State == EditorEditUnit || Editor.State == EditorSetStartLocation) {
|
||||
// Scrollbar
|
||||
if (UI.ButtonPanel.X + 4 < CursorScreenPos.x
|
||||
&& CursorScreenPos.x < UI.ButtonPanel.X + 176 - 4
|
||||
&& UI.ButtonPanel.Y + 4 < CursorScreenPos.y
|
||||
&& CursorScreenPos.y < UI.ButtonPanel.Y + 24) {
|
||||
if (EditorCallbackMouse_EditUnitArea(screenPos) == true) {
|
||||
return;
|
||||
}
|
||||
int bx = UI.InfoPanel.X + 8;
|
||||
int by = UI.InfoPanel.Y + 4 + IconHeight + 10;
|
||||
for (int i = 0; i < PlayerMax; ++i) {
|
||||
if (i == PlayerMax / 2) {
|
||||
bx = UI.InfoPanel.X + 8;
|
||||
by += 20;
|
||||
}
|
||||
if (bx < screenPos.x && screenPos.x < bx + 20 && by < screenPos.y && screenPos.y < by + 20) {
|
||||
if (Map.Info.PlayerType[i] != PlayerNobody) {
|
||||
snprintf(buf, sizeof(buf), "Select player #%d", i);
|
||||
UI.StatusLine.Set(buf);
|
||||
} else {
|
||||
UI.StatusLine.Clear();
|
||||
}
|
||||
Editor.CursorPlayer = i;
|
||||
#if 0
|
||||
ButtonUnderCursor = i + 100;
|
||||
CursorOn = CursorOnButton;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
bx += 20;
|
||||
}
|
||||
|
||||
int i = Editor.UnitIndex;
|
||||
by = UI.ButtonPanel.Y + 24;
|
||||
while (by < UI.ButtonPanel.Y + ButtonPanelHeight - IconHeight) {
|
||||
if (i >= (int)Editor.ShownUnitTypes.size()) {
|
||||
break;
|
||||
}
|
||||
bx = UI.ButtonPanel.X + 10;
|
||||
while (bx < UI.ButtonPanel.X + ButtonPanelWidth - IconWidth) {
|
||||
if (i >= (int)Editor.ShownUnitTypes.size()) {
|
||||
break;
|
||||
}
|
||||
if (bx < screenPos.x && screenPos.x < bx + IconWidth
|
||||
&& by < screenPos.y && screenPos.y < by + IconHeight) {
|
||||
snprintf(buf, sizeof(buf), "%s \"%s\"",
|
||||
Editor.ShownUnitTypes[i]->Ident.c_str(),
|
||||
Editor.ShownUnitTypes[i]->Name.c_str());
|
||||
UI.StatusLine.Set(buf);
|
||||
Editor.CursorUnitIndex = i;
|
||||
#if 0
|
||||
ButtonUnderCursor = i + 100;
|
||||
CursorOn = CursorOnButton;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
bx += IconWidth + 8;
|
||||
i++;
|
||||
}
|
||||
by += IconHeight + 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle tile area
|
||||
if (Editor.State == EditorEditTile) {
|
||||
int bx = UI.InfoPanel.X + 4;
|
||||
int by = UI.InfoPanel.Y + 4 + IconHeight + 10;
|
||||
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
if (bx < screenPos.x && screenPos.x < bx + 100 && by < screenPos.y && screenPos.y < by + 18) {
|
||||
ButtonUnderCursor = i + 300;
|
||||
CursorOn = CursorOnButton;
|
||||
return;
|
||||
}
|
||||
by += 20;
|
||||
}
|
||||
|
||||
int i = Editor.TileIndex;
|
||||
by = UI.ButtonPanel.Y + 24;
|
||||
while (by < UI.ButtonPanel.Y + ButtonPanelHeight - PixelTileSize.y) {
|
||||
if (i >= (int)Editor.ShownTileTypes.size()) {
|
||||
break;
|
||||
}
|
||||
bx = UI.ButtonPanel.X + 10;
|
||||
while (bx < UI.ButtonPanel.X + ButtonPanelWidth - PixelTileSize.x) {
|
||||
if (i >= (int)Editor.ShownTileTypes.size()) {
|
||||
break;
|
||||
}
|
||||
if (bx < screenPos.x && screenPos.x < bx + PixelTileSize.x
|
||||
&& by < screenPos.y && screenPos.y < by + PixelTileSize.y) {
|
||||
int base = Map.Tileset->Tiles[Editor.ShownTileTypes[i]].BaseTerrain;
|
||||
UI.StatusLine.Set(Map.Tileset->SolidTerrainTypes[base].TerrainName);
|
||||
Editor.CursorTileIndex = i;
|
||||
return;
|
||||
}
|
||||
bx += PixelTileSize.x + 8;
|
||||
i++;
|
||||
}
|
||||
by += PixelTileSize.y + 2;
|
||||
if (EditorCallbackMouse_EditTileArea(screenPos) == true) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1797,13 +1764,11 @@ static void EditorCallbackMouse(const PixelPos &pos)
|
|||
UI.StatusLine.Set(_("Set start location mode"));
|
||||
return;
|
||||
}
|
||||
if (UI.MenuButton.X != -1) {
|
||||
if (UI.MenuButton.Contains(screenPos)) {
|
||||
ButtonAreaUnderCursor = ButtonAreaMenu;
|
||||
ButtonUnderCursor = ButtonUnderMenu;
|
||||
CursorOn = CursorOnButton;
|
||||
return;
|
||||
}
|
||||
if (UI.MenuButton.X != -1 && UI.MenuButton.Contains(screenPos)) {
|
||||
ButtonAreaUnderCursor = ButtonAreaMenu;
|
||||
ButtonUnderCursor = ButtonUnderMenu;
|
||||
CursorOn = CursorOnButton;
|
||||
return;
|
||||
}
|
||||
|
||||
// Minimap
|
||||
|
@ -1854,27 +1819,6 @@ static void EditorCallbackExit()
|
|||
{
|
||||
}
|
||||
|
||||
/**
|
||||
** Create the tile icons
|
||||
*/
|
||||
static void CreateTileIcons()
|
||||
{
|
||||
for (int i = 0; 0x10 + i < Map.Tileset->NumTiles; i += 16) {
|
||||
TileInfo *info = &Map.Tileset->Tiles[0x10 + i];
|
||||
if (info->BaseTerrain && !info->MixTerrain) {
|
||||
Editor.ShownTileTypes.push_back(0x10 + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
** Clean up the tile icons
|
||||
*/
|
||||
static void CleanTileIcons()
|
||||
{
|
||||
Editor.ShownTileTypes.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
** Create editor.
|
||||
*/
|
||||
|
@ -1965,7 +1909,7 @@ void CEditor::Init()
|
|||
Units.Icon = NULL;
|
||||
Units.Load();
|
||||
|
||||
CreateTileIcons();
|
||||
Map.Tileset->fillSolidTiles(&Editor.ShownTileTypes);
|
||||
VisibleTileIcons = CalculateVisibleIcons(true);
|
||||
|
||||
RecalculateShownUnits();
|
||||
|
@ -2160,7 +2104,7 @@ void StartEditor(const char *filename)
|
|||
|
||||
Editor.TerrainEditable = true;
|
||||
|
||||
CleanTileIcons();
|
||||
Editor.ShownTileTypes.clear();
|
||||
CleanGame();
|
||||
CleanPlayers();
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
#define RH_QUAD_M 0x00FF00FF /// Right half quad mask
|
||||
|
||||
/// Callback for changed tile (with direction mask)
|
||||
static void EditorTileChanged2(const Vec2i &pos, int d);
|
||||
static void EditorChangeSurrounding(const Vec2i &pos, int d);
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Variables
|
||||
|
@ -86,57 +86,35 @@ static void EditorTileChanged2(const Vec2i &pos, int d);
|
|||
*/
|
||||
static unsigned QuadFromTile(const Vec2i &pos)
|
||||
{
|
||||
int i;
|
||||
|
||||
// find the abstact tile number
|
||||
const int tile = Map.Field(pos)->Tile;
|
||||
for (i = 0; i < Map.Tileset->NumTiles; ++i) {
|
||||
if (tile == Map.Tileset->Table[i]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Assert(i != Map.Tileset->NumTiles);
|
||||
const int tileIndex = Map.Tileset->findTileIndexByTile(tile);
|
||||
Assert(tileIndex != -1);
|
||||
|
||||
unsigned base = Map.Tileset->Tiles[i].BaseTerrain;
|
||||
unsigned mix = Map.Tileset->Tiles[i].MixTerrain;
|
||||
unsigned base = Map.Tileset->Tiles[tileIndex].BaseTerrain;
|
||||
unsigned mix = Map.Tileset->Tiles[tileIndex].MixTerrain;
|
||||
|
||||
if (!mix) { // a solid tile
|
||||
return base | (base << 8) | (base << 16) | (base << 24);
|
||||
}
|
||||
// Mixed tiles, mix together
|
||||
switch ((i & 0x00F0) >> 4) {
|
||||
case 0:
|
||||
return (base << 24) | (mix << 16) | (mix << 8) | mix;
|
||||
case 1:
|
||||
return (mix << 24) | (base << 16) | (mix << 8) | mix;
|
||||
case 2:
|
||||
return (base << 24) | (base << 16) | (mix << 8) | mix;
|
||||
case 3:
|
||||
return (mix << 24) | (mix << 16) | (base << 8) | mix;
|
||||
case 4:
|
||||
return (base << 24) | (mix << 16) | (base << 8) | mix;
|
||||
case 5:
|
||||
return (base << 24) | (base << 16) | (base << 8) | mix;
|
||||
case 6:
|
||||
return (base << 24) | (base << 16) | (base << 8) | mix;
|
||||
case 7:
|
||||
return (mix << 24) | (mix << 16) | (mix << 8) | base;
|
||||
case 8:
|
||||
return (base << 24) | (mix << 16) | (mix << 8) | base;
|
||||
case 9:
|
||||
return (mix << 24) | (base << 16) | (mix << 8) | base;
|
||||
case 10:
|
||||
return (base << 24) | (base << 16) | (mix << 8) | base;
|
||||
case 11:
|
||||
return (mix << 24) | (mix << 16) | (base << 8) | base;
|
||||
case 12:
|
||||
return (base << 24) | (mix << 16) | (base << 8) | base;
|
||||
case 13:
|
||||
return (mix << 24) | (base << 16) | (base << 8) | base;
|
||||
switch ((tileIndex & 0x00F0) >> 4) {
|
||||
case 0: return (base << 24) | (mix << 16) | (mix << 8) | mix;
|
||||
case 1: return (mix << 24) | (base << 16) | (mix << 8) | mix;
|
||||
case 2: return (base << 24) | (base << 16) | (mix << 8) | mix;
|
||||
case 3: return (mix << 24) | (mix << 16) | (base << 8) | mix;
|
||||
case 4: return (base << 24) | (mix << 16) | (base << 8) | mix;
|
||||
case 5: return (base << 24) | (base << 16) | (base << 8) | mix;
|
||||
case 6: return (base << 24) | (base << 16) | (base << 8) | mix;
|
||||
case 7: return (mix << 24) | (mix << 16) | (mix << 8) | base;
|
||||
case 8: return (base << 24) | (mix << 16) | (mix << 8) | base;
|
||||
case 9: return (mix << 24) | (base << 16) | (mix << 8) | base;
|
||||
case 10: return (base << 24) | (base << 16) | (mix << 8) | base;
|
||||
case 11: return (mix << 24) | (mix << 16) | (base << 8) | base;
|
||||
case 12: return (base << 24) | (mix << 16) | (base << 8) | base;
|
||||
case 13: return (mix << 24) | (base << 16) | (base << 8) | base;
|
||||
}
|
||||
|
||||
Assert(0);
|
||||
|
||||
return base | (base << 8) | (base << 16) | (base << 24);
|
||||
}
|
||||
|
||||
|
@ -147,16 +125,16 @@ static unsigned QuadFromTile(const Vec2i &pos)
|
|||
** @param goal Goal tile type.
|
||||
** @param length Best found path length.
|
||||
** @param marks Already visited tile types.
|
||||
** @param tile Tile pointer.
|
||||
** @param tileIndex Tile pointer.
|
||||
*/
|
||||
static int FindTilePath(int base, int goal, int length, std::vector<char> &marks, int *tile)
|
||||
static int FindTilePath(int base, int goal, int length, std::vector<char> &marks, int *tileIndex)
|
||||
{
|
||||
int tileres = Map.Tileset->findTileIndex(base, goal);
|
||||
if (tileres == -1) {
|
||||
tileres = Map.Tileset->findTileIndex(goal, base);
|
||||
}
|
||||
if (tileres != -1) {
|
||||
*tile = tileres;
|
||||
*tileIndex = tileres;
|
||||
return length;
|
||||
}
|
||||
|
||||
|
@ -169,11 +147,11 @@ static int FindTilePath(int base, int goal, int length, std::vector<char> &marks
|
|||
const int j = Map.Tileset->Tiles[i].MixTerrain;
|
||||
if (!marks[j]) {
|
||||
marks[j] = j;
|
||||
int dummytile;
|
||||
const int n = FindTilePath(j, goal, length + 1, marks, &dummytile);
|
||||
int dummytileIndex;
|
||||
const int n = FindTilePath(j, goal, length + 1, marks, &dummytileIndex);
|
||||
marks[j] = 0;
|
||||
if (n < l) {
|
||||
*tile = i;
|
||||
*tileIndex = i;
|
||||
l = n;
|
||||
}
|
||||
}
|
||||
|
@ -183,11 +161,11 @@ static int FindTilePath(int base, int goal, int length, std::vector<char> &marks
|
|||
const int j = Map.Tileset->Tiles[i].BaseTerrain;
|
||||
if (!marks[j]) {
|
||||
marks[j] = j;
|
||||
int dummytile;
|
||||
const int n = FindTilePath(j, goal, length + 1, marks, &dummytile);
|
||||
int dummytileIndex;
|
||||
const int n = FindTilePath(j, goal, length + 1, marks, &dummytileIndex);
|
||||
marks[j] = 0;
|
||||
if (n < l) {
|
||||
*tile = i;
|
||||
*tileIndex = i;
|
||||
l = n;
|
||||
}
|
||||
}
|
||||
|
@ -238,7 +216,7 @@ static int TileFromQuad(unsigned fixed, unsigned quad)
|
|||
}
|
||||
} else {
|
||||
std::vector<char> marks;
|
||||
int dummytile;
|
||||
int dummytileIndex;
|
||||
|
||||
marks.resize(Map.Tileset->SolidTerrainTypes.size(), 0);
|
||||
|
||||
|
@ -246,85 +224,44 @@ static int TileFromQuad(unsigned fixed, unsigned quad)
|
|||
marks[type2] = type2;
|
||||
|
||||
// What fixed tile-type should replace the non useable tile-types.
|
||||
// FIXME: write a loop.
|
||||
fixed = (quad >> 0) & 0xFF;
|
||||
if (fixed != type1 && fixed != type2) {
|
||||
quad &= 0xFFFFFF00;
|
||||
if (FindTilePath(type1, fixed, 0, marks, &dummytile) < FindTilePath(type2, fixed, 0, marks, &dummytile)) {
|
||||
quad |= type1 << 0;
|
||||
} else {
|
||||
quad |= type2 << 0;
|
||||
}
|
||||
}
|
||||
fixed = (quad >> 8) & 0xFF;
|
||||
if (fixed != type1 && fixed != type2) {
|
||||
quad &= 0xFFFF00FF;
|
||||
if (FindTilePath(type1, fixed, 0, marks, &dummytile) < FindTilePath(type2, fixed, 0, marks, &dummytile)) {
|
||||
quad |= type1 << 8;
|
||||
} else {
|
||||
quad |= type2 << 8;
|
||||
}
|
||||
}
|
||||
fixed = (quad >> 16) & 0xFF;
|
||||
if (fixed != type1 && fixed != type2) {
|
||||
quad &= 0xFF00FFFF;
|
||||
if (FindTilePath(type1, fixed, 0, marks, &dummytile) < FindTilePath(type2, fixed, 0, marks, &dummytile)) {
|
||||
quad |= type1 << 16;
|
||||
} else {
|
||||
quad |= type2 << 16;
|
||||
}
|
||||
}
|
||||
fixed = (quad >> 24) & 0xFF;
|
||||
if (fixed != type1 && fixed != type2) {
|
||||
quad &= 0x00FFFFFF;
|
||||
if (FindTilePath(type1, fixed, 0, marks, &dummytile) < FindTilePath(type2, fixed, 0, marks, &dummytile)) {
|
||||
quad |= type1 << 24;
|
||||
} else {
|
||||
quad |= type2 << 24;
|
||||
for (int i = 0; i != 4; ++i) {
|
||||
unsigned int type3 = (quad >> (8 * i)) & 0xFF;
|
||||
if (type3 != type1 && type3 != type2) {
|
||||
quad &= ~(0xFF << (8 * i));
|
||||
if (FindTilePath(type1, type3, 0, marks, &dummytileIndex) < FindTilePath(type2, fixed, 0, marks, &dummytileIndex)) {
|
||||
quad |= type1 << (8 * i);
|
||||
} else {
|
||||
quad |= type2 << (8 * i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Need a mixed tile
|
||||
int tile = Map.Tileset->findTileIndex(type1, type2);
|
||||
if (tile == -1) {
|
||||
tile = Map.Tileset->findTileIndex(type1, type2);
|
||||
if (tile != -1) {
|
||||
std::swap(type1, type2);
|
||||
}
|
||||
int tileIndex = Map.Tileset->getTileIndex(type1, type2, quad);
|
||||
if (tileIndex != -1) {
|
||||
return tileIndex;
|
||||
}
|
||||
|
||||
if (tile == -1) {
|
||||
// Find the best tile path.
|
||||
std::vector<char> marks;
|
||||
marks.resize(Map.Tileset->SolidTerrainTypes.size(), 0);
|
||||
marks[type1] = type1;
|
||||
if (FindTilePath(type1, type2, 0, marks, &tile) == INT_MAX) {
|
||||
DebugPrint("Huch, no mix found!!!!!!!!!!!\n");
|
||||
const int res = Map.Tileset->findTileIndex(type1);
|
||||
Assert(res != -1);
|
||||
return res;
|
||||
}
|
||||
if (type1 == Map.Tileset->Tiles[tile].MixTerrain) {
|
||||
// Other mixed
|
||||
std::swap(type1, type2);
|
||||
}
|
||||
// Find the best tile path.
|
||||
std::vector<char> marks;
|
||||
marks.resize(Map.Tileset->SolidTerrainTypes.size(), 0);
|
||||
marks[type1] = type1;
|
||||
if (FindTilePath(type1, type2, 0, marks, &tileIndex) == INT_MAX) {
|
||||
DebugPrint("Huch, no mix found!!!!!!!!!!!\n");
|
||||
const int res = Map.Tileset->findTileIndex(type1);
|
||||
Assert(res != -1);
|
||||
return res;
|
||||
}
|
||||
|
||||
int base = tile;
|
||||
|
||||
if (type1 == Map.Tileset->Tiles[tileIndex].MixTerrain) {
|
||||
// Other mixed
|
||||
std::swap(type1, type2);
|
||||
}
|
||||
int base = tileIndex;
|
||||
int direction = 0;
|
||||
if (((quad >> 24) & 0xFF) == type1) {
|
||||
direction |= 8;
|
||||
}
|
||||
if (((quad >> 16) & 0xFF) == type1) {
|
||||
direction |= 4;
|
||||
}
|
||||
if (((quad >> 8) & 0xFF) == type1) {
|
||||
direction |= 2;
|
||||
}
|
||||
if (((quad >> 0) & 0xFF) == type1) {
|
||||
direction |= 1;
|
||||
for (int i = 0; i != 4; ++i) {
|
||||
if (((quad >> (8 * i)) & 0xFF) == type1) {
|
||||
direction |= 1 << i;
|
||||
}
|
||||
}
|
||||
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||
const char table[16] = { 0, 7, 3, 11, 1, 9, 5, 13, 0, 8, 4, 12, 2, 10, 6, 0 };
|
||||
|
@ -335,18 +272,17 @@ static int TileFromQuad(unsigned fixed, unsigned quad)
|
|||
** Change tile from abstract tile-type.
|
||||
**
|
||||
** @param pos map tile coordinate.
|
||||
** @param tile Abstract tile type to edit.
|
||||
** @param tile tile type to edit.
|
||||
**
|
||||
** @note this is a rather dumb function, doesn't do any tile fixing.
|
||||
*/
|
||||
void ChangeTile(const Vec2i &pos, int tile)
|
||||
{
|
||||
Assert(Map.Info.IsPointOnMap(pos));
|
||||
Assert(tile >= 0 && tile < Map.Tileset->NumTiles);
|
||||
|
||||
CMapField *mf = Map.Field(pos);
|
||||
mf->Tile = Map.Tileset->Table[tile];
|
||||
mf->playerInfo.SeenTile = mf->Tile;
|
||||
CMapField &mf = *Map.Field(pos);
|
||||
mf.Tile = tile;
|
||||
mf.playerInfo.SeenTile = tile;
|
||||
}
|
||||
|
||||
#define DIR_UP 8 /// Go up allowed
|
||||
|
@ -358,29 +294,27 @@ void ChangeTile(const Vec2i &pos, int tile)
|
|||
** Editor change tile.
|
||||
**
|
||||
** @param pos map tile coordinate.
|
||||
** @param tile Tile type to edit.
|
||||
** @param tileIndex Tile type to edit.
|
||||
** @param d Fix direction flag 8 up, 4 down, 2 left, 1 right.
|
||||
*/
|
||||
static void EditorChangeTile(const Vec2i &pos, int tile, int d)
|
||||
static void EditorChangeTile(const Vec2i &pos, int tileIndex, int d)
|
||||
{
|
||||
Assert(Map.Info.IsPointOnMap(pos));
|
||||
|
||||
ChangeTile(pos, tile);
|
||||
ChangeTile(pos, Map.Tileset->Table[tileIndex]);
|
||||
|
||||
//
|
||||
// Change the flags
|
||||
//
|
||||
CMapField *mf = Map.Field(pos);
|
||||
mf->Flags &= ~(MapFieldHuman | MapFieldLandAllowed | MapFieldCoastAllowed
|
||||
| MapFieldWaterAllowed | MapFieldNoBuilding | MapFieldUnpassable
|
||||
| MapFieldWall | MapFieldRocks | MapFieldForest);
|
||||
CMapField &mf = *Map.Field(pos);
|
||||
mf.Flags &= ~(MapFieldHuman | MapFieldLandAllowed | MapFieldCoastAllowed
|
||||
| MapFieldWaterAllowed | MapFieldNoBuilding | MapFieldUnpassable
|
||||
| MapFieldWall | MapFieldRocks | MapFieldForest);
|
||||
|
||||
mf->Flags |= Map.Tileset->FlagsTable[tile];
|
||||
mf.Flags |= Map.Tileset->FlagsTable[tileIndex];
|
||||
|
||||
UI.Minimap.UpdateSeenXY(pos);
|
||||
UI.Minimap.UpdateXY(pos);
|
||||
|
||||
EditorTileChanged2(pos, d);
|
||||
EditorChangeSurrounding(pos, d);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -389,7 +323,7 @@ static void EditorChangeTile(const Vec2i &pos, int tile, int d)
|
|||
** @param pos Map tile position of change.
|
||||
** @param d Fix direction flag 8 up, 4 down, 2 left, 1 right.
|
||||
*/
|
||||
static void EditorTileChanged2(const Vec2i &pos, int d)
|
||||
static void EditorChangeSurrounding(const Vec2i &pos, int d)
|
||||
{
|
||||
unsigned quad = QuadFromTile(pos);
|
||||
|
||||
|
@ -397,26 +331,20 @@ static void EditorTileChanged2(const Vec2i &pos, int d)
|
|||
// Change the surrounding
|
||||
//
|
||||
|
||||
//
|
||||
// Special case 1) Walls.
|
||||
//
|
||||
CMapField *mf = Map.Field(pos);
|
||||
if (mf->Flags & MapFieldWall) {
|
||||
Map.SetWall(pos, mf->Flags & MapFieldHuman);
|
||||
CMapField &mf = *Map.Field(pos);
|
||||
if (mf.Flags & MapFieldWall) {
|
||||
Map.SetWall(pos, mf.Flags & MapFieldHuman);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// How this works:
|
||||
// first get the quad of the neighbouring tile, then
|
||||
// check if the margin matches. otherwise, call
|
||||
// EditorChangeTile again.
|
||||
//
|
||||
if (d & DIR_UP && 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) {
|
||||
|
@ -426,9 +354,7 @@ static void EditorTileChanged2(const Vec2i &pos, int d)
|
|||
}
|
||||
if (d & DIR_DOWN && 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) {
|
||||
|
@ -438,9 +364,7 @@ static void EditorTileChanged2(const Vec2i &pos, int d)
|
|||
}
|
||||
if (d & DIR_LEFT && 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) {
|
||||
|
@ -450,9 +374,7 @@ static void EditorTileChanged2(const Vec2i &pos, int d)
|
|||
}
|
||||
if (d & DIR_RIGHT && 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) {
|
||||
|
@ -469,7 +391,7 @@ static void EditorTileChanged2(const Vec2i &pos, int d)
|
|||
*/
|
||||
void EditorTileChanged(const Vec2i &pos)
|
||||
{
|
||||
EditorTileChanged2(pos, 0xF);
|
||||
EditorChangeSurrounding(pos, 0x0F);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -127,11 +127,6 @@ extern int EditorSaveMap(const std::string &file);
|
|||
/// Register ccl features
|
||||
extern void EditorCclRegister();
|
||||
|
||||
/// Edit tile
|
||||
extern void EditTile(const Vec2i &pos, int tile);
|
||||
/// Edit tiles
|
||||
extern void EditTiles(const Vec2i &pos, int tile, int size);
|
||||
|
||||
/// Change the view of a tile
|
||||
extern void ChangeTile(const Vec2i &pos, int tile);
|
||||
/// Update surroundings for tile changes
|
||||
|
|
|
@ -98,8 +98,11 @@ public:
|
|||
public:
|
||||
unsigned int getOrAddSolidTileIndexByName(const std::string &name);
|
||||
int findTileIndex(unsigned char baseTerrain, unsigned char mixTerrain = 0) const;
|
||||
int findTileIndexByTile(unsigned int tile) const;
|
||||
int getTileIndex(unsigned char baseTerrain, unsigned char mixTerrain, unsigned int quad) const;
|
||||
|
||||
int findTileIndexByTile(unsigned int tile) const;
|
||||
unsigned int getTileNumber(int basic, bool random, bool filler) const;
|
||||
void fillSolidTiles(std::vector<unsigned int> *tiles) const;
|
||||
public:
|
||||
void parse(lua_State *l);
|
||||
void buildTable(lua_State *l);
|
||||
|
|
|
@ -307,6 +307,29 @@ int CTileset::findTileIndex(unsigned char baseTerrain, unsigned char mixTerrain)
|
|||
return -1;
|
||||
}
|
||||
|
||||
int CTileset::getTileIndex(unsigned char baseTerrain, unsigned char mixTerrain, unsigned int quad) const
|
||||
{
|
||||
int tileIndex = findTileIndex(baseTerrain, mixTerrain);
|
||||
if (tileIndex == -1) {
|
||||
tileIndex = findTileIndex(mixTerrain, baseTerrain);
|
||||
if (tileIndex == -1) {
|
||||
return -1;
|
||||
}
|
||||
std::swap(baseTerrain, mixTerrain);
|
||||
}
|
||||
int base = tileIndex;
|
||||
|
||||
int direction = 0;
|
||||
for (int i = 0; i != 4; ++i) {
|
||||
if (((quad >> (8 * i)) & 0xFF) == baseTerrain) {
|
||||
direction |= 1 << i;
|
||||
}
|
||||
}
|
||||
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||
const char table[16] = { 0, 7, 3, 11, 1, 9, 5, 13, 0, 8, 4, 12, 2, 10, 6, 0 };
|
||||
return base | (table[direction] << 4);
|
||||
}
|
||||
|
||||
int CTileset::findTileIndexByTile(unsigned int tile) const
|
||||
{
|
||||
for (int i = 0; i != NumTiles; ++i) {
|
||||
|
@ -317,6 +340,65 @@ int CTileset::findTileIndexByTile(unsigned int tile) const
|
|||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
** Get tile number.
|
||||
**
|
||||
** @param basic Basic tile number
|
||||
** @param random Return random tile
|
||||
** @param filler Get a decorated tile.
|
||||
**
|
||||
** @return Tile number.
|
||||
**
|
||||
** @todo FIXME: Solid tiles are here still hardcoded.
|
||||
*/
|
||||
unsigned int CTileset::getTileNumber(int basic, bool random, bool filler) const
|
||||
{
|
||||
int tile = basic;
|
||||
if (random) {
|
||||
int n = 0;
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
if (!Table[tile + i]) {
|
||||
if (!filler) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
++n;
|
||||
}
|
||||
}
|
||||
n = MyRand() % n;
|
||||
int i = -1;
|
||||
do {
|
||||
while (++i < 16 && !Map.Tileset->Table[tile + i]) {
|
||||
}
|
||||
} while (i < 16 && n--);
|
||||
Assert(i != 16);
|
||||
return tile + i;
|
||||
}
|
||||
if (filler) {
|
||||
int i = 0;
|
||||
for (; i < 16 && Table[tile + i]; ++i) {
|
||||
}
|
||||
for (; i < 16 && !Table[tile + i]; ++i) {
|
||||
}
|
||||
if (i != 16) {
|
||||
return Table[tile + i];
|
||||
}
|
||||
}
|
||||
return Table[tile];
|
||||
}
|
||||
|
||||
void CTileset::fillSolidTiles(std::vector<unsigned int> *tiles) const
|
||||
{
|
||||
for (int i = 16; i < Map.Tileset->NumTiles; i += 16) {
|
||||
const TileInfo &info = Map.Tileset->Tiles[i];
|
||||
|
||||
if (info.BaseTerrain && info.MixTerrain == 0) {
|
||||
tiles->push_back(Map.Tileset->Table[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsigned CTileset::getHumanWallTile(int index) const
|
||||
{
|
||||
unsigned tile = HumanWallTable[index];
|
||||
|
|
Loading…
Add table
Reference in a new issue