feat: unify authored activity commands

This commit is contained in:
Rijad Zuzo
2026-08-13 00:08:30 +02:00
parent e5aecee0de
commit b3b98c6456
36 changed files with 3013 additions and 96 deletions
+68 -31
View File
@@ -117,16 +117,8 @@ func try_interact() -> void:
_execute_animal_interaction(context)
PlayerInteractionResult.KIND_RESOURCE:
_execute_resource_interaction(context)
PlayerInteractionResult.KIND_GUARD:
simulation_manager.add_safety(3.0)
interaction_feedback.emit(
"Village guarded", "Safety increased through real guard-post work.", true
)
PlayerInteractionResult.KIND_STUDY:
simulation_manager.add_knowledge(2.0)
interaction_feedback.emit(
"Knowledge shared", "Village knowledge increased at the study desk.", true
)
PlayerInteractionResult.KIND_ACTIVITY:
_execute_activity_interaction(context)
PlayerInteractionResult.KIND_PANTRY:
_execute_pantry_interaction(context)
PlayerInteractionResult.KIND_STORAGE_DEPOSIT:
@@ -153,26 +145,34 @@ func get_interaction_context() -> PlayerInteractionResult:
var resource := _find_resource_node()
if resource != null:
return _build_resource_context(resource)
if is_near_activity_site(guard_site):
return PlayerInteractionResult.new(
PlayerInteractionResult.KIND_GUARD,
SimulationIds.ACTION_PATROL,
guard_site.site_id,
guard_site.display_name,
"Help guard the village",
"Work here · +3 safety",
guard_site
)
if is_near_activity_site(study_site):
return PlayerInteractionResult.new(
PlayerInteractionResult.KIND_STUDY,
SimulationIds.ACTION_STUDY,
study_site.site_id,
study_site.display_name,
"Share knowledge",
"Work here · +2 knowledge",
study_site
if simulation_manager.has_method("get_player_activity_offer"):
var activity_offer: Dictionary = simulation_manager.call(
"get_player_activity_offer", global_position, interaction_range
)
if not activity_offer.is_empty():
var effect: Dictionary = activity_offer.get("effect", {})
var amount := float(effect.get("amount", 0.0))
var metric_name := String(effect.get("metric_id", "benefit")).capitalize()
return (
PlayerInteractionResult
. new(
PlayerInteractionResult.KIND_ACTIVITY,
StringName(activity_offer["action_id"]),
StringName(activity_offer["target_id"]),
String(activity_offer["display_name"]),
String(activity_offer["action_name"]),
"Work here · +%.1f %s" % [amount, metric_name.to_lower()],
null,
{
"blocked_reason": String(activity_offer.get("blocked_reason", "")),
"expected_state_revision": int(activity_offer.get("state_revision", -1)),
"target_generation": int(activity_offer.get("target_generation", -1)),
"target_context_id": String(activity_offer.get("target_context_id", "")),
"target_registry_instance_id":
int(activity_offer.get("target_registry_instance_id", 0)),
}
)
)
if is_near_storage(pantry_storage):
if _get_carried_food() > 0.0:
return _build_deposit_context(SimulationIds.RESOURCE_FOOD, pantry_storage)
@@ -429,7 +429,7 @@ func _build_animal_context(node: AnimalNode) -> PlayerInteractionResult:
"Feed %s" % node.display_name,
detail,
node,
blocked_reason
{"blocked_reason": blocked_reason}
)
@@ -469,7 +469,7 @@ func _build_pantry_context() -> PlayerInteractionResult:
"Eat from the pantry",
detail,
pantry_storage,
blocked_reason
{"blocked_reason": blocked_reason}
)
@@ -545,6 +545,43 @@ func _execute_resource_interaction(context: PlayerInteractionResult) -> void:
)
func _execute_activity_interaction(context: PlayerInteractionResult) -> void:
if not context.is_available():
interaction_feedback.emit(
"%s unavailable" % context.display_name, context.blocked_reason, false
)
return
if not simulation_manager.has_method("execute_player_activity_action"):
push_error("Player: SimulationManager cannot execute authored activity actions")
return
if simulation_manager.has_method("update_player_combatant"):
simulation_manager.call("update_player_combatant", global_position)
var result := (
simulation_manager.call(
"execute_player_activity_action",
context.action_id,
context.target_id,
context.expected_state_revision,
context.target_generation,
context.target_context_id,
context.target_registry_instance_id
)
as ActionResult
)
if result == null or not result.did_succeed():
var reason := result.get_message() if result != null else "Activity service unavailable."
interaction_feedback.emit("%s unavailable" % context.display_name, reason, false)
return
var payload := result.get_payload()
var amount := float(payload.get("amount", 0.0))
var metric_name := String(payload.get("metric_id", "benefit")).capitalize()
interaction_feedback.emit(
String(context.action_id).capitalize(),
"%s increased by %.1f through authoritative work." % [metric_name, amount],
true
)
func _execute_pantry_interaction(context: PlayerInteractionResult) -> void:
if not context.is_available():
interaction_feedback.emit("The pantry is empty", context.blocked_reason, false)