Clean up what the AI did
This commit is contained in:
+13
-24
@@ -17,6 +17,13 @@ func _ready() -> void:
|
|||||||
if not _food_item:
|
if not _food_item:
|
||||||
push_error("CombinableItem is missing FoodItem reference. must be a sibling of a FoodItem on ", get_parent().name, ".")
|
push_error("CombinableItem is missing FoodItem reference. must be a sibling of a FoodItem on ", get_parent().name, ".")
|
||||||
|
|
||||||
|
if not _pickable:
|
||||||
|
push_error("CombineZone must be a grand child of an XRToolsPickable.")
|
||||||
|
return
|
||||||
|
if not _food_item:
|
||||||
|
push_error("CombineZone requires a FoodItem sibling on ", _pickable.name, ".")
|
||||||
|
return
|
||||||
|
|
||||||
# Detect items whether held (layer 17 "Held Objects") or loose
|
# Detect items whether held (layer 17 "Held Objects") or loose
|
||||||
# (layer 3 "Pickable Objects"). Don't advertise a layer of our own.
|
# (layer 3 "Pickable Objects"). Don't advertise a layer of our own.
|
||||||
combine_area_3d.collision_mask = 0b0000_0000_0000_0001_0000_0000_0000_0100
|
combine_area_3d.collision_mask = 0b0000_0000_0000_0001_0000_0000_0000_0100
|
||||||
@@ -26,40 +33,22 @@ func _ready() -> void:
|
|||||||
set_deferred("monitoring", false)
|
set_deferred("monitoring", false)
|
||||||
set_deferred("monitorable", false)
|
set_deferred("monitorable", false)
|
||||||
|
|
||||||
if not _pickable:
|
# Signals
|
||||||
push_error("CombineZone must be a grand child of an XRToolsPickable.")
|
|
||||||
return
|
|
||||||
if not _food_item:
|
|
||||||
push_error("CombineZone requires a FoodItem sibling on ", _pickable.name, ".")
|
|
||||||
return
|
|
||||||
|
|
||||||
_pickable.picked_up.connect(_on_item_picked_up)
|
_pickable.picked_up.connect(_on_item_picked_up)
|
||||||
_pickable.dropped.connect(_on_item_dropped)
|
_pickable.dropped.connect(_on_item_dropped)
|
||||||
combine_area_3d.body_entered.connect(_on_body_entered)
|
combine_area_3d.body_entered.connect(_on_body_entered)
|
||||||
|
|
||||||
|
|
||||||
func get_result_for(other_id: StringName) -> PackedScene:
|
|
||||||
return RECIPE_MANAGER.get_combination(_food_item.id, other_id)
|
|
||||||
|
|
||||||
|
|
||||||
## Trigger area that lets a snapped item combine with another item pushed into
|
|
||||||
## it. The zone only monitors while its owning item is held by an
|
|
||||||
## [XRToolsSnapZone]; when an item carrying a matching [FoodItem.id]
|
|
||||||
## enters, the snapped (base) item transforms into the recipe result and the
|
|
||||||
## incoming item is consumed.
|
|
||||||
|
|
||||||
|
|
||||||
# Enable the trigger only while snapped into a snap zone (not hand-held).
|
# Enable the trigger only while snapped into a snap zone (not hand-held).
|
||||||
func _on_item_picked_up(_item: Node3D) -> void:
|
func _on_item_picked_up(_item: Node3D) -> void:
|
||||||
var by := _pickable.get_picked_up_by()
|
var by := _pickable.get_picked_up_by()
|
||||||
var snapped: bool = by != null and by.has_method("is_xr_class") and by.is_xr_class("XRToolsSnapZone")
|
var snapped: bool = by != null and by.has_method("is_xr_class") and by.is_xr_class("XRToolsSnapZone")
|
||||||
set_deferred("monitoring", snapped)
|
set_deferred("monitoring", snapped)
|
||||||
|
|
||||||
|
|
||||||
func _on_item_dropped(_item: Node3D) -> void:
|
func _on_item_dropped(_item: Node3D) -> void:
|
||||||
set_deferred("monitoring", false)
|
set_deferred("monitoring", false)
|
||||||
|
|
||||||
|
# If the other body is a FoodItem, check for a recipe and combine if one exists.
|
||||||
func _on_body_entered(body: Node3D) -> void:
|
func _on_body_entered(body: Node3D) -> void:
|
||||||
print("CombinableItem _on_body_entered")
|
print("CombinableItem _on_body_entered")
|
||||||
if _combining or body == _pickable:
|
if _combining or body == _pickable:
|
||||||
@@ -78,12 +67,12 @@ func _on_body_entered(body: Node3D) -> void:
|
|||||||
|
|
||||||
_combine(body, result)
|
_combine(body, result)
|
||||||
|
|
||||||
|
# Instantiate the result of combination and free the two ingredient items
|
||||||
# Transform the base item into [param result], consuming the incoming item.
|
|
||||||
func _combine(other_body: Node3D, result: PackedScene) -> void:
|
func _combine(other_body: Node3D, result: PackedScene) -> void:
|
||||||
print("CombinableItem _combine: combining %s + %s into %s" % [_food_item.id, _find_food_item(other_body).id, result.resource_path])
|
print("CombinableItem _combine: combining %s + %s into %s" % [_food_item.id, _find_food_item(other_body).id, result.resource_path])
|
||||||
_combining = true
|
_combining = true
|
||||||
|
|
||||||
|
# Get Snapzone
|
||||||
var snap_zone := _pickable.get_picked_up_by()
|
var snap_zone := _pickable.get_picked_up_by()
|
||||||
if not snap_zone or not snap_zone.has_method("pick_up_object"):
|
if not snap_zone or not snap_zone.has_method("pick_up_object"):
|
||||||
push_warning("CombineZone: base item is not held by a snap zone; cannot combine.")
|
push_warning("CombineZone: base item is not held by a snap zone; cannot combine.")
|
||||||
@@ -96,10 +85,10 @@ func _combine(other_body: Node3D, result: PackedScene) -> void:
|
|||||||
_pickable.get_tree().current_scene.add_child(result_instance)
|
_pickable.get_tree().current_scene.add_child(result_instance)
|
||||||
result_instance.global_transform = base_transform
|
result_instance.global_transform = base_transform
|
||||||
|
|
||||||
# Free the base item and consume the incoming item.
|
# Free the pickable / root of this item and consume the incoming item.
|
||||||
snap_zone.drop_object()
|
snap_zone.drop_object()
|
||||||
_pickable.queue_free()
|
_pickable.queue_free()
|
||||||
if other_body.has_method("drop_and_free"):
|
if other_body.has_method("drop_and_free"): # XRToolsPickable has this method
|
||||||
other_body.drop_and_free()
|
other_body.drop_and_free()
|
||||||
else:
|
else:
|
||||||
other_body.queue_free()
|
other_body.queue_free()
|
||||||
|
|||||||
+9
-81
@@ -3,7 +3,7 @@ extends Node
|
|||||||
|
|
||||||
static var _recipes: Dictionary = {}
|
static var _recipes: Dictionary = {}
|
||||||
static var _combining_map: Dictionary = {}
|
static var _combining_map: Dictionary = {}
|
||||||
static var _scene_paths: Dictionary = {}
|
static var _scene_paths: Dictionary
|
||||||
static var _loaded: bool = false
|
static var _loaded: bool = false
|
||||||
|
|
||||||
static func load_recipes() -> void:
|
static func load_recipes() -> void:
|
||||||
@@ -20,25 +20,14 @@ static func load_recipes() -> void:
|
|||||||
var result = ClassDB.class_call_static("YAML", "load_file", recipe_path)
|
var result = ClassDB.class_call_static("YAML", "load_file", recipe_path)
|
||||||
if result != null and not result.has_error():
|
if result != null and not result.has_error():
|
||||||
var data = result.get_data()
|
var data = result.get_data()
|
||||||
if typeof(data) == TYPE_DICTIONARY:
|
if typeof(data) != TYPE_DICTIONARY:
|
||||||
|
push_warning("RecipeManager: YAML addon parsed recipes.yaml but returned an unsupported structure")
|
||||||
|
|
||||||
_recipes = data
|
_recipes = data
|
||||||
_build_scene_paths()
|
_build_scene_paths()
|
||||||
_build_combining_map()
|
_build_combining_map()
|
||||||
_loaded = true
|
_loaded = true
|
||||||
return
|
|
||||||
push_warning("RecipeManager: YAML addon parsed recipes.yaml but returned an unsupported structure; falling back to built-in parser")
|
|
||||||
else:
|
|
||||||
push_warning("RecipeManager: YAML addon failed to read %s; falling back to built-in parser: %s" % [recipe_path, result.get_error() if result != null else "unknown error"])
|
|
||||||
|
|
||||||
var fallback_data = _load_recipes_with_fallback_parser(recipe_path)
|
|
||||||
if typeof(fallback_data) != TYPE_DICTIONARY:
|
|
||||||
push_error("RecipeManager: failed to parse recipes.yaml with both YAML addon and built-in fallback")
|
|
||||||
return
|
|
||||||
|
|
||||||
_recipes = fallback_data
|
|
||||||
_build_scene_paths()
|
|
||||||
_build_combining_map()
|
|
||||||
_loaded = true
|
|
||||||
|
|
||||||
static func get_combination(first_id: StringName, second_id: StringName) -> PackedScene:
|
static func get_combination(first_id: StringName, second_id: StringName) -> PackedScene:
|
||||||
load_recipes()
|
load_recipes()
|
||||||
@@ -47,6 +36,7 @@ static func get_combination(first_id: StringName, second_id: StringName) -> Pack
|
|||||||
return null
|
return null
|
||||||
return get_item_scene(result_id)
|
return get_item_scene(result_id)
|
||||||
|
|
||||||
|
|
||||||
static func get_item_scene(item_id: StringName) -> PackedScene:
|
static func get_item_scene(item_id: StringName) -> PackedScene:
|
||||||
load_recipes()
|
load_recipes()
|
||||||
var scene_path = _scene_paths.get(str(item_id), "")
|
var scene_path = _scene_paths.get(str(item_id), "")
|
||||||
@@ -60,6 +50,7 @@ static func get_item_scene(item_id: StringName) -> PackedScene:
|
|||||||
return null
|
return null
|
||||||
return scene as PackedScene
|
return scene as PackedScene
|
||||||
|
|
||||||
|
|
||||||
static func print_all_recipes() -> void:
|
static func print_all_recipes() -> void:
|
||||||
load_recipes()
|
load_recipes()
|
||||||
if not _loaded:
|
if not _loaded:
|
||||||
@@ -91,72 +82,6 @@ static func print_all_recipes() -> void:
|
|||||||
else:
|
else:
|
||||||
print("RecipeManager: invalid combining recipe for '%s'" % result_id)
|
print("RecipeManager: invalid combining recipe for '%s'" % result_id)
|
||||||
|
|
||||||
static func _load_recipes_with_fallback_parser(recipe_path: String) -> Dictionary:
|
|
||||||
var file := FileAccess.open(recipe_path, FileAccess.READ)
|
|
||||||
if file == null:
|
|
||||||
push_error("RecipeManager: could not open %s: %s" % [recipe_path, FileAccess.get_open_error()])
|
|
||||||
return {}
|
|
||||||
|
|
||||||
var lines := file.get_as_text().split("\n")
|
|
||||||
var result := {
|
|
||||||
"items": {},
|
|
||||||
"combining": {}
|
|
||||||
}
|
|
||||||
var current_section := ""
|
|
||||||
var current_result_id := ""
|
|
||||||
var current_item_id := ""
|
|
||||||
var current_item_def: Dictionary = {}
|
|
||||||
|
|
||||||
for line in lines:
|
|
||||||
var trimmed := line.strip_edges()
|
|
||||||
if trimmed.is_empty() or trimmed.begins_with("#"):
|
|
||||||
continue
|
|
||||||
|
|
||||||
var indent := line.length() - line.lstrip(" \t").length()
|
|
||||||
if indent == 0:
|
|
||||||
current_section = ""
|
|
||||||
current_result_id = ""
|
|
||||||
current_item_id = ""
|
|
||||||
if trimmed == "items:":
|
|
||||||
current_section = "items"
|
|
||||||
elif trimmed == "combining:":
|
|
||||||
current_section = "combining"
|
|
||||||
continue
|
|
||||||
|
|
||||||
if current_section == "items":
|
|
||||||
if indent == 2 and trimmed.ends_with(":"):
|
|
||||||
current_item_id = trimmed.trim_suffix(":")
|
|
||||||
current_item_def = {}
|
|
||||||
result["items"][current_item_id] = current_item_def
|
|
||||||
continue
|
|
||||||
|
|
||||||
if indent >= 4 and not current_item_id.is_empty():
|
|
||||||
var parts := trimmed.split(":", true, 1)
|
|
||||||
if parts.size() == 2:
|
|
||||||
var key := parts[0].strip_edges()
|
|
||||||
var value := parts[1].strip_edges()
|
|
||||||
current_item_def[key] = value
|
|
||||||
continue
|
|
||||||
|
|
||||||
if current_section == "combining":
|
|
||||||
if indent == 2 and trimmed.ends_with(":"):
|
|
||||||
current_result_id = trimmed.trim_suffix(":")
|
|
||||||
result["combining"][current_result_id] = []
|
|
||||||
continue
|
|
||||||
|
|
||||||
if trimmed.begins_with("- ") and not current_result_id.is_empty():
|
|
||||||
var item_text := trimmed.substr(2).strip_edges()
|
|
||||||
if item_text.begins_with("[") and item_text.ends_with("]"):
|
|
||||||
var inner := item_text.substr(1, item_text.length() - 2).strip_edges()
|
|
||||||
var parts := inner.split(",", false)
|
|
||||||
var recipe := []
|
|
||||||
for part in parts:
|
|
||||||
recipe.append(part.strip_edges())
|
|
||||||
result["combining"][current_result_id].append(recipe)
|
|
||||||
else:
|
|
||||||
result["combining"][current_result_id].append([item_text])
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
static func _build_scene_paths() -> void:
|
static func _build_scene_paths() -> void:
|
||||||
_scene_paths.clear()
|
_scene_paths.clear()
|
||||||
@@ -171,6 +96,7 @@ static func _build_scene_paths() -> void:
|
|||||||
if typeof(scene_path) == TYPE_STRING and not scene_path.is_empty():
|
if typeof(scene_path) == TYPE_STRING and not scene_path.is_empty():
|
||||||
_scene_paths[str(item_id)] = scene_path
|
_scene_paths[str(item_id)] = scene_path
|
||||||
|
|
||||||
|
|
||||||
static func _get_recipe_entries(recipe_value: Variant) -> Array:
|
static func _get_recipe_entries(recipe_value: Variant) -> Array:
|
||||||
var recipes: Array = []
|
var recipes: Array = []
|
||||||
if typeof(recipe_value) != TYPE_ARRAY:
|
if typeof(recipe_value) != TYPE_ARRAY:
|
||||||
@@ -186,6 +112,7 @@ static func _get_recipe_entries(recipe_value: Variant) -> Array:
|
|||||||
recipes.append(recipe_value)
|
recipes.append(recipe_value)
|
||||||
return recipes
|
return recipes
|
||||||
|
|
||||||
|
|
||||||
static func _build_combining_map() -> void:
|
static func _build_combining_map() -> void:
|
||||||
_combining_map.clear()
|
_combining_map.clear()
|
||||||
var combining = _recipes.get("combining", {})
|
var combining = _recipes.get("combining", {})
|
||||||
@@ -200,6 +127,7 @@ static func _build_combining_map() -> void:
|
|||||||
var key = _make_pair_key(first, second)
|
var key = _make_pair_key(first, second)
|
||||||
_combining_map[key] = result_id
|
_combining_map[key] = result_id
|
||||||
|
|
||||||
|
|
||||||
static func _make_pair_key(first_id: StringName, second_id: StringName) -> StringName:
|
static func _make_pair_key(first_id: StringName, second_id: StringName) -> StringName:
|
||||||
if str(first_id) <= str(second_id):
|
if str(first_id) <= str(second_id):
|
||||||
return StringName(str(first_id) + "|" + str(second_id))
|
return StringName(str(first_id) + "|" + str(second_id))
|
||||||
|
|||||||
+1
-5
@@ -1,19 +1,14 @@
|
|||||||
items:
|
items:
|
||||||
hamburger:
|
hamburger:
|
||||||
scene: res://Items/hamburger.tscn
|
scene: res://Items/hamburger.tscn
|
||||||
type: meal
|
|
||||||
burger_buns:
|
burger_buns:
|
||||||
scene: res://Items/BurgerBuns.tscn
|
scene: res://Items/BurgerBuns.tscn
|
||||||
type: ingredient
|
|
||||||
cooked_burger:
|
cooked_burger:
|
||||||
scene: res://Items/cooked_burger.tscn
|
scene: res://Items/cooked_burger.tscn
|
||||||
type: ingredient
|
|
||||||
cube:
|
cube:
|
||||||
scene: res://Items/PickupCube.tscn
|
scene: res://Items/PickupCube.tscn
|
||||||
type: ingredient
|
|
||||||
charcoal:
|
charcoal:
|
||||||
scene: res://Items/Charcoal.tscn
|
scene: res://Items/Charcoal.tscn
|
||||||
type: ingredient
|
|
||||||
|
|
||||||
combining:
|
combining:
|
||||||
hamburger:
|
hamburger:
|
||||||
@@ -21,3 +16,4 @@ combining:
|
|||||||
- [charcoal, charcoal]
|
- [charcoal, charcoal]
|
||||||
charcoal:
|
charcoal:
|
||||||
- [cube, cube]
|
- [cube, cube]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user