Fix raw map overlays (#2917)

* Store raw data with map nodes for overlays

Fixes #2916

Note: Saves from older versions will not show overlay flags since they
need to be saved with the map in this version to avoid the need for the
original map file.

* Update CorsixTH/Lua/map.lua

Co-authored-by: Alberth289346 <alberth289346@gmail.com>
This commit is contained in:
Stephen E. Baker
2025-06-17 20:10:15 -04:00
committed by GitHub
parent 5431213426
commit 4128051b1b
6 changed files with 53 additions and 30 deletions

View File

@@ -32,4 +32,4 @@ Note: This file compiles as both Lua and C++. */
#endif /*]] --*/
return 2692;
return 2693;

View File

@@ -839,13 +839,13 @@ function UIMenuBar:makeGameMenu(app)
:appendCheckItem(_S.menu_debug_overlay.flags, false, overlay("flags"), "")
:appendCheckItem(_S.menu_debug_overlay.positions, false, overlay("positions"), "")
:appendCheckItem(_S.menu_debug_overlay.heat, false, overlay("heat"), "")
:appendCheckItem(_S.menu_debug_overlay.byte_0_1, false, overlay(35, 8, 0, 1, false), "")
:appendCheckItem(_S.menu_debug_overlay.byte_floor, false, overlay(35, 8, 2, 2, false), "")
:appendCheckItem(_S.menu_debug_overlay.byte_n_wall, false, overlay(35, 8, 3, 3, false), "")
:appendCheckItem(_S.menu_debug_overlay.byte_w_wall, false, overlay(35, 8, 4, 4, false), "")
:appendCheckItem(_S.menu_debug_overlay.byte_5, false, overlay(35, 8, 5, 5, true), "")
:appendCheckItem(_S.menu_debug_overlay.byte_6, false, overlay(35, 8, 6, 6, true), "")
:appendCheckItem(_S.menu_debug_overlay.byte_7, false, overlay(35, 8, 7, 7, true), "")
:appendCheckItem(_S.menu_debug_overlay.byte_0_1, false, overlay(0, 1, false), "")
:appendCheckItem(_S.menu_debug_overlay.byte_floor, false, overlay(2, 2, false), "")
:appendCheckItem(_S.menu_debug_overlay.byte_n_wall, false, overlay(3, 3, false), "")
:appendCheckItem(_S.menu_debug_overlay.byte_w_wall, false, overlay(4, 4, false), "")
:appendCheckItem(_S.menu_debug_overlay.byte_5, false, overlay(5, 5, true), "")
:appendCheckItem(_S.menu_debug_overlay.byte_6, false, overlay(6, 6, true), "")
:appendCheckItem(_S.menu_debug_overlay.byte_7, false, overlay(7, 7, true), "")
:appendCheckItem(_S.menu_debug_overlay.parcel, false, overlay("parcel"), "")
)
:appendItem(_S.menu_debug.sprite_viewer, function() corsixth.require("sprite_viewer") end)

View File

@@ -578,11 +578,12 @@ function Map:updateDebugOverlayHeliport()
end
end
function Map:loadDebugText(base_offset, xy_offset, first, last, bits_)
-- If both 'first' and 'last' are numbers, they are indices starting at 0.
function Map:loadDebugText(first, last, bits_)
self.debug_text = false
self.debug_flags = false
self.updateDebugOverlay = nil
if base_offset == "flags" then
if first == "flags" then
self.debug_flags = {}
for x = 1, self.width do
for y = 1, self.height do
@@ -592,7 +593,7 @@ function Map:loadDebugText(base_offset, xy_offset, first, last, bits_)
end
self.updateDebugOverlay = self.updateDebugOverlayFlags
self:updateDebugOverlay()
elseif base_offset == "positions" then
elseif first == "positions" then
self.debug_text = {}
for x = 1, self.width do
for y = 1, self.height do
@@ -600,32 +601,30 @@ function Map:loadDebugText(base_offset, xy_offset, first, last, bits_)
self.debug_text[xy] = x .. "," .. y
end
end
elseif base_offset == "heat" then
elseif first == "heat" then
self.debug_text = {}
self.updateDebugOverlay = self.updateDebugOverlayHeat
self:updateDebugOverlay()
elseif base_offset == "parcel" then
elseif first == "parcel" then
self.debug_text = {}
self.updateDebugOverlay = self.updateDebugOverlayParcels
self:updateDebugOverlay()
elseif base_offset == "camera" then
elseif first == "camera" then
self.debug_text = {}
self.updateDebugOverlay = self.updateDebugOverlayCamera
self:updateDebugOverlay()
elseif base_offset == "heliport" then
elseif first == "heliport" then
self.debug_text = {}
self.updateDebugOverlay = self.updateDebugOverlayHeliport
self:updateDebugOverlay()
else
local thData = self:getRawData()
for x = 1, self.width do
for y = 1, self.height do
local xy = (y - 1) * self.width + x - 1
local offset = base_offset + xy * xy_offset
local raw = self.th:getCellRaw(x, y)
if bits_ then
self:setDebugText(x, y, bits(thData:byte(offset + first, offset + last)))
self:setDebugText(x, y, bits(raw:byte(first + 1, last + 1)))
else
self:setDebugText(x, y, thData:byte(offset + first, offset + last))
self:setDebugText(x, y, raw:byte(first + 1, last + 1))
end
end
end

View File

@@ -563,6 +563,20 @@ int l_map_getcellflags(lua_State* L) {
return 1;
}
int l_map_getcellraw(lua_State* L) {
level_map* pMap = luaT_testuserdata<level_map>(L);
int iX = static_cast<int>(luaL_checkinteger(L, 2) -
1); // Lua arrays start at 1 - pretend
int iY = static_cast<int>(luaL_checkinteger(L, 3) - 1); // the map does too.
map_tile* pNode = pMap->get_tile(iX, iY);
if (pNode == nullptr) {
return luaL_argerror(L, 2, "Map coordinates out of bounds");
}
lua_pushlstring(L, reinterpret_cast<const char*>(pNode->raw),
map_tile::raw_length);
return 1;
}
/* because all the thobs are not retrieved when the map is loaded in c
lua objects use the afterLoad function to be registered after a load,
if the object list would not be cleared it would result in duplication
@@ -1015,6 +1029,7 @@ void lua_register_map(const lua_register_state* pState) {
lcb.add_function(l_map_gettemperature, "getCellTemperature");
lcb.add_function(l_map_getcellflags, "getCellFlags");
lcb.add_function(l_map_setcellflags, "setCellFlags");
lcb.add_function(l_map_getcellraw, "getCellRaw");
lcb.add_function(l_map_setcell, "setCell");
lcb.add_function(l_map_setwallflags, "setWallDrawFlags");
lcb.add_function(l_map_settemperaturedisplay, "setTemperatureDisplay");

View File

@@ -24,6 +24,7 @@ SOFTWARE.
#include "config.h"
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <fstream>
@@ -247,7 +248,7 @@ map_tile_flags::operator uint32_t() const {
return raw;
}
map_tile::map_tile() : iParcelId(0), iRoomId(0), flags({}), objects() {
map_tile::map_tile() : iParcelId(0), iRoomId(0), flags({}), objects{}, raw{} {
tile_layers[tile_layer::ground] = 0;
tile_layers[tile_layer::north_wall] = 0;
tile_layers[tile_layer::west_wall] = 0;
@@ -434,6 +435,7 @@ bool level_map::load_from_th_file(const uint8_t* pData, size_t iDataLength,
pNode->objects.clear();
for (int iY = 0; iY < height; ++iY) {
for (int iX = 0; iX < width; ++iX) {
std::copy_n(pData, map_tile::raw_length, pNode->raw);
uint8_t iBaseTile = gs_iTHMapBlockLUT[pData[2]];
pNode->flags.can_travel_n = true;
pNode->flags.can_travel_e = true;
@@ -1485,7 +1487,7 @@ void level_map::persist(lua_persist_writer* pWriter) const {
lua_State* L = pWriter->get_stack();
integer_run_length_encoder oEncoder;
uint32_t iVersion = 4;
uint32_t iVersion = 5;
pWriter->write_uint(iVersion);
pWriter->write_uint(player_count);
for (int i = 0; i < player_count; ++i) {
@@ -1518,6 +1520,7 @@ void level_map::persist(lua_persist_writer* pWriter) const {
pWriter->write_uint(static_cast<uint32_t>(pNode->flags));
pWriter->write_uint(pNode->aiTemperature[0]);
pWriter->write_uint(pNode->aiTemperature[1]);
pWriter->write_byte_stream(pNode->raw, map_tile::raw_length);
lua_rawgeti(L, luaT_upvalueindex(1), 2);
lua_pushlightuserdata(L, pNode->entities.next);
@@ -1555,14 +1558,12 @@ void level_map::depersist(lua_persist_reader* pReader) {
uint32_t iVersion;
if (!pReader->read_uint(iVersion)) return;
if (iVersion != 4) {
if (iVersion < 2 || iVersion == 128) {
luaL_error(L,
"TODO: Write code to load map data from earlier "
"savegame versions (if really necessary).");
} else if (iVersion > 4) {
luaL_error(L, "Cannot load savegame from a newer version.");
}
if (iVersion < 2 || iVersion == 128) {
luaL_error(L,
"TODO: Write code to load map data from earlier "
"savegame versions (if really necessary).");
} else if (iVersion > 5) {
luaL_error(L, "Cannot load savegame from a newer version.");
}
if (!pReader->read_uint(player_count)) return;
for (int i = 0; i < player_count; ++i) {
@@ -1618,6 +1619,9 @@ void level_map::depersist(lua_persist_reader* pReader) {
return;
}
}
if (iVersion >= 5) {
if (!pReader->read_byte_stream(pNode->raw, map_tile::raw_length)) return;
}
if (!pReader->read_stack_object()) return;
pNode->entities.next = luaT_toanimationbase(L, -1);

View File

@@ -230,6 +230,11 @@ struct map_tile {
//! objects in this tile
std::list<object_type> objects;
static constexpr int raw_length = 8;
//! raw data from map file for debugging
std::uint8_t raw[raw_length];
};
//! Prototype for object callbacks from THMap::loadFromTHFile