1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
# Hurry Curry! - a game about cooking
# Copyright (C) 2025 Hurry Curry! contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, version 3 of the License only.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
class_name Map
extends Node3D
var tile_by_pos: Dictionary = {} # Dictionary[String, [Vector2i, String, Tile, Array]]
var autobake = false
var currently_baked = false
var floor_node := MeshInstance3D.new()
var tile_factory = TileFactory.new()
func get_tile_name(pos: Vector2i): # -> String?
var e = tile_by_pos.get(str(pos))
if e != null: return e[1]
else: return null
func get_tile_instance(pos: Vector2i) -> Tile:
var e = tile_by_pos.get(str(pos))
if e != null: return e[2]
else: return null
func set_tile(pos: Vector2i, name_: String, neighbors: Array = [null,null,null,null]) -> Tile:
clear_tile(pos)
var tile := tile_factory.produce(name_, pos, neighbors)
add_child(tile)
tile.position = Vector3(pos.x, 0, pos.y)
tile_by_pos[str(pos)] = [pos, name_, tile, neighbors]
return tile
func clear_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()
tile_by_pos.erase(str(pos))
tile.name += "_queued_free"
@onready var voxelgi: VoxelGI = $VoxelGI
func _ready():
Settings.hook_changed("graphics.gi", false, apply_gi_setting)
floor_node.material_override = preload("res://map/tiles/floor_material.tres")
for fm in tile_factory.floor_meshers.values():
add_child(fm.mesh_instance)
add_child(floor_node)
func flush() -> void:
for fm in tile_factory.floor_meshers.values():
fm.flush()
gi_bake()
func apply_gi_setting(state):
if state == "voxelgi" and not currently_baked:
gi_bake()
else:
currently_baked = false
voxelgi.data = null
func gi_bake():
if Settings.read("graphics.gi") != "voxelgi": return
print("Map: Rebaking VoxelGI")
currently_baked = true
gi_bake_blocking()
func gi_bake_blocking():
var map_extents = extents()
var extent_min = map_extents[0]
var extent_max = map_extents[1]
var center = (extent_max + extent_min) / 2
var size = extent_max - extent_min
voxelgi.position = Vector3(center.x, 3., center.y)
voxelgi.size = Vector3(size.x, 8., size.y)
print("Baking now!")
var start = Time.get_ticks_msec()
voxelgi.bake()
voxelgi.visible = true
print("Bake done. elapsed=", Time.get_ticks_msec() - start)
func extents() -> Array[Vector2]:
var extent_min = Vector2(0,0)
var extent_max = Vector2(0,0)
for e in tile_by_pos.values():
extent_min.x = min(extent_min.x, e[0].x)
extent_min.y = min(extent_min.y, e[0].y)
extent_max.x = max(extent_max.x, e[0].x)
extent_max.y = max(extent_max.y, e[0].y)
return [extent_min, extent_max + Vector2(1., 1.)]
|