RapidGameFramework
Reusable Godot managers for data-driven small games
Loading...
Searching...
No Matches
grid_world_manager.gd
Go to the documentation of this file.
1extends RefCounted
2
3
6
7var world_config := {}
8var tile_size := 40.0
9
10
11
12func configure(config:Dictionary, next_tile_size := 40.0) -> void:
13 world_config = config.duplicate(true)
14 tile_size = max(1.0, float(next_tile_size))
15
16
17func get_grid_size() -> Vector2i:
18 return _cell_from_value(world_config.get("grid_size", [12, 12]))
19
20
21func get_bounds() -> Rect2:
22 return Rect2(Vector2.ZERO, Vector2(get_grid_size()) * tile_size)
23
24
25func get_blocked_cells() -> Array:
26 var cells := []
27 for obstacle in world_config.get("obstacles", []):
28 if not obstacle is Dictionary:
29 continue
30 for cell in cells_from_obstacle(obstacle):
31 cells.append(cell)
32 return cells
33
34
35func get_movement_blocked_cells(occupied_cells:Array) -> Array:
36 var cells = get_blocked_cells()
37 for cell in occupied_cells:
38 cells.append(_cell_from_value(cell))
39 return cells
40
41
42func cells_from_obstacle(obstacle:Dictionary) -> Array:
43 var cells := []
44 if obstacle.has("cells"):
45 for cell in obstacle.get("cells", []):
46 cells.append(_cell_from_value(cell))
47 elif obstacle.has("rect"):
48 cells = rect_to_cells(_rect_from_value(obstacle.get("rect", [])))
49 return cells
50
51
52func rect_to_cells(rect:Rect2) -> Array:
53 var min_cell = Vector2i(int(floor(rect.position.x / tile_size)), int(floor(rect.position.y / tile_size)))
54 var max_cell = Vector2i(
55 int(floor((rect.position.x + max(0.0, rect.size.x - 0.01)) / tile_size)),
56 int(floor((rect.position.y + max(0.0, rect.size.y - 0.01)) / tile_size))
57 )
58 var cells := []
59 for y in range(min_cell.y, max_cell.y + 1):
60 for x in range(min_cell.x, max_cell.x + 1):
61 cells.append(Vector2i(x, y))
62 return cells
63
64
65
66func collect_material_at(cell:Vector2i, collected_nodes:Dictionary) -> Dictionary:
67 for node in world_config.get("material_nodes", []):
68 if not node is Dictionary:
69 continue
70 var node_id = str(node.get("id", ""))
71 if node_id == "" or collected_nodes.has(node_id):
72 continue
73 if _cell_from_value(node.get("cell", [0, 0])) != cell:
74 continue
75 return {
76 "collected": true,
77 "node_id": node_id,
78 "element": str(node.get("element", "")),
79 "amount": int(node.get("amount", 1))
80 }
81 return {"collected": false}
82
83
84
85func resolve_spell_interactions(card:Dictionary, affected_cells:Array, activated_interactions:Dictionary) -> Array:
86 var activated := []
87 for interaction in world_config.get("spell_interactions", []):
88 if not interaction is Dictionary:
89 continue
90 var id = str(interaction.get("id", ""))
91 if id == "" or activated_interactions.has(id):
92 continue
93 var cell = _cell_from_value(interaction.get("cell", [0, 0]))
94 if not affected_cells.has(cell):
95 continue
96 if not _card_matches_interaction(card, interaction):
97 continue
98 var entry = interaction.duplicate(true)
99 entry["activated"] = true
100 activated.append(entry)
101 return activated
102
103
104func _rect_from_value(value) -> Rect2:
105 if value is Rect2:
106 return value
107 if value is Array and value.size() >= 4:
108 return Rect2(Vector2(float(value[0]), float(value[1])), Vector2(float(value[2]), float(value[3])))
109 return Rect2()
110
111
112func _cell_from_value(value) -> Vector2i:
113 if value is Vector2i:
114 return value
115 if value is Vector2:
116 return Vector2i(int(value.x), int(value.y))
117 if value is Array and value.size() >= 2:
118 return Vector2i(int(value[0]), int(value[1]))
119 if value is Dictionary and value.has("cell"):
120 return _cell_from_value(value.get("cell"))
121 return Vector2i.ZERO
122
123
124func _card_matches_interaction(card:Dictionary, interaction:Dictionary) -> bool:
125 var requires = interaction.get("requires", {})
126 if not requires is Dictionary or requires.is_empty():
127 return true
128 for key in requires.keys():
129 var expected = requires[key]
130 if key == "compound" and str(card.get("compound", "")) != str(expected):
131 return false
132 if key == "manifestation" and str(card.get("manifestation", "")) != str(expected):
133 return false
134 if key == "card_id" and str(card.get("id", "")) != str(expected):
135 return false
136 if key == "modifier" and not card.get("modifiers", []).has(str(expected)):
137 return false
138 return true
139
140