Save / load advanced to usability
This commit is contained in:
parent
1bb038d8b7
commit
949bc9f4ff
21
addons/godot_object_serializer/LICENSE
Normal file
21
addons/godot_object_serializer/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 Charles Crete
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
63
addons/godot_object_serializer/binary_serializer.gd
Normal file
63
addons/godot_object_serializer/binary_serializer.gd
Normal file
@ -0,0 +1,63 @@
|
||||
## Serializer to be used with Godot's built-in binary serialization ([method @GlobalScope.var_to_bytes] and [method @GlobalScope.bytes_to_var]).
|
||||
## This serializes objects but leaves built-in Godot types as-is.
|
||||
class_name BinarySerializer
|
||||
|
||||
|
||||
## Serialize [param data] to value which can be passed to [method @GlobalScope.var_to_bytes].
|
||||
static func serialize_var(value: Variant) -> Variant:
|
||||
match typeof(value):
|
||||
TYPE_OBJECT:
|
||||
var name: StringName = value.get_script().get_global_name()
|
||||
var object_entry := ObjectSerializer._get_entry(name, value.get_script())
|
||||
if !object_entry:
|
||||
assert(
|
||||
false,
|
||||
(
|
||||
"Could not find type (%s) in registry\n%s"
|
||||
% [name if name else "no name", value.get_script().source_code]
|
||||
)
|
||||
)
|
||||
|
||||
return object_entry.serialize(value, serialize_var)
|
||||
TYPE_ARRAY:
|
||||
return value.map(serialize_var)
|
||||
TYPE_DICTIONARY:
|
||||
var result := {}
|
||||
for i: Variant in value:
|
||||
result[i] = serialize_var(value[i])
|
||||
return result
|
||||
|
||||
return value
|
||||
|
||||
|
||||
## Serialize [param data] into bytes with [method BinaryObjectSerializer.serialize_var] and [method @GlobalScope.var_to_bytes].
|
||||
static func serialize_bytes(value: Variant) -> PackedByteArray:
|
||||
return var_to_bytes(serialize_var(value))
|
||||
|
||||
|
||||
## Deserialize [param data] from [method @GlobalScope.bytes_to_var] to value.
|
||||
static func deserialize_var(value: Variant) -> Variant:
|
||||
match typeof(value):
|
||||
TYPE_DICTIONARY:
|
||||
if value.has(ObjectSerializer.type_field):
|
||||
var type: String = value.get(ObjectSerializer.type_field)
|
||||
if type.begins_with(ObjectSerializer.object_type_prefix):
|
||||
var entry := ObjectSerializer._get_entry(type)
|
||||
if !entry:
|
||||
assert(false, "Could not find type (%s) in registry" % type)
|
||||
|
||||
return entry.deserialize(value, deserialize_var)
|
||||
|
||||
var result := {}
|
||||
for i: Variant in value:
|
||||
result[i] = deserialize_var(value[i])
|
||||
return result
|
||||
TYPE_ARRAY:
|
||||
return value.map(deserialize_var)
|
||||
|
||||
return value
|
||||
|
||||
|
||||
## Deserialize bytes [param data] to value with [method @GlobalScope.bytes_to_var] and [method BinaryObjectSerializer.deserialize_var].
|
||||
static func deserialize_bytes(value: PackedByteArray) -> Variant:
|
||||
return deserialize_var(bytes_to_var(value))
|
||||
1
addons/godot_object_serializer/binary_serializer.gd.uid
Normal file
1
addons/godot_object_serializer/binary_serializer.gd.uid
Normal file
@ -0,0 +1 @@
|
||||
uid://82dofbvl1g6n
|
||||
101
addons/godot_object_serializer/dictionary_serializer.gd
Normal file
101
addons/godot_object_serializer/dictionary_serializer.gd
Normal file
@ -0,0 +1,101 @@
|
||||
## Serializer to be used with JSON serialization ([method JSON.stringify] and [method JSON.parse_string]).
|
||||
## This serializes objects and built-in Godot types.
|
||||
class_name DictionarySerializer
|
||||
|
||||
# Types that can natively be represented in JSON
|
||||
const _JSON_SERIALIZABLE_TYPES = [
|
||||
TYPE_NIL, TYPE_BOOL, TYPE_INT, TYPE_FLOAT, TYPE_STRING, TYPE_STRING_NAME
|
||||
]
|
||||
|
||||
## Controls if [PackedByteArray] should be serialized as base64 (instead of array of bytes as uint8).
|
||||
## It's highly recommended to leave this enabled as it will result to smaller serialized payloads and should be faster.
|
||||
## This can be changed, but must be configured before any serialization or deserialization.
|
||||
static var bytes_as_base64 := true
|
||||
## The type of the object for [PackedByteArray] when [member bytes_as_base64] is enabled.
|
||||
## This should be set to something unlikely to clash with built-in type names or [member ObjectSerializer.object_type_prefix].
|
||||
## This can be changed, but must be configured before any serialization or deserialization.
|
||||
static var bytes_to_base64_type := "PackedByteArray_Base64"
|
||||
|
||||
|
||||
## Serialize [param data] into value which can be passed to [method JSON.stringify].
|
||||
static func serialize_var(value: Variant) -> Variant:
|
||||
match typeof(value):
|
||||
TYPE_OBJECT:
|
||||
var name: StringName = value.get_script().get_global_name()
|
||||
var object_entry := ObjectSerializer._get_entry(name, value.get_script())
|
||||
if !object_entry:
|
||||
assert(
|
||||
false,
|
||||
(
|
||||
"Could not find type (%s) in registry\n%s"
|
||||
% [name if name else "no name", value.get_script().source_code]
|
||||
)
|
||||
)
|
||||
|
||||
return object_entry.serialize(value, serialize_var)
|
||||
|
||||
TYPE_ARRAY:
|
||||
return value.map(serialize_var)
|
||||
|
||||
TYPE_DICTIONARY:
|
||||
var result := {}
|
||||
for i: Variant in value:
|
||||
result[i] = serialize_var(value[i])
|
||||
return result
|
||||
|
||||
TYPE_PACKED_BYTE_ARRAY:
|
||||
if bytes_as_base64:
|
||||
return {
|
||||
ObjectSerializer.type_field: bytes_to_base64_type,
|
||||
ObjectSerializer.args_field:
|
||||
Marshalls.raw_to_base64(value) if !value.is_empty() else ""
|
||||
}
|
||||
|
||||
if _JSON_SERIALIZABLE_TYPES.has(typeof(value)):
|
||||
return value
|
||||
|
||||
return {
|
||||
ObjectSerializer.type_field: type_string(typeof(value)),
|
||||
ObjectSerializer.args_field: JSON.from_native(value)["args"]
|
||||
}
|
||||
|
||||
|
||||
## Serialize [param data] into JSON string with [method DictionaryObjectSerializer.serialize_var] and [method JSON.stringify]. Supports same arguments as [method JSON.stringify]
|
||||
static func serialize_json(
|
||||
value: Variant, indent := "", sort_keys := true, full_precision := false
|
||||
) -> String:
|
||||
return JSON.stringify(serialize_var(value), indent, sort_keys, full_precision)
|
||||
|
||||
|
||||
## Deserialize [data] from [JSON.parse_string] into value.
|
||||
static func deserialize_var(value: Variant) -> Variant:
|
||||
match typeof(value):
|
||||
TYPE_DICTIONARY:
|
||||
if value.has(ObjectSerializer.type_field):
|
||||
var type: String = value.get(ObjectSerializer.type_field)
|
||||
if bytes_as_base64 and type == bytes_to_base64_type:
|
||||
return Marshalls.base64_to_raw(value[ObjectSerializer.args_field])
|
||||
|
||||
if type.begins_with(ObjectSerializer.object_type_prefix):
|
||||
var entry := ObjectSerializer._get_entry(type)
|
||||
if !entry:
|
||||
assert(false, "Could not find type (%s) in registry" % type)
|
||||
|
||||
return entry.deserialize(value, deserialize_var, true)
|
||||
|
||||
return JSON.to_native({"type": type, "args": value[ObjectSerializer.args_field]})
|
||||
|
||||
var result := {}
|
||||
for i: Variant in value:
|
||||
result[i] = deserialize_var(value[i])
|
||||
return result
|
||||
|
||||
TYPE_ARRAY:
|
||||
return value.map(deserialize_var)
|
||||
|
||||
return value
|
||||
|
||||
|
||||
## Deserialize JSON string [param data] to value with [method JSON.parse_string] and [method DictionaryObjectSerializer.deserialize_var].
|
||||
static func deserialize_json(value: String) -> Variant:
|
||||
return deserialize_var(JSON.parse_string(value))
|
||||
@ -0,0 +1 @@
|
||||
uid://cejorwceoqbqe
|
||||
131
addons/godot_object_serializer/example
Normal file
131
addons/godot_object_serializer/example
Normal file
@ -0,0 +1,131 @@
|
||||
extends SceneTree
|
||||
|
||||
|
||||
# Example data class. Can extend any type, include Resource
|
||||
class Data:
|
||||
# Supports all primitive types (String, int, float, bool, null), including @export variables
|
||||
@export var string: String
|
||||
# Supports all extended built-in types (Vector2/3/4/i, Rect2/i, Transform2D/3D, Color, Packed*Array, etc)
|
||||
var vector: Vector3
|
||||
# Supports enum
|
||||
var enum_state: State
|
||||
# Supports arrays, including Array[Variant]
|
||||
var array: Array[int]
|
||||
# Supports dictionaries, including Dictionary[Variant, Variant]
|
||||
var dictionary: Dictionary[String, Vector2]
|
||||
# Supports efficient byte array serialization to base64
|
||||
var packed_byte_array: PackedByteArray
|
||||
# Supports nested data, either as a field or in array/dictionary
|
||||
var nested: DataResource
|
||||
|
||||
|
||||
class DataResource:
|
||||
extends Resource
|
||||
var name: String
|
||||
|
||||
|
||||
enum State { OPENED, CLOSED }
|
||||
|
||||
|
||||
# _static_init is used to register scripts without having to instanciate the script.
|
||||
# It's recommended to either place all registrations in a single script, or have each script register itself.
|
||||
static func _static_init() -> void:
|
||||
# Required: Register possible object scripts
|
||||
ObjectSerializer.register_script("Data", Data)
|
||||
ObjectSerializer.register_script("DataResource", DataResource)
|
||||
|
||||
|
||||
# Setup testing data
|
||||
var data := Data.new()
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
data.string = "Lorem ipsum"
|
||||
data.vector = Vector3(1, 2, 3)
|
||||
data.enum_state = State.CLOSED
|
||||
data.array = [1, 2]
|
||||
data.dictionary = {"position": Vector2(1, 2)}
|
||||
data.packed_byte_array = PackedByteArray([1, 2, 3, 4, 5, 6, 7, 8])
|
||||
var data_resource := DataResource.new()
|
||||
data_resource.name = "dolor sit amet"
|
||||
data.nested = data_resource
|
||||
|
||||
json_serialization()
|
||||
binary_serialization()
|
||||
|
||||
|
||||
func json_serialization() -> void:
|
||||
# Serialize to JSON
|
||||
# Alternative: DictionarySerializer.serialize_json(data)
|
||||
var serialized: Variant = DictionarySerializer.serialize_var(data)
|
||||
var json := JSON.stringify(serialized, "\t")
|
||||
print(json)
|
||||
""" Output:
|
||||
{
|
||||
"._type": "Object_Data",
|
||||
"string": "Lorem ipsum",
|
||||
"vector": {
|
||||
"._type": "Vector3",
|
||||
"._": [
|
||||
1.0,
|
||||
2.0,
|
||||
3.0
|
||||
]
|
||||
},
|
||||
"enum_state": 1,
|
||||
"array": [
|
||||
1,
|
||||
2
|
||||
],
|
||||
"dictionary": {
|
||||
"position": {
|
||||
"._type": "Vector2",
|
||||
"._": [
|
||||
1.0,
|
||||
2.0
|
||||
]
|
||||
}
|
||||
},
|
||||
"packed_byte_array": {
|
||||
"._type": "PackedByteArray_Base64",
|
||||
"._": "AQIDBAUGBwg="
|
||||
},
|
||||
"nested": {
|
||||
"._type": "Object_DataResource",
|
||||
"name": "dolor sit amet"
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
# Verify after JSON deserialization
|
||||
# Alternative: DictionarySerializer.deserialize_json(json)
|
||||
var parsed_json = JSON.parse_string(json)
|
||||
var deserialized: Data = DictionarySerializer.deserialize_var(parsed_json)
|
||||
_assert_data(deserialized)
|
||||
|
||||
|
||||
func binary_serialization() -> void:
|
||||
# Serialize to bytes
|
||||
# Alternative: BinarySerializer.serialize_bytes(data)
|
||||
var serialized: Variant = BinarySerializer.serialize_var(data)
|
||||
var bytes := var_to_bytes(serialized)
|
||||
print(bytes)
|
||||
# Output: List of bytes
|
||||
|
||||
# Verify after bytes deserialization.
|
||||
# Alternative: BinarySerializer.deserialize_bytes(bytes)
|
||||
var parsed_bytes = bytes_to_var(bytes)
|
||||
var deserialized: Data = BinarySerializer.deserialize_var(parsed_bytes)
|
||||
_assert_data(deserialized)
|
||||
|
||||
|
||||
func _assert_data(deserialized: Data) -> void:
|
||||
assert(data.string == deserialized.string, "string is different")
|
||||
assert(data.vector == deserialized.vector, "vector is different")
|
||||
assert(data.enum_state == deserialized.enum_state, "enum_state is different")
|
||||
assert(data.array == deserialized.array, "array is different")
|
||||
assert(data.dictionary == deserialized.dictionary, "dictionary is different")
|
||||
assert(
|
||||
data.packed_byte_array == deserialized.packed_byte_array, "packed_byte_array is different"
|
||||
)
|
||||
assert(data.nested.name == deserialized.nested.name, "nested.name is different")
|
||||
1
addons/godot_object_serializer/example.uid
Normal file
1
addons/godot_object_serializer/example.uid
Normal file
@ -0,0 +1 @@
|
||||
uid://cnmoj6e2jq737
|
||||
185
addons/godot_object_serializer/object_serializer.gd
Normal file
185
addons/godot_object_serializer/object_serializer.gd
Normal file
@ -0,0 +1,185 @@
|
||||
## Main godot-object-serializer class. Stores the script registry.
|
||||
## [url]https://github.com/Cretezy/godot-object-serializer[/url]
|
||||
class_name ObjectSerializer
|
||||
|
||||
## The field containing the type in serialized object values. Not recommended to change.
|
||||
##
|
||||
## This should be set to something unlikely to clash with keys in objects/dictionaries.
|
||||
##
|
||||
## This can be changed, but must be configured before any serialization or deserialization.
|
||||
static var type_field := "._type"
|
||||
|
||||
## The field containing the constructor arguments in serialized object values. Not recommended to change.
|
||||
##
|
||||
## This should be set to something unlikely to clash with keys in objects.
|
||||
##
|
||||
## This can be changed, but must be configured before any serialization or deserialization.
|
||||
static var args_field := "._"
|
||||
|
||||
## The prefix for object types stored in [member type_field]. Not recommended to change.
|
||||
##
|
||||
## This should be set to something unlikely to clash with built-in type names.
|
||||
##
|
||||
## This can be changed, but must be configured before any serialization or deserialization.
|
||||
static var object_type_prefix := "Object_"
|
||||
|
||||
## By default, variables with [@GlobalScope.PROPERTY_USAGE_SCRIPT_VARIABLE] are serialized (all variables have this by default).
|
||||
## When [member require_export_storage] is true, variables will also require [@GlobalScope.PROPERTY_USAGE_STORAGE] to be serialized.
|
||||
## This can be set on variables using [annotation @GDScript.@export_storage]. Example: [code]@export_storage var name: String[/code]
|
||||
static var require_export_storage := false
|
||||
|
||||
## Registry of object types
|
||||
static var _script_registry: Dictionary[String, _ScriptRegistryEntry]
|
||||
|
||||
|
||||
## Registers a script (an object type) to be serialized/deserialized. All custom types (including nested types) must be registered [b]before[/b] using this library.
|
||||
## [param name] can be empty if script uses [code]class_name[/code] (e.g [code]ObjectSerializer.register_script("", Data)[/code]), but it's generally better to set the name.
|
||||
static func register_script(name: StringName, script: Script) -> void:
|
||||
var script_name := _get_script_name(script, name)
|
||||
assert(script_name, "Script must have name\n" + script.source_code)
|
||||
var entry := _ScriptRegistryEntry.new()
|
||||
entry.script_type = script
|
||||
entry.type = object_type_prefix + script_name
|
||||
_script_registry[entry.type] = entry
|
||||
|
||||
|
||||
## Registers multiple scripts (object types) to be serialized/deserialized from a dictionary.
|
||||
## See [method ObjectSerializer.register_script]
|
||||
static func register_scripts(scripts: Dictionary[String, Script]) -> void:
|
||||
for name in scripts:
|
||||
register_script(name, scripts[name])
|
||||
|
||||
|
||||
static func _get_script_name(script: Script, name: StringName = "") -> StringName:
|
||||
if name:
|
||||
return name
|
||||
if script.resource_name:
|
||||
return script.resource_name
|
||||
if script.get_global_name():
|
||||
return script.get_global_name()
|
||||
return ""
|
||||
|
||||
|
||||
static func _get_entry(name: StringName = "", script: Script = null) -> _ScriptRegistryEntry:
|
||||
if name:
|
||||
var entry: _ScriptRegistryEntry = _script_registry.get(name)
|
||||
if entry:
|
||||
return entry
|
||||
|
||||
if script:
|
||||
for i: String in _script_registry:
|
||||
var entry: _ScriptRegistryEntry = _script_registry.get(i)
|
||||
if entry:
|
||||
if script == entry.script_type:
|
||||
return entry
|
||||
|
||||
return null
|
||||
|
||||
|
||||
class _ScriptRegistryEntry:
|
||||
var type: String
|
||||
var script_type: Script
|
||||
|
||||
func serialize(value: Variant, next: Callable) -> Variant:
|
||||
if value.has_method("_serialize"):
|
||||
var result: Dictionary = value._serialize(next)
|
||||
result[ObjectSerializer.type_field] = type
|
||||
return result
|
||||
|
||||
var result := {ObjectSerializer.type_field: type}
|
||||
|
||||
var excluded_properties: Array[String] = []
|
||||
if value.has_method("_get_excluded_properties"):
|
||||
excluded_properties = value._get_excluded_properties()
|
||||
|
||||
var partial: Dictionary = {}
|
||||
if value.has_method("_serialize_partial"):
|
||||
partial = value._serialize_partial(next)
|
||||
|
||||
for property: Dictionary in value.get_property_list():
|
||||
if (
|
||||
property.usage & PROPERTY_USAGE_SCRIPT_VARIABLE
|
||||
and (
|
||||
!ObjectSerializer.require_export_storage
|
||||
or property.usage & PROPERTY_USAGE_STORAGE
|
||||
)
|
||||
and !excluded_properties.has(property.name)
|
||||
and !partial.has(property.name)
|
||||
):
|
||||
result[property.name] = next.call(value.get(property.name))
|
||||
|
||||
for key in partial:
|
||||
result[key] = partial[key]
|
||||
|
||||
if value.has_method("_get_constructor_args"):
|
||||
var args: Array = value._get_constructor_args()
|
||||
result[ObjectSerializer.args_field] = args
|
||||
|
||||
return result
|
||||
|
||||
## When [param json_keys] is enabled, attempt to convert int/float/bool string keys into values
|
||||
func deserialize(value: Variant, next: Callable, json_keys := false) -> Variant:
|
||||
if script_type.has_method("_deserialize"):
|
||||
return script_type._deserialize(value, next)
|
||||
|
||||
var instance: Variant
|
||||
if value.has(ObjectSerializer.args_field):
|
||||
instance = script_type.new.callv(value[ObjectSerializer.args_field])
|
||||
else:
|
||||
instance = script_type.new()
|
||||
|
||||
var excluded_properties: Array[String] = []
|
||||
if instance.has_method("_get_excluded_properties"):
|
||||
excluded_properties = instance._get_excluded_properties()
|
||||
|
||||
var partial: Dictionary = {}
|
||||
if instance.has_method("_deserialize_partial"):
|
||||
partial = instance._deserialize_partial(value, next)
|
||||
|
||||
for key: String in value:
|
||||
if (
|
||||
key == ObjectSerializer.type_field
|
||||
or key == ObjectSerializer.args_field
|
||||
or excluded_properties.has(key)
|
||||
or partial.has(key)
|
||||
):
|
||||
continue
|
||||
|
||||
var key_value: Variant = next.call(value[key])
|
||||
match typeof(key_value):
|
||||
TYPE_DICTIONARY:
|
||||
if json_keys and instance[key].is_typed_key():
|
||||
match instance[key].get_typed_key_builtin():
|
||||
TYPE_STRING:
|
||||
instance[key].assign(key_value)
|
||||
TYPE_BOOL:
|
||||
var dict: Dictionary[bool, Variant] = {}
|
||||
for i in key_value:
|
||||
dict[i == "true"] = key_value[i]
|
||||
instance[key].assign(dict)
|
||||
TYPE_INT:
|
||||
var dict: Dictionary[int, Variant] = {}
|
||||
for i in key_value:
|
||||
dict[int(i)] = key_value[i]
|
||||
instance[key].assign(dict)
|
||||
TYPE_FLOAT:
|
||||
var dict: Dictionary[float, Variant] = {}
|
||||
for i in key_value:
|
||||
dict[float(i)] = key_value[i]
|
||||
instance[key].assign(dict)
|
||||
_:
|
||||
assert(
|
||||
false,
|
||||
"Trying to deserialize from JSON to a dictionary with non-primitive (String/int/float/bool) keys"
|
||||
)
|
||||
else:
|
||||
instance[key].assign(key_value)
|
||||
TYPE_ARRAY:
|
||||
instance[key].assign(key_value)
|
||||
_:
|
||||
instance[key] = key_value
|
||||
|
||||
for key in partial:
|
||||
instance[key] = partial[key]
|
||||
|
||||
return instance
|
||||
1
addons/godot_object_serializer/object_serializer.gd.uid
Normal file
1
addons/godot_object_serializer/object_serializer.gd.uid
Normal file
@ -0,0 +1 @@
|
||||
uid://dn0k1lmeff72p
|
||||
7
addons/godot_object_serializer/plugin.cfg
Normal file
7
addons/godot_object_serializer/plugin.cfg
Normal file
@ -0,0 +1,7 @@
|
||||
[plugin]
|
||||
|
||||
name="Godot Object Serializer"
|
||||
description="Safely serialize/deserialize objects and built-in types in Godot"
|
||||
author="Cretezy"
|
||||
version="0.3.0"
|
||||
script=""
|
||||
@ -41,6 +41,11 @@ offset_right = 1142.0
|
||||
offset_bottom = 604.0
|
||||
text = "Load Map"
|
||||
|
||||
[node name="Button" type="Button" parent="InterfaceLayer"]
|
||||
offset_right = 8.0
|
||||
offset_bottom = 8.0
|
||||
text = "Init Grid"
|
||||
|
||||
[node name="GameCam" type="Camera3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 0.182236, 0.983255, 0, -0.983255, 0.182236, 24.5127, 23.2849, 20.9667)
|
||||
size = 31.34
|
||||
@ -55,4 +60,5 @@ script = ExtResource("5_7jktm")
|
||||
[connection signal="pressed" from="InterfaceLayer/BuildButton" to="PlaceManager" method="_on_confirm_button_pressed"]
|
||||
[connection signal="pressed" from="InterfaceLayer/SaveButton" to="SaveLoad" method="_on_save_button_pressed"]
|
||||
[connection signal="pressed" from="InterfaceLayer/LoadButton" to="SaveLoad" method="_on_load_button_pressed"]
|
||||
[connection signal="pressed" from="InterfaceLayer/Button" to="PlaceManager" method="_on_init_grid_button_pressed"]
|
||||
[connection signal="room_built" from="PlaceManager" to="InterfaceLayer/BuildToggle" method="_on_room_built"]
|
||||
|
||||
@ -1,5 +1,29 @@
|
||||
extends Node
|
||||
|
||||
class SaveData:
|
||||
var type: String
|
||||
var position: Vector3
|
||||
var parent: String
|
||||
var scene_file_path: String
|
||||
var id: int
|
||||
|
||||
#Connections
|
||||
var place_id: int
|
||||
var room_array: Array
|
||||
|
||||
#Tile data
|
||||
var grid_pos: Vector3i
|
||||
var face_dict: Array
|
||||
var construction_mode: int
|
||||
|
||||
func _init():
|
||||
ObjectSerializer.register_scripts({
|
||||
"SaveData": SaveData,
|
||||
"Tile": Tile,
|
||||
"Room": Room,
|
||||
"Wall": Wall,
|
||||
})
|
||||
|
||||
func _on_save_button_pressed() -> void:
|
||||
var save_nodes = get_tree().get_nodes_in_group("SaveObjects")
|
||||
var save_file = FileAccess.open("user://savegame.save", FileAccess.WRITE)
|
||||
@ -10,8 +34,15 @@ func _on_save_button_pressed() -> void:
|
||||
continue
|
||||
|
||||
var node_data = node.save()
|
||||
var save_data = SaveData.new()
|
||||
for i in node_data:
|
||||
save_data.set(i, node_data[i])
|
||||
|
||||
save_file.store_var(node_data)
|
||||
var serialized_save_data = BinarySerializer.serialize_var(save_data)
|
||||
|
||||
var byte_data = var_to_bytes(serialized_save_data)
|
||||
|
||||
save_file.store_var(byte_data)
|
||||
|
||||
pass # Replace with function body.
|
||||
|
||||
@ -21,18 +52,83 @@ func _on_load_button_pressed():
|
||||
print("no save to load")
|
||||
return
|
||||
|
||||
#var save_nodes = get_tree().get_nodes_in_group("SaveObjects")
|
||||
#for i in save_nodes:
|
||||
#print(i)
|
||||
#i.free()
|
||||
var save_nodes = get_tree().get_nodes_in_group("SaveObjects")
|
||||
for i in save_nodes:
|
||||
if i:
|
||||
i.free()
|
||||
|
||||
get_node("/root/Game/PlaceManager/BasePlace").free()
|
||||
#if get_node("/root/Game/PlaceManager/BasePlace"):
|
||||
#get_node("/root/Game/PlaceManager/BasePlace").free()
|
||||
|
||||
var save_file = FileAccess.open("user://savegame.save", FileAccess.READ)
|
||||
|
||||
var place_id_dict: Dictionary = {}
|
||||
var room_id_dict: Dictionary = {}
|
||||
|
||||
var load_place_room_array: Dictionary = {}
|
||||
var load_place_tile_dict: Dictionary = {}
|
||||
var load_room_tile_array: Dictionary = {}
|
||||
|
||||
while save_file.get_position() < save_file.get_length():
|
||||
var next_load = save_file.get_var()
|
||||
|
||||
|
||||
|
||||
var next_load_bytes = save_file.get_var()
|
||||
var next_load = bytes_to_var(next_load_bytes)
|
||||
var load_object = load(next_load["scene_file_path"]).instantiate()
|
||||
for i in next_load.keys():
|
||||
load_object.set(i, next_load[i])
|
||||
get_node(next_load["parent"]).add_child(load_object)
|
||||
var id = next_load["id"]
|
||||
|
||||
match next_load["type"]:
|
||||
"Place":
|
||||
var new_place_id = load_object.get_instance_id()
|
||||
place_id_dict[id] = new_place_id
|
||||
load_place_room_array[load_object] = []
|
||||
load_place_tile_dict[load_object] = {}
|
||||
for j in next_load.keys():
|
||||
load_object.set(j, next_load[j])
|
||||
get_node(next_load["parent"]).add_child(load_object)
|
||||
|
||||
"Room":
|
||||
room_id_dict[id] = load_object.get_instance_id()
|
||||
load_room_tile_array[load_object] = []
|
||||
for j in next_load.keys():
|
||||
if j == "place_id":
|
||||
var new_place_id = place_id_dict[next_load[j]]
|
||||
var place = instance_from_id(new_place_id)
|
||||
load_place_room_array[place].append(load_object)
|
||||
load_object.set(j, new_place_id)
|
||||
else:
|
||||
load_object.set(j, next_load[j])
|
||||
get_node(next_load["parent"]).add_child(load_object)
|
||||
|
||||
"Tile":
|
||||
for j in next_load.keys():
|
||||
if j == "place_id":
|
||||
var new_place_id = place_id_dict[next_load[j]]
|
||||
var place = instance_from_id(new_place_id)
|
||||
load_place_tile_dict[place].merge({next_load["grid_pos"]: load_object})
|
||||
load_object.set(j, new_place_id)
|
||||
elif j == "room_array":
|
||||
for k in next_load["room_array"]:
|
||||
var new_room_id = room_id_dict[k]
|
||||
var room = instance_from_id(new_room_id)
|
||||
load_room_tile_array[room].append(load_object)
|
||||
load_object[j].append(room)
|
||||
else:
|
||||
load_object.set(j, next_load[j])
|
||||
get_node(next_load["parent"]).add_child(load_object)
|
||||
|
||||
_:
|
||||
for j in next_load.keys():
|
||||
load_object.set(j, next_load[j])
|
||||
get_node(next_load["parent"]).add_child(load_object)
|
||||
|
||||
for i in load_place_room_array.keys():
|
||||
i.place_room_array = load_place_room_array[i]
|
||||
|
||||
for i in load_place_tile_dict.keys():
|
||||
i.place_tile_dict.merge(load_place_tile_dict[i])
|
||||
|
||||
for i in load_room_tile_array.keys():
|
||||
i.room_tile_array = load_room_tile_array[i]
|
||||
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
extends Node3D
|
||||
|
||||
class_name Place
|
||||
|
||||
var tile_grid_size: int = 8
|
||||
|
||||
var load_tile = preload("res://tiles/base_tile/base_tile.tscn")
|
||||
@ -15,7 +17,7 @@ var selection_drag_dict: Dictionary = {}
|
||||
var selection_dict: Dictionary = {}
|
||||
|
||||
#Contains all rooms in a workplace.
|
||||
var room_dict: Dictionary = {}
|
||||
var place_room_array: Array = []
|
||||
|
||||
#Tracks the previous amount of tiles counted in a selection drac
|
||||
var tile_count_x_hist: int = 0
|
||||
@ -30,7 +32,19 @@ var current_room_walls: Array = []
|
||||
var current_door: Object = null
|
||||
|
||||
func _ready():
|
||||
self.name = "BasePlace"
|
||||
|
||||
pass
|
||||
|
||||
func place_tile_check(new_dict):
|
||||
place_tile_dict = new_dict
|
||||
#if type_string(typeof(new_dict)) == "Array":
|
||||
#for i in new_dict:
|
||||
#
|
||||
#place_tile_dict[]
|
||||
|
||||
|
||||
func init_grid():
|
||||
|
||||
#TEMP: Sets up a simple 2D grid of blank tiles.
|
||||
|
||||
for x in range(tile_grid_size):
|
||||
@ -42,40 +56,39 @@ func _ready():
|
||||
|
||||
tile.grid_pos = pos
|
||||
tile.name = str("Tile", tile.get_instance_id())
|
||||
|
||||
tile.place_id = self.get_instance_id()
|
||||
tile.selection_mode = Tile.SEL_MODE.NONE
|
||||
tile.construction_mode = Tile.CON_MODE.CLOSED
|
||||
|
||||
place_tile_dict[pos] = tile
|
||||
|
||||
add_child(tile)
|
||||
|
||||
tile.connect("neighbor_request", give_neighbors)
|
||||
|
||||
var pos = Vector3i(1, 0, 1)
|
||||
|
||||
var tile = place_tile_dict[pos]
|
||||
|
||||
var trickydict = {pos: tile}
|
||||
|
||||
tile.room = create_room(trickydict)
|
||||
|
||||
tile.construction_mode = Tile.CON_MODE.BUILT
|
||||
|
||||
$TileContainer.add_child(tile)
|
||||
|
||||
#var pos = Vector3i(1, 0, 1)
|
||||
#
|
||||
#var tile = place_tile_dict[pos]
|
||||
#
|
||||
#var trickydict = {pos: tile}
|
||||
#
|
||||
#tile.room = create_room(trickydict)
|
||||
#
|
||||
#tile.construction_mode = Tile.CON_MODE.BUILT
|
||||
#
|
||||
#selection_drag_dict[pos] = tile
|
||||
#end_select_drag()
|
||||
#build_selection()
|
||||
|
||||
func save():
|
||||
var save_data = {
|
||||
"test": "test",
|
||||
# Basics
|
||||
"name": name,
|
||||
"type": "Place",
|
||||
"id": self.get_instance_id(),
|
||||
"scene_file_path": scene_file_path,
|
||||
"parent": get_parent().get_path(),
|
||||
"place_tile_dict": place_tile_dict,
|
||||
"room_dict": room_dict
|
||||
# Connections
|
||||
# Data
|
||||
}
|
||||
|
||||
return save_data
|
||||
|
||||
func draw_tile_click(click_pos):
|
||||
@ -234,16 +247,17 @@ func create_room(selection):
|
||||
|
||||
room.position = (selection.keys().min())
|
||||
|
||||
room.room_tile_dict = selection.duplicate()
|
||||
room.room_tile_array = selection.values()
|
||||
room.place_id = self.get_instance_id()
|
||||
|
||||
room.name = str("Room", room.get_instance_id())
|
||||
|
||||
add_child(room)
|
||||
$RoomContainer.add_child(room)
|
||||
|
||||
for i in room.room_tile_dict:
|
||||
place_tile_dict[i].room = room
|
||||
for i in room.room_tile_array:
|
||||
i.room_array.append(room)
|
||||
|
||||
current_room = room
|
||||
place_room_array.append(room)
|
||||
|
||||
return room
|
||||
|
||||
@ -280,44 +294,44 @@ func hover_door(mouse_pos):
|
||||
current_door.position = closest
|
||||
current_door.rotation_degrees = Vector3(0, 180 * fmod(closest.z, 1), 0)
|
||||
|
||||
func confirm_door():
|
||||
#Builds the door at the hovered location
|
||||
|
||||
var tile_1: Object
|
||||
var tile_2: Object
|
||||
|
||||
if fmod(current_door.position.x, 1) == 0:
|
||||
tile_1 = place_tile_dict[Vector3i(current_door.position.x, 0, current_door.position.z)]
|
||||
tile_2 = place_tile_dict[Vector3i(current_door.position.x - 1, 0, current_door.position.z)]
|
||||
else:
|
||||
tile_1 = place_tile_dict[Vector3i(current_door.position.x, 0, current_door.position.z)]
|
||||
tile_2 = place_tile_dict[Vector3i(current_door.position.x, 0, current_door.position.z - 1)]
|
||||
|
||||
var tile_1_door_face: Vector3i = tile_2.position - tile_1.position
|
||||
|
||||
var tile_1_door_face_direction: int = tile_1.direction_vector_array.find(tile_1_door_face)
|
||||
|
||||
tile_1.update_face(tile_1_door_face_direction, Tile.FACE_MODE.DOOR, current_door)
|
||||
|
||||
var tile_1_room: Object = tile_1.room_id
|
||||
|
||||
tile_1_room.room_door_array.append(current_door)
|
||||
|
||||
var tile_2_door_face: Vector3i = tile_1.position - tile_2.position
|
||||
|
||||
var tile_2_door_face_direction: int = tile_2.direction_vector_array.find(tile_2_door_face)
|
||||
|
||||
tile_2.update_face(tile_2_door_face_direction, Tile.FACE_MODE.DOOR, current_door)
|
||||
|
||||
var tile_2_room: Object = tile_2.room_id
|
||||
|
||||
tile_2_room.room_door_array.append(current_door)
|
||||
|
||||
current_door.door_room_array = [tile_1_room, tile_2_room]
|
||||
|
||||
current_room = null
|
||||
current_room_walls = []
|
||||
current_door = null
|
||||
#func confirm_door():
|
||||
##Builds the door at the hovered location
|
||||
#
|
||||
#var tile_1: Object
|
||||
#var tile_2: Object
|
||||
#
|
||||
#if fmod(current_door.position.x, 1) == 0:
|
||||
#tile_1 = place_tile_dict[Vector3i(current_door.position.x, 0, current_door.position.z)]
|
||||
#tile_2 = place_tile_dict[Vector3i(current_door.position.x - 1, 0, current_door.position.z)]
|
||||
#else:
|
||||
#tile_1 = place_tile_dict[Vector3i(current_door.position.x, 0, current_door.position.z)]
|
||||
#tile_2 = place_tile_dict[Vector3i(current_door.position.x, 0, current_door.position.z - 1)]
|
||||
#
|
||||
#var tile_1_door_face: Vector3i = tile_2.position - tile_1.position
|
||||
#
|
||||
#var tile_1_door_face_direction: int = tile_1.direction_vector_array.find(tile_1_door_face)
|
||||
#
|
||||
#tile_1.update_face(tile_1_door_face_direction, Tile.FACE_MODE.DOOR, current_door)
|
||||
#
|
||||
#var tile_1_room: Object = tile_1.room_id
|
||||
#
|
||||
#tile_1_room.room_door_array.append(current_door)
|
||||
#
|
||||
#var tile_2_door_face: Vector3i = tile_1.position - tile_2.position
|
||||
#
|
||||
#var tile_2_door_face_direction: int = tile_2.direction_vector_array.find(tile_2_door_face)
|
||||
#
|
||||
#tile_2.update_face(tile_2_door_face_direction, Tile.FACE_MODE.DOOR, current_door)
|
||||
#
|
||||
#var tile_2_room: Object = tile_2.room_id
|
||||
#
|
||||
#tile_2_room.room_door_array.append(current_door)
|
||||
#
|
||||
#current_door.door_room_array = [tile_1_room, tile_2_room]
|
||||
#
|
||||
#current_room = null
|
||||
#current_room_walls = []
|
||||
#current_door = null
|
||||
|
||||
func give_neighbors(tile, grid_pos, directions):
|
||||
var neighbor_dict = {}
|
||||
@ -325,3 +339,7 @@ func give_neighbors(tile, grid_pos, directions):
|
||||
if place_tile_dict.has(directions[i] + grid_pos):
|
||||
neighbor_dict[directions[i]] = place_tile_dict[directions[i] + grid_pos]
|
||||
tile.neighbor_dict = neighbor_dict
|
||||
|
||||
|
||||
func _on_tile_container_child_entered_tree(node: Node) -> void:
|
||||
node.connect("neighbor_request", give_neighbors)
|
||||
|
||||
@ -7,3 +7,11 @@ script = ExtResource("1_uq3a8")
|
||||
|
||||
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 0.345446, 0.938439, 0, -0.938439, 0.345446, 41.393, 18.7409, 34.4224)
|
||||
|
||||
[node name="RoomContainer" type="Node" parent="."]
|
||||
|
||||
[node name="TileContainer" type="Node" parent="."]
|
||||
|
||||
[node name="Objects" type="Node" parent="."]
|
||||
|
||||
[connection signal="child_entered_tree" from="TileContainer" to="." method="_on_tile_container_child_entered_tree"]
|
||||
|
||||
@ -1,11 +1,14 @@
|
||||
extends Node
|
||||
class_name Room
|
||||
|
||||
var room_tile_dict = {}
|
||||
var room_tile_array = []: set = setup_path_grid
|
||||
|
||||
var path_grid = AStar3D.new()
|
||||
|
||||
var room_door_array = []
|
||||
|
||||
var place_id: int = 0
|
||||
|
||||
#TODO: replace with global dict?
|
||||
var direction_array = [
|
||||
Vector3i(0, 0, -1),
|
||||
@ -14,32 +17,36 @@ var direction_array = [
|
||||
Vector3i(-1, 0, 0),
|
||||
]
|
||||
|
||||
func _ready():
|
||||
self.name = str("Room", self.get_instance_id())
|
||||
|
||||
init_path_grid()
|
||||
|
||||
pass
|
||||
|
||||
func save():
|
||||
var save_data = {
|
||||
"test": "test",
|
||||
# Basics
|
||||
"name": name,
|
||||
"type": "Room",
|
||||
"id": self.get_instance_id(),
|
||||
"scene_file_path": scene_file_path,
|
||||
"parent": get_parent().get_path(),
|
||||
"room_tile_dict": room_tile_dict,
|
||||
"room_door_array": room_door_array,
|
||||
"path_grid": path_grid
|
||||
# Connections
|
||||
"place_id": place_id,
|
||||
# Data
|
||||
}
|
||||
return save_data
|
||||
|
||||
func init_path_grid():
|
||||
func init_room(new_dict):
|
||||
setup_path_grid(new_dict)
|
||||
for i in new_dict.values():
|
||||
i.room = self
|
||||
|
||||
for i in room_tile_dict.keys():
|
||||
|
||||
func setup_path_grid(new_array):
|
||||
|
||||
room_tile_array = new_array
|
||||
|
||||
for i in room_tile_array:
|
||||
var id = path_grid.get_available_point_id()
|
||||
path_grid.add_point(id, i)
|
||||
path_grid.add_point(id, i.grid_pos)
|
||||
|
||||
for n in direction_array:
|
||||
if room_tile_dict.has(i + n):
|
||||
if room_tile_array.has(i.grid_pos + n):
|
||||
var closest = path_grid.get_closest_point(i + n)
|
||||
if (i + n) == Vector3i(path_grid.get_point_position(closest)):
|
||||
path_grid.connect_points(id, closest)
|
||||
|
||||
@ -2,5 +2,5 @@
|
||||
|
||||
[ext_resource type="Script" uid="uid://c2neixe7kpvma" path="res://places/base_place/base_room.gd" id="1_3l4mp"]
|
||||
|
||||
[node name="BaseRoom" type="Node3D"]
|
||||
[node name="BaseRoom" type="Node3D" groups=["SaveObjects"]]
|
||||
script = ExtResource("1_3l4mp")
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
extends Node3D
|
||||
|
||||
var load_place = preload("res://places/base_place/base_place.tscn")
|
||||
var place = load_place.instantiate()
|
||||
var place = null
|
||||
|
||||
enum ROOM_BUILD_STATE {NONE, ALLOWED, BUILDING, IS_PLACING_DOOR}
|
||||
|
||||
@ -16,10 +16,6 @@ var build_drag_start_pos = null
|
||||
|
||||
signal room_built
|
||||
|
||||
func _ready():
|
||||
#TEMP loads in a workplace.
|
||||
add_child(place)
|
||||
|
||||
func _on_build_toggle(toggled_on):
|
||||
#Responds to the 'Build A Room' toggle
|
||||
if toggled_on:
|
||||
@ -63,3 +59,15 @@ func _on_confirm_button_pressed() -> void:
|
||||
|
||||
else:
|
||||
pass
|
||||
|
||||
|
||||
func _on_init_grid_button_pressed() -> void:
|
||||
if place:
|
||||
place.queue_free()
|
||||
var new_place = load_place.instantiate()
|
||||
add_child(new_place)
|
||||
place.init_grid()
|
||||
|
||||
func _on_child_entered_tree(node: Node) -> void:
|
||||
if node is Place:
|
||||
place = node
|
||||
|
||||
@ -14,4 +14,5 @@ script = ExtResource("1_rcbs8")
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 128, 0, 128)
|
||||
shape = SubResource("BoxShape3D_rcbs8")
|
||||
|
||||
[connection signal="child_entered_tree" from="." to="." method="_on_child_entered_tree"]
|
||||
[connection signal="input_event" from="FloorPlane" to="." method="_on_area_3d_input_event"]
|
||||
|
||||
@ -1,78 +1,90 @@
|
||||
extends Node3D
|
||||
class_name Tile
|
||||
|
||||
var id = null
|
||||
var place_id: int = 0
|
||||
|
||||
#This tile's current construction and selection modes.
|
||||
@export var construction_mode = 0: set = update_construction
|
||||
@export var selection_mode = 0: set = update_selection
|
||||
|
||||
var orange = preload("res://tiles/base_tile/orange.tres")
|
||||
var gray = preload("res://tiles/base_tile/gray.tres")
|
||||
var red = preload("res://tiles/base_tile/red.tres")
|
||||
var blue = preload("res://tiles/base_tile/blue.tres")
|
||||
var lightblue = preload("res://tiles/base_tile/lightblue.tres")
|
||||
const orange = preload("res://tiles/base_tile/orange.tres")
|
||||
const gray = preload("res://tiles/base_tile/gray.tres")
|
||||
const red = preload("res://tiles/base_tile/red.tres")
|
||||
const blue = preload("res://tiles/base_tile/blue.tres")
|
||||
const lightblue = preload("res://tiles/base_tile/lightblue.tres")
|
||||
|
||||
#Lists of possible states for various modes.
|
||||
enum SEL_MODE {NONE, ROOM, BUILD, INVALID}
|
||||
|
||||
enum CON_MODE {NONE, NON_INTERACTABLE, CLOSED, OPEN, BUILT, REINFORCED, CONSTRUCTION}
|
||||
|
||||
enum FACE_MODE {NONE, FULL, PARTIAL, DOOR}
|
||||
#enum FACE_MODE {NONE, FULL, PARTIAL, DOOR}
|
||||
|
||||
var direction_vector_dict = {
|
||||
const direction_vector_dict = {
|
||||
"North": Vector3i(0, 0, -1),
|
||||
"East": Vector3i(1, 0, 0),
|
||||
"South": Vector3i(0, 0, 1),
|
||||
"West": Vector3i(-1, 0, 0),
|
||||
}
|
||||
|
||||
var wall_position_dict = {
|
||||
const wall_position_dict = {
|
||||
"North": Vector3i(0, 0, 0),
|
||||
"East": Vector3i(1, 0, 0),
|
||||
"South": Vector3i(1, 0, 1),
|
||||
"West": Vector3i(0, 0, 1),
|
||||
}
|
||||
|
||||
var load_wall = preload("res://tiles/base_tile/base_wall.tscn")
|
||||
const load_wall = preload("res://tiles/base_tile/base_wall.tscn")
|
||||
|
||||
@export var grid_pos = null
|
||||
|
||||
@export var face_dict = {}: set = update_faces
|
||||
|
||||
@export var room = null
|
||||
@export var room_array = []
|
||||
|
||||
var neighbor_dict = []
|
||||
|
||||
signal wall_built
|
||||
var neighbor_dict = {}
|
||||
|
||||
signal neighbor_request
|
||||
|
||||
func _ready():
|
||||
|
||||
|
||||
pass
|
||||
|
||||
func save():
|
||||
|
||||
var room_id_array: Array
|
||||
|
||||
for i in room_array:
|
||||
room_id_array.append(i.get_instance_id())
|
||||
|
||||
var save_data = {
|
||||
"test": "test",
|
||||
"position": position,
|
||||
# Basics
|
||||
"name": name,
|
||||
"type": "Tile",
|
||||
"id": self.get_instance_id(),
|
||||
"scene_file_path": scene_file_path,
|
||||
"parent": get_parent().get_path(),
|
||||
# Connections
|
||||
"place_id": place_id,
|
||||
"room_array": room_id_array,
|
||||
# Data
|
||||
"position": position,
|
||||
"grid_pos": grid_pos,
|
||||
"face_dict": face_dict,
|
||||
"room": room
|
||||
"face_dict": face_dict.keys(),
|
||||
"construction_mode": construction_mode,
|
||||
}
|
||||
|
||||
return save_data
|
||||
|
||||
func update_faces(new_dict):
|
||||
|
||||
face_dict = new_dict
|
||||
#for i in $Walls.get_children():
|
||||
#i.queue_free()
|
||||
|
||||
for i in $Walls.get_children():
|
||||
i.queue_free()
|
||||
if type_string(typeof(new_dict)) == "Array":
|
||||
var temp_new_dict: Dictionary
|
||||
for i in new_dict:
|
||||
temp_new_dict[i] = null
|
||||
new_dict = temp_new_dict.duplicate()
|
||||
|
||||
for i in new_dict.keys():
|
||||
var direction: String = direction_vector_dict.find_key(i)
|
||||
@ -88,6 +100,7 @@ func update_faces(new_dict):
|
||||
"West":
|
||||
wall.rotation_degrees = Vector3(0, -270, 0)
|
||||
$Walls.add_child(wall)
|
||||
face_dict[i] = wall
|
||||
|
||||
func update_neighbors():
|
||||
neighbor_dict = {}
|
||||
@ -120,12 +133,10 @@ func update_construction(mode):
|
||||
var temp_face_dict = {}
|
||||
|
||||
for i in neighbor_dict.keys():
|
||||
if not neighbor_dict[i].room == room:
|
||||
#print(neighbor_dict[i].room)
|
||||
if not neighbor_dict[i].room_array == room_array:
|
||||
temp_face_dict[i] = null
|
||||
|
||||
face_dict = temp_face_dict.duplicate()
|
||||
print(face_dict)
|
||||
|
||||
CON_MODE.REINFORCED:
|
||||
face_dict = {}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
[ext_resource type="Script" uid="uid://jqjcr7dxjnbt" path="res://tiles/base_tile/base_tile.gd" id="1_yoisu"]
|
||||
[ext_resource type="PlaneMesh" uid="uid://bis4hdushjnjm" path="res://tiles/base_tile/base_floor.tres" id="2_wxg2y"]
|
||||
|
||||
[node name="Tile" type="Node3D" groups=["SaveObjects"]]
|
||||
[node name="BaseTile" type="Node3D" groups=["SaveObjects"]]
|
||||
script = ExtResource("1_yoisu")
|
||||
|
||||
[node name="Floor" type="Node3D" parent="."]
|
||||
|
||||
3
tiles/base_tile/base_wall.gd
Normal file
3
tiles/base_tile/base_wall.gd
Normal file
@ -0,0 +1,3 @@
|
||||
extends Node3D
|
||||
|
||||
class_name Wall
|
||||
1
tiles/base_tile/base_wall.gd.uid
Normal file
1
tiles/base_tile/base_wall.gd.uid
Normal file
@ -0,0 +1 @@
|
||||
uid://cx6bmej4pcjlt
|
||||
@ -1,9 +1,16 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://diovc4myisuow"]
|
||||
[gd_scene load_steps=4 format=3 uid="uid://diovc4myisuow"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://cx6bmej4pcjlt" path="res://tiles/base_tile/base_wall.gd" id="1_lirtl"]
|
||||
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_xdfmn"]
|
||||
|
||||
[node name="Node3D" type="Node3D"]
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_lirtl"]
|
||||
albedo_color = Color(0.0574887, 2.24891e-05, 0.240434, 1)
|
||||
|
||||
[node name="BaseWall" type="Node3D"]
|
||||
script = ExtResource("1_lirtl")
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 0.1, 0.5, 0.5, 0.05)
|
||||
mesh = SubResource("BoxMesh_xdfmn")
|
||||
surface_material_override/0 = SubResource("StandardMaterial3D_lirtl")
|
||||
|
||||
Loading…
Reference in New Issue
Block a user