level building tool good enough for first cave draft
This commit is contained in:
@@ -12,6 +12,7 @@ var flow_node_scene: PackedScene = preload("res://Scenes/FlowField/flow_node.tsc
|
||||
var nodes: Array[FlowNode] = []
|
||||
var start_nodes: Array[FlowNode] = []
|
||||
var goal_nodes: Array[FlowNode] = []
|
||||
var created_nodes: int = 0
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
@@ -21,20 +22,22 @@ func _ready() -> void:
|
||||
|
||||
|
||||
func load_from_data(data: FlowFieldData = data_file) -> void:
|
||||
data_file = data
|
||||
for node: FlowNode in nodes:
|
||||
delete_node(node)
|
||||
nodes = []
|
||||
start_nodes = []
|
||||
goal_nodes = []
|
||||
var dict: Dictionary[FlowNodeData, FlowNode] = {}
|
||||
created_nodes = 0
|
||||
for node_data: FlowNodeData in data_file.nodes:
|
||||
var new_flow_node: FlowNode = create_node(node_data.position)
|
||||
new_flow_node.node_id = node_data.node_id
|
||||
new_flow_node.grid_id = node_data.grid_id
|
||||
new_flow_node.grid_x = node_data.grid_x
|
||||
new_flow_node.grid_y = node_data.grid_y
|
||||
new_flow_node.buildable = node_data.buildable
|
||||
dict[node_data] = new_flow_node
|
||||
nodes.append(new_flow_node)
|
||||
if node_data.type == FlowNodeData.NodeType.START:
|
||||
start_nodes.append(new_flow_node)
|
||||
elif node_data.type == FlowNodeData.NodeType.GOAL:
|
||||
@@ -191,6 +194,7 @@ func toggle_buildable(node: FlowNode) -> void:
|
||||
|
||||
func create_node(pos: Vector3 = Vector3.ZERO, grid_id: int = -1, grid_x: int = 0, grid_y: int = 0) -> FlowNode:
|
||||
var node: FlowNode = flow_node_scene.instantiate()
|
||||
node.node_id = created_nodes
|
||||
node.grid_id = grid_id
|
||||
node.grid_x = grid_x
|
||||
node.grid_y = grid_y
|
||||
@@ -199,6 +203,7 @@ func create_node(pos: Vector3 = Vector3.ZERO, grid_id: int = -1, grid_x: int = 0
|
||||
nodes.append(node)
|
||||
add_child(node)
|
||||
node.owner = self
|
||||
created_nodes += 1
|
||||
return node
|
||||
|
||||
|
||||
|
||||
@@ -3,3 +3,25 @@ extends Resource
|
||||
|
||||
@export var nodes: Array[FlowNodeData]
|
||||
@export var grids: int = 0
|
||||
|
||||
|
||||
func to_dict() -> Dictionary:
|
||||
var dict: Dictionary = {}
|
||||
for node: FlowNodeData in nodes:
|
||||
dict[node.node_id] = node.to_dict()
|
||||
dict["grids"] = grids
|
||||
return dict
|
||||
|
||||
|
||||
static func from_dict(dict: Dictionary) -> FlowFieldData:
|
||||
var flow: FlowFieldData = FlowFieldData.new()
|
||||
var unpopulated: Dictionary[FlowNodeData, Dictionary] = {}
|
||||
for key: String in dict.keys():
|
||||
if key.is_valid_int():
|
||||
var data: FlowNodeData = FlowNodeData.from_dict(dict[key])
|
||||
flow.nodes.append(data)
|
||||
unpopulated[data] = dict[key]
|
||||
for key: FlowNodeData in unpopulated.keys():
|
||||
key.populate_connections(unpopulated[key], flow.nodes)
|
||||
flow.grids = dict["grids"]
|
||||
return flow
|
||||
|
||||
@@ -29,6 +29,7 @@ var level: Level
|
||||
var radius: float = 0
|
||||
var up_angle: float = 0
|
||||
var rotate_held: bool = false
|
||||
var flow_field_data: FlowFieldData
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
@@ -50,10 +51,10 @@ func load_zone() -> void:
|
||||
if level:
|
||||
level.queue_free()
|
||||
level = zone_list[selected_zone].instantiate() as Level
|
||||
level.flow_field = flow_field
|
||||
zone_holder.add_child(level)
|
||||
camera.make_current()
|
||||
editing = true
|
||||
print("set editing true")
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
@@ -63,12 +64,16 @@ func _process(delta: float) -> void:
|
||||
if hover and !raycast.is_colliding():
|
||||
hover = null
|
||||
if selected.size() == 1 and vector_dirty:
|
||||
$Position/Button.visible = true
|
||||
position_field.visible = true
|
||||
x_field.text = str(selected[0].global_position.x)
|
||||
y_field.text = str(selected[0].global_position.y)
|
||||
z_field.text = str(selected[0].global_position.z)
|
||||
vector_dirty = false
|
||||
elif selected.size() != 1:
|
||||
elif selected.size() > 1:
|
||||
$Position/Button.visible = false
|
||||
position_field.visible = true
|
||||
elif selected.size() < 1:
|
||||
position_field.visible = false
|
||||
|
||||
set_node_colors()
|
||||
@@ -152,6 +157,16 @@ func _on_z_field_changed(text: String) -> void:
|
||||
selected[0].global_position.z = float(text)
|
||||
|
||||
|
||||
func set_position() -> void:
|
||||
for node: FlowNode in selected:
|
||||
node.global_position = Vector3(float($Position/x.text), float($Position/y.text), float($Position/z.text))
|
||||
|
||||
|
||||
func offset_position() -> void:
|
||||
for node: FlowNode in selected:
|
||||
node.global_position += Vector3(float($Position/x.text), float($Position/y.text), float($Position/z.text))
|
||||
|
||||
|
||||
func _on_create_button_pressed() -> void:
|
||||
flow_field.create_node()
|
||||
|
||||
@@ -159,6 +174,14 @@ func _on_create_button_pressed() -> void:
|
||||
func _on_generate_grid_button_pressed() -> void:
|
||||
flow_field.create_grid(int(x_size_field.text), int(y_size_field.text), float(gap_field.text))
|
||||
selected.append_array(flow_field.nodes)
|
||||
create_grid_select_button(flow_field.data_file.grids)
|
||||
|
||||
|
||||
func create_grid_select_button(grid: int) -> void:
|
||||
var button: Button = Button.new()
|
||||
button.text = "Grid " + str(grid)
|
||||
button.pressed.connect(select_in_grid.bind(grid))
|
||||
$VBoxContainer3.add_child(button)
|
||||
|
||||
|
||||
func _on_calculate_button_pressed() -> void:
|
||||
@@ -222,9 +245,13 @@ func _on_project_downwards_button_pressed() -> void:
|
||||
func _on_save_button_pressed() -> void:
|
||||
var new_flow_field_data: FlowFieldData = FlowFieldData.new()
|
||||
var dict: Dictionary[FlowNode, FlowNodeData] = {}
|
||||
var grid_num: int = -1
|
||||
for node: FlowNode in flow_field.nodes:
|
||||
var new_flow_node_data: FlowNodeData = FlowNodeData.new()
|
||||
new_flow_node_data.node_id = node.node_id
|
||||
new_flow_node_data.grid_id = node.grid_id
|
||||
if node.grid_id > grid_num:
|
||||
grid_num += 1
|
||||
new_flow_node_data.grid_x = node.grid_x
|
||||
new_flow_node_data.grid_y = node.grid_y
|
||||
new_flow_node_data.position = node.global_position
|
||||
@@ -241,18 +268,77 @@ func _on_save_button_pressed() -> void:
|
||||
for neighbor: FlowNode in node.connections:
|
||||
flow_node_data.connected_nodes.append(dict[neighbor])
|
||||
new_flow_field_data.nodes.append(flow_node_data)
|
||||
ResourceSaver.save(new_flow_field_data, save_path.text)
|
||||
new_flow_field_data.grids = grid_num
|
||||
|
||||
var string: String = JSON.stringify(new_flow_field_data.to_dict())
|
||||
var path: String = save_path.text + ".json"
|
||||
var dir: DirAccess = DirAccess.open("user://")
|
||||
if !dir.dir_exists("pathing_graphs"):
|
||||
dir.make_dir("pathing_graphs")
|
||||
dir.change_dir("pathing_graphs")
|
||||
var save_file: FileAccess = FileAccess.open("user://pathing_graphs/" + path, FileAccess.WRITE)
|
||||
save_file.store_line(string)
|
||||
|
||||
|
||||
static func load_flow_field_from_disc(path: String) -> FlowFieldData:
|
||||
if FileAccess.file_exists(path):
|
||||
var save_file: FileAccess = FileAccess.open(path, FileAccess.READ)
|
||||
var json_string: String = save_file.get_line()
|
||||
var json: JSON = JSON.new()
|
||||
var parse_result: Error = json.parse(json_string)
|
||||
if parse_result == OK:
|
||||
var dict: Dictionary = json.data
|
||||
var flow_field_data: FlowFieldData = FlowFieldData.from_dict(dict)
|
||||
return flow_field_data
|
||||
return FlowFieldData.new()
|
||||
|
||||
|
||||
func _on_load_button_pressed() -> void:
|
||||
if ResourceLoader.exists(save_path.text):
|
||||
var resource: Resource = ResourceLoader.load(save_path.text)
|
||||
if resource is FlowFieldData:
|
||||
flow_field.load_from_data(resource)
|
||||
if FileAccess.file_exists("user://pathing_graphs/" + save_path.text + ".json"):
|
||||
var save_file: FileAccess = FileAccess.open("user://pathing_graphs/" + save_path.text + ".json", FileAccess.READ)
|
||||
var json_string: String = save_file.get_line()
|
||||
var json: JSON = JSON.new()
|
||||
var parse_result: Error = json.parse(json_string)
|
||||
if parse_result == OK:
|
||||
var dict: Dictionary = json.data
|
||||
var flow_field_data: FlowFieldData = FlowFieldData.from_dict(dict)
|
||||
flow_field.load_from_data(flow_field_data)
|
||||
for grid: int in flow_field_data.grids:
|
||||
create_grid_select_button(grid + 1)
|
||||
|
||||
|
||||
#func _on_load_button_pressed() -> void:
|
||||
#if ResourceLoader.exists(save_path.text + ".res"):
|
||||
#print("file exists")
|
||||
#var resource: Resource = ResourceLoader.load(save_path.text + ".res", "", ResourceLoader.CACHE_MODE_IGNORE)
|
||||
#if resource is FlowFieldData:
|
||||
#flow_field.load_from_data(resource)
|
||||
#print("loaded some data")
|
||||
#else:
|
||||
#print("some error loading!")
|
||||
|
||||
|
||||
func _on_trash_button_pressed() -> void:
|
||||
if flow_field:
|
||||
flow_field.queue_free()
|
||||
for child: Node in $VBoxContainer3.get_children():
|
||||
child.queue_free()
|
||||
flow_field = FlowField.new()
|
||||
flow_field_data = FlowFieldData.new()
|
||||
flow_field.data_file = flow_field_data
|
||||
add_child(flow_field)
|
||||
if level:
|
||||
level.flow_field = flow_field
|
||||
|
||||
|
||||
func _on_select_all_pressed() -> void:
|
||||
selected = []
|
||||
for node: FlowNode in flow_field.nodes:
|
||||
selected.append(node)
|
||||
|
||||
|
||||
func select_in_grid(grid: int) -> void:
|
||||
selected = []
|
||||
for node: FlowNode in flow_field.nodes:
|
||||
if node.grid_id == grid:
|
||||
selected.append(node)
|
||||
|
||||
@@ -68,6 +68,10 @@ layout_mode = 2
|
||||
text = "2.5"
|
||||
placeholder_text = "gap"
|
||||
|
||||
[node name="SelectAll" type="Button" parent="VBoxContainer" unique_id=1460776735]
|
||||
layout_mode = 2
|
||||
text = "Select All Nodes"
|
||||
|
||||
[node name="Connect" type="Button" parent="VBoxContainer" unique_id=330867073]
|
||||
layout_mode = 2
|
||||
text = "Connect Nodes"
|
||||
@@ -123,13 +127,10 @@ size_flags_horizontal = 3
|
||||
text = "Load"
|
||||
|
||||
[node name="Position" type="HBoxContainer" parent="." unique_id=1194117729]
|
||||
visible = false
|
||||
anchors_preset = 1
|
||||
anchor_left = 1.0
|
||||
anchor_right = 1.0
|
||||
offset_left = -323.0
|
||||
offset_bottom = 41.0
|
||||
grow_horizontal = 0
|
||||
anchors_preset = -1
|
||||
anchor_left = 0.4
|
||||
anchor_right = 0.6
|
||||
grow_horizontal = 2
|
||||
|
||||
[node name="x" type="LineEdit" parent="Position" unique_id=1634710518]
|
||||
layout_mode = 2
|
||||
@@ -143,6 +144,14 @@ size_flags_horizontal = 3
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="Button" type="Button" parent="Position" unique_id=362195148]
|
||||
layout_mode = 2
|
||||
text = "Set Position"
|
||||
|
||||
[node name="Button2" type="Button" parent="Position" unique_id=1670413853]
|
||||
layout_mode = 2
|
||||
text = "Add Offset"
|
||||
|
||||
[node name="CameraFocus" type="Node3D" parent="." unique_id=1567712529]
|
||||
|
||||
[node name="Camera3D" type="Camera3D" parent="CameraFocus" unique_id=1970273041]
|
||||
@@ -169,10 +178,19 @@ layout_mode = 2
|
||||
layout_mode = 2
|
||||
text = "Load zone"
|
||||
|
||||
[node name="VBoxContainer3" type="VBoxContainer" parent="." unique_id=179301019]
|
||||
anchors_preset = 2
|
||||
anchor_top = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_top = -40.0
|
||||
offset_right = 40.0
|
||||
grow_vertical = 0
|
||||
|
||||
[connection signal="pressed" from="VBoxContainer/Button" to="." method="_on_trash_button_pressed"]
|
||||
[connection signal="pressed" from="VBoxContainer/Create" to="." method="_on_create_button_pressed"]
|
||||
[connection signal="pressed" from="VBoxContainer/Delete" to="." method="_on_create_button_pressed"]
|
||||
[connection signal="pressed" from="VBoxContainer/HBoxContainer/GenerateGrid" to="." method="_on_generate_grid_button_pressed"]
|
||||
[connection signal="pressed" from="VBoxContainer/SelectAll" to="." method="_on_select_all_pressed"]
|
||||
[connection signal="pressed" from="VBoxContainer/Connect" to="." method="_on_connect_button_pressed"]
|
||||
[connection signal="pressed" from="VBoxContainer/ProjectDownwards" to="." method="_on_project_downwards_button_pressed"]
|
||||
[connection signal="pressed" from="VBoxContainer/MarkGoal" to="." method="_on_mark_goal_button_pressed"]
|
||||
@@ -183,7 +201,6 @@ text = "Load zone"
|
||||
[connection signal="pressed" from="VBoxContainer/Calculate" to="." method="_on_calculate_button_pressed"]
|
||||
[connection signal="pressed" from="VBoxContainer/HBoxContainer2/Save" to="." method="_on_save_button_pressed"]
|
||||
[connection signal="pressed" from="VBoxContainer/HBoxContainer2/Load" to="." method="_on_load_button_pressed"]
|
||||
[connection signal="text_changed" from="Position/x" to="." method="_on_x_field_changed"]
|
||||
[connection signal="text_changed" from="Position/y" to="." method="_on_y_field_changed"]
|
||||
[connection signal="text_changed" from="Position/z" to="." method="_on_z_field_changed"]
|
||||
[connection signal="pressed" from="Position/Button" to="." method="set_position"]
|
||||
[connection signal="pressed" from="Position/Button2" to="." method="offset_position"]
|
||||
[connection signal="pressed" from="VBoxContainer2/Button" to="." method="load_zone"]
|
||||
|
||||
@@ -7,6 +7,7 @@ extends StaticBody3D
|
||||
@export var buildable: bool = true
|
||||
|
||||
var visual_scene: PackedScene = preload("res://Scenes/FlowField/cube2.tscn")
|
||||
var node_id: int = 0
|
||||
var grid_id: int = -1
|
||||
var grid_x: int = 0
|
||||
var grid_y: int = 0
|
||||
|
||||
@@ -7,6 +7,7 @@ enum NodeType {
|
||||
GOAL = 2,
|
||||
}
|
||||
|
||||
@export var node_id: int = -1
|
||||
@export var position: Vector3 = Vector3.ZERO
|
||||
@export var type: NodeType = NodeType.STANDARD
|
||||
@export var buildable: bool = true
|
||||
@@ -15,3 +16,47 @@ enum NodeType {
|
||||
@export var grid_id: int = -1
|
||||
@export var grid_x: int = 0
|
||||
@export var grid_y: int = 0
|
||||
|
||||
|
||||
#This function cannot fill in the connection information until a complete set
|
||||
#of nodes have been loaded and can be looped over
|
||||
static func from_dict(dict: Dictionary) -> FlowNodeData:
|
||||
var data: FlowNodeData = FlowNodeData.new()
|
||||
data.node_id = dict["node_id"]
|
||||
data.position.x = dict["position_x"]
|
||||
data.position.y = dict["position_y"]
|
||||
data.position.z = dict["position_z"]
|
||||
data.type = dict["type"]
|
||||
data.buildable = dict["buildable"]
|
||||
data.in_grid = dict["in_grid"]
|
||||
data.grid_id = dict["grid_id"]
|
||||
data.grid_x = dict["grid_x"]
|
||||
data.grid_y = dict["grid_y"]
|
||||
return data
|
||||
|
||||
|
||||
func populate_connections(dict: Dictionary, node_array: Array[FlowNodeData]) -> void:
|
||||
var connections_array: Array = dict["connected_nodes"]
|
||||
for x: float in connections_array:
|
||||
for y: FlowNodeData in node_array:
|
||||
if y.node_id == int(x):
|
||||
connected_nodes.append(y)
|
||||
|
||||
|
||||
func to_dict() -> Dictionary:
|
||||
var dict: Dictionary = {}
|
||||
var connections: Array[int] = []
|
||||
for node: FlowNodeData in connected_nodes:
|
||||
connections.append(node.node_id)
|
||||
dict["connected_nodes"] = connections
|
||||
dict["node_id"] = node_id
|
||||
dict["position_x"] = position.x
|
||||
dict["position_y"] = position.y
|
||||
dict["position_z"] = position.z
|
||||
dict["type"] = type
|
||||
dict["buildable"] = buildable
|
||||
dict["in_grid"] = in_grid
|
||||
dict["grid_id"] = grid_id
|
||||
dict["grid_x"] = grid_x
|
||||
dict["grid_y"] = grid_y
|
||||
return dict
|
||||
|
||||
Reference in New Issue
Block a user