aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/game.gd72
-rw-r--r--client/gui/menus/main/background.gd20
-rw-r--r--client/map/map.gd70
-rw-r--r--client/map/tile_factory.gd6
-rw-r--r--client/map/tiles/active_interact_counter.gd5
-rw-r--r--client/map/tiles/book.tscn7
-rw-r--r--client/map/tiles/exterior_tree.gd2
-rw-r--r--client/map/tiles/tile.gd2
-rw-r--r--client/player/controllable_player.gd7
9 files changed, 102 insertions, 89 deletions
diff --git a/client/game.gd b/client/game.gd
index 8d2a33a0..d82ccad3 100644
--- a/client/game.gd
+++ b/client/game.gd
@@ -43,12 +43,11 @@ enum JoinState {
var my_player_id: float = -1
var item_names: Array = []
-var item_index_by_name: Dictionary = {}
var tile_names: Array = []
-var tile_index_by_name: Dictionary = {}
-var tile_collide: Dictionary = {}
-var tile_placeable_items: Dictionary = {}
-var tile_interactable_empty: Dictionary = {}
+var tile_collide: Array[String] = []
+var tile_placeable_any: Array[String] = []
+var tile_placeable_items: Dictionary[String, Array] = {} # Dictionary[String, Array[String]]
+var tile_interactable_empty: Array[String] = []
var maps: Array = []
var bot_algos: Array
var text_message_history: Array[TextMessage] = []
@@ -93,26 +92,21 @@ func handle_packet(p):
"data":
item_names = p["data"]["item_names"]
tile_names = p["data"]["tile_names"]
- tile_collide = {}
- for tile in p["data"]["tile_collide"]: tile_collide[int(tile)] = true
- tile_interactable_empty = {}
- for tile in p["data"]["tile_interactable_empty"]: tile_interactable_empty[int(tile)] = true
+ tile_collide = []
+ tile_interactable_empty = []
+ tile_placeable_any = []
tile_placeable_items = {}
+ for tile in p["data"]["tile_collide"]: tile_collide.append(tile_names[int(tile)])
+ for tile in p["data"]["tile_interactable_empty"]: tile_interactable_empty.append(tile_names[int(tile)])
+ for tile in p["data"]["tile_placeable_any"]: tile_placeable_any.append(tile_names[int(tile)])
+ print(tile_placeable_any)
for tile in p["data"]["tile_placeable_items"]:
- tile_placeable_items[int(tile)] = p["data"]["tile_placeable_items"][tile].map(func(x): return int(x))
+ tile_placeable_items[tile_names[int(tile)]] = p["data"]["tile_placeable_items"][tile].map(func(x): return item_names[int(x)])
maps = p["data"]["maps"]
bot_algos = p["data"]["bot_algos"]
Global.hand_count = p["data"]["hand_count"]
Global.hand_count_change.emit(Global.hand_count)
- tile_index_by_name.clear()
- for id in tile_names.size():
- tile_index_by_name[tile_names[id]] = id
-
- item_index_by_name.clear()
- for i in range(item_names.size()):
- item_index_by_name[item_names[i]] = i
-
Global.last_map_name = Global.current_map_name
Global.current_map_name = p["data"]["current_map"]
@@ -165,18 +159,18 @@ func handle_packet(p):
if "player" in p.from and "player" in p.to:
players[p.from.player[0]].pass_to(players[p.to.player[0]], int(p.from.player[1]), int(p.to.player[1]))
elif "tile" in p.from and "player" in p.to:
- var t: Tile = map.get_tile_instance(p.from.tile)
+ var t: Tile = map.get_topmost_instance(p.from.tile)
players[p.to.player[0]].take_item(t, int(p.to.player[1]))
elif "player" in p.from and "tile" in p.to:
- var t: Tile = map.get_tile_instance(p.to.tile)
+ var t: Tile = map.get_topmost_instance(p.to.tile)
players[p.from.player[0]].put_item(t, int(p.from.player[1]))
elif "tile" in p.from and "tile" in p.to:
- var from_tile2: Tile = map.get_tile_instance(p.from.tile)
- var to_tile2: Tile = map.get_tile_instance(p.to.tile)
+ var from_tile2: Tile = map.get_topmost_instance(p.from.tile)
+ var to_tile2: Tile = map.get_topmost_instance(p.to.tile)
from_tile2.pass_to(to_tile2)
"set_progress":
if "tile" in p.item:
- var t: Tile = map.get_tile_instance(p.item.tile)
+ var t: Tile = map.get_topmost_instance(p.item.tile)
var acting_players: Array[Player] = []
for id: float in p.players:
if !players.has(id): continue
@@ -186,7 +180,7 @@ func handle_packet(p):
players[p.item.player[0]].progress(p.position, p.speed, p.warn, int(p.item.player[1]))
"clear_progress":
if "tile" in p.item:
- var t: Tile = map.get_tile_instance(p.item.tile)
+ var t: Tile = map.get_topmost_instance(p.item.tile)
t.finish()
else:
players[p.item.player[0]].finish(int(p.item.player[1]))
@@ -194,7 +188,7 @@ func handle_packet(p):
var location: Dictionary = p["location"]
if p.item != null:
if "tile" in p.location:
- var t: Tile = map.get_tile_instance(p.location.tile)
+ var t: Tile = map.get_topmost_instance(p.location.tile)
var i = ItemFactory.produce(item_names[p.item], t.item_base)
i.animate_spawn()
i.position = t.item_base.global_position
@@ -218,7 +212,7 @@ func handle_packet(p):
pl.set_item(i, h)
else:
if "tile" in p.location:
- var t: Tile = map.get_tile_instance(p.location.tile)
+ var t: Tile = map.get_topmost_instance(p.location.tile)
t.finish()
t.set_item(null)
else:
@@ -437,21 +431,23 @@ func _process(delta):
mp.send_replay_tick(delta * float(Cli.opts.get("timescale", "1")))
func get_tile_collision(pos: Vector2i) -> bool:
- var t = map.get_tile_name(pos)
+ var t = map.get_tiles_at(pos)
if t == null: return true
- else: return tile_collide.has(tile_index_by_name[t])
+ else: return G.has_one(t, tile_collide)
func is_tile_interactive(pos: Vector2i, hands: Array) -> bool:
- var tile_name = map.get_tile_name(pos)
- if tile_name == null: return false
- var tile = tile_index_by_name[tile_name]
- if map.get_tile_instance(pos).item != null: return true
- for hand in hands:
- if hand == null:
- if tile_interactable_empty.has(tile): return true
- else:
- if not tile_placeable_items.has(tile): return true
- if item_index_by_name[hand.item_name] in tile_placeable_items[tile]: return true
+ var tiles = map.get_tiles_at(pos)
+ if tiles == null: return false
+ if map.get_tile_item(pos) != null: return true # We can pick up this item with our empty hand!
+ for i in range(tiles.size() - 1, -1, -1):
+ var tile: String = tiles[i]
+ for hand in hands:
+ if hand == null:
+ if tile_interactable_empty.has(tile): return true
+ else:
+ if tile_placeable_any.has(tile): return true
+ if tile_placeable_items.has(tile):
+ return tile_placeable_items[tile].has(hand.item_name)
return false
func reset_camera():
diff --git a/client/gui/menus/main/background.gd b/client/gui/menus/main/background.gd
index e45fdaaa..7a2adef4 100644
--- a/client/gui/menus/main/background.gd
+++ b/client/gui/menus/main/background.gd
@@ -26,25 +26,25 @@ func _ready():
if !Global.on_vulkan():
environment.environment.tonemap_exposure = 0.25
- var tiles: Dictionary[Vector2i, Array] = {} # : Dictionary[Vector2i, Array[String]]
+ var tiles_dict: Dictionary[Vector2i, Array] = {} # : Dictionary[Vector2i, Array[String]]
var item_counters := []
for x in range(-10, 11):
for y in range(-10, 11):
var w = exp(-Vector2(x, y).length() * 0.15)
var k = randf() * w
- var tile = null # : String?
- if k > 0.25: tile = "floor"
- if k > 0.4: tile = choose(CRATES) if randf() > 0.7 else "counter"
- if k > 0.6: tile = choose(TOOLS)
- if tile != null:
- tiles[Vector2i(x,y)] = [tile]
- if tile == "counter" and randf() > 0.5 and w > 0.45:
+ var tiles: Array = []
+ if k > 0.25: tiles = ["floor"]
+ if k > 0.4: tiles = ["floor"] + [choose(CRATES)] if randf() > 0.7 else ["floor", "counter"]
+ if k > 0.6: tiles = ["floor"] + [choose(TOOLS)]
+ if not tiles.is_empty():
+ tiles_dict[Vector2i(x,y)] = tiles
+ if tiles.has("counter") and randf() > 0.5 and w > 0.45:
item_counters.push_back(Vector2i(x, y))
- map.set_all_tiles(tiles)
+ map.set_all_tiles(tiles_dict)
map.flush()
for v: Vector2i in item_counters:
- var t: Tile = map.get_tile_instance(v)
+ var t = map.get_topmost_instance(v)
var item := ItemFactory.produce(choose(ITEMS), t)
add_child(item)
item.position = t.item_base.global_position
diff --git a/client/map/map.gd b/client/map/map.gd
index acf7c1a4..d2467fd6 100644
--- a/client/map/map.gd
+++ b/client/map/map.gd
@@ -17,12 +17,13 @@ class_name Map
extends Node3D
class TileInfo:
- func _init(position_, name_, tile_, neighbours_) -> void:
- position = position_; name = name_; tile = tile_; neighbours = neighbours_
+ func _init(position_, tiles_, tile_instances_, tile_parent_) -> void:
+ position = position_; tiles = tiles_; tile_instances = tile_instances_; tile_parent = tile_parent_
var position: Vector2i
- var name: String
- var tile: Tile
- var neighbours: Array
+ var tiles: Array # Array[String]
+ var tile_instances: Array[Tile]
+ var tile_parent: Node3D
+ var interact_tile: Tile
const NEIGHBOR_OFFSETS: Array[Vector2i] = [Vector2i.UP, Vector2i.LEFT, Vector2i.DOWN, Vector2i.RIGHT]
@@ -32,26 +33,30 @@ var currently_baked = false
var floor_node := MeshInstance3D.new()
var tile_factory := TileFactory.new()
-func get_tile_name(pos: Vector2i): # -> String?
+func get_tiles_at(pos: Vector2i): # -> Array[String]?
var e = tile_by_pos.get(pos)
- if e != null: return e.name
- else: return null
-func get_tile_instance(pos: Vector2i) -> Tile:
+ if e == null: return null
+ return e.tiles
+func get_topmost_instance(pos: Vector2i): # -> Tile?
var e = tile_by_pos.get(pos)
- if e != null: return e.tile
- else: return null
+ if e == null: return null
+ return e.tile_instances[-1]
+func get_tile_item(pos: Vector2i): # -> Item?
+ var e = get_topmost_instance(pos)
+ if e == null: return null
+ return e.item
func set_all_tiles(changes: Dictionary[Vector2i, Array]):
for pos: Vector2i in changes:
set_tiles(Vector2i(pos.x, pos.y), changes[pos], changes)
func set_tiles(pos: Vector2i, tiles: Array = [], pending_changes: Dictionary[Vector2i, Array] = {}): # tiles: Array[String]
- var inst = get_tile_instance(pos)
- 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!
+ var tile_info = tile_by_pos.get(pos)
+ if tile_info != null:
+ for inst: Tile in tile_info.tile_instances:
+ 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 not tiles.is_empty(): _add_tiles(pos, tiles, pending_changes)
if autoflush: flush()
@@ -67,23 +72,32 @@ func _add_tiles(pos: Vector2i, tiles: Array, pending_changes: Dictionary[Vector2
neighbors.append(tile_by_pos[neighbor_pos])
else: neighbors.append([])
+ var tiles_parent = Node3D.new()
+ tiles_parent.name = str(pos)
+ add_child(tiles_parent)
+ var tile_instances: Array[Tile] = []
for tile_name: String in tiles:
var tile := tile_factory.produce(tile_name, pos, neighbors)
- add_child(tile)
+ tile_instances.append(tile)
tile.position = Vector3(pos.x, 0, pos.y)
- tile_by_pos[pos] = TileInfo.new(pos, tile_name, tile, neighbors)
+ tiles_parent.add_child(tile)
+ tile_by_pos[pos] = TileInfo.new(pos, tiles, tile_instances, tiles_parent)
func _remove_tile(pos: Vector2i):
- var tile := get_tile_instance(pos)
- if tile == null: return
- if tile.item != null: tile.item.queue_free()
- if tile is FloorLike:
- var floor_mesher = tile_factory.floor_meshers.get(tile.fm_id())
- if floor_mesher != null:
- floor_mesher.remove_tile(pos)
- tile.queue_free()
+ var tile_info = tile_by_pos.get(pos)
+ if tile_info == null: return
+
+ var topmost_instance = get_topmost_instance(pos)
+ if topmost_instance.item != null:
+ topmost_instance.item.queue_free()
+
+ for instance: Tile in tile_info.tile_instances:
+ if instance is FloorLike:
+ var floor_mesher = tile_factory.floor_meshers.get(instance.fm_id())
+ if floor_mesher != null:
+ floor_mesher.remove_tile(pos)
+ instance.queue_free()
tile_by_pos.erase(pos)
- tile.name += "_queued_free"
@onready var voxelgi: VoxelGI = $VoxelGI
diff --git a/client/map/tile_factory.gd b/client/map/tile_factory.gd
index 1640e512..dc108392 100644
--- a/client/map/tile_factory.gd
+++ b/client/map/tile_factory.gd
@@ -20,8 +20,10 @@ extends Object
class TileName:
var name# : String
var variant #: String?
- func _init(raw_name: String):
- var c = Array(raw_name.split(":"))
+ var raw_name: String
+ func _init(raw_name_: String):
+ raw_name = raw_name_
+ var c = Array(raw_name_.split(":"))
name = c[0]; variant = c[1] if c.size() >= 2 else null # TODO Array.get throws errors
class TileCC:
diff --git a/client/map/tiles/active_interact_counter.gd b/client/map/tiles/active_interact_counter.gd
index 742f147f..11ab9d5a 100644
--- a/client/map/tiles/active_interact_counter.gd
+++ b/client/map/tiles/active_interact_counter.gd
@@ -15,7 +15,7 @@
#
@abstract
class_name ActiveInteractCounter
-extends CounterBase
+extends Tile
var interact_sound: AudioStreamPlayer3D = AudioStreamPlayer3D.new()
var interact_tool: Node3D
@@ -23,7 +23,8 @@ var acting_players: Array[Player] = []
var play_character_animation: Callable
func _init(ctx: TileFactory.TileCC, station_model_: PackedScene, interact_tool_path: NodePath, play_character_animation_: Callable, audio_stream_: AudioStream):
- super(ctx, station_model_)
+ super(ctx)
+ base.add_child(station_model_.instantiate())
interact_sound.stream = audio_stream_
add_child(interact_sound)
interact_tool = base.get_node(interact_tool_path)
diff --git a/client/map/tiles/book.tscn b/client/map/tiles/book.tscn
index 9e1b144c..c7e9d141 100644
--- a/client/map/tiles/book.tscn
+++ b/client/map/tiles/book.tscn
@@ -1,10 +1,9 @@
-[gd_scene load_steps=2 format=3 uid="uid://c7fjfp5ygxsjc"]
+[gd_scene format=3 uid="uid://c7fjfp5ygxsjc"]
[ext_resource type="ArrayMesh" uid="uid://cgvow28wkwesp" path="res://map/tiles/book.res" id="1_vxs3d"]
-[node name="Book" type="Node3D"]
+[node name="Book" type="Node3D" unique_id=517586832]
-[node name="Mesh" type="MeshInstance3D" parent="."]
+[node name="Mesh" type="MeshInstance3D" parent="." unique_id=664640069]
transform = Transform3D(1.19249e-08, 0, -1, 0, 1, 0, 1, 0, 1.19249e-08, 0, 0.5, 0)
mesh = ExtResource("1_vxs3d")
-skeleton = NodePath("")
diff --git a/client/map/tiles/exterior_tree.gd b/client/map/tiles/exterior_tree.gd
index 7db57cd7..faaede1c 100644
--- a/client/map/tiles/exterior_tree.gd
+++ b/client/map/tiles/exterior_tree.gd
@@ -14,7 +14,7 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
class_name ExteriorTree
-extends Grass
+extends Tile
const SCALE: Vector3 = Vector3(100., 100., 100.)
const ROT: Vector3 = Vector3(1.5 * PI, 0., 0.)
diff --git a/client/map/tiles/tile.gd b/client/map/tiles/tile.gd
index b4928aa1..7473ff78 100644
--- a/client/map/tiles/tile.gd
+++ b/client/map/tiles/tile.gd
@@ -32,7 +32,7 @@ func _init(ctx: TileFactory.TileCC):
base.name = "Base"
base.position += Vector3(0.5, 0, 0.5)
add_child(base)
- self.name = str(ctx.position)
+ self.name = ctx.tile_name.raw_name
var item_base_ = Node3D.new()
# this method is supposed to be overriden
@warning_ignore("static_called_on_instance")
diff --git a/client/player/controllable_player.gd b/client/player/controllable_player.gd
index 15567d65..cd96a0ff 100644
--- a/client/player/controllable_player.gd
+++ b/client/player/controllable_player.gd
@@ -221,7 +221,7 @@ func get_interact_target_fps() -> InteractTarget:
if target is PlayerTarget and target.distance < 1.25:
best_interact_target = target
- var tile = game.map.get_tile_instance(target_tile)
+ var tile = game.map.get_topmost_instance(target_tile)
if game.is_tile_interactive(target_tile, hand):
var target_rot: float = tile.item.rotation.y if tile.item != null and not tile.item.is_round() else 0.
best_interact_target = TileTarget.new(target_tile, tile, tile.item_base.global_position, target_rot)
@@ -255,8 +255,9 @@ func get_interact_target() -> InteractTarget:
var self_target_distance := movement_base_2d.distance_to(tile_center)
if self_target_distance < MAX_PLAYER_INTERACT_DIST && distance < best_distance:
best_distance = distance
- var tile := game.map.get_tile_instance(offset_cursor)
- var target_rot := tile.item.rotation.y if tile.item != null and not tile.item.is_round() else 0.
+ var tile = game.map.get_topmost_instance(offset_cursor)
+ var tile_item = game.map.get_tile_item(offset_cursor)
+ var target_rot: float = tile_item.rotation.y if tile_item != null and not tile_item.is_round() else 0.
best_interact_target = TileTarget.new(offset_cursor, tile, tile.item_base.global_position, target_rot)
return best_interact_target