From 04dd47d13a8da9224e7f9ea8ccacf64129717ec1 Mon Sep 17 00:00:00 2001 From: tpart Date: Thu, 26 Feb 2026 20:30:49 +0100 Subject: Implement tile stacks in client; Upgrade to Godot 4.6 --- client/map/map.gd | 38 +++++++++++++++++++++++++++----------- client/map/map.tscn | 6 +++--- client/map/tile_factory.gd | 6 +++++- client/map/tiles/chair.gd | 9 ++++----- client/map/tiles/conveyor.gd | 2 +- client/map/tiles/counter.gd | 18 ++++++++---------- client/map/tiles/door.gd | 2 +- client/map/tiles/generic_tile.gd | 2 +- client/map/tiles/grass_side.tres | 2 +- client/map/tiles/player_portal.gd | 2 +- client/map/tiles/screen/screen.gd | 2 +- client/map/tiles/table.gd | 2 +- client/map/tiles/unknown_tile.gd | 2 +- client/map/tiles/wall_tile.gd | 12 ++++++------ 14 files changed, 61 insertions(+), 44 deletions(-) (limited to 'client/map') diff --git a/client/map/map.gd b/client/map/map.gd index 4dd76ec4..afac0a1b 100644 --- a/client/map/map.gd +++ b/client/map/map.gd @@ -23,12 +23,14 @@ class TileInfo: var name: String var tile: Tile var neighbours: Array + +const NEIGHBOR_OFFSETS: Array[Vector2i] = [Vector2i.UP, Vector2i.LEFT, Vector2i.DOWN, Vector2i.RIGHT] var tile_by_pos: Dictionary[Vector2i, TileInfo] = {} var autoflush = false var currently_baked = false var floor_node := MeshInstance3D.new() -var tile_factory = TileFactory.new() +var tile_factory := TileFactory.new() func get_tile_name(pos: Vector2i): # -> String? var e = tile_by_pos.get(pos) @@ -39,22 +41,36 @@ func get_tile_instance(pos: Vector2i) -> Tile: if e != null: return e.tile else: return null -func set_tile(pos: Vector2i, tilename = null, neighbors: Array = [null,null,null,null]): +func set_tiles(pos: Vector2i, tiles: Array = [], pending_changes: Dictionary[Vector2i, Array] = {}): # tiles: Array[String] var inst = get_tile_instance(pos) - if inst and tilename: if inst.change(tilename): return # instance handled change itself + if inst != null and not tiles.is_empty(): + for tile: String in tiles: + # TODO: Don't return, but handle changes which weren't handled by the instance below. + if inst.change(tile): + return # Instance handled change itself! _remove_tile(pos) - if tilename: _add_tile(pos, tilename, neighbors) + if not tiles.is_empty(): _add_tiles(pos, tiles, pending_changes) if autoflush: flush() -func _add_tile(pos: Vector2i, tilename: String, neighbors: Array) -> Tile: - var tile := tile_factory.produce(tilename, pos, neighbors) - add_child(tile) - tile.position = Vector3(pos.x, 0, pos.y) - tile_by_pos[pos] = TileInfo.new(pos, tilename, tile, neighbors) - return tile +func _add_tiles(pos: Vector2i, tiles: Array, pending_changes: Dictionary[Vector2i, Array] = {}) -> void: + # Find neighbor tile names + var neighbors: Array[Array] = [] # Array[Array[String]] + for offset: Vector2i in NEIGHBOR_OFFSETS: + var neighbor_pos: Vector2i = pos + offset + if pending_changes.has(neighbor_pos): + neighbors.append(pending_changes[neighbor_pos]) + elif tile_by_pos.has(neighbor_pos): + neighbors.append(tile_by_pos[neighbor_pos]) + else: neighbors.append([]) + + for tile_name: String in tiles: + var tile := tile_factory.produce(tile_name, pos, neighbors) + add_child(tile) + tile.position = Vector3(pos.x, 0, pos.y) + tile_by_pos[pos] = TileInfo.new(pos, tile_name, tile, neighbors) func _remove_tile(pos: Vector2i): - var tile = get_tile_instance(pos) + var tile := get_tile_instance(pos) if tile == null: return if tile.item != null: tile.item.queue_free() if tile is FloorLike: diff --git a/client/map/map.tscn b/client/map/map.tscn index 84a4f09b..27cd3900 100644 --- a/client/map/map.tscn +++ b/client/map/map.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=4 format=3 uid="uid://b4gone8fu53r7"] +[gd_scene format=3 uid="uid://b4gone8fu53r7"] [ext_resource type="Script" uid="uid://bxuukjyme1git" path="res://map/map.gd" id="1_3en0a"] @@ -6,9 +6,9 @@ [sub_resource type="VoxelGIData" id="VoxelGIData_m5j5n"] -[node name="Map" type="Node3D"] +[node name="Map" type="Node3D" unique_id=764657840] script = ExtResource("1_3en0a") -[node name="VoxelGI" type="VoxelGI" parent="."] +[node name="VoxelGI" type="VoxelGI" parent="." unique_id=1789448607] camera_attributes = SubResource("CameraAttributesPractical_kwk4i") data = SubResource("VoxelGIData_m5j5n") diff --git a/client/map/tile_factory.gd b/client/map/tile_factory.gd index ad415cfc..1640e512 100644 --- a/client/map/tile_factory.gd +++ b/client/map/tile_factory.gd @@ -43,7 +43,11 @@ func produce(raw_name: String, position: Vector2i, neighbors: Array) -> Tile: var ctx := TileCC.new() ctx.tile_name = tile_name ctx.position = position - ctx.neighbors = neighbors.map(func(n): return null if n == null else TileName.new(n).name) + ctx.neighbors = neighbors.map(func(a): + if a != null: + return a.map(func(b): return null if b == null else TileName.new(b).name) + else: return null + ) ctx.floor_meshers = floor_meshers match tile_name.name: diff --git a/client/map/tiles/chair.gd b/client/map/tiles/chair.gd index 45b45638..4cd28cf7 100644 --- a/client/map/tiles/chair.gd +++ b/client/map/tiles/chair.gd @@ -14,17 +14,16 @@ # along with this program. If not, see . # class_name Chair -extends Floor +extends Tile func _init(ctx: TileFactory.TileCC): super(ctx) var chair = preload("res://map/tiles/chair.tscn").instantiate() var facing = 0; for i in range(4): - match ctx.neighbors[i]: - "coveyor", "table", "counter": - facing = i - break + if G.has_one(ctx.neighbors[i], ["coveyor", "table", "counter"]): + facing = i + break base.add_child(chair) turn_facing(facing) diff --git a/client/map/tiles/conveyor.gd b/client/map/tiles/conveyor.gd index 60505425..8f2c6d12 100644 --- a/client/map/tiles/conveyor.gd +++ b/client/map/tiles/conveyor.gd @@ -14,7 +14,7 @@ # along with this program. If not, see . # class_name Conveyor -extends Floor +extends Tile var conveyor: ConveyorModel = preload("res://map/tiles/conveyor.tscn").instantiate() diff --git a/client/map/tiles/counter.gd b/client/map/tiles/counter.gd index bd16c7a3..fc302694 100644 --- a/client/map/tiles/counter.gd +++ b/client/map/tiles/counter.gd @@ -14,7 +14,7 @@ # along with this program. If not, see . # class_name Counter -extends Floor +extends Tile const COUNTERS: Array = [ "counter", @@ -52,7 +52,7 @@ func _init(ctx: TileFactory.TileCC): for start in range(4): var series = 0 for i in range(4): - if Counter.is_floor(ctx.neighbors[(start + i) % 4]): + if not is_attachable(ctx.neighbors[(start + i) % 4]): series += 1 else: break @@ -64,7 +64,7 @@ func _init(ctx: TileFactory.TileCC): # backsplash facing = max_idx if max_series == 1: - if WallTile.WALLS.has(ctx.neighbors[(max_idx + 2) % 4]): + if G.has_one(WallTile.WALLS, ctx.neighbors[(max_idx + 2) % 4]): kind = CounterKind.STRAIGHT_BACKSPLASH else: kind = CounterKind.STRAIGHT @@ -73,10 +73,8 @@ func _init(ctx: TileFactory.TileCC): turn_facing(facing) -static func is_counter(tile_name_t) -> bool: - if tile_name_t == null: - return false - return tile_name_t.ends_with("crate") or COUNTERS.has(tile_name_t) - -static func is_floor(floor_name) -> bool: - return FLOORS.has(floor_name) +static func is_attachable(neighbor: Array) -> bool: + for tile: String in neighbor: + if tile.ends_with("crate"): return true + if COUNTERS.has(tile): return true + return false diff --git a/client/map/tiles/door.gd b/client/map/tiles/door.gd index 7fe23c93..0473c337 100644 --- a/client/map/tiles/door.gd +++ b/client/map/tiles/door.gd @@ -21,7 +21,7 @@ func _init(ctx: TileFactory.TileCC): var new_facing = 0 for i in range(4): - if ctx.neighbors[i] == "door": + if ctx.neighbors[i].has("door"): new_facing = i turn_facing(new_facing) add_dyed_mesh(ctx, load("res://map/tiles/door.tscn").instantiate(), "Door", 1) diff --git a/client/map/tiles/generic_tile.gd b/client/map/tiles/generic_tile.gd index abcb4d05..33c01cdb 100644 --- a/client/map/tiles/generic_tile.gd +++ b/client/map/tiles/generic_tile.gd @@ -14,7 +14,7 @@ # along with this program. If not, see . # class_name GenericTile -extends Floor +extends Tile func _init(ctx: TileFactory.TileCC, scene: PackedScene): super(ctx) diff --git a/client/map/tiles/grass_side.tres b/client/map/tiles/grass_side.tres index 3f29e10e..52042308 100644 --- a/client/map/tiles/grass_side.tres +++ b/client/map/tiles/grass_side.tres @@ -1,4 +1,4 @@ -[gd_resource type="ArrayMesh" load_steps=4 format=3 uid="uid://l2by4gv4wpd1"] +[gd_resource type="ArrayMesh" format=3 uid="uid://l2by4gv4wpd1"] [ext_resource type="Texture2D" uid="uid://p35o0tkyfmrl" path="res://map/tiles/grass_side.webp" id="1_d17wb"] diff --git a/client/map/tiles/player_portal.gd b/client/map/tiles/player_portal.gd index 8339a797..c78bcf0a 100644 --- a/client/map/tiles/player_portal.gd +++ b/client/map/tiles/player_portal.gd @@ -14,7 +14,7 @@ # along with this program. If not, see . # class_name PlayerPortal -extends Floor +extends Tile var model: PortalModel = load("res://map/tiles/portal.tscn").instantiate() func _init(ctx: TileFactory.TileCC): diff --git a/client/map/tiles/screen/screen.gd b/client/map/tiles/screen/screen.gd index c1d93e03..c95f0753 100644 --- a/client/map/tiles/screen/screen.gd +++ b/client/map/tiles/screen/screen.gd @@ -14,7 +14,7 @@ # along with this program. If not, see . # class_name Screen -extends Floor +extends Tile func _init(ctx: TileFactory.TileCC): super(ctx) diff --git a/client/map/tiles/table.gd b/client/map/tiles/table.gd index 43e3dbea..046749d7 100644 --- a/client/map/tiles/table.gd +++ b/client/map/tiles/table.gd @@ -14,7 +14,7 @@ # along with this program. If not, see . # class_name Table -extends Floor +extends Tile func _init(ctx: TileFactory.TileCC): super(ctx) diff --git a/client/map/tiles/unknown_tile.gd b/client/map/tiles/unknown_tile.gd index 0a11efc6..f3524834 100644 --- a/client/map/tiles/unknown_tile.gd +++ b/client/map/tiles/unknown_tile.gd @@ -14,7 +14,7 @@ # along with this program. If not, see . # class_name UnknownTile -extends Floor +extends Tile func _init(ctx: TileFactory.TileCC): super(ctx) diff --git a/client/map/tiles/wall_tile.gd b/client/map/tiles/wall_tile.gd index b8109516..244b2294 100644 --- a/client/map/tiles/wall_tile.gd +++ b/client/map/tiles/wall_tile.gd @@ -14,7 +14,7 @@ # along with this program. If not, see . # class_name WallTile -extends Floor +extends Tile static func create_material(color: Color): var mat = StandardMaterial3D.new() @@ -56,8 +56,8 @@ func _init(ctx: TileFactory.TileCC): for start in range(4): var series = 0 for i in range(4): - var i_name = ctx.neighbors[(start + i) % 4] - if is_wall(i_name): + var neighbor: Array = ctx.neighbors[(start + i) % 4] + if is_wall(neighbor): series += 1 else: break @@ -68,7 +68,7 @@ func _init(ctx: TileFactory.TileCC): if max_series == 1: facing = max_idx kind = WallKind.STRAIGHT - if not env.is_empty() and env.has(ctx.neighbors[(facing + 1) % 4]) or ctx.neighbors[(facing + 1) % 4] == null: + if not env.is_empty() and G.has_one(env, ctx.neighbors[(facing + 1) % 4]) or ctx.neighbors[(facing + 1) % 4].is_empty(): facing = (facing + 2) % 4 elif max_series == 2: facing = max_idx @@ -86,5 +86,5 @@ func add_dyed_mesh(ctx: TileFactory.TileCC, node: Node3D, node_name = "Mesh", su meshi.set_surface_override_material(surface, MATERIALS.get(ctx.tile_name.variant, MATERIALS["green"])) base.add_child(node) -func is_wall(tile_name_t) -> bool: - return walls.has(tile_name_t) +func is_wall(neighbor: Array) -> bool: + return G.has_one(neighbor, walls) -- cgit v1.3