From 2f09c6139a279469f617ee0550dbbf3add77eb93 Mon Sep 17 00:00:00 2001 From: snipercup <50166150+snipercup@users.noreply.github.com> Date: Fri, 13 Dec 2024 22:49:51 +0100 Subject: [PATCH 1/9] Implement regeneration mechanic --- .../Custom_Editors/FurnitureEditor.tscn | 19 ++++++- .../Custom_Editors/Scripts/FurnitureEditor.gd | 19 +++++++ Scripts/FurnitureStaticSpawner.gd | 1 + Scripts/FurnitureStaticSrv.gd | 56 +++++++++++++++++++ Scripts/Gamedata/DFurniture.gd | 46 ++++++++++++++- Scripts/Helper/time_helper.gd | 8 +-- Scripts/Runtimedata/RFurniture.gd | 8 ++- Scripts/Runtimedata/RMobfaction.gd | 4 +- 8 files changed, 151 insertions(+), 10 deletions(-) diff --git a/Scenes/ContentManager/Custom_Editors/FurnitureEditor.tscn b/Scenes/ContentManager/Custom_Editors/FurnitureEditor.tscn index 95b490d7..8800f0ec 100644 --- a/Scenes/ContentManager/Custom_Editors/FurnitureEditor.tscn +++ b/Scenes/ContentManager/Custom_Editors/FurnitureEditor.tscn @@ -7,7 +7,7 @@ [ext_resource type="PackedScene" uid="uid://dsax7il2yggw8" path="res://Scenes/ContentManager/Custom_Widgets/DropEnabledTextEdit.tscn" id="4_fbact"] [ext_resource type="Texture2D" uid="uid://lqavxdrjc078" path="res://Mods/Core/Furniture/wardrobe_80_40.png" id="5_61cds"] -[node name="FurnitureEditor" type="Control" node_paths=PackedStringArray("tab_container", "furnitureImageDisplay", "IDTextLabel", "NameTextEdit", "DescriptionTextEdit", "CategoriesList", "furnitureSelector", "imageNameStringLabel", "moveableCheckboxButton", "weightLabel", "weightSpinBox", "edgeSnappingOptionButton", "doorOptionButton", "containerCheckBox", "containerTextEdit", "destroyHboxContainer", "canDestroyCheckbox", "destructionTextEdit", "destructionImageDisplay", "destructionSpriteNameLabel", "disassemblyHboxContainer", "canDisassembleCheckbox", "disassemblyTextEdit", "disassemblyImageDisplay", "disassemblySpriteNameLabel", "support_shape_option_button", "width_scale_label", "depth_scale_label", "radius_scale_label", "width_scale_spin_box", "depth_scale_spin_box", "radius_scale_spin_box", "heigth_spin_box", "color_picker", "sprite_texture_rect", "transparent_check_box")] +[node name="FurnitureEditor" type="Control" node_paths=PackedStringArray("tab_container", "furnitureImageDisplay", "IDTextLabel", "NameTextEdit", "DescriptionTextEdit", "CategoriesList", "furnitureSelector", "imageNameStringLabel", "moveableCheckboxButton", "weightLabel", "weightSpinBox", "edgeSnappingOptionButton", "doorOptionButton", "containerCheckBox", "containerTextEdit", "regeneration_label", "regeneration_spin_box", "destroyHboxContainer", "canDestroyCheckbox", "destructionTextEdit", "destructionImageDisplay", "destructionSpriteNameLabel", "disassemblyHboxContainer", "canDisassembleCheckbox", "disassemblyTextEdit", "disassemblyImageDisplay", "disassemblySpriteNameLabel", "support_shape_option_button", "width_scale_label", "depth_scale_label", "radius_scale_label", "width_scale_spin_box", "depth_scale_spin_box", "radius_scale_spin_box", "heigth_spin_box", "color_picker", "sprite_texture_rect", "transparent_check_box")] layout_mode = 3 anchors_preset = 15 anchor_right = 1.0 @@ -30,6 +30,8 @@ edgeSnappingOptionButton = NodePath("VBoxContainer/TabContainer/General/Snapping doorOptionButton = NodePath("VBoxContainer/TabContainer/General/FunctionControlContainer/DoorOptionButton") containerCheckBox = NodePath("VBoxContainer/TabContainer/General/FunctionControlContainer/ContainerCheckBox") containerTextEdit = NodePath("VBoxContainer/TabContainer/General/FunctionControlContainer/ContainerTextEdit") +regeneration_label = NodePath("VBoxContainer/TabContainer/General/FunctionControlContainer/RegenerationLabel") +regeneration_spin_box = NodePath("VBoxContainer/TabContainer/General/FunctionControlContainer/RegenerationSpinBox") destroyHboxContainer = NodePath("VBoxContainer/TabContainer/General/DestructionHBoxContainer") canDestroyCheckbox = NodePath("VBoxContainer/TabContainer/General/DestructionHBoxContainer/CanDestroyCheckBox") destructionTextEdit = NodePath("VBoxContainer/TabContainer/General/DestructionHBoxContainer/DestructionTextEdit") @@ -336,6 +338,21 @@ spawned. If container is not checked on, it will not act as a container." myplaceholdertext = "Drag an itemgroup from the left to here" +[node name="RegenerationLabel" type="Label" parent="VBoxContainer/TabContainer/General/FunctionControlContainer"] +layout_mode = 2 +text = "Regeneration time (in-game days)" + +[node name="RegenerationSpinBox" type="SpinBox" parent="VBoxContainer/TabContainer/General/FunctionControlContainer"] +layout_mode = 2 +tooltip_text = "The amount of in-game days that have to pass before the container regenerates the items from the itemgroup. +This is useful for plants that re-grow fruits or nuts. When regenerating, any existing items will disappear. If the +value is -1, the container does not regenerate. Only works for furniture that can't move. If you enter 1, the +container will reset when the player approaches it, no matter how many days have passed (but at least one)." +min_value = -1.0 +max_value = 10000.0 +step = 0.1 +value = -1.0 + [node name="Shape" type="GridContainer" parent="VBoxContainer/TabContainer"] visible = false layout_mode = 2 diff --git a/Scenes/ContentManager/Custom_Editors/Scripts/FurnitureEditor.gd b/Scenes/ContentManager/Custom_Editors/Scripts/FurnitureEditor.gd index 03a9c0f4..8c999bb7 100644 --- a/Scenes/ContentManager/Custom_Editors/Scripts/FurnitureEditor.gd +++ b/Scenes/ContentManager/Custom_Editors/Scripts/FurnitureEditor.gd @@ -21,6 +21,8 @@ extends Control @export var doorOptionButton: OptionButton = null # Maks the furniture as a door @export var containerCheckBox: CheckBox = null # Marks the furniture as a container @export var containerTextEdit: HBoxContainer = null # Might contain the id of a loot group +@export var regeneration_label: Label = null +@export var regeneration_spin_box: SpinBox = null # The time in days before regeneration @export var destroyHboxContainer: HBoxContainer = null # contains destroy controls @export var canDestroyCheckbox: CheckBox = null # If the furniture can be destroyed or not @@ -134,9 +136,16 @@ func load_furniture_data(): containerTextEdit.set_text(itemgroup) else: containerTextEdit.mytextedit.clear() # Clear the text edit if no itemgroup is specified + + # Load regeneration time if applicable + if dfurniture.function.container_regeneration_time >= 0.0: + regeneration_spin_box.value = dfurniture.function.container_regeneration_time + else: + regeneration_spin_box.value = -1.0 # Default to -1.0 if no regeneration time is set else: containerCheckBox.button_pressed = false # Uncheck the container checkbox containerTextEdit.mytextedit.clear() # Clear the text edit as no container data is present + regeneration_spin_box.value = -1.0 # Reset regeneration spin box # Call the function to load the support shape data load_support_shape_option() @@ -256,9 +265,13 @@ func handle_container_option(): if containerCheckBox.is_pressed(): dfurniture.function.is_container = true dfurniture.function.container_group = containerTextEdit.get_text() + # Save the regeneration time + dfurniture.function.container_regeneration_time = regeneration_spin_box.value else: dfurniture.function.is_container = false dfurniture.function.container_group = "" + # Reset the regeneration time + dfurniture.function.container_regeneration_time = -1 func handle_destruction_option(): @@ -437,6 +450,12 @@ func _on_unmoveable_check_box_toggled(toggled_on): if toggled_on: # Hide the second tab in the tab container tab_container.set_tab_hidden(1, true) + # Hide the regeneration controls + regeneration_label.visible = false + regeneration_spin_box.visible = false else: # Show the second tab in the tab container tab_container.set_tab_hidden(1, false) + # Show the regeneration controls + regeneration_label.visible = true + regeneration_spin_box.visible = true diff --git a/Scripts/FurnitureStaticSpawner.gd b/Scripts/FurnitureStaticSpawner.gd index d5d51a28..ec00acdb 100644 --- a/Scripts/FurnitureStaticSpawner.gd +++ b/Scripts/FurnitureStaticSpawner.gd @@ -125,6 +125,7 @@ func _on_body_entered_item_detector(body_rid: RID) -> void: # because that's what the signal will send var furniturenode: Node3D = collider_to_furniture[body_rid] if furniturenode.is_container(): + furniturenode.regenerate() # Check if it needs to regenerate Helper.signal_broker.container_entered_proximity.emit(furniturenode) diff --git a/Scripts/FurnitureStaticSrv.gd b/Scripts/FurnitureStaticSrv.gd index 4bb9de19..71618328 100644 --- a/Scripts/FurnitureStaticSrv.gd +++ b/Scripts/FurnitureStaticSrv.gd @@ -42,6 +42,11 @@ var current_health: float = 100.0 # Default health var is_animating_hit: bool = false # Flag to prevent multiple hit animations var original_material_color: Color = Color(1, 1, 1) # Store the original material color +# Store the container timer state +var last_time_checked: float = 0.0 # To track the last time the container was checked +var regeneration_interval: float = -1.0 # In-game days for regeneration interval + + signal about_to_be_destroyed(me: FurnitureStaticSrv) @@ -134,6 +139,7 @@ func _init(furniturepos: Vector3, newFurnitureJSON: Dictionary, world3d: World3D set_new_rotation(furniture_rotation) # Apply rotation after setting up the shape and visual instance check_door_functionality() # Check if this furniture is a door + check_regeneration_functionality() # Check if this furniture regenerates the items if rfurniture.support_shape.shape == "Box": create_box_shape() @@ -413,6 +419,15 @@ func check_door_functionality(): door_state = "Closed" # Default if not found in saved data +# Function to check if this furniture acts as a door +func check_regeneration_functionality(): + if not rfurniture.function: + return + if not rfurniture.function.container_regeneration_time: + return + regeneration_interval = rfurniture.function.container_regeneration_time + + # Function to interact with the furniture (e.g., toggling door state) func interact(): if is_door: @@ -730,3 +745,44 @@ func show_hit_indicator(): # Function to show a miss indicator func show_miss_indicator(): show_indicator("Miss!", Color(1, 0, 0)) # Red for miss + + +# Regenerate the container if the interval is more then -1 +# This function is run by FurnitureStaticSpawner when the player enters proximity +func regenerate(): + # Check if the signal refers to this container and if it regenerates + if regeneration_interval <= -1: + return + + # Get the total days passed and calculate the days since last check + var total_days_passed: float = Helper.time_helper.get_days_since_start() + var days_passed: float = total_days_passed - last_time_checked + + # Check if enough days have passed to regenerate + if days_passed >= regeneration_interval: + # Update the last time checked + last_time_checked = total_days_passed + + # Regenerate items if the container has an itemgroup + _reset_inventory_and_regenerate_items() + + +# Add this function to handle inventory reset and item regeneration +func _reset_inventory_and_regenerate_items(): + if not itemgroup or itemgroup == "": + return # Do nothing if no itemgroup is present + + # Clear existing inventory + inventory.clear() + + # Populate inventory with items from the itemgroup + var ritemgroup: RItemgroup = Runtimedata.itemgroups.by_id(itemgroup) + if ritemgroup: + var group_mode: String = ritemgroup.mode # can be "Collection" or "Distribution" + if group_mode == "Collection": + _add_items_to_inventory_collection_mode(ritemgroup.items) + elif group_mode == "Distribution": + _add_items_to_inventory_distribution_mode(ritemgroup.items) + + # Update container visuals + set_random_inventory_item_texture() diff --git a/Scripts/Gamedata/DFurniture.gd b/Scripts/Gamedata/DFurniture.gd index 0c956f1e..82041c17 100644 --- a/Scripts/Gamedata/DFurniture.gd +++ b/Scripts/Gamedata/DFurniture.gd @@ -5,6 +5,44 @@ extends RefCounted # This script is intended to be used inside the GameData autoload singleton # This script handles the data for one furniture. You can access it through Gamedata.mods.by_id("Core").furnitures +# Example json: +# { +# "id": "countertop_wood", +# "name": "Wooden countertop", +# "description": "One of the central pieces of fruniture that make up a kitchen", +# "sprite": "countertop_100_52.png", +# "Function": { +# "container_group": "kitchen_cupboard", +# "is_container": true, +# "container_regeneration_time": -1 +# }, +# "categories": [ +# "Urban", +# "Kitchen", +# "Indoor" +# ], +# "destruction": { +# "group": "destroyed_furniture_medium", +# "sprite": "wreck_wood_generic_32.png" +# }, +# "disassembly": { +# "group": "disassembled_furniture_medium", +# "sprite": "wreck_wood_generic_32.png" +# }, +# "edgesnapping": "North", +# "moveable": false, +# "support_shape": { +# "color": "8d401bff", +# "depth_scale": 100, +# "height": 0.5, +# "shape": "Box", +# "transparent": false, +# "width_scale": 100 +# }, +# "weight": 1 +# } + + # This class represents a piece of furniture with its properties var id: String var name: String @@ -24,15 +62,17 @@ var parent: DFurnitures # Inner class to handle the Function property class Function: - var door: String # Can be "None", "Open" or "Closed" + var door: String # Can be "None", "Open" or "Closed" var is_container: bool var container_group: String + var container_regeneration_time: float # Time in days for container regeneration (-1.0 if it doesn't regenerate) # Constructor to initialize function properties from a dictionary func _init(data: Dictionary): door = data.get("door", "None") is_container = data.get("is_container", false) container_group = data.get("container_group", "") + container_regeneration_time = data.get("container_regeneration_time", -1.0) # Default to -1.0 # Get data function to return a dictionary with all properties func get_data() -> Dictionary: @@ -41,9 +81,11 @@ class Function: functiondata["is_container"] = is_container if not container_group == "": functiondata["container_group"] = container_group + if container_regeneration_time != -1: # Only include if not the default + functiondata["container_regeneration_time"] = container_regeneration_time if not door == "None": functiondata["door"] = door - return functiondata # Potentially return an empty dictionary + return functiondata # Potentially return an empty dictionary # Inner class to handle the Support Shape property diff --git a/Scripts/Helper/time_helper.gd b/Scripts/Helper/time_helper.gd index 6a780126..6431c8c1 100644 --- a/Scripts/Helper/time_helper.gd +++ b/Scripts/Helper/time_helper.gd @@ -92,14 +92,14 @@ func set_elapsed_time(new_time: float): _last_tick_time = Time.get_ticks_msec() -# Returns the time difference between a given past time and the current time. +# Returns the time difference between a given past time and the current time in seconds. func get_time_difference(past_time: float) -> float: return max(0.0, _elapsed_time - past_time) # Returns the number of in-game days since the start -func get_days_since_start() -> int: - return int(_elapsed_time / (day_duration * 60)) # Convert minutes to seconds +func get_days_since_start() -> float: + return float(_elapsed_time / (day_duration * 60)) # Convert minutes to seconds # The current time string, representing the time of day @@ -108,7 +108,7 @@ func get_current_time() -> String: var current_minutes_of_day = get_current_in_game_minutes() # Calculate hours and minutes - var hours: int = current_minutes_of_day / 60 + var hours: int = current_minutes_of_day / 60.0 var minutes: int = current_minutes_of_day % 60 return "%02d:%02d" % [hours, minutes] diff --git a/Scripts/Runtimedata/RFurniture.gd b/Scripts/Runtimedata/RFurniture.gd index c41398f3..059aa7ad 100644 --- a/Scripts/Runtimedata/RFurniture.gd +++ b/Scripts/Runtimedata/RFurniture.gd @@ -14,7 +14,8 @@ extends RefCounted # "Function": { # "door": "None", # "is_container": true, -# "container_group": "basic_loot" +# "container_group": "basic_loot", +# "container_regeneration_time": -1 # }, # "support_shape": { # "shape": "Box", @@ -39,12 +40,15 @@ class Function: var door: String # Can be "None", "Open" or "Closed" var is_container: bool var container_group: String + var container_regeneration_time: float # Time in minutes for container regeneration (-1 if it doesn't regenerate) + # Constructor to initialize function properties from a dictionary func _init(data: Dictionary): door = data.get("door", "None") is_container = data.get("is_container", false) container_group = data.get("container_group", "") + container_regeneration_time = data.get("container_regeneration_time", -1.0) # Default to -1 # Get data function to return a dictionary with all properties func get_data() -> Dictionary: @@ -53,6 +57,8 @@ class Function: functiondata["is_container"] = is_container if not container_group == "": functiondata["container_group"] = container_group + if container_regeneration_time != -1: # Only include if not the default + functiondata["container_regeneration_time"] = container_regeneration_time if not door == "None": functiondata["door"] = door return functiondata diff --git a/Scripts/Runtimedata/RMobfaction.gd b/Scripts/Runtimedata/RMobfaction.gd index ba3ae609..1b8a74c7 100644 --- a/Scripts/Runtimedata/RMobfaction.gd +++ b/Scripts/Runtimedata/RMobfaction.gd @@ -43,8 +43,8 @@ func overwrite_from_dmobfaction(dmobfaction: DMobfaction) -> void: return name = dmobfaction.name description = dmobfaction.description - relations = dmobfaction.relations - references = dmobfaction.references + #relations = dmobfaction.relations + #references = dmobfaction.references # Get data function to return a dictionary with all properties func get_data() -> Dictionary: From f8f843cc18f8cdec3619a83842e041720b64d74c Mon Sep 17 00:00:00 2001 From: snipercup <50166150+snipercup@users.noreply.github.com> Date: Sat, 14 Dec 2024 00:34:55 +0100 Subject: [PATCH 2/9] Save and load container group --- Scripts/FurnitureStaticSrv.gd | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/Scripts/FurnitureStaticSrv.gd b/Scripts/FurnitureStaticSrv.gd index 71618328..57d8c72f 100644 --- a/Scripts/FurnitureStaticSrv.gd +++ b/Scripts/FurnitureStaticSrv.gd @@ -162,6 +162,7 @@ func add_container(): create_loot() else: deserialize_container_data() + set_random_inventory_item_texture() func is_container() -> bool: @@ -426,6 +427,16 @@ func check_regeneration_functionality(): if not rfurniture.function.container_regeneration_time: return regeneration_interval = rfurniture.function.container_regeneration_time + + if not is_new_furniture(): + # Ensure the door_state is properly set + if furnitureJSON.has("Function") and furnitureJSON["Function"].has("container"): + if furnitureJSON.Function.container.has("container_last_time_checked"): + last_time_checked = furnitureJSON.Function.container.container_last_time_checked + if furnitureJSON.Function.container.has("container_itemgroup"): + itemgroup = furnitureJSON.Function.container.container_itemgroup + else: + last_time_checked = 0.0 # Default if not found in saved data # Function to interact with the furniture (e.g., toggling door state) @@ -483,7 +494,7 @@ func apply_transform_to_instance(rotation_angle: int, position_offset: Vector3): -# Returns this furniture's data for saving, including door state if applicable +# Returns this furniture's data for saving, including door state, container state, and last checked time func get_data() -> Dictionary: var newfurniturejson = { "id": furnitureJSON.id, @@ -506,6 +517,10 @@ func get_data() -> Dictionary: # If there are no items in the inventory, keep an empty object. Else, # keep an object with the items key and the serialized items var containerobject = {} if containerdata.is_empty() else {"items": containerdata} + + # Add the last_time_checked to the container data + containerobject["container_last_time_checked"] = last_time_checked + containerobject["container_itemgroup"] = itemgroup newfurniturejson["Function"]["container"] = containerobject return newfurniturejson @@ -675,6 +690,7 @@ func get_sprite() -> Texture: func set_random_inventory_item_texture(): var items: Array[InventoryItem] = inventory.get_items() if items.size() == 0: + container_sprite_mesh.material = Gamedata.materials.container # set empty container return # Pick a random item from the inventory From bdeb3e69796e3c9cec8683b5d11a7a28ca176288 Mon Sep 17 00:00:00 2001 From: snipercup <50166150+snipercup@users.noreply.github.com> Date: Sat, 14 Dec 2024 06:41:50 +0100 Subject: [PATCH 3/9] Add regenerating trees --- Mods/Core/Furniture/Furniture.json | 15 ++ Mods/Core/Itemgroups/Itemgroups.json | 313 ++++----------------------- Mods/Core/Itemgroups/references.json | 7 + Mods/Core/Items/references.json | 27 +++ Scripts/Helper/time_helper.gd | 4 +- Scripts/Runtimedata/RItemgroup.gd | 2 + Scripts/Runtimedata/RMobgroup.gd | 22 ++ 7 files changed, 115 insertions(+), 275 deletions(-) create mode 100644 Mods/Core/Items/references.json diff --git a/Mods/Core/Furniture/Furniture.json b/Mods/Core/Furniture/Furniture.json index a827c26f..9a62ef72 100644 --- a/Mods/Core/Furniture/Furniture.json +++ b/Mods/Core/Furniture/Furniture.json @@ -68,6 +68,11 @@ "weight": 1 }, { + "Function": { + "container_group": "tree_forage", + "container_regeneration_time": 0.1, + "is_container": true + }, "categories": [ "Nature" ], @@ -91,6 +96,11 @@ "weight": 1 }, { + "Function": { + "container_group": "tree_forage", + "container_regeneration_time": 0.1, + "is_container": true + }, "categories": [ "Nature" ], @@ -114,6 +124,11 @@ "weight": 1 }, { + "Function": { + "container_group": "tree_forage", + "container_regeneration_time": 0.1, + "is_container": true + }, "categories": [ "Nature" ], diff --git a/Mods/Core/Itemgroups/Itemgroups.json b/Mods/Core/Itemgroups/Itemgroups.json index 3a5bb910..d2b7d7d7 100644 --- a/Mods/Core/Itemgroups/Itemgroups.json +++ b/Mods/Core/Itemgroups/Itemgroups.json @@ -60,20 +60,6 @@ ], "mode": "Collection", "name": "Kitchen cupboard", - "references": { - "core": { - "furniture": [ - "countertop_wood" - ], - "maps": [ - "store_groceries", - "office_building_00" - ], - "mobs": [ - "scrapwalker" - ] - } - }, "sprite": "canned_food_32.png", "use_sprite": false }, @@ -108,13 +94,6 @@ ], "mode": "Collection", "name": "Mob loot", - "references": { - "core": { - "mobs": [ - "rust_sentinel" - ] - } - }, "sprite": "machete_32.png", "use_sprite": false }, @@ -203,20 +182,6 @@ ], "mode": "Collection", "name": "General cabinet contents", - "references": { - "core": { - "furniture": [ - "cabinet_wood_00", - "wall_shelf" - ], - "maps": [ - "store_groceries", - "generichouse_end", - "office_building_00", - "police_station" - ] - } - }, "sprite": "flashlight_32.png", "use_sprite": false }, @@ -245,46 +210,6 @@ ], "mode": "Collection", "name": "Medium destroyed furniture", - "references": { - "core": { - "furniture": [ - "countertop_wood", - "table_round_wood", - "chair_wood", - "bench_wood", - "bed_wood_single_00", - "cabinet_wood_00", - "bookcase_wood_00", - "door_wood", - "bench_garden", - "wardrobe", - "table_picknic", - "standing_mirror", - "chair_office", - "table_metal", - "lamp_standing", - "desk", - "bathtub", - "stove", - "sofa", - "cash_register", - "shopping_cart", - "display_case", - "vending_machine", - "toilet_00", - "damaged_shelves", - "destroyed_fence", - "railroad_midsection" - ], - "maps": [ - "abandoned_building", - "subway_station", - "city_square", - "skyscraper", - "neighborhood_school" - ] - } - }, "sprite": "wreck_wood_generic_32.png", "use_sprite": true }, @@ -307,13 +232,6 @@ ], "mode": "Collection", "name": "Medium disassembled furniture", - "references": { - "core": { - "furniture": [ - "countertop_wood" - ] - } - }, "sprite": "plank.png", "use_sprite": false }, @@ -420,17 +338,6 @@ ], "mode": "Collection", "name": "Refridgerator", - "references": { - "core": { - "furniture": [ - "refrigerator_00", - "display_case" - ], - "maps": [ - "store_groceries" - ] - } - }, "sprite": "bottle_empty_32.png", "use_sprite": false }, @@ -519,14 +426,6 @@ ], "mode": "Collection", "name": "General clothing", - "references": { - "core": { - "furniture": [ - "wardrobe", - "clothing_rack" - ] - } - }, "sprite": "jacket_32.png", "use_sprite": false }, @@ -573,13 +472,6 @@ ], "mode": "Collection", "name": "Electronics store (medium appliances)", - "references": { - "core": { - "maps": [ - "store_electronic_clothing" - ] - } - }, "sprite": "microwave_oven_32.png", "use_sprite": false }, @@ -632,14 +524,6 @@ ], "mode": "Collection", "name": "Electronics store (small products)", - "references": { - "core": { - "maps": [ - "store_electronic_clothing", - "radio_tower" - ] - } - }, "sprite": "screwdriver_32.png", "use_sprite": false }, @@ -722,13 +606,6 @@ ], "mode": "Collection", "name": "Electronics store (mixed products)", - "references": { - "core": { - "maps": [ - "store_electronic_clothing" - ] - } - }, "sprite": "electrical_components_32.png", "use_sprite": false }, @@ -763,21 +640,6 @@ ], "mode": "Collection", "name": "Vending machine (drinks)", - "references": { - "core": { - "furniture": [ - "vending_machine" - ], - "maps": [ - "store_electronic_clothing", - "store_groceries", - "subway_station", - "city_square", - "neighborhood_school", - "police_station" - ] - } - }, "sprite": "can_beer_32.png", "use_sprite": false }, @@ -800,18 +662,6 @@ ], "mode": "Collection", "name": "Vending machine (snacks)", - "references": { - "core": { - "maps": [ - "store_groceries", - "subway_station", - "city_square", - "office_building_00", - "neighborhood_school", - "police_station" - ] - } - }, "sprite": "chocolate_32.png", "use_sprite": false }, @@ -852,15 +702,6 @@ ], "mode": "Collection", "name": "Destroyed tree", - "references": { - "core": { - "furniture": [ - "Tree_00", - "PineTree_00", - "WillowTree_00" - ] - } - }, "sprite": "log_32.png", "use_sprite": false }, @@ -913,25 +754,6 @@ ], "mode": "Distribution", "name": "Generic field items", - "references": { - "core": { - "maps": [ - "field_grass_basic_00", - "field_grass_flowers_00", - "RockyHill_SE", - "RockyHill_SW", - "field_grass_hill_00", - "field_grass_hole_00", - "RockyHill_NE", - "RockyHill_NW", - "urbanroad_corner", - "urbanroad_cross", - "urbanroad_t", - "urbanroad", - "police_station" - ] - } - }, "sprite": "leaves_32.png", "use_sprite": false }, @@ -1038,17 +860,6 @@ ], "mode": "Distribution", "name": "Generic forest finds", - "references": { - "core": { - "maps": [ - "forest_basic_00", - "forest_road_straight", - "forest_road_corner", - "forest_road_t", - "forest_road_cross" - ] - } - }, "sprite": "branches_32.png", "use_sprite": false }, @@ -1123,13 +934,6 @@ ], "mode": "Collection", "name": "M4A1 Gun and ammo", - "references": { - "core": { - "maps": [ - "RockyHill_SW" - ] - } - }, "sprite": "rifle_64_32.png", "use_sprite": false }, @@ -1170,14 +974,6 @@ ], "mode": "Collection", "name": "Rock debris", - "references": { - "core": { - "maps": [ - "abandoned_building", - "subway_station" - ] - } - }, "sprite": "rock_large_32.png", "use_sprite": false }, @@ -1260,14 +1056,6 @@ ], "mode": "Collection", "name": "Urban debris", - "references": { - "core": { - "maps": [ - "abandoned_building", - "subway_station" - ] - } - }, "sprite": "rusted_metal_sheets_32.png", "use_sprite": false }, @@ -1326,18 +1114,6 @@ ], "mode": "Collection", "name": "Urban litter", - "references": { - "core": { - "maps": [ - "subway_station", - "parking_garage", - "city_square", - "office_building_00", - "skyscraper", - "police_station" - ] - } - }, "sprite": "bottle_empty_32.png", "use_sprite": false }, @@ -1372,14 +1148,6 @@ ], "mode": "Collection", "name": "Damaged electronics", - "references": { - "core": { - "maps": [ - "abandoned_building", - "radio_tower" - ] - } - }, "sprite": "transmitter_broken_32.png", "use_sprite": false }, @@ -1426,18 +1194,6 @@ ], "mode": "Collection", "name": "Electronic Mob loot", - "references": { - "core": { - "maps": [ - "radio_tower" - ], - "mobs": [ - "disruptor_drone", - "scavenger_skitter", - "venom_crawler" - ] - } - }, "sprite": "electrical_components_32.png", "use_sprite": false }, @@ -1478,14 +1234,6 @@ ], "mode": "Collection", "name": "First aid", - "references": { - "core": { - "maps": [ - "radio_tower", - "police_station" - ] - } - }, "sprite": "bandage_32.png", "use_sprite": false }, @@ -1574,13 +1322,6 @@ ], "mode": "Collection", "name": "Police station locker", - "references": { - "core": { - "maps": [ - "police_station" - ] - } - }, "sprite": "pistol_magazine.png", "use_sprite": false }, @@ -1771,21 +1512,47 @@ ], "mode": "Collection", "name": "Mob loot", - "references": { - "core": { - "mobs": [ - "basic_zombie_1", - "basic_zombie_2", - "bloated_zombie", - "rushing_zombie", - "charred_zombie", - "heavy_zombie", - "skeleton_zombie", - "limping_zombie" - ] - } - }, "sprite": "zombie_eye_32.png", "use_sprite": false + }, + { + "description": "The player is looking to the tree and see what can be foraged.", + "id": "tree_forage", + "items": [ + { + "id": "branch", + "max": 5, + "min": 2, + "probability": 80 + }, + { + "id": "leaf", + "max": 25, + "min": 10, + "probability": 95 + }, + { + "id": "long_stick", + "max": 3, + "min": 1, + "probability": 20 + }, + { + "id": "pine_branch", + "max": 1, + "min": 1, + "probability": 20 + }, + { + "id": "stick", + "max": 3, + "min": 1, + "probability": 60 + } + ], + "mode": "Collection", + "name": "Tree foraging", + "sprite": "plant_remnants_32.png", + "use_sprite": false } ] \ No newline at end of file diff --git a/Mods/Core/Itemgroups/references.json b/Mods/Core/Itemgroups/references.json index edcb9bf5..fcb9c3b6 100644 --- a/Mods/Core/Itemgroups/references.json +++ b/Mods/Core/Itemgroups/references.json @@ -108,6 +108,13 @@ "store_groceries" ] }, + "tree_forage": { + "furnitures": [ + "Tree_00", + "PineTree_00", + "WillowTree_00" + ] + }, "urban_litter": { "maps": [ "office_building_00", diff --git a/Mods/Core/Items/references.json b/Mods/Core/Items/references.json new file mode 100644 index 00000000..272e48b4 --- /dev/null +++ b/Mods/Core/Items/references.json @@ -0,0 +1,27 @@ +{ + "branch": { + "itemgroups": [ + "tree_forage" + ] + }, + "leaf": { + "itemgroups": [ + "tree_forage" + ] + }, + "long_stick": { + "itemgroups": [ + "tree_forage" + ] + }, + "pine_branch": { + "itemgroups": [ + "tree_forage" + ] + }, + "stick": { + "itemgroups": [ + "tree_forage" + ] + } +} \ No newline at end of file diff --git a/Scripts/Helper/time_helper.gd b/Scripts/Helper/time_helper.gd index 6431c8c1..ad747c19 100644 --- a/Scripts/Helper/time_helper.gd +++ b/Scripts/Helper/time_helper.gd @@ -11,8 +11,8 @@ var _is_tracking_time: bool = false # Flag to track if we are actively counting var _last_tick_time: int = 0 # The last recorded tick time (in milliseconds) # Time constants -const daytime: int = 20 # Daytime in minutes -const nighttime: int = 15 # Nighttime in minutes +const daytime: int = 20 # Daytime in real-life minutes +const nighttime: int = 15 # Nighttime in real-life minutes const day_duration: int = daytime + nighttime # Total duration of a day in real-life minutes const in_game_day_minutes: int = 24 * 60 # In-game minutes in a full day (1440) diff --git a/Scripts/Runtimedata/RItemgroup.gd b/Scripts/Runtimedata/RItemgroup.gd index a31fb798..3b645740 100644 --- a/Scripts/Runtimedata/RItemgroup.gd +++ b/Scripts/Runtimedata/RItemgroup.gd @@ -52,6 +52,7 @@ var description: String var mode: String # "Collection" or "Distribution" var items: Array[Item] = [] var use_sprite: bool = false +var spriteid: String var parent: RItemgroups # Reference to the list containing all runtime itemgroups for this mod # Constructor to initialize itemgroup properties @@ -69,6 +70,7 @@ func overwrite_from_ditemgroup(ditemgroup: DItemgroup) -> void: description = ditemgroup.description mode = ditemgroup.mode use_sprite = ditemgroup.use_sprite + spriteid = ditemgroup.spriteid # Convert DItemgroup items to RItemgroup items items.clear() diff --git a/Scripts/Runtimedata/RMobgroup.gd b/Scripts/Runtimedata/RMobgroup.gd index 1ae0df31..4d7ac5c5 100644 --- a/Scripts/Runtimedata/RMobgroup.gd +++ b/Scripts/Runtimedata/RMobgroup.gd @@ -63,3 +63,25 @@ func get_data() -> Dictionary: # Function to check if a specific mob ID exists in the "mobs" property func has_mob(mob_id: String) -> bool: return mobs.has(mob_id) + + +func get_random_mob_id() -> String: + # If no mobs are present, return an empty string + if mobs.is_empty(): + return "" + + # Calculate the total weight + var total_weight: int = 0 + for weight in mobs.values(): + total_weight += weight + + # Generate a random number within the total weight + var random_pick: int = randi() % total_weight + + # Iterate through the mobs and select the mob based on the random pick + for mob_id in mobs.keys(): + random_pick -= mobs[mob_id] + if random_pick < 0: + return mob_id # Return the selected mob ID + + return "" # Fallback in case of an error, should not be reached From 42b5894a219adae3173e9ba24445bd127ace93ea Mon Sep 17 00:00:00 2001 From: snipercup <50166150+snipercup@users.noreply.github.com> Date: Sat, 14 Dec 2024 06:53:39 +0100 Subject: [PATCH 4/9] Balance tree regen --- Mods/Core/Furniture/Furniture.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Mods/Core/Furniture/Furniture.json b/Mods/Core/Furniture/Furniture.json index 9a62ef72..f6fdf57e 100644 --- a/Mods/Core/Furniture/Furniture.json +++ b/Mods/Core/Furniture/Furniture.json @@ -70,7 +70,7 @@ { "Function": { "container_group": "tree_forage", - "container_regeneration_time": 0.1, + "container_regeneration_time": 10, "is_container": true }, "categories": [ @@ -98,7 +98,7 @@ { "Function": { "container_group": "tree_forage", - "container_regeneration_time": 0.1, + "container_regeneration_time": 10, "is_container": true }, "categories": [ @@ -126,7 +126,7 @@ { "Function": { "container_group": "tree_forage", - "container_regeneration_time": 0.1, + "container_regeneration_time": 10, "is_container": true }, "categories": [ From 39ceaea3da13ec7e21029f8d810318d293b25b23 Mon Sep 17 00:00:00 2001 From: snipercup <50166150+snipercup@users.noreply.github.com> Date: Sat, 14 Dec 2024 08:19:53 +0100 Subject: [PATCH 5/9] Create dimensionfall mod --- Mods/Dimensionfall/modinfo.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 Mods/Dimensionfall/modinfo.json diff --git a/Mods/Dimensionfall/modinfo.json b/Mods/Dimensionfall/modinfo.json new file mode 100644 index 00000000..48356ae7 --- /dev/null +++ b/Mods/Dimensionfall/modinfo.json @@ -0,0 +1,12 @@ +{ + "author": "Khaligufzel", + "dependencies": [], + "description": "This is the core content mod of the game. It provides the foundational systems and data required for other mods to function.", + "homepage": "https://github.com/Khaligufzel/Dimensionfall", + "id": "Dimensionfall", + "license": "GPL-3.0 License", + "name": "Dimensionfall", + "tags": [ + "Dimensionfall" + ] +} From ca28e01fbd2c26badedef369d0d212b88528bf82 Mon Sep 17 00:00:00 2001 From: snipercup <50166150+snipercup@users.noreply.github.com> Date: Sat, 14 Dec 2024 09:48:16 +0100 Subject: [PATCH 6/9] Duplicate map to mod --- Scenes/ContentManager/Scripts/content_list.gd | 34 ++++++++++++++++--- Scenes/ContentManager/content_list.tscn | 22 +++++++++--- Scripts/Gamedata/DItems.gd | 3 -- Scripts/Gamedata/DMaps.gd | 22 ++++++++---- 4 files changed, 62 insertions(+), 19 deletions(-) diff --git a/Scenes/ContentManager/Scripts/content_list.gd b/Scenes/ContentManager/Scripts/content_list.gd index 2e2d06d7..564780a5 100644 --- a/Scenes/ContentManager/Scripts/content_list.gd +++ b/Scenes/ContentManager/Scripts/content_list.gd @@ -10,6 +10,10 @@ extends Control @export var collapseButton: Button = null @export var pupup_ID: Popup = null @export var popup_textedit: TextEdit = null +@export var to_mod_h_box_container: HBoxContainer = null +@export var mod_option_button: OptionButton = null + + signal item_activated(type: DMod.ContentType, itemID: String, list: Control) var popupAction: String = "" var datainstance: RefCounted # One of the data classes like DMap, DTile, DMob and so on @@ -36,8 +40,22 @@ var is_collapsed: bool = false: save_collapse_state() - func _ready(): + # Populate mod_option_button with IDs from all mods + mod_option_button.clear() # Clear any existing entries + var all_mod_ids: Array = Gamedata.mods.get_all_mod_ids() # Get all mod IDs + for mymod_id in all_mod_ids: + mod_option_button.add_item(mymod_id) # Add each mod ID to the OptionButton + + # Set the selected value to the current `mod_id` + var selected_index = all_mod_ids.find(mod_id) # Find the index of the current mod_id + if selected_index != -1: + mod_option_button.select(selected_index) # Select the current mod_id in the OptionButton + else: + mod_id = all_mod_ids[0] if all_mod_ids.size() > 0 else "Core" # Default to the first mod or "Core" + mod_option_button.select(0) + + # Other existing setup for the contentItems drag forwarding contentItems.set_drag_forwarding(_create_drag_data, Callable(), Callable()) @@ -70,7 +88,8 @@ func add_item_to_data(id: String): func _on_add_button_button_up(): popupAction = "Add" popup_textedit.text = "" - pupup_ID.show() + to_mod_h_box_container.show() + mod_option_button.hide() # This function requires that an item from the list is selected # Once clicked, it will show pupup_ID to ask the user for a new ID @@ -84,6 +103,7 @@ func _on_duplicate_button_button_up(): return popupAction = "Duplicate" popup_textedit.text = selected_id + to_mod_h_box_container.show() pupup_ID.show() # Called after the user enters an ID into the popup textbox and presses OK @@ -92,10 +112,15 @@ func _on_ok_button_up(): var myText = popup_textedit.text if myText == "": return + if popupAction == "Add": datainstance.add_new(myText) - if popupAction == "Duplicate": - datainstance.duplicate_to_disk(get_selected_item_text(), myText) + elif popupAction == "Duplicate": + # Get the selected mod ID from the mod_option_button + var selected_mod_id = mod_option_button.get_item_text(mod_option_button.get_selected_id()) + # Pass the selected mod ID to the duplicate_to_disk function + datainstance.duplicate_to_disk(get_selected_item_text(), myText, selected_mod_id) + popupAction = "" # Check if the list is collapsed and expand it if true if is_collapsed: @@ -103,6 +128,7 @@ func _on_ok_button_up(): load_data() + # Called after the users presses cancel on the popup asking for an ID func _on_cancel_button_up(): pupup_ID.hide() diff --git a/Scenes/ContentManager/content_list.tscn b/Scenes/ContentManager/content_list.tscn index d22345a3..88dfcc70 100644 --- a/Scenes/ContentManager/content_list.tscn +++ b/Scenes/ContentManager/content_list.tscn @@ -2,7 +2,7 @@ [ext_resource type="Script" path="res://Scenes/ContentManager/Scripts/content_list.gd" id="1_ly1kh"] -[node name="ContentList" type="Control" node_paths=PackedStringArray("contentItems", "collapseButton", "pupup_ID", "popup_textedit")] +[node name="ContentList" type="Control" node_paths=PackedStringArray("contentItems", "collapseButton", "pupup_ID", "popup_textedit", "to_mod_h_box_container", "mod_option_button")] custom_minimum_size = Vector2(200, 30) layout_mode = 3 anchors_preset = 15 @@ -16,7 +16,9 @@ script = ExtResource("1_ly1kh") contentItems = NodePath("Content/ContentItems") collapseButton = NodePath("Content/HBoxContainer/CollapseButton") pupup_ID = NodePath("ID_Input") -popup_textedit = NodePath("ID_Input/VBoxContainer/TextEdit") +popup_textedit = NodePath("ID_Input/VBoxContainer/IdTextEdit") +to_mod_h_box_container = NodePath("ID_Input/VBoxContainer/ToModHBoxContainer") +mod_option_button = NodePath("ID_Input/VBoxContainer/ToModHBoxContainer/ModOptionButton") [node name="Content" type="VBoxContainer" parent="."] layout_mode = 1 @@ -68,7 +70,7 @@ fixed_icon_size = Vector2i(32, 32) [node name="ID_Input" type="Popup" parent="."] title = "Input ID" initial_position = 2 -size = Vector2i(200, 150) +size = Vector2i(200, 152) unresizable = false borderless = false @@ -81,16 +83,26 @@ grow_vertical = 2 size_flags_horizontal = 3 size_flags_vertical = 3 -[node name="Label" type="Label" parent="ID_Input/VBoxContainer"] +[node name="IdLabel" type="Label" parent="ID_Input/VBoxContainer"] layout_mode = 2 text = "Input an ID" -[node name="TextEdit" type="TextEdit" parent="ID_Input/VBoxContainer"] +[node name="IdTextEdit" type="TextEdit" parent="ID_Input/VBoxContainer"] layout_mode = 2 size_flags_vertical = 3 placeholder_text = "ex: pistol_9mm" scroll_fit_content_height = true +[node name="ToModHBoxContainer" type="HBoxContainer" parent="ID_Input/VBoxContainer"] +layout_mode = 2 + +[node name="ModLabel" type="Label" parent="ID_Input/VBoxContainer/ToModHBoxContainer"] +layout_mode = 2 +text = "To mod:" + +[node name="ModOptionButton" type="OptionButton" parent="ID_Input/VBoxContainer/ToModHBoxContainer"] +layout_mode = 2 + [node name="HBoxContainer" type="HBoxContainer" parent="ID_Input/VBoxContainer"] layout_mode = 2 size_flags_vertical = 3 diff --git a/Scripts/Gamedata/DItems.gd b/Scripts/Gamedata/DItems.gd index a68da67e..35bf4f76 100644 --- a/Scripts/Gamedata/DItems.gd +++ b/Scripts/Gamedata/DItems.gd @@ -62,9 +62,6 @@ func get_all() -> Dictionary: func duplicate_to_disk(itemid: String, newitemid: String) -> void: var itemdata: Dictionary = by_id(itemid).get_data().duplicate(true) - # A duplicated item is brand new and can't already be referenced by something - # So we delete the references from the duplicated data if it is present - itemdata.erase("references") itemdata.id = newitemid var newitem: DItem = DItem.new(itemdata, self) itemdict[newitemid] = newitem diff --git a/Scripts/Gamedata/DMaps.gd b/Scripts/Gamedata/DMaps.gd index 47a28809..647984d1 100644 --- a/Scripts/Gamedata/DMaps.gd +++ b/Scripts/Gamedata/DMaps.gd @@ -20,10 +20,11 @@ extends RefCounted var dataPath: String = "./Mods/Core/Maps/" var mapdict: Dictionary = {} var references: Dictionary = {} - +var mod_id: String = "Core" # Load references from references.json during initialization -func _init(mod_id: String): +func _init(new_mod_id: String): + mod_id = new_mod_id dataPath = "./Mods/" + mod_id + "/Maps/" load_references() load_maps_from_disk() @@ -54,21 +55,28 @@ func get_all() -> Dictionary: return mapdict -func duplicate_to_disk(mapid: String, newmapid: String) -> void: +func duplicate_to_disk(mapid: String, newmapid: String, new_mod_id: String) -> void: + if new_mod_id != mod_id: + var other_maps: DMaps = Gamedata.mods.by_id(new_mod_id).maps + var newmap: DMap = other_maps.add_new(newmapid) + var newdata: Dictionary = by_id(mapid).get_data().duplicate(true) + newmap.set_data(newdata) + newmap.save_data_to_disk() + return # Exit the function if the mod IDs don't match + + # Proceed with duplication if mod IDs are equal var newmap: DMap = DMap.new(newmapid, dataPath, self) var newdata: Dictionary = by_id(mapid).get_data().duplicate(true) - # A duplicated map is brand new and can't already be referenced by something - # So we delete the references from the duplicated data if it is present - newdata.erase("references") newmap.set_data(newdata) newmap.save_data_to_disk() mapdict[newmapid] = newmap -func add_new(newid: String) -> void: +func add_new(newid: String) -> DMap: var newmap: DMap = DMap.new(newid, dataPath, self) newmap.save_data_to_disk() mapdict[newid] = newmap + return newmap func delete_by_id(mapid: String) -> void: From 3956ee2ddd21834263591e11eff9056d560f4499 Mon Sep 17 00:00:00 2001 From: snipercup <50166150+snipercup@users.noreply.github.com> Date: Sat, 14 Dec 2024 13:14:58 +0100 Subject: [PATCH 7/9] Duplicate items and furniture to mod --- Scenes/ContentManager/Scripts/content_list.gd | 4 +-- Scripts/Gamedata/DFurniture.gd | 2 +- Scripts/Gamedata/DFurnitures.gd | 31 ++++++++++++------- Scripts/Gamedata/DItems.gd | 26 ++++++++++++---- Scripts/Gamedata/DTacticalmaps.gd | 24 ++++++++++++-- 5 files changed, 64 insertions(+), 23 deletions(-) diff --git a/Scenes/ContentManager/Scripts/content_list.gd b/Scenes/ContentManager/Scripts/content_list.gd index 564780a5..cb6b1d56 100644 --- a/Scenes/ContentManager/Scripts/content_list.gd +++ b/Scenes/ContentManager/Scripts/content_list.gd @@ -88,8 +88,8 @@ func add_item_to_data(id: String): func _on_add_button_button_up(): popupAction = "Add" popup_textedit.text = "" - to_mod_h_box_container.show() - mod_option_button.hide() + to_mod_h_box_container.hide() + pupup_ID.show() # This function requires that an item from the list is selected # Once clicked, it will show pupup_ID to ask the user for a new ID diff --git a/Scripts/Gamedata/DFurniture.gd b/Scripts/Gamedata/DFurniture.gd index 82041c17..820eeb2a 100644 --- a/Scripts/Gamedata/DFurniture.gd +++ b/Scripts/Gamedata/DFurniture.gd @@ -256,7 +256,7 @@ func on_data_changed(olddfurniture: DFurniture): func delete(): Gamedata.mods.remove_reference(DMod.ContentType.ITEMGROUPS, function.container_group, DMod.ContentType.FURNITURES, id) Gamedata.mods.remove_reference(DMod.ContentType.ITEMGROUPS, destruction.group, DMod.ContentType.FURNITURES, id) - Gamedata.mods.remove_reference(DMod.ContentType.ITEMGROUPS, disassembly.container_group, DMod.ContentType.FURNITURES, id) + Gamedata.mods.remove_reference(DMod.ContentType.ITEMGROUPS, disassembly.group, DMod.ContentType.FURNITURES, id) # Get a list of all maps that reference this mob var myreferences: Dictionary = parent.references.get(id, {}) diff --git a/Scripts/Gamedata/DFurnitures.gd b/Scripts/Gamedata/DFurnitures.gd index 7ad7d7ca..a34fd7bb 100644 --- a/Scripts/Gamedata/DFurnitures.gd +++ b/Scripts/Gamedata/DFurnitures.gd @@ -14,9 +14,11 @@ var sprites: Dictionary = {} var shader_materials: Dictionary = {} # Cache for shader materials by furniture ID var shape_materials: Dictionary = {} # Cache for shape materials by furniture ID var references: Dictionary = {} +var mod_id: String = "Core" # Add a mod_id parameter to dynamically initialize paths -func _init(mod_id: String) -> void: +func _init(new_mod_id: String) -> void: + mod_id = new_mod_id # Update dataPath and spritePath using the provided mod_id dataPath = "./Mods/" + mod_id + "/Furniture/" filePath = "./Mods/" + mod_id + "/Furniture/Furniture.json" @@ -39,7 +41,7 @@ func load_furnitures_from_disk() -> void: var furniturelist: Array = Helper.json_helper.load_json_array_file(filePath) for furnitureitem in furniturelist: var furniture: DFurniture = DFurniture.new(furnitureitem, self) - if furniture.spriteid: + if furniture.spriteid and sprites.has(furniture.spriteid): furniture.sprite = sprites[furniture.spriteid] furnituredict[furniture.id] = furniture @@ -69,19 +71,26 @@ func get_all() -> Dictionary: return furnituredict -func duplicate_to_disk(furnitureid: String, newfurnitureid: String) -> void: +# Duplicate the furniture to disk. A new mod id may be provided to save the duplicate to +# furnitureid: The furniture to duplicate +# newfurnitureid: The id of the new duplicate (can be the same as furnitureid if new_mod_id equals mod_id) +# new_mod_id: The id of the mod that the duplicate will be entered into. May differ from mod_id +func duplicate_to_disk(furnitureid: String, newfurnitureid: String, new_mod_id: String) -> void: + # Duplicate the furniture data and set the new id var furnituredata: Dictionary = by_id(furnitureid).get_data().duplicate(true) - # A duplicated furniture is brand new and can't already be referenced by something - # So we delete the references from the duplicated data if it is present - furnituredata.erase("references") furnituredata.id = newfurnitureid - var newfurniture: DFurniture = DFurniture.new(furnituredata, self) - furnituredict[newfurnitureid] = newfurniture - save_furnitures_to_disk() + # Determine the new parent based on the new_mod_id + var newparent: DFurnitures = self if new_mod_id == mod_id else Gamedata.mods.by_id(new_mod_id).furnitures + # Instantiate and append the new DFurniture instance + var newfurniture: DFurniture = DFurniture.new(furnituredata, newparent) + newparent.append_new(newfurniture) func add_new(newid: String) -> void: - var newfurniture: DFurniture = DFurniture.new({"id":newid}, self) + append_new(DFurniture.new({"id":newid}, self)) + + +func append_new(newfurniture: DFurniture) -> void: furnituredict[newfurniture.id] = newfurniture save_furnitures_to_disk() @@ -107,7 +116,7 @@ func sprite_by_id(furnitureid: String) -> Texture: # Returns the sprite of the furniture # furnitureid: The id of the furniture to return the sprite of func sprite_by_file(spritefile: String) -> Texture: - return sprites[spritefile] + return sprites[spritefile] if sprites.has(spritefile) else null func is_moveable(id: String) -> bool: diff --git a/Scripts/Gamedata/DItems.gd b/Scripts/Gamedata/DItems.gd index 35bf4f76..c20cc12d 100644 --- a/Scripts/Gamedata/DItems.gd +++ b/Scripts/Gamedata/DItems.gd @@ -12,9 +12,11 @@ var spritePath: String = "./Mods/Core/Items/" var itemdict: Dictionary = {} var sprites: Dictionary = {} var references: Dictionary = {} +var mod_id: String = "Core" # Add a mod_id parameter to dynamically initialize paths -func _init(mod_id: String) -> void: +func _init(new_mod_id: String) -> void: + mod_id = new_mod_id # Update dataPath and spritePath using the provided mod_id dataPath = "./Mods/" + mod_id + "/Items/" filePath = "./Mods/" + mod_id + "/Items/Items.json" @@ -60,16 +62,28 @@ func get_all() -> Dictionary: return itemdict -func duplicate_to_disk(itemid: String, newitemid: String) -> void: +# Duplicate the item to disk. A new mod id may be provided to save the duplicate to. +# itemid: The item to duplicate. +# newitemid: The id of the new duplicate (can be the same as itemid if new_mod_id equals mod_id). +# new_mod_id: The id of the mod that the duplicate will be entered into. May differ from mod_id. +func duplicate_to_disk(itemid: String, newitemid: String, new_mod_id: String) -> void: + # Duplicate the item data and set the new id var itemdata: Dictionary = by_id(itemid).get_data().duplicate(true) itemdata.id = newitemid - var newitem: DItem = DItem.new(itemdata, self) - itemdict[newitemid] = newitem - save_items_to_disk() + + # Determine the new parent based on the new_mod_id + var newparent: DItems = self if new_mod_id == mod_id else Gamedata.mods.by_id(new_mod_id).items + + # Instantiate and append the new DItem instance + var newitem: DItem = DItem.new(itemdata, newparent) + newparent.append_new(newitem) func add_new(newid: String) -> void: - var newitem: DItem = DItem.new({"id":newid}, self) + append_new(DItem.new({"id":newid}, self)) + + +func append_new(newitem: DItem) -> void: itemdict[newitem.id] = newitem save_items_to_disk() diff --git a/Scripts/Gamedata/DTacticalmaps.gd b/Scripts/Gamedata/DTacticalmaps.gd index 84573371..d27f54ec 100644 --- a/Scripts/Gamedata/DTacticalmaps.gd +++ b/Scripts/Gamedata/DTacticalmaps.gd @@ -7,8 +7,10 @@ extends RefCounted var dataPath: String = "./Mods/Core/TacticalMaps/" var mapdict: Dictionary = {} +var mod_id: String = "Core" -func _init(mod_id: String): +func _init(new_mod_id: String): + mod_id = new_mod_id # Update dataPath using the provided mod_id dataPath = "./Mods/" + mod_id + "/TacticalMaps/" load_maps_from_disk() @@ -25,16 +27,32 @@ func load_maps_from_disk() -> void: func get_all() -> Dictionary: return mapdict -func duplicate_to_disk(mapid: String, newmapid: String) -> void: +func duplicate_to_disk(mapid: String, newmapid: String, new_mod_id: String) -> void: + if new_mod_id != mod_id: + # Access the DTacticalmaps instance for the target mod + var other_maps: DTacticalmaps = Gamedata.mods.by_id(new_mod_id).tacticalmaps + + # Add a new tacticalmap to the target mod + var newmap: DTacticalmap = other_maps.add_new(newmapid) + + # Duplicate the data from the current map and set it in the new map + var newdata: Dictionary = mapdict[mapid].get_data().duplicate(true) + newmap.set_data(newdata) + newmap.save_data_to_disk() + return # Exit if mod IDs don't match + + # Proceed with duplication if mod IDs are equal var newmap: DTacticalmap = DTacticalmap.new(newmapid, dataPath, self) newmap.set_data(mapdict[mapid].get_data().duplicate(true)) newmap.save_data_to_disk() mapdict[newmapid] = newmap -func add_new(newid: String) -> void: + +func add_new(newid: String) -> DTacticalmap: var newmap: DTacticalmap = DTacticalmap.new(newid, dataPath, self) newmap.save_data_to_disk() mapdict[newid] = newmap + return newmap func delete_by_id(mapid: String) -> void: mapdict[mapid].delete() From 03e32f5014157a2ce1747af003ee9b07a8e65d55 Mon Sep 17 00:00:00 2001 From: snipercup <50166150+snipercup@users.noreply.github.com> Date: Sat, 14 Dec 2024 13:35:22 +0100 Subject: [PATCH 8/9] Add mod id --- Scripts/Gamedata/DItemgroups.gd | 4 +++- Scripts/Gamedata/DMobfactions.gd | 4 +++- Scripts/Gamedata/DMobgroups.gd | 4 +++- Scripts/Gamedata/DMobs.gd | 4 +++- Scripts/Gamedata/DOvermapareas.gd | 4 +++- Scripts/Gamedata/DPlayerAttributes.gd | 4 +++- Scripts/Gamedata/DQuests.gd | 4 +++- Scripts/Gamedata/DSkills.gd | 4 +++- Scripts/Gamedata/DStats.gd | 4 +++- Scripts/Gamedata/DTiles.gd | 4 +++- Scripts/Gamedata/DWearableSlots.gd | 4 +++- 11 files changed, 33 insertions(+), 11 deletions(-) diff --git a/Scripts/Gamedata/DItemgroups.gd b/Scripts/Gamedata/DItemgroups.gd index 5f0f384d..4041e2ab 100644 --- a/Scripts/Gamedata/DItemgroups.gd +++ b/Scripts/Gamedata/DItemgroups.gd @@ -12,9 +12,11 @@ var spritePath: String = "./Mods/Core/Items/" var itemgroupdict: Dictionary = {} var sprites: Dictionary = {} var references: Dictionary = {} +var mod_id: String = "Core" # Add a mod_id parameter to dynamically initialize paths -func _init(mod_id: String) -> void: +func _init(new_mod_id: String) -> void: + mod_id = new_mod_id # Update dataPath and spritePath using the provided mod_id dataPath = "./Mods/" + mod_id + "/Itemgroups/" filePath = "./Mods/" + mod_id + "/Itemgroups/Itemgroups.json" diff --git a/Scripts/Gamedata/DMobfactions.gd b/Scripts/Gamedata/DMobfactions.gd index 259c12a1..766445df 100644 --- a/Scripts/Gamedata/DMobfactions.gd +++ b/Scripts/Gamedata/DMobfactions.gd @@ -11,9 +11,11 @@ var spritePath: String = "./Mods/Core/Items/" var mobfactiondict: Dictionary = {} var sprites: Dictionary = {} var references: Dictionary = {} +var mod_id: String = "Core" # Add a mod_id parameter to dynamically initialize paths -func _init(mod_id: String) -> void: +func _init(new_mod_id: String) -> void: + mod_id = new_mod_id # Update dataPath and spritePath using the provided mod_id dataPath = "./Mods/" + mod_id + "/Mobfaction/" filePath = "./Mods/" + mod_id + "/Mobfaction/Mobfactions.json" diff --git a/Scripts/Gamedata/DMobgroups.gd b/Scripts/Gamedata/DMobgroups.gd index 9ace5eee..164fb428 100644 --- a/Scripts/Gamedata/DMobgroups.gd +++ b/Scripts/Gamedata/DMobgroups.gd @@ -11,9 +11,11 @@ var spritePath: String = "./Mods/Core/Mobs/" var mobgroupdict: Dictionary = {} var sprites: Dictionary = {} var references: Dictionary = {} +var mod_id: String = "Core" # Add a mod_id parameter to dynamically initialize paths -func _init(mod_id: String) -> void: +func _init(new_mod_id: String) -> void: + mod_id = new_mod_id # Update dataPath and spritePath using the provided mod_id dataPath = "./Mods/" + mod_id + "/Mobgroups/" filePath = "./Mods/" + mod_id + "/Mobgroups/Mobgroups.json" diff --git a/Scripts/Gamedata/DMobs.gd b/Scripts/Gamedata/DMobs.gd index 76d14ff4..5ee0d778 100644 --- a/Scripts/Gamedata/DMobs.gd +++ b/Scripts/Gamedata/DMobs.gd @@ -12,9 +12,11 @@ var spritePath: String = "./Mods/Core/Mobs/" var mobdict: Dictionary = {} var sprites: Dictionary = {} var references: Dictionary = {} +var mod_id: String = "Core" # Add a mod_id parameter to dynamically initialize paths -func _init(mod_id: String) -> void: +func _init(new_mod_id: String) -> void: + mod_id = new_mod_id # Update dataPath and spritePath using the provided mod_id dataPath = "./Mods/" + mod_id + "/Mobs/" filePath = "./Mods/" + mod_id + "/Mobs/Mobs.json" diff --git a/Scripts/Gamedata/DOvermapareas.gd b/Scripts/Gamedata/DOvermapareas.gd index 8315d9f2..75dea5b3 100644 --- a/Scripts/Gamedata/DOvermapareas.gd +++ b/Scripts/Gamedata/DOvermapareas.gd @@ -10,9 +10,11 @@ var dataPath: String = "./Mods/Core/Overmapareas/" var filePath: String = "./Mods/Core/Overmapareas/Overmapareas.json" var overmapareadict: Dictionary = {} var references: Dictionary = {} +var mod_id: String = "Core" # Add a mod_id parameter to dynamically initialize paths -func _init(mod_id: String) -> void: +func _init(new_mod_id: String) -> void: + mod_id = new_mod_id # Update dataPath and spritePath using the provided mod_id dataPath = "./Mods/" + mod_id + "/Overmapareas/" filePath = "./Mods/" + mod_id + "/Overmapareas/Overmapareas.json" diff --git a/Scripts/Gamedata/DPlayerAttributes.gd b/Scripts/Gamedata/DPlayerAttributes.gd index e6b27f47..e0521d77 100644 --- a/Scripts/Gamedata/DPlayerAttributes.gd +++ b/Scripts/Gamedata/DPlayerAttributes.gd @@ -13,10 +13,12 @@ var playerattributedict: Dictionary = {} var sprites: Dictionary = {} var hardcoded: Array = ["player_inventory"] var references: Dictionary = {} +var mod_id: String = "Core" # Add a mod_id parameter to dynamically initialize paths -func _init(mod_id: String) -> void: +func _init(new_mod_id: String) -> void: + mod_id = new_mod_id # Update dataPath and spritePath using the provided mod_id dataPath = "./Mods/" + mod_id + "/PlayerAttributes/" filePath = "./Mods/" + mod_id + "/PlayerAttributes/PlayerAttributes.json" diff --git a/Scripts/Gamedata/DQuests.gd b/Scripts/Gamedata/DQuests.gd index 3da7a48a..30c58df3 100644 --- a/Scripts/Gamedata/DQuests.gd +++ b/Scripts/Gamedata/DQuests.gd @@ -12,10 +12,12 @@ var spritePath: String = "./Mods/Core/Items/" var questdict: Dictionary = {} var sprites: Dictionary = {} var references: Dictionary = {} +var mod_id: String = "Core" # Add a mod_id parameter to dynamically initialize paths -func _init(mod_id: String) -> void: +func _init(new_mod_id: String) -> void: + mod_id = new_mod_id # Update dataPath and spritePath using the provided mod_id dataPath = "./Mods/" + mod_id + "/Quests/" filePath = "./Mods/" + mod_id + "/Quests/Quests.json" diff --git a/Scripts/Gamedata/DSkills.gd b/Scripts/Gamedata/DSkills.gd index 6bdcf5b3..3ea8c1a4 100644 --- a/Scripts/Gamedata/DSkills.gd +++ b/Scripts/Gamedata/DSkills.gd @@ -12,10 +12,12 @@ var spritePath: String = "./Mods/Core/Skills/" var skilldict: Dictionary = {} var sprites: Dictionary = {} var references: Dictionary = {} +var mod_id: String = "Core" # Add a mod_id parameter to dynamically initialize paths -func _init(mod_id: String) -> void: +func _init(new_mod_id: String) -> void: + mod_id = new_mod_id # Update dataPath and spritePath using the provided mod_id dataPath = "./Mods/" + mod_id + "/Skills/" filePath = "./Mods/" + mod_id + "/Skills/Skills.json" diff --git a/Scripts/Gamedata/DStats.gd b/Scripts/Gamedata/DStats.gd index 3febe268..d613e75e 100644 --- a/Scripts/Gamedata/DStats.gd +++ b/Scripts/Gamedata/DStats.gd @@ -10,9 +10,11 @@ var dataPath: String = "./Mods/Core/Stats/Stats.json" var spritePath: String = "./Mods/Core/Stats/" var statdict: Dictionary = {} var sprites: Dictionary = {} +var mod_id: String = "Core" # Add a mod_id parameter to dynamically initialize paths -func _init(mod_id: String) -> void: +func _init(new_mod_id: String) -> void: + mod_id = new_mod_id # Update dataPath and spritePath using the provided mod_id dataPath = "./Mods/" + mod_id + "/Stats/Stats.json" spritePath = "./Mods/" + mod_id + "/Stats/" diff --git a/Scripts/Gamedata/DTiles.gd b/Scripts/Gamedata/DTiles.gd index 047cbffe..06d19d7b 100644 --- a/Scripts/Gamedata/DTiles.gd +++ b/Scripts/Gamedata/DTiles.gd @@ -12,10 +12,12 @@ var spritePath: String = "./Mods/Core/Tiles/" var tiledict: Dictionary = {} var sprites: Dictionary = {} var references: Dictionary = {} +var mod_id: String = "Core" # Add a mod_id parameter to dynamically initialize paths -func _init(mod_id: String) -> void: +func _init(new_mod_id: String) -> void: + mod_id = new_mod_id # Update dataPath and spritePath using the provided mod_id dataPath = "./Mods/" + mod_id + "/Tiles/" filePath = "./Mods/" + mod_id + "/Tiles/Tiles.json" diff --git a/Scripts/Gamedata/DWearableSlots.gd b/Scripts/Gamedata/DWearableSlots.gd index e4a08535..815c44aa 100644 --- a/Scripts/Gamedata/DWearableSlots.gd +++ b/Scripts/Gamedata/DWearableSlots.gd @@ -12,9 +12,11 @@ var spritePath: String = "./Mods/Core/Wearableslots/" var wearableslotdict: Dictionary = {} var sprites: Dictionary = {} var references: Dictionary = {} +var mod_id: String = "Core" # Add a mod_id parameter to dynamically initialize paths -func _init(mod_id: String) -> void: +func _init(new_mod_id: String) -> void: + mod_id = new_mod_id # Update dataPath and spritePath using the provided mod_id dataPath = "./Mods/" + mod_id + "/Wearableslots/" filePath = "./Mods/" + mod_id + "/Wearableslots/Wearableslots.json" From cdbb15956bf9986cacb54fdda00c55a0c8ab9dbf Mon Sep 17 00:00:00 2001 From: snipercup <50166150+snipercup@users.noreply.github.com> Date: Sat, 14 Dec 2024 14:29:54 +0100 Subject: [PATCH 9/9] Allow duplication to other mods --- Scripts/Gamedata/DItemgroups.gd | 27 ++++++++++++++------- Scripts/Gamedata/DMobfactions.gd | 30 ++++++++++++++++------- Scripts/Gamedata/DMobgroups.gd | 31 +++++++++++++++++------- Scripts/Gamedata/DMobs.gd | 28 +++++++++++++++------- Scripts/Gamedata/DOvermapareas.gd | 32 +++++++++++++++++-------- Scripts/Gamedata/DPlayerAttributes.gd | 28 +++++++++++++++------- Scripts/Gamedata/DQuests.gd | 30 ++++++++++++++++------- Scripts/Gamedata/DSkills.gd | 31 ++++++++++++++++-------- Scripts/Gamedata/DStats.gd | 34 ++++++++++++++++++--------- Scripts/Gamedata/DTiles.gd | 28 +++++++++++++++------- Scripts/Gamedata/DWearableSlots.gd | 28 +++++++++++++++------- 11 files changed, 229 insertions(+), 98 deletions(-) diff --git a/Scripts/Gamedata/DItemgroups.gd b/Scripts/Gamedata/DItemgroups.gd index 4041e2ab..57d0ecd8 100644 --- a/Scripts/Gamedata/DItemgroups.gd +++ b/Scripts/Gamedata/DItemgroups.gd @@ -70,19 +70,30 @@ func get_all() -> Dictionary: return itemgroupdict -func duplicate_to_disk(itemgroupid: String, newitemgroupid: String) -> void: +# Duplicate the itemgroup to disk. A new mod id may be provided to save the duplicate to. +# itemgroupid: The itemgroup to duplicate. +# newitemgroupid: The id of the new duplicate (can be the same as itemgroupid if new_mod_id equals mod_id). +# new_mod_id: The id of the mod that the duplicate will be entered into. May differ from mod_id. +func duplicate_to_disk(itemgroupid: String, newitemgroupid: String, new_mod_id: String) -> void: + # Duplicate the itemgroup data and set the new id var itemgroupdata: Dictionary = by_id(itemgroupid).get_data().duplicate(true) - # A duplicated itemgroup is brand new and can't already be referenced by something - # So we delete the references from the duplicated data if it is present - itemgroupdata.erase("references") itemgroupdata.id = newitemgroupid - var newitemgroup: DItemgroup = DItemgroup.new(itemgroupdata, self) - itemgroupdict[newitemgroupid] = newitemgroup - save_itemgroups_to_disk() + + # Determine the new parent based on the new_mod_id + var newparent: DItemgroups = self if new_mod_id == mod_id else Gamedata.mods.by_id(new_mod_id).itemgroups + + # Instantiate and append the new DItemgroup instance + var newitemgroup: DItemgroup = DItemgroup.new(itemgroupdata, newparent) + newparent.append_new(newitemgroup) +# Add a new itemgroup to the dictionary and save it to disk. func add_new(newid: String) -> void: - var newitemgroup: DItemgroup = DItemgroup.new({"id":newid}, self) + append_new(DItemgroup.new({"id": newid}, self)) + + +# Append a new itemgroup to the dictionary and save it to disk. +func append_new(newitemgroup: DItemgroup) -> void: itemgroupdict[newitemgroup.id] = newitemgroup save_itemgroups_to_disk() diff --git a/Scripts/Gamedata/DMobfactions.gd b/Scripts/Gamedata/DMobfactions.gd index 766445df..86f02976 100644 --- a/Scripts/Gamedata/DMobfactions.gd +++ b/Scripts/Gamedata/DMobfactions.gd @@ -67,22 +67,34 @@ func save_mobfactions_to_disk() -> void: func get_all() -> Dictionary: return mobfactiondict -func duplicate_to_disk(mobfactionid: String, newmobfactionid: String) -> void: +# Duplicate the mobfaction to disk. A new mod id may be provided to save the duplicate to. +# mobfactionid: The mobfaction to duplicate. +# newmobfactionid: The id of the new duplicate (can be the same as mobfactionid if new_mod_id equals mod_id). +# new_mod_id: The id of the mod that the duplicate will be entered into. May differ from mod_id. +func duplicate_to_disk(mobfactionid: String, newmobfactionid: String, new_mod_id: String) -> void: + # Duplicate the mobfaction data and set the new id var mobfactiondata: Dictionary = by_id(mobfactionid).get_data().duplicate(true) - # A duplicated mob faction is brand new and can't already be referenced by something - # So we delete the references from the duplicated data if it is present - mobfactiondata.erase("references") mobfactiondata["id"] = newmobfactionid - var newmobfaction: DMobfaction = DMobfaction.new(mobfactiondata, self) - mobfactiondict[newmobfactionid] = newmobfaction - save_mobfactions_to_disk() -# Adds a new faction with a given ID + # Determine the new parent based on the new_mod_id + var newparent: DMobfactions = self if new_mod_id == mod_id else Gamedata.mods.by_id(new_mod_id).mobfactions + + # Instantiate and append the new DMobfaction instance + var newmobfaction: DMobfaction = DMobfaction.new(mobfactiondata, newparent) + newparent.append_new(newmobfaction) + + +# Add a new mobfaction with a given ID. func add_new(newid: String) -> void: - var newmobfaction: DMobfaction = DMobfaction.new({"id": newid}, self) + append_new(DMobfaction.new({"id": newid}, self)) + + +# Append a new mobfaction to the dictionary and save it to disk. +func append_new(newmobfaction: DMobfaction) -> void: mobfactiondict[newmobfaction.id] = newmobfaction save_mobfactions_to_disk() + # Deletes a faction by its ID and saves changes to disk func delete_by_id(mobfactionid: String) -> void: mobfactiondict[mobfactionid].delete() diff --git a/Scripts/Gamedata/DMobgroups.gd b/Scripts/Gamedata/DMobgroups.gd index 164fb428..f673ef9b 100644 --- a/Scripts/Gamedata/DMobgroups.gd +++ b/Scripts/Gamedata/DMobgroups.gd @@ -54,21 +54,34 @@ func save_mobgroups_to_disk() -> void: func get_all() -> Dictionary: return mobgroupdict -func duplicate_to_disk(mobgroupid: String, newmobgroupid: String) -> void: +# Duplicate the mobgroup to disk. A new mod id may be provided to save the duplicate to. +# mobgroupid: The mobgroup to duplicate. +# newmobgroupid: The id of the new duplicate (can be the same as mobgroupid if new_mod_id equals mod_id). +# new_mod_id: The id of the mod that the duplicate will be entered into. May differ from mod_id. +func duplicate_to_disk(mobgroupid: String, newmobgroupid: String, new_mod_id: String) -> void: + # Duplicate the mobgroup data and set the new id var mobgroupdata: Dictionary = by_id(mobgroupid).get_data().duplicate(true) - # A duplicated mob group is brand new and can't already be referenced by something - # So we delete the references from the duplicated data if it is present - mobgroupdata.erase("references") - mobgroupdata.id = newmobgroupid - var newmobgroup: DMobgroup = DMobgroup.new(mobgroupdata, self) - mobgroupdict[newmobgroupid] = newmobgroup - save_mobgroups_to_disk() + mobgroupdata["id"] = newmobgroupid + + # Determine the new parent based on the new_mod_id + var newparent: DMobgroups = self if new_mod_id == mod_id else Gamedata.mods.by_id(new_mod_id).mobgroups + + # Instantiate and append the new DMobgroup instance + var newmobgroup: DMobgroup = DMobgroup.new(mobgroupdata, newparent) + newparent.append_new(newmobgroup) + +# Add a new mobgroup with a given ID. func add_new(newid: String) -> void: - var newmobgroup: DMobgroup = DMobgroup.new({"id": newid}, self) + append_new(DMobgroup.new({"id": newid}, self)) + + +# Append a new mobgroup to the dictionary and save it to disk. +func append_new(newmobgroup: DMobgroup) -> void: mobgroupdict[newmobgroup.id] = newmobgroup save_mobgroups_to_disk() + func delete_by_id(mobgroupid: String) -> void: mobgroupdict[mobgroupid].delete() mobgroupdict.erase(mobgroupid) diff --git a/Scripts/Gamedata/DMobs.gd b/Scripts/Gamedata/DMobs.gd index 5ee0d778..7032a221 100644 --- a/Scripts/Gamedata/DMobs.gd +++ b/Scripts/Gamedata/DMobs.gd @@ -71,23 +71,35 @@ func get_all() -> Dictionary: return mobdict -func duplicate_to_disk(mobid: String, newmobid: String) -> void: +# Duplicate the mob to disk. A new mod id may be provided to save the duplicate to. +# mobid: The mob to duplicate. +# newmobid: The id of the new duplicate (can be the same as mobid if new_mod_id equals mod_id). +# new_mod_id: The id of the mod that the duplicate will be entered into. May differ from mod_id. +func duplicate_to_disk(mobid: String, newmobid: String, new_mod_id: String) -> void: + # Duplicate the mob data and set the new id var mobdata: Dictionary = by_id(mobid).get_data().duplicate(true) - # A duplicated mob is brand new and can't already be referenced by something - # So we delete the references from the duplicated data if it is present - mobdata.erase("references") mobdata.id = newmobid - var newmob: DMob = DMob.new(mobdata, self) - mobdict[newmobid] = newmob - save_mobs_to_disk() + + # Determine the new parent based on the new_mod_id + var newparent: DMobs = self if new_mod_id == mod_id else Gamedata.mods.by_id(new_mod_id).mobs + + # Instantiate and append the new DMob instance + var newmob: DMob = DMob.new(mobdata, newparent) + newparent.append_new(newmob) +# Add a new mob to the dictionary and save it to disk. func add_new(newid: String) -> void: - var newmob: DMob = DMob.new({"id":newid}, self) + append_new(DMob.new({"id": newid}, self)) + + +# Append a new mob to the dictionary and save it to disk. +func append_new(newmob: DMob) -> void: mobdict[newmob.id] = newmob save_mobs_to_disk() + func delete_by_id(mobid: String) -> void: mobdict[mobid].delete() mobdict.erase(mobid) diff --git a/Scripts/Gamedata/DOvermapareas.gd b/Scripts/Gamedata/DOvermapareas.gd index 75dea5b3..d9cc716a 100644 --- a/Scripts/Gamedata/DOvermapareas.gd +++ b/Scripts/Gamedata/DOvermapareas.gd @@ -53,22 +53,34 @@ func get_all() -> Dictionary: return overmapareadict # Duplicates a overmaparea and saves it to disk with a new ID -func duplicate_to_disk(overmapareaid: String, newovermapareaid: String) -> void: +# Duplicate the overmaparea to disk. A new mod id may be provided to save the duplicate to. +# overmapareaid: The overmaparea to duplicate. +# newovermapareaid: The id of the new duplicate (can be the same as overmapareaid if new_mod_id equals mod_id). +# new_mod_id: The id of the mod that the duplicate will be entered into. May differ from mod_id. +func duplicate_to_disk(overmapareaid: String, newovermapareaid: String, new_mod_id: String) -> void: + # Duplicate the overmaparea data and set the new id var overmapareadata: Dictionary = by_id(overmapareaid).get_data().duplicate(true) - # A duplicated overmaparea is brand new and can't already be referenced by something - # So we delete the references from the duplicated data if it is present - overmapareadata.erase("references") - overmapareadata.id = newovermapareaid - var newovermaparea: DOvermaparea = DOvermaparea.new(overmapareadata, self) - overmapareadict[newovermapareaid] = newovermaparea - save_overmapareas_to_disk() + overmapareadata["id"] = newovermapareaid + + # Determine the new parent based on the new_mod_id + var newparent: DOvermapareas = self if new_mod_id == mod_id else Gamedata.mods.by_id(new_mod_id).overmapareas + + # Instantiate and append the new DOvermaparea instance + var newovermaparea: DOvermaparea = DOvermaparea.new(overmapareadata, newparent) + newparent.append_new(newovermaparea) + -# Adds a new overmaparea with a given ID +# Add a new overmaparea with a given ID. func add_new(newid: String) -> void: - var newovermaparea: DOvermaparea = DOvermaparea.new({"id": newid}, self) + append_new(DOvermaparea.new({"id": newid}, self)) + + +# Append a new overmaparea to the dictionary and save it to disk. +func append_new(newovermaparea: DOvermaparea) -> void: overmapareadict[newovermaparea.id] = newovermaparea save_overmapareas_to_disk() + # Deletes a overmaparea by its ID and saves changes to disk func delete_by_id(overmapareaid: String) -> void: overmapareadict[overmapareaid].delete() diff --git a/Scripts/Gamedata/DPlayerAttributes.gd b/Scripts/Gamedata/DPlayerAttributes.gd index e0521d77..8ab04723 100644 --- a/Scripts/Gamedata/DPlayerAttributes.gd +++ b/Scripts/Gamedata/DPlayerAttributes.gd @@ -72,23 +72,35 @@ func get_all() -> Dictionary: return playerattributedict -func duplicate_to_disk(playerattributeid: String, newplayerattributeid: String) -> void: +# Duplicate the player attribute to disk. A new mod id may be provided to save the duplicate to. +# playerattributeid: The player attribute to duplicate. +# newplayerattributeid: The id of the new duplicate (can be the same as playerattributeid if new_mod_id equals mod_id). +# new_mod_id: The id of the mod that the duplicate will be entered into. May differ from mod_id. +func duplicate_to_disk(playerattributeid: String, newplayerattributeid: String, new_mod_id: String) -> void: + # Duplicate the player attribute data and set the new id var playerattributedata: Dictionary = by_id(playerattributeid).get_data().duplicate(true) - # A duplicated playerattribute is brand new and can't already be referenced by something - # So we delete the references from the duplicated data if it is present - playerattributedata.erase("references") playerattributedata.id = newplayerattributeid - var newplayerattribute: DPlayerAttribute = DPlayerAttribute.new(playerattributedata, self) - playerattributedict[newplayerattributeid] = newplayerattribute - save_playerattributes_to_disk() + + # Determine the new parent based on the new_mod_id + var newparent: DPlayerAttributes = self if new_mod_id == mod_id else Gamedata.mods.by_id(new_mod_id).playerattributes + + # Instantiate and append the new DPlayerAttribute instance + var newplayerattribute: DPlayerAttribute = DPlayerAttribute.new(playerattributedata, newparent) + newparent.append_new(newplayerattribute) +# Add a new player attribute to the dictionary and save it to disk. func add_new(newid: String) -> void: - var newplayerattribute: DPlayerAttribute = DPlayerAttribute.new({"id":newid}, self) + append_new(DPlayerAttribute.new({"id": newid}, self)) + + +# Append a new player attribute to the dictionary and save it to disk. +func append_new(newplayerattribute: DPlayerAttribute) -> void: playerattributedict[newplayerattribute.id] = newplayerattribute save_playerattributes_to_disk() + func delete_by_id(playerattributeid: String) -> void: playerattributedict[playerattributeid].delete() playerattributedict.erase(playerattributeid) diff --git a/Scripts/Gamedata/DQuests.gd b/Scripts/Gamedata/DQuests.gd index 30c58df3..a7288a33 100644 --- a/Scripts/Gamedata/DQuests.gd +++ b/Scripts/Gamedata/DQuests.gd @@ -61,22 +61,34 @@ func get_all() -> Dictionary: return questdict # Duplicates a quest and saves it to disk with a new ID -func duplicate_to_disk(questid: String, newquestid: String) -> void: +# Duplicate the quest to disk. A new mod id may be provided to save the duplicate to. +# questid: The quest to duplicate. +# newquestid: The id of the new duplicate (can be the same as questid if new_mod_id equals mod_id). +# new_mod_id: The id of the mod that the duplicate will be entered into. May differ from mod_id. +func duplicate_to_disk(questid: String, newquestid: String, new_mod_id: String) -> void: + # Duplicate the quest data and set the new id var questdata: Dictionary = by_id(questid).get_data().duplicate(true) - # A duplicated quest is brand new and can't already be referenced by something - # So we delete the references from the duplicated data if it is present - questdata.erase("references") questdata["id"] = newquestid - var newquest: DQuest = DQuest.new(questdata, self) - questdict[newquestid] = newquest - save_quests_to_disk() -# Adds a new quest with a given ID + # Determine the new parent based on the new_mod_id + var newparent: DQuests = self if new_mod_id == mod_id else Gamedata.mods.by_id(new_mod_id).quests + + # Instantiate and append the new DQuest instance + var newquest: DQuest = DQuest.new(questdata, newparent) + newparent.append_new(newquest) + + +# Add a new quest with a given ID. func add_new(newid: String) -> void: - var newquest: DQuest = DQuest.new({"id": newid}, self) + append_new(DQuest.new({"id": newid}, self)) + + +# Append a new quest to the dictionary and save it to disk. +func append_new(newquest: DQuest) -> void: questdict[newquest.id] = newquest save_quests_to_disk() + # Deletes a quest by its ID and saves changes to disk func delete_by_id(questid: String) -> void: questdict[questid].delete() diff --git a/Scripts/Gamedata/DSkills.gd b/Scripts/Gamedata/DSkills.gd index 3ea8c1a4..8bfe25a5 100644 --- a/Scripts/Gamedata/DSkills.gd +++ b/Scripts/Gamedata/DSkills.gd @@ -71,23 +71,34 @@ func save_skills_to_disk() -> void: func get_all() -> Dictionary: return skilldict -# Duplicates a skill and saves it to disk with a new ID -func duplicate_to_disk(skillid: String, newskillid: String) -> void: +# Duplicate the skill to disk. A new mod id may be provided to save the duplicate to. +# skillid: The skill to duplicate. +# newskillid: The id of the new duplicate (can be the same as skillid if new_mod_id equals mod_id). +# new_mod_id: The id of the mod that the duplicate will be entered into. May differ from mod_id. +func duplicate_to_disk(skillid: String, newskillid: String, new_mod_id: String) -> void: + # Duplicate the skill data and set the new id var skilldata: Dictionary = by_id(skillid).get_data().duplicate(true) - # A duplicated quest is brand new and can't already be referenced by something - # So we delete the references from the duplicated data if it is present - skilldata.erase("references") skilldata["id"] = newskillid - var newskill: DSkill = DSkill.new(skilldata, self) - skilldict[newskillid] = newskill - save_skills_to_disk() -# Adds a new skill with a given ID + # Determine the new parent based on the new_mod_id + var newparent: DSkills = self if new_mod_id == mod_id else Gamedata.mods.by_id(new_mod_id).skills + + # Instantiate and append the new DSkill instance + var newskill: DSkill = DSkill.new(skilldata, newparent) + newparent.append_new(newskill) + + +# Add a new skill with a given ID. func add_new(newid: String) -> void: - var newskill: DSkill = DSkill.new({"id": newid}, self) + append_new(DSkill.new({"id": newid}, self)) + + +# Append a new skill to the dictionary and save it to disk. +func append_new(newskill: DSkill) -> void: skilldict[newskill.id] = newskill save_skills_to_disk() + # Deletes a skill by its ID and saves changes to disk func delete_by_id(skillid: String) -> void: skilldict[skillid].delete() diff --git a/Scripts/Gamedata/DStats.gd b/Scripts/Gamedata/DStats.gd index d613e75e..16e24fe9 100644 --- a/Scripts/Gamedata/DStats.gd +++ b/Scripts/Gamedata/DStats.gd @@ -57,23 +57,35 @@ func save_stats_to_disk() -> void: func get_all() -> Dictionary: return statdict -# Duplicates a stat and saves it to disk with a new ID -func duplicate_to_disk(statid: String, newstatid: String) -> void: + +# Duplicate the stat to disk. A new mod id may be provided to save the duplicate to. +# statid: The stat to duplicate. +# newstatid: The id of the new duplicate (can be the same as statid if new_mod_id equals mod_id). +# new_mod_id: The id of the mod that the duplicate will be entered into. May differ from mod_id. +func duplicate_to_disk(statid: String, newstatid: String, new_mod_id: String) -> void: + # Duplicate the stat data and set the new id var statdata: Dictionary = by_id(statid).get_data().duplicate(true) - # A duplicated stat is brand new and can't already be referenced by something - # So we delete the references from the duplicated data if it is present - statdata.erase("references") - statdata.id = newstatid - var newstat: DStat = DStat.new(statdata, self) - statdict[newstatid] = newstat - save_stats_to_disk() + statdata["id"] = newstatid + + # Determine the new parent based on the new_mod_id + var newparent: DStats = self if new_mod_id == mod_id else Gamedata.mods.by_id(new_mod_id).stats + + # Instantiate and append the new DStat instance + var newstat: DStat = DStat.new(statdata, newparent) + newparent.append_new(newstat) -# Adds a new stat with a given ID + +# Add a new stat with a given ID. func add_new(newid: String) -> void: - var newstat: DStat = DStat.new({"id": newid}, self) + append_new(DStat.new({"id": newid}, self)) + + +# Append a new stat to the dictionary and save it to disk. +func append_new(newstat: DStat) -> void: statdict[newstat.id] = newstat save_stats_to_disk() + # Deletes a stat by its ID and saves changes to disk func delete_by_id(statid: String) -> void: statdict[statid].delete() diff --git a/Scripts/Gamedata/DTiles.gd b/Scripts/Gamedata/DTiles.gd index 06d19d7b..765c8218 100644 --- a/Scripts/Gamedata/DTiles.gd +++ b/Scripts/Gamedata/DTiles.gd @@ -72,23 +72,35 @@ func get_all() -> Dictionary: return tiledict -func duplicate_to_disk(tileid: String, newtileid: String) -> void: +# Duplicate the tile to disk. A new mod id may be provided to save the duplicate to. +# tileid: The tile to duplicate. +# newtileid: The id of the new duplicate (can be the same as tileid if new_mod_id equals mod_id). +# new_mod_id: The id of the mod that the duplicate will be entered into. May differ from mod_id. +func duplicate_to_disk(tileid: String, newtileid: String, new_mod_id: String) -> void: + # Duplicate the tile data and set the new id var tiledata: Dictionary = by_id(tileid).get_data().duplicate(true) - # A duplicated tile is brand new and can't already be referenced by something - # So we delete the references from the duplicated data if it is present - tiledata.erase("references") tiledata.id = newtileid - var newtile: DTile = DTile.new(tiledata, self) - tiledict[newtileid] = newtile - save_tiles_to_disk() + + # Determine the new parent based on the new_mod_id + var newparent: DTiles = self if new_mod_id == mod_id else Gamedata.mods.by_id(new_mod_id).tiles + + # Instantiate and append the new DTile instance + var newtile: DTile = DTile.new(tiledata, newparent) + newparent.append_new(newtile) +# Add a new tile to the dictionary and save it to disk. func add_new(newid: String) -> void: - var newtile: DTile = DTile.new({"id":newid}, self) + append_new(DTile.new({"id": newid}, self)) + + +# Append a new tile to the dictionary and save it to disk. +func append_new(newtile: DTile) -> void: tiledict[newtile.id] = newtile save_tiles_to_disk() + func delete_by_id(tileid: String) -> void: tiledict[tileid].delete() tiledict.erase(tileid) diff --git a/Scripts/Gamedata/DWearableSlots.gd b/Scripts/Gamedata/DWearableSlots.gd index 815c44aa..a9ca31b2 100644 --- a/Scripts/Gamedata/DWearableSlots.gd +++ b/Scripts/Gamedata/DWearableSlots.gd @@ -70,23 +70,35 @@ func get_all() -> Dictionary: return wearableslotdict -func duplicate_to_disk(wearableslotid: String, newwearableslotid: String) -> void: +# Duplicate the wearable slot to disk. A new mod id may be provided to save the duplicate to. +# wearableslotid: The wearable slot to duplicate. +# newwearableslotid: The id of the new duplicate (can be the same as wearableslotid if new_mod_id equals mod_id). +# new_mod_id: The id of the mod that the duplicate will be entered into. May differ from mod_id. +func duplicate_to_disk(wearableslotid: String, newwearableslotid: String, new_mod_id: String) -> void: + # Duplicate the wearable slot data and set the new id var wearableslotdata: Dictionary = by_id(wearableslotid).get_data().duplicate(true) - # A duplicated wearableslot is brand new and can't already be referenced by something - # So we delete the references from the duplicated data if it is present - wearableslotdata.erase("references") wearableslotdata.id = newwearableslotid - var newwearableslot: DWearableSlot = DWearableSlot.new(wearableslotdata, self) - wearableslotdict[newwearableslotid] = newwearableslot - save_wearableslots_to_disk() + + # Determine the new parent based on the new_mod_id + var newparent: DWearableSlots = self if new_mod_id == mod_id else Gamedata.mods.by_id(new_mod_id).wearableslots + + # Instantiate and append the new DWearableSlot instance + var newwearableslot: DWearableSlot = DWearableSlot.new(wearableslotdata, newparent) + newparent.append_new(newwearableslot) +# Add a new wearable slot to the dictionary and save it to disk. func add_new(newid: String) -> void: - var newwearableslot: DWearableSlot = DWearableSlot.new({"id":newid}, self) + append_new(DWearableSlot.new({"id": newid}, self)) + + +# Append a new wearable slot to the dictionary and save it to disk. +func append_new(newwearableslot: DWearableSlot) -> void: wearableslotdict[newwearableslot.id] = newwearableslot save_wearableslots_to_disk() + func delete_by_id(wearableslotid: String) -> void: wearableslotdict[wearableslotid].delete() wearableslotdict.erase(wearableslotid)