Skip to content

Commit

Permalink
Render tile updates
Browse files Browse the repository at this point in the history
  • Loading branch information
Danielv123 committed Apr 14, 2024
1 parent b2a3958 commit ad1a3d9
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 7 deletions.
6 changes: 4 additions & 2 deletions messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -602,16 +602,18 @@ module.exports = {
type: "array",
items: { type: "string" },
},
layer: { type: "string" }, // optional, defaults to "" for entities
},
};
constructor(type, data, position, size) {
constructor(type, data, position, size, layer = "") {
this.type = type;
this.data = data;
this.position = position;
this.size = size;
this.layer = layer;
}
static fromJSON(json) {
return new this(json.type, json.data, json.position, json.size);
return new this(json.type, json.data, json.position, json.size, json.layer);
}
},
RefreshTileData: class RefreshTileData {
Expand Down
26 changes: 26 additions & 0 deletions module/gridworld.lua
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ gridworld.events[clusterio_api.events.on_server_startup] = function()
added_entities_to_update = nil,
removed_entities_to_update = nil,
entity_registrations = {},
tiles_to_update = nil,
}
end
if global.gridworld.map.entity_registrations == nil then
Expand Down Expand Up @@ -247,6 +248,31 @@ gridworld.events[defines.events.on_tick] = function(event)
worldgen.events.on_tick(event)
end
end
gridworld.events[defines.events.on_player_built_tile] = function(event)
if not global.gridworld.lobby_server then
map.events.on_player_built_tile(event)
end
end
gridworld.events[defines.events.on_robot_built_tile] = function(event)
if not global.gridworld.lobby_server then
map.events.on_robot_built_tile(event)
end
end
gridworld.events[defines.events.on_player_mined_tile] = function(event)
if not global.gridworld.lobby_server then
map.events.on_player_mined_tile(event)
end
end
gridworld.events[defines.events.on_robot_mined_tile] = function(event)
if not global.gridworld.lobby_server then
map.events.on_robot_mined_tile(event)
end
end
gridworld.events[defines.events.script_raised_set_tiles] = function(event)
if not global.gridworld.lobby_server then
map.events.script_raised_set_tiles(event)
end
end
gridworld.on_nth_tick = {}
gridworld.on_nth_tick[37] = function()
if not global.gridworld.lobby_server then
Expand Down
1 change: 1 addition & 0 deletions module/map/dump_mapview.lua
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ local function dump_mapview(position_a, position_b)
position = position_a,
size = CHUNK_SIZE,
data = table.concat(map_data, ";"),
layer = "tiles_"
})
end
-- dump_mapview(game.player.position, {x = game.player.position.x + 128, y = game.player.position.y + 128})
Expand Down
28 changes: 28 additions & 0 deletions module/map/dump_tiles.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
--[[
Dump changed tiles
Unlike dump_mapview, this one dumps an array of single tiles. This is less
space efficient than the chunked format for normal exports, but nmore
efficient for many small updates such as what happens when robots build concrete.
]]

local clusterio_api = require("modules/clusterio/api")

local function dump_tiles(tiles)
local map_data = {}
for _, tilePosition in pairs(tiles) do
local tile = game.surfaces[1].get_tile(tilePosition)
local map_color = tile.prototype.map_color
table.insert(map_data, tilePosition.x)
table.insert(map_data, tilePosition.y)
table.insert(map_data, string.format("%02x%02x%02x%02x", map_color.r, map_color.g, map_color.b, map_color.a))
end

clusterio_api.send_json("gridworld:tile_data", {
type = "pixels",
data = table.concat(map_data, ";"),
layer = "tiles_",
})
end

return dump_tiles
5 changes: 5 additions & 0 deletions module/map/events/on_nth_tick.lua
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
local dump_entities = require("modules/gridworld/map/dump_entities")
local dump_tiles = require("modules/gridworld/map/dump_tiles")

local function on_nth_tick()
if global.gridworld.map.added_entities_to_update or (global.gridworld.map.removed_entities_to_update and #global.gridworld.map.removed_entities_to_update > 0) then
dump_entities(global.gridworld.map.added_entities_to_update, global.gridworld.map.removed_entities_to_update)
global.gridworld.map.added_entities_to_update = nil
global.gridworld.map.removed_entities_to_update = {}
end
if global.gridworld.map.tiles_to_update ~= nil then
dump_tiles(global.gridworld.map.tiles_to_update)
global.gridworld.map.tiles_to_update = nil
end
end

return on_nth_tick
11 changes: 11 additions & 0 deletions module/map/events/on_tile_changed.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
local function on_tile_changed(event)
local tiles = event.tiles
if global.gridworld.map.tiles_to_update == nil then
global.gridworld.map.tiles_to_update = {}
end
for _, tile in pairs(tiles) do
table.insert(global.gridworld.map.tiles_to_update, tile.position)
end
end

return on_tile_changed
7 changes: 7 additions & 0 deletions module/map/map.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ local entity_removed_unregistered = require("modules/gridworld/map/entity_remove

local on_nth_tick = require("modules/gridworld/map/events/on_nth_tick")
local on_chunk_generated = require("modules/gridworld/map/events/on_chunk_generated")
local on_tile_changed = require("modules/gridworld/map/events/on_tile_changed")

return {
dump_mapview = dump_mapview,
Expand All @@ -26,5 +27,11 @@ return {
on_robot_mined_entity = entity_removed_unregistered,
on_entity_died = entity_removed_unregistered,
on_pre_robot_exploded_cliff = entity_removed_unregistered,
-- Tile update events
on_player_built_tile = on_tile_changed,
on_player_mined_tile = on_tile_changed,
on_robot_built_tile = on_tile_changed,
on_robot_mined_tile = on_tile_changed,
script_raised_set_tiles = on_tile_changed,
},
}
8 changes: 4 additions & 4 deletions src/mapview/tileDataEventHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ const path = require("path");
sharp.cache(false);
const sleep = require("../util/sleep");

const TILE_SIZE = 512;
const fileLocks = {}; // Used to prevent multiple writes to the same file
const updates = new Map();

module.exports = async function tileDataEventHandler({ type, data, size, position }) {
module.exports = async function tileDataEventHandler({ type, data, size, position, layer }) {
// console.log(type, size, position);
// Image tiles are 512x512 pixels arranged in a grid, starting at 0,0
const TILE_SIZE = 512;
if (type === "pixels") {
if (data.length % 3 !== 0) {
this.logger.error(`Invalid pixel data length: ${data.length}`);
Expand All @@ -24,7 +24,7 @@ module.exports = async function tileDataEventHandler({ type, data, size, positio
// Figure out which image tile the pixel belongs to
const x_tile = (x - x % TILE_SIZE) / TILE_SIZE + (x < 0 ? -1 : 0);
const y_tile = (y - y % TILE_SIZE) / TILE_SIZE + (y < 0 ? -1 : 0);
const filename = `z10x${x_tile}y${y_tile}.png`;
const filename = `${layer}z10x${x_tile}y${y_tile}.png`;
if (!updates.has(filename)) {
updates.set(filename, new Set());
}
Expand All @@ -51,7 +51,7 @@ module.exports = async function tileDataEventHandler({ type, data, size, positio
const pixel_world_y = originPosition[1] + y;
const x_tile = (pixel_world_x - pixel_world_x % TILE_SIZE) / TILE_SIZE + (pixel_world_x < 0 ? -1 : 0);
const y_tile = (pixel_world_y - pixel_world_y % TILE_SIZE) / TILE_SIZE + (pixel_world_y < 0 ? -1 : 0);
const filename = `tiles_z10x${x_tile}y${y_tile}.png`;
const filename = `${layer}z10x${x_tile}y${y_tile}.png`;
if (!updates.has(filename)) {
updates.set(filename, new Set());
}
Expand Down
2 changes: 1 addition & 1 deletion src/mapview/tileDataIpcHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ module.exports = async function handleTileDataIpc(instancePlugin, json) {
instancePlugin.logger.error(`Received tile data with invalid type ${type}`);
}

await instancePlugin.instance.sendTo("controller", new messages.TileData(type, tileData, json.position, json.size));
await instancePlugin.instance.sendTo("controller", new messages.TileData(type, tileData, json.position, json.size, json.layer));
};

0 comments on commit ad1a3d9

Please sign in to comment.