MODIFIED escoria.gdgit add . Action manager extended to apply needed changes for monkey UI
This commit is contained in:
@@ -18,7 +18,8 @@ onready var main = $main
|
|||||||
|
|
||||||
func _init():
|
func _init():
|
||||||
escoria.inventory_manager = ESCInventoryManager.new()
|
escoria.inventory_manager = ESCInventoryManager.new()
|
||||||
escoria.action_manager = ESCActionManager.new()
|
# MODIFIED FOR RETURN TO MONKEY UI
|
||||||
|
escoria.action_manager = ESCActionManagerMonkey.new()
|
||||||
escoria.event_manager = ESCEventManager.new()
|
escoria.event_manager = ESCEventManager.new()
|
||||||
escoria.globals_manager = ESCGlobalsManager.new()
|
escoria.globals_manager = ESCGlobalsManager.new()
|
||||||
add_child(escoria.event_manager)
|
add_child(escoria.event_manager)
|
||||||
|
|||||||
@@ -0,0 +1,364 @@
|
|||||||
|
# Manages currently carried out actions
|
||||||
|
# MODIFIED FOR RETURN TO MONKEY UI
|
||||||
|
extends ESCActionManager
|
||||||
|
class_name ESCActionManagerMonkey
|
||||||
|
|
||||||
|
# Set the current action verb
|
||||||
|
#
|
||||||
|
# ## Parameters
|
||||||
|
# - action: The action verb to set
|
||||||
|
func set_current_action(action: String):
|
||||||
|
# MODIFIED FOR RETURN TO MONKEY UI
|
||||||
|
if (action != current_action) && (action_state != ACTION_INPUT_STATE.AWAITING_TARGET_ITEM):
|
||||||
|
clear_current_tool()
|
||||||
|
|
||||||
|
current_action = action
|
||||||
|
|
||||||
|
if action_state == ACTION_INPUT_STATE.AWAITING_VERB_OR_ITEM:
|
||||||
|
set_action_input_state(ACTION_INPUT_STATE.AWAITING_ITEM)
|
||||||
|
elif action_state == ACTION_INPUT_STATE.AWAITING_VERB:
|
||||||
|
set_action_input_state(ACTION_INPUT_STATE.AWAITING_VERB_CONFIRM)
|
||||||
|
|
||||||
|
emit_signal("action_changed")
|
||||||
|
|
||||||
|
|
||||||
|
# Checks if the specified action is valid and returns the associated event;
|
||||||
|
# otherwise, we see if there's a "fallback" event and use that if necessary and,
|
||||||
|
# if not, we return no event as there's nothing to do.
|
||||||
|
#
|
||||||
|
# #### Parameters
|
||||||
|
#
|
||||||
|
# - action: Action to execute (defined in attached ESC file and in
|
||||||
|
# action verbs UI) eg: arrived, use, look, pickup...
|
||||||
|
# - target: Target ESC object
|
||||||
|
# - combine_with: ESC object to combine with
|
||||||
|
#
|
||||||
|
# *Returns* the appropriate ESCEvent to queue/run, or null if none can be found
|
||||||
|
# or there's a reason not to run an event.
|
||||||
|
func _get_event_to_queue(
|
||||||
|
action: String,
|
||||||
|
target: ESCObject,
|
||||||
|
combine_with: ESCObject = null
|
||||||
|
) -> ESCEvent:
|
||||||
|
|
||||||
|
escoria.logger.info(
|
||||||
|
self,
|
||||||
|
"Checking if action '%s' on '%s' is valid..." % [action, target]
|
||||||
|
)
|
||||||
|
|
||||||
|
var event_to_return: ESCEvent = null
|
||||||
|
|
||||||
|
# If we're using an action which item requires to combine
|
||||||
|
if target.node is ESCItem \
|
||||||
|
and (action in target.node.combine_when_selected_action_is_in
|
||||||
|
# MODIFIED FOR RETURN TO MONKEY UI
|
||||||
|
or (combine_with && action in combine_with.node.combine_when_selected_action_is_in)):
|
||||||
|
|
||||||
|
# Check if object must be in inventory to be used
|
||||||
|
if target.node.use_from_inventory_only:
|
||||||
|
if escoria.inventory_manager.inventory_has(target.global_id):
|
||||||
|
# Player has item in inventory, we check the element to use on
|
||||||
|
if combine_with:
|
||||||
|
var do_combine = true
|
||||||
|
if combine_with.node is ESCItem \
|
||||||
|
and combine_with.node.use_from_inventory_only\
|
||||||
|
and not escoria.inventory_manager.inventory_has(
|
||||||
|
combine_with.global_id
|
||||||
|
):
|
||||||
|
do_combine = false
|
||||||
|
|
||||||
|
if do_combine:
|
||||||
|
var target_event = "%s %s" % [
|
||||||
|
action,
|
||||||
|
combine_with.global_id
|
||||||
|
]
|
||||||
|
var combine_with_event = "%s %s" % [
|
||||||
|
action,
|
||||||
|
target.global_id
|
||||||
|
]
|
||||||
|
|
||||||
|
if target.events.has(target_event):
|
||||||
|
event_to_return = target.events[target_event]
|
||||||
|
elif combine_with.events.has(combine_with_event)\
|
||||||
|
and not combine_with.node.combine_is_one_way:
|
||||||
|
|
||||||
|
event_to_return = combine_with.events[combine_with_event]
|
||||||
|
else:
|
||||||
|
# Check to see if there isn't a "fallback" action to
|
||||||
|
# run before we declare this a failure.
|
||||||
|
if escoria.action_default_script \
|
||||||
|
and escoria.action_default_script.events.has(action):
|
||||||
|
|
||||||
|
event_to_return = escoria.action_default_script.events[action]
|
||||||
|
else:
|
||||||
|
var errors = [
|
||||||
|
"Attempted to execute action %s between item %s and item %s" % [
|
||||||
|
action,
|
||||||
|
target.global_id,
|
||||||
|
combine_with.global_id
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
if combine_with.node.combine_is_one_way:
|
||||||
|
errors.append(
|
||||||
|
("Reason: %s's item interaction " + \
|
||||||
|
"is one-way.") % combine_with.global_id
|
||||||
|
)
|
||||||
|
|
||||||
|
escoria.logger.warn(
|
||||||
|
self,
|
||||||
|
"Invalid action: " + str(errors)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
escoria.logger.warn(
|
||||||
|
self,
|
||||||
|
"Invalid action on item: " +
|
||||||
|
(
|
||||||
|
"Trying to combine object %s with %s, "+
|
||||||
|
"but %s is not in inventory."
|
||||||
|
) % [
|
||||||
|
target.global_id,
|
||||||
|
combine_with.global_id,
|
||||||
|
combine_with.global_id
|
||||||
|
]
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
escoria.logger.warn(
|
||||||
|
self,
|
||||||
|
"Invalid action on item: " +
|
||||||
|
"Trying to run action %s on object %s, " %
|
||||||
|
[
|
||||||
|
action,
|
||||||
|
target.node.global_id
|
||||||
|
]
|
||||||
|
+ "but item must be in inventory."
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
if target.events.has(action):
|
||||||
|
event_to_return = target.events[action]
|
||||||
|
elif escoria.action_default_script \
|
||||||
|
and escoria.action_default_script.events.has(action):
|
||||||
|
|
||||||
|
# If there's a "fallback" action to run, return it
|
||||||
|
event_to_return = escoria.action_default_script.events[action]
|
||||||
|
else:
|
||||||
|
escoria.logger.warn(
|
||||||
|
self,
|
||||||
|
"Invalid action: " +
|
||||||
|
"Event for action %s on object %s not found." % [
|
||||||
|
action,
|
||||||
|
target.global_id
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
return event_to_return
|
||||||
|
|
||||||
|
|
||||||
|
# Event handler when an object/item was clicked
|
||||||
|
#
|
||||||
|
# #### Parameters
|
||||||
|
#
|
||||||
|
# - obj: Object that was left clicked
|
||||||
|
# - event: Input event that was received
|
||||||
|
# - default_action: if true, run the inventory default action
|
||||||
|
func perform_inputevent_on_object(
|
||||||
|
obj: ESCObject,
|
||||||
|
event: InputEvent,
|
||||||
|
default_action: bool = false
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
This algorithm:
|
||||||
|
- validates the requested action
|
||||||
|
- grabs the corresponding event for the action, if available
|
||||||
|
- makes the player move to the clicked object location, if needed
|
||||||
|
(if it is located in the room for example) and wait for reaching.
|
||||||
|
- when reached, performs an action depending on current defined action
|
||||||
|
* no current action defined: do nothing else
|
||||||
|
* current action defined:
|
||||||
|
* item requires no combination: perform the current action
|
||||||
|
on the item
|
||||||
|
* item requires combination: check the status of the combination
|
||||||
|
A combination requires 3 elements to fulfill:
|
||||||
|
1/ a verb action
|
||||||
|
2/ a first "tool" (item to use)
|
||||||
|
3/ a second "tool" (item to use ON)
|
||||||
|
Whatever the user inputs to fulfill the combination (this is
|
||||||
|
determined by gamedev in his game.gd script)
|
||||||
|
- combination not fulfilled: no not perform until fulfilled
|
||||||
|
- combination fulfilled: perform the combination.
|
||||||
|
* else do nothing, except if default_action is requested.
|
||||||
|
In this case, perform the default_action on the item.
|
||||||
|
"""
|
||||||
|
|
||||||
|
escoria.logger.info(
|
||||||
|
self,
|
||||||
|
"%s to perform event %s." % [obj.global_id, event]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Don't interact after player movement towards object
|
||||||
|
# (because object is inactive for example)
|
||||||
|
var dont_interact = false
|
||||||
|
|
||||||
|
# We need to have the new action input state BEFORE initiating the player
|
||||||
|
# move so we determine now if the object clicked will require a combination
|
||||||
|
# depending on the used action verb.
|
||||||
|
var tool_just_set = _set_tool_and_action(obj, default_action)
|
||||||
|
# MODIFIED FOR RETURN TO MONKEY UI
|
||||||
|
var need_combine = _check_item_needs_combine_obj(obj)
|
||||||
|
|
||||||
|
# If the current tool was not set, this is our first item, make it the tool
|
||||||
|
if not current_tool or (current_tool and not need_combine):
|
||||||
|
current_tool = obj
|
||||||
|
# Else, if we have a tool and combination required, this is our second item,
|
||||||
|
# make it the target.
|
||||||
|
elif need_combine and not tool_just_set:
|
||||||
|
current_target = obj
|
||||||
|
|
||||||
|
# Update the action input state
|
||||||
|
if action_state == ACTION_INPUT_STATE.AWAITING_TARGET_ITEM and current_target:
|
||||||
|
set_action_input_state(ACTION_INPUT_STATE.COMPLETED)
|
||||||
|
elif action_state == ACTION_INPUT_STATE.AWAITING_ITEM and \
|
||||||
|
not need_combine:
|
||||||
|
set_action_input_state(ACTION_INPUT_STATE.COMPLETED)
|
||||||
|
elif action_state == ACTION_INPUT_STATE.AWAITING_ITEM and need_combine and not tool_just_set:
|
||||||
|
set_action_input_state(ACTION_INPUT_STATE.AWAITING_TARGET_ITEM)
|
||||||
|
|
||||||
|
var event_to_queue: ESCEvent = null
|
||||||
|
|
||||||
|
# Manage exits
|
||||||
|
if obj.node.is_exit and current_action in ["", ACTION_WALK]:
|
||||||
|
event_to_queue = _get_event_to_queue(ACTION_EXIT_SCENE, obj)
|
||||||
|
else:
|
||||||
|
# Manage movements towards object before activating it
|
||||||
|
if current_action in ["", ACTION_WALK] and \
|
||||||
|
not escoria.inventory_manager.inventory_has(obj.global_id):
|
||||||
|
event_to_queue = _get_event_to_queue(ACTION_ARRIVED, obj)
|
||||||
|
# Manage action on object
|
||||||
|
elif not current_action in ["", ACTION_WALK]:
|
||||||
|
if need_combine and current_target:
|
||||||
|
event_to_queue = _get_event_to_queue(
|
||||||
|
current_action,
|
||||||
|
current_tool,
|
||||||
|
current_target
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
# Check if object must be in inventory to be used and update
|
||||||
|
# action state if necessary
|
||||||
|
if obj.node.use_from_inventory_only and \
|
||||||
|
escoria.inventory_manager.inventory_has(obj.global_id) and \
|
||||||
|
need_combine:
|
||||||
|
|
||||||
|
# We're missing a target here for our tool to be used on
|
||||||
|
current_tool = obj
|
||||||
|
set_action_input_state(
|
||||||
|
ACTION_INPUT_STATE.AWAITING_TARGET_ITEM
|
||||||
|
)
|
||||||
|
|
||||||
|
# We need to wait for that target
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
event_to_queue = _get_event_to_queue(
|
||||||
|
current_action,
|
||||||
|
obj
|
||||||
|
)
|
||||||
|
|
||||||
|
# Get out of here if there's a specified action but an event couldn't be found.
|
||||||
|
# Note that `event_to_queue` may still be null, but we do need to start the
|
||||||
|
# player walking towards the destination.
|
||||||
|
if current_action and not event_to_queue:
|
||||||
|
clear_current_action()
|
||||||
|
emit_signal("action_finished")
|
||||||
|
return
|
||||||
|
|
||||||
|
var event_flags = event_to_queue.flags if event_to_queue else 0
|
||||||
|
|
||||||
|
if escoria.main.current_scene.player:
|
||||||
|
var destination_position: Vector2 = escoria.main.current_scene.player \
|
||||||
|
.global_position
|
||||||
|
|
||||||
|
# If clicked object not in inventory, player walks towards it
|
||||||
|
if not obj.node is ESCPlayer and \
|
||||||
|
not escoria.inventory_manager.inventory_has(obj.global_id) and \
|
||||||
|
not event_flags & ESCEvent.FLAG_TK:
|
||||||
|
var context = _walk_towards_object(
|
||||||
|
obj,
|
||||||
|
event.position,
|
||||||
|
event.doubleclick
|
||||||
|
)
|
||||||
|
|
||||||
|
if context is GDScriptFunctionState:
|
||||||
|
context = yield(context, "completed")
|
||||||
|
|
||||||
|
# In case of an interrupted walk, we don't want to proceed.
|
||||||
|
if context == null:
|
||||||
|
return
|
||||||
|
|
||||||
|
destination_position = context.target_position
|
||||||
|
dont_interact = context.dont_interact_on_arrival
|
||||||
|
|
||||||
|
var player_global_pos = escoria.main.current_scene.player.global_position
|
||||||
|
var clicked_position = event.position
|
||||||
|
|
||||||
|
# Using this instead of is_equal_approx due to
|
||||||
|
# https://github.com/godotengine/godot/issues/65257
|
||||||
|
if (player_global_pos - destination_position).length() > 1:
|
||||||
|
dont_interact = true
|
||||||
|
escoria.logger.info(
|
||||||
|
self,
|
||||||
|
"Player could not reach destination coordinates %s. " % str(destination_position) \
|
||||||
|
+ "Any requested action for %s will not fire." % obj.global_id
|
||||||
|
)
|
||||||
|
if escoria.event_manager.EVENT_CANT_REACH in obj.events:
|
||||||
|
escoria.event_manager.queue_event(obj.events[escoria.event_manager.EVENT_CANT_REACH])
|
||||||
|
else:
|
||||||
|
escoria.logger.info(
|
||||||
|
self,
|
||||||
|
"%s event not found for object %s so nothing to do." % \
|
||||||
|
[escoria.event_manager.EVENT_CANT_REACH, obj.global_id]
|
||||||
|
)
|
||||||
|
|
||||||
|
# If no interaction should happen after player has arrived, leave
|
||||||
|
# immediately.
|
||||||
|
if not dont_interact and event_to_queue:
|
||||||
|
_run_event(event_to_queue)
|
||||||
|
|
||||||
|
# Prepare the "obj" object for current_action: if required, set the object as
|
||||||
|
# current tool.
|
||||||
|
#
|
||||||
|
# #### Parameters
|
||||||
|
#
|
||||||
|
# - obj: the ESCObject to prepare
|
||||||
|
# - default_action: if true, the default action set on the item is used
|
||||||
|
#
|
||||||
|
# *Returns* True if the tool was set in this function
|
||||||
|
func _set_tool_and_action(obj: ESCObject, default_action: bool):
|
||||||
|
var tool_just_set: bool = false
|
||||||
|
# Check if current_action and current_tool are already set
|
||||||
|
if current_action and current_tool:
|
||||||
|
# MODIFIED FOR RETURN TO MONKEY UI
|
||||||
|
if (not current_action in escoria.action_manager\
|
||||||
|
.current_tool.node.combine_when_selected_action_is_in and not current_action in obj.node.combine_when_selected_action_is_in):
|
||||||
|
current_tool = obj
|
||||||
|
tool_just_set = true
|
||||||
|
elif default_action:
|
||||||
|
if escoria.inventory_manager.inventory_has(obj.global_id):
|
||||||
|
current_action = obj.node.default_action_inventory
|
||||||
|
else:
|
||||||
|
current_action = obj.node.default_action
|
||||||
|
elif current_action in obj.node.combine_when_selected_action_is_in:
|
||||||
|
current_tool = obj
|
||||||
|
tool_just_set = true
|
||||||
|
return tool_just_set
|
||||||
|
|
||||||
|
|
||||||
|
# Checks if object requires a combination with another, according to
|
||||||
|
# currently selected action verb (or check with default action of the item).
|
||||||
|
#
|
||||||
|
# *Returns* True if current action on "obj" requires a combination
|
||||||
|
# MODIFIED FOR RETURN TO MONKEY UI
|
||||||
|
func _check_item_needs_combine_obj(obj: ESCObject) -> bool:
|
||||||
|
return current_action \
|
||||||
|
and current_tool \
|
||||||
|
and (current_action in current_tool.node.combine_when_selected_action_is_in
|
||||||
|
# MODIFIED FOR RETURN TO MONKEY UI
|
||||||
|
or current_action in obj.node.combine_when_selected_action_is_in)
|
||||||
@@ -65,7 +65,7 @@ global_id = "l_exit"
|
|||||||
esc_script = "res://gymkhana/rooms/trasera_cocina/esc/entrada_cocina.esc"
|
esc_script = "res://gymkhana/rooms/trasera_cocina/esc/entrada_cocina.esc"
|
||||||
is_exit = true
|
is_exit = true
|
||||||
tooltip_name = "Esto es una puerta y tiene una descripcion mu larga"
|
tooltip_name = "Esto es una puerta y tiene una descripcion mu larga"
|
||||||
combine_when_selected_action_is_in = [ ]
|
combine_when_selected_action_is_in = [ "action4" ]
|
||||||
dialog_color = Color( 1, 1, 1, 1 )
|
dialog_color = Color( 1, 1, 1, 1 )
|
||||||
action1_text = "Esto es una puerta y tiene una descripcion mu larga"
|
action1_text = "Esto es una puerta y tiene una descripcion mu larga"
|
||||||
action2_text = "Entrar! con descricion..."
|
action2_text = "Entrar! con descricion..."
|
||||||
|
|||||||
@@ -149,6 +149,11 @@ _global_script_classes=[ {
|
|||||||
"language": "GDScript",
|
"language": "GDScript",
|
||||||
"path": "res://addons/escoria-core/game/core-scripts/esc/esc_action_manager.gd"
|
"path": "res://addons/escoria-core/game/core-scripts/esc/esc_action_manager.gd"
|
||||||
}, {
|
}, {
|
||||||
|
"base": "ESCActionManager",
|
||||||
|
"class": "ESCActionManagerMonkey",
|
||||||
|
"language": "GDScript",
|
||||||
|
"path": "res://gymkhana/addons/escoria-ui-return-monkey-island/esc/esc_action_manager_monkey.gd"
|
||||||
|
}, {
|
||||||
"base": "Resource",
|
"base": "Resource",
|
||||||
"class": "ESCAnimationName",
|
"class": "ESCAnimationName",
|
||||||
"language": "GDScript",
|
"language": "GDScript",
|
||||||
@@ -733,6 +738,7 @@ _global_script_class_icons={
|
|||||||
"DialogSayFinish": "",
|
"DialogSayFinish": "",
|
||||||
"DialogVisible": "",
|
"DialogVisible": "",
|
||||||
"ESCActionManager": "",
|
"ESCActionManager": "",
|
||||||
|
"ESCActionManagerMonkey": "",
|
||||||
"ESCAnimationName": "",
|
"ESCAnimationName": "",
|
||||||
"ESCAnimationPlayer": "",
|
"ESCAnimationPlayer": "",
|
||||||
"ESCAnimationResource": "",
|
"ESCAnimationResource": "",
|
||||||
|
|||||||
Reference in New Issue
Block a user