Removed ESCController and greatly reworked ESCActionManager (#480)
This commit is contained in:
@@ -3,12 +3,37 @@ extends Object
|
||||
class_name ESCActionManager
|
||||
|
||||
|
||||
# The current action was changed
|
||||
# The current action verb was changed
|
||||
signal action_changed
|
||||
|
||||
# Emitted, when an action has been completed
|
||||
signal action_finished
|
||||
|
||||
# Emitted when the action input state has changed
|
||||
signal action_input_state_changed
|
||||
|
||||
|
||||
# States of the action input (verb, item, target)
|
||||
# (I) -> AWAITING_VERB_OR_ITEM -> AWAITING_ITEM -> COMPLETED -> (E)
|
||||
# or
|
||||
# (I) -> AWAITING_VERB_OR_ITEM -> AWAITING_ITEM -> AWAITING_TARGET_ITEM -> COMPLETED -> (E)
|
||||
# or
|
||||
# (I) -> AWAITING_VERB_OR_ITEM -> AWAITING_VERB -> AWAITING_VERB_CONFIRMATION -> COMPLETED -> (E)
|
||||
enum ACTION_INPUT_STATE {
|
||||
# Initial state
|
||||
AWAITING_VERB_OR_ITEM,
|
||||
# After initial state, verb is defined
|
||||
AWAITING_ITEM,
|
||||
# Item defined requires combine, waiting for target
|
||||
AWAITING_TARGET_ITEM
|
||||
# After initial state, item is defined
|
||||
AWAITING_VERB,
|
||||
# Item was defined first, next verb, need verb confirmation
|
||||
AWAITING_VERB_CONFIRMATION,
|
||||
# Final state
|
||||
COMPLETED
|
||||
}
|
||||
|
||||
|
||||
# Current verb used
|
||||
var current_action: String = "" setget set_current_action
|
||||
@@ -16,24 +41,56 @@ var current_action: String = "" setget set_current_action
|
||||
# Current tool (ESCItem/ESCInventoryItem) used
|
||||
var current_tool: ESCObject
|
||||
|
||||
# Current target where the tool is being used on/with (if any)
|
||||
var current_target: ESCObject
|
||||
|
||||
# Set the current action
|
||||
# Current action input state
|
||||
var action_state = ACTION_INPUT_STATE.AWAITING_VERB_OR_ITEM \
|
||||
setget set_action_input_state
|
||||
|
||||
|
||||
# Sets the current state of action input.
|
||||
#
|
||||
# ## Parameters
|
||||
# - p_state: the action input state to set
|
||||
func set_action_input_state(p_state):
|
||||
action_state = p_state
|
||||
emit_signal("action_input_state_changed")
|
||||
|
||||
|
||||
# Set the current action verb
|
||||
#
|
||||
# ## Parameters
|
||||
# - action: The action verb to set
|
||||
func set_current_action(action: String):
|
||||
if action != current_action:
|
||||
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")
|
||||
|
||||
|
||||
# Clear the current action
|
||||
func clear_current_action():
|
||||
set_current_action("")
|
||||
set_action_input_state(ACTION_INPUT_STATE.AWAITING_VERB_OR_ITEM)
|
||||
emit_signal("action_changed")
|
||||
|
||||
|
||||
# Clear the current tool
|
||||
func clear_current_tool():
|
||||
current_tool = null
|
||||
current_target = null
|
||||
if action_state == ACTION_INPUT_STATE.AWAITING_VERB:
|
||||
set_action_input_state(ACTION_INPUT_STATE.AWAITING_VERB_OR_ITEM)
|
||||
elif action_state == ACTION_INPUT_STATE.AWAITING_TARGET_ITEM:
|
||||
set_action_input_state(ACTION_INPUT_STATE.AWAITING_ITEM)
|
||||
|
||||
|
||||
# Activates the action for given params
|
||||
@@ -44,7 +101,7 @@ func clear_current_tool():
|
||||
# action verbs UI) eg: arrived, use, look, pickup...
|
||||
# - target: Target ESC object
|
||||
# - combine_with: ESC object to combine with
|
||||
func activate(
|
||||
func _activate(
|
||||
action: String,
|
||||
target: ESCObject,
|
||||
combine_with: ESCObject = null
|
||||
@@ -90,8 +147,7 @@ func activate(
|
||||
"event_finished"
|
||||
)
|
||||
if event_returned[0] == ESCExecution.RC_OK:
|
||||
escoria.action_manager\
|
||||
.clear_current_action()
|
||||
escoria.action_manager.clear_current_action()
|
||||
emit_signal("action_finished")
|
||||
return event_returned[0]
|
||||
elif combine_with.events.has(combine_with_event)\
|
||||
@@ -111,8 +167,7 @@ func activate(
|
||||
"event_finished"
|
||||
)
|
||||
if event_returned[0] == ESCExecution.RC_OK:
|
||||
escoria.action_manager\
|
||||
.clear_current_action()
|
||||
escoria.action_manager.clear_current_action()
|
||||
emit_signal("action_finished")
|
||||
return event_returned[0]
|
||||
else:
|
||||
@@ -151,11 +206,11 @@ func activate(
|
||||
emit_signal("action_finished")
|
||||
return ESCExecution.RC_ERROR
|
||||
else:
|
||||
# We're missing a target here.
|
||||
# Tell the Label to add a conjunction and wait for another
|
||||
# click to add the target to p_param. Until then, return
|
||||
# We're missing a target here for our tool to be used on
|
||||
current_tool = target
|
||||
emit_signal("action_finished")
|
||||
set_action_input_state(
|
||||
ACTION_INPUT_STATE.AWAITING_TARGET_ITEM
|
||||
)
|
||||
return ESCExecution.RC_OK
|
||||
else:
|
||||
escoria.logger.report_warnings(
|
||||
@@ -170,7 +225,6 @@ func activate(
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
if target.events.has(action):
|
||||
escoria.event_manager.queue_event(target.events[action])
|
||||
var event_returned = yield(
|
||||
@@ -183,7 +237,7 @@ func activate(
|
||||
"event_finished"
|
||||
)
|
||||
if event_returned[0] == ESCExecution.RC_OK:
|
||||
escoria.action_manager.clear_current_action()
|
||||
clear_current_action()
|
||||
emit_signal("action_finished")
|
||||
return event_returned[0]
|
||||
else:
|
||||
@@ -198,3 +252,276 @@ func activate(
|
||||
)
|
||||
emit_signal("action_finished")
|
||||
return ESCExecution.RC_ERROR
|
||||
|
||||
|
||||
# Makes an object walk to a destination. This can be either a 2D position or
|
||||
# another object.
|
||||
#
|
||||
# #### Parameters
|
||||
#
|
||||
# - moving_obj_id: global id of the object that needs to move
|
||||
# - destination: Position2D or ESCObject holding the moving object to head to
|
||||
# - is_fast: if true, the walk is performed at fast speed (defined in the moving
|
||||
# object.
|
||||
func perform_walk(
|
||||
moving_obj: ESCObject,
|
||||
destination,
|
||||
is_fast: bool = false
|
||||
):
|
||||
# Walk to Position2D.
|
||||
if destination is Vector2:
|
||||
var walk_context = ESCWalkContext.new(
|
||||
null,
|
||||
destination,
|
||||
is_fast,
|
||||
true
|
||||
)
|
||||
moving_obj.node.walk_to(destination, walk_context)
|
||||
|
||||
# Walk to object
|
||||
elif destination is ESCObject:
|
||||
if destination.node:
|
||||
var target_position: Vector2
|
||||
if destination.node is ESCLocation:
|
||||
target_position = destination.node.global_position
|
||||
else:
|
||||
target_position = destination.node.get_interact_position()
|
||||
|
||||
var walk_context = ESCWalkContext.new(
|
||||
destination,
|
||||
target_position,
|
||||
is_fast,
|
||||
true
|
||||
)
|
||||
|
||||
moving_obj.node.walk_to(target_position, walk_context)
|
||||
|
||||
else:
|
||||
escoria.logger.report_errors(
|
||||
"esc_controller.gd:perform_walk()",
|
||||
[
|
||||
"Function expected either a Vector2 or ESCObject type " + \
|
||||
"for destination parameter. Actual was: %s " % destination
|
||||
]
|
||||
)
|
||||
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:
|
||||
- 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("%s left-clicked with event " % obj.global_id, [event])
|
||||
|
||||
var event_flags = 0
|
||||
var has_current_action: bool = false
|
||||
if obj.events.has(current_action):
|
||||
event_flags = obj.events[current_action].flags
|
||||
has_current_action = true
|
||||
|
||||
# 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)
|
||||
var need_combine = _check_item_needs_combine()
|
||||
|
||||
# If the current tool was not set, this is our first item, make it tool
|
||||
if not current_tool or (current_tool and not need_combine):
|
||||
current_tool = obj
|
||||
# Else, if we have a tool an combination required, this is our second item,
|
||||
# make it 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)
|
||||
|
||||
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 has_current_action or not event_flags & ESCEvent.FLAG_TK):
|
||||
var context = _walk_towards_object(
|
||||
obj,
|
||||
event.position,
|
||||
event.doubleclick
|
||||
)
|
||||
if context is GDScriptFunctionState:
|
||||
context = yield(_walk_towards_object(
|
||||
obj,
|
||||
event.position,
|
||||
event.doubleclick
|
||||
), "completed")
|
||||
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
|
||||
|
||||
if not player_global_pos.is_equal_approx(destination_position):
|
||||
dont_interact = true
|
||||
|
||||
# If no interaction should happen after player has arrived, leave
|
||||
# immediately.
|
||||
if dont_interact:
|
||||
return
|
||||
|
||||
# Manage exits
|
||||
if obj.node.is_exit and current_action in ["", "walk"]:
|
||||
_activate("exit_scene", obj)
|
||||
else:
|
||||
# Manage movements towards object before activating it
|
||||
if current_action in ["", "walk"] and \
|
||||
not escoria.inventory_manager.inventory_has(obj.global_id):
|
||||
_activate("arrived", obj)
|
||||
# Manage action on object
|
||||
elif not current_action in ["", "walk"]:
|
||||
if need_combine and current_target:
|
||||
_activate(
|
||||
current_action,
|
||||
current_tool,
|
||||
current_target
|
||||
)
|
||||
|
||||
else:
|
||||
_activate(
|
||||
current_action,
|
||||
obj
|
||||
)
|
||||
|
||||
|
||||
# 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:
|
||||
if not current_action in escoria.action_manager\
|
||||
.current_tool.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
|
||||
func _check_item_needs_combine() -> bool:
|
||||
return current_action \
|
||||
and current_tool \
|
||||
and current_action in current_tool.node.combine_when_selected_action_is_in
|
||||
|
||||
|
||||
# Makes the player character walk towards the clicked item.
|
||||
# Returns the resulting walk context.
|
||||
#
|
||||
# #### Parameters
|
||||
#
|
||||
# - obj: the object that was clicked
|
||||
# - clicked_position: the Position2D of the input click
|
||||
# - walk_fast: if true, the player will walk fast to the object
|
||||
func _walk_towards_object(
|
||||
obj: ESCObject,
|
||||
clicked_position: Vector2,
|
||||
walk_fast: bool
|
||||
) -> ESCWalkContext:
|
||||
var destination_position: Vector2
|
||||
var dont_interact: bool = false
|
||||
|
||||
# If clicked object is interactive, get destination position from it.
|
||||
if escoria.object_manager.get_object(obj.global_id).interactive:
|
||||
if obj.node.get_interact_position() != null:
|
||||
destination_position = obj.node.get_interact_position()
|
||||
else:
|
||||
destination_position = obj.node.position
|
||||
else:
|
||||
destination_position = clicked_position
|
||||
dont_interact = true
|
||||
|
||||
# Create walk context
|
||||
var walk_context = ESCWalkContext.new(
|
||||
obj,
|
||||
destination_position,
|
||||
walk_fast,
|
||||
dont_interact
|
||||
)
|
||||
|
||||
# Walk towards the clicked object
|
||||
escoria.main.current_scene.player.walk_to(destination_position,
|
||||
walk_context)
|
||||
|
||||
# Wait for the player to arrive before continuing with action.
|
||||
var context: ESCWalkContext = yield(
|
||||
escoria.main.current_scene.player,
|
||||
"arrived"
|
||||
)
|
||||
escoria.logger.info("Context arrived: %s" % context)
|
||||
|
||||
# Confirm that reached item was the one user clicked in the first place.
|
||||
# Don't interact if that is not the case.
|
||||
if (context.target_object and context.target_object.\
|
||||
global_id != walk_context.\
|
||||
target_object.global_id) or \
|
||||
(context.target_position != walk_context.target_position):
|
||||
walk_context.dont_interact_on_arrival = true
|
||||
|
||||
return context
|
||||
|
||||
@@ -1,252 +0,0 @@
|
||||
# This class performs certain tasks as a reaction to certain inputs, such as
|
||||
# player walking, player walking towards an object, etc.
|
||||
class_name ESCController
|
||||
|
||||
|
||||
# Makes an object walk to a destination. This can be either a 2D position or
|
||||
# another object.
|
||||
#
|
||||
# #### Parameters
|
||||
#
|
||||
# - moving_obj_id: global id of the object that needs to move
|
||||
# - destination: Position2D or ESCObject holding the moving object to head to
|
||||
# - is_fast: if true, the walk is performed at fast speed (defined in the moving
|
||||
# object.
|
||||
func perform_walk(
|
||||
moving_obj: ESCObject,
|
||||
destination,
|
||||
is_fast: bool = false
|
||||
):
|
||||
# Walk to Position2D.
|
||||
if destination is Vector2:
|
||||
var walk_context = ESCWalkContext.new(
|
||||
null,
|
||||
destination,
|
||||
is_fast,
|
||||
true
|
||||
)
|
||||
moving_obj.node.walk_to(destination, walk_context)
|
||||
|
||||
# Walk to object
|
||||
elif destination is ESCObject:
|
||||
if destination.node:
|
||||
var target_position: Vector2
|
||||
if destination.node is ESCLocation:
|
||||
target_position = destination.node.global_position
|
||||
else:
|
||||
target_position = destination.node.get_interact_position()
|
||||
|
||||
var walk_context = ESCWalkContext.new(
|
||||
destination,
|
||||
target_position,
|
||||
is_fast,
|
||||
true
|
||||
)
|
||||
|
||||
moving_obj.node.walk_to(target_position, walk_context)
|
||||
|
||||
else:
|
||||
escoria.logger.report_errors(
|
||||
"esc_controller.gd:perform_walk()",
|
||||
[
|
||||
"Function expected either a Vector2 or ESCObject type " + \
|
||||
"for destination parameter. Actual was: %s " % destination
|
||||
]
|
||||
)
|
||||
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:
|
||||
- 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("%s left-clicked with event " % obj.global_id, [event])
|
||||
|
||||
var event_flags = 0
|
||||
var has_current_action: bool = false
|
||||
if obj.events.has(escoria.action_manager.current_action):
|
||||
event_flags = obj.events[escoria.action_manager.current_action].flags
|
||||
has_current_action = true
|
||||
|
||||
# Don't interact after player movement towards object
|
||||
# (because object is inactive for example)
|
||||
var dont_interact = false
|
||||
|
||||
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 has_current_action or not event_flags & ESCEvent.FLAG_TK):
|
||||
var context = _walk_towards_object(
|
||||
obj,
|
||||
event.position,
|
||||
event.doubleclick
|
||||
)
|
||||
if context is GDScriptFunctionState:
|
||||
context = yield(_walk_towards_object(
|
||||
obj,
|
||||
event.position,
|
||||
event.doubleclick
|
||||
), "completed")
|
||||
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
|
||||
|
||||
if not player_global_pos.is_equal_approx(destination_position):
|
||||
dont_interact = true
|
||||
|
||||
# If no interaction should happen after player has arrived, leave
|
||||
# immediately.
|
||||
if dont_interact:
|
||||
return
|
||||
|
||||
# Manage exits
|
||||
if obj.node.is_exit and escoria.action_manager.current_action \
|
||||
in ["", "walk"]:
|
||||
escoria.action_manager.activate("exit_scene", obj)
|
||||
else:
|
||||
# Manage movements towards object before activating it
|
||||
if escoria.action_manager.current_action in ["", "walk"] and \
|
||||
not escoria.inventory_manager.inventory_has(obj.global_id):
|
||||
escoria.action_manager.activate("arrived", obj)
|
||||
# Manage action on object
|
||||
elif not escoria.action_manager.current_action in ["", "walk"]:
|
||||
# Check if clicked item awaits a combination
|
||||
var need_combine = _check_item_needs_combine(
|
||||
obj,
|
||||
default_action
|
||||
)
|
||||
|
||||
# If apply_interact, perform combine between items
|
||||
if need_combine:
|
||||
escoria.action_manager.activate(
|
||||
escoria.action_manager.current_action,
|
||||
escoria.action_manager.current_tool,
|
||||
obj
|
||||
)
|
||||
|
||||
else:
|
||||
escoria.action_manager.activate(
|
||||
escoria.action_manager.current_action,
|
||||
obj
|
||||
)
|
||||
|
||||
# Checks if object requires a combination with another, according to
|
||||
# currently selected action verb (or check with default action of the item).
|
||||
#
|
||||
# #### Parameters
|
||||
#
|
||||
# - obj: the ESCObject to test
|
||||
# - default_action: if true, the check is done on the object's default action
|
||||
func _check_item_needs_combine(obj: ESCObject, default_action: bool) -> bool:
|
||||
var need_combine = false
|
||||
# Check if current_action and current_tool are already set
|
||||
if escoria.action_manager.current_action and \
|
||||
escoria.action_manager.current_tool:
|
||||
if escoria.action_manager.current_action in escoria.action_manager\
|
||||
.current_tool.node.combine_when_selected_action_is_in:
|
||||
need_combine = true
|
||||
else:
|
||||
escoria.action_manager.current_tool = obj
|
||||
elif default_action:
|
||||
if escoria.inventory_manager.inventory_has(obj.global_id):
|
||||
escoria.action_manager.current_action = \
|
||||
obj.node.default_action_inventory
|
||||
else:
|
||||
escoria.action_manager.current_action = \
|
||||
obj.node.default_action
|
||||
elif escoria.action_manager.current_action in \
|
||||
obj.node.combine_when_selected_action_is_in:
|
||||
escoria.action_manager.current_tool = obj
|
||||
return need_combine
|
||||
|
||||
|
||||
# Makes the player character walk towards the clicked item.
|
||||
# Returns the resulting walk context.
|
||||
#
|
||||
# #### Parameters
|
||||
#
|
||||
# - obj: the object that was clicked
|
||||
# - clicked_position: the Position2D of the input click
|
||||
# - walk_fast: if true, the player will walk fast to the object
|
||||
func _walk_towards_object(
|
||||
obj: ESCObject,
|
||||
clicked_position: Vector2,
|
||||
walk_fast: bool
|
||||
) -> ESCWalkContext:
|
||||
var destination_position: Vector2
|
||||
var dont_interact: bool = false
|
||||
|
||||
# If clicked object is interactive, get destination position from it.
|
||||
if escoria.object_manager.get_object(obj.global_id).interactive:
|
||||
if obj.node.get_interact_position() != null:
|
||||
destination_position = obj.node.get_interact_position()
|
||||
else:
|
||||
destination_position = obj.node.position
|
||||
else:
|
||||
destination_position = clicked_position
|
||||
dont_interact = true
|
||||
|
||||
# Create walk context
|
||||
var walk_context = ESCWalkContext.new(
|
||||
obj,
|
||||
destination_position,
|
||||
walk_fast,
|
||||
dont_interact
|
||||
)
|
||||
|
||||
# Walk towards the clicked object
|
||||
escoria.main.current_scene.player.walk_to(destination_position,
|
||||
walk_context)
|
||||
|
||||
# Wait for the player to arrive before continuing with action.
|
||||
var context: ESCWalkContext = yield(
|
||||
escoria.main.current_scene.player,
|
||||
"arrived"
|
||||
)
|
||||
escoria.logger.info("Context arrived: %s" % context)
|
||||
|
||||
# Confirm that reached item was the one user clicked in the first place.
|
||||
# Don't interact if that is not the case.
|
||||
if (context.target_object and context.target_object.\
|
||||
global_id != walk_context.\
|
||||
target_object.global_id) or \
|
||||
(context.target_position != walk_context.target_position):
|
||||
walk_context.dont_interact_on_arrival = true
|
||||
|
||||
return context
|
||||
@@ -94,8 +94,7 @@ func set_debug_mode(p_debug_mode: bool):
|
||||
# - needs_second_target: if true, the label will prepare for a second target
|
||||
func set_target(target: String, needs_second_target: bool = false) -> void:
|
||||
current_target = target
|
||||
if needs_second_target:
|
||||
waiting_for_target2 = true
|
||||
waiting_for_target2 = needs_second_target
|
||||
update_tooltip_text()
|
||||
|
||||
|
||||
@@ -219,6 +218,7 @@ func tooltip_distance_to_edge_right(position: Vector2):
|
||||
|
||||
# Clear the tooltip targets texts
|
||||
func clear():
|
||||
waiting_for_target2 = false
|
||||
set_target("")
|
||||
set_target2("")
|
||||
|
||||
|
||||
@@ -86,10 +86,6 @@ var inputs_manager: ESCInputsManager
|
||||
# Savegames and settings manager
|
||||
var save_manager: ESCSaveManager
|
||||
|
||||
# The controller in charge of converting an action verb on a game object
|
||||
# into an actual action
|
||||
var controller: ESCController
|
||||
|
||||
# The game scene loaded
|
||||
var game_scene: ESCGame
|
||||
|
||||
@@ -115,7 +111,6 @@ func _init():
|
||||
self.resource_cache.start()
|
||||
self.save_manager = ESCSaveManager.new()
|
||||
self.inputs_manager = ESCInputsManager.new()
|
||||
self.controller = ESCController.new()
|
||||
self.room_manager = ESCRoomManager.new()
|
||||
|
||||
settings = ESCSaveSettings.new()
|
||||
@@ -218,7 +213,7 @@ func do(action: String, params: Array = [], can_interrupt: bool = false) -> void
|
||||
elif params[1] is Vector2:
|
||||
target = params[1]
|
||||
|
||||
self.controller.perform_walk(moving_obj, target, walk_fast)
|
||||
self.action_manager.perform_walk(moving_obj, target, walk_fast)
|
||||
|
||||
"item_left_click":
|
||||
if params[0] is String:
|
||||
@@ -231,7 +226,7 @@ func do(action: String, params: Array = [], can_interrupt: bool = false) -> void
|
||||
event_manager.interrupt_running_event()
|
||||
|
||||
var item = self.object_manager.get_object(params[0])
|
||||
self.controller.perform_inputevent_on_object(item, params[1])
|
||||
self.action_manager.perform_inputevent_on_object(item, params[1])
|
||||
|
||||
"item_right_click":
|
||||
if params[0] is String:
|
||||
@@ -244,7 +239,7 @@ func do(action: String, params: Array = [], can_interrupt: bool = false) -> void
|
||||
event_manager.interrupt_running_event()
|
||||
|
||||
var item = self.object_manager.get_object(params[0])
|
||||
self.controller.perform_inputevent_on_object(item, params[1], true)
|
||||
self.action_manager.perform_inputevent_on_object(item, params[1], true)
|
||||
|
||||
"trigger_in":
|
||||
var trigger_id = params[0]
|
||||
|
||||
@@ -82,6 +82,8 @@ func left_click_on_bg(position: Vector2) -> void:
|
||||
true
|
||||
)
|
||||
escoria.action_manager.clear_current_action()
|
||||
escoria.action_manager.clear_current_tool()
|
||||
tooltip.clear()
|
||||
verbs_menu.unselect_actions()
|
||||
|
||||
|
||||
@@ -93,6 +95,8 @@ func right_click_on_bg(position: Vector2) -> void:
|
||||
true
|
||||
)
|
||||
escoria.action_manager.clear_current_action()
|
||||
escoria.action_manager.clear_current_tool()
|
||||
tooltip.clear()
|
||||
verbs_menu.unselect_actions()
|
||||
|
||||
|
||||
@@ -111,21 +115,72 @@ func left_double_click_on_bg(position: Vector2) -> void:
|
||||
|
||||
func element_focused(element_id: String) -> void:
|
||||
var target_obj = escoria.object_manager.get_object(element_id).node
|
||||
tooltip.set_target(target_obj.tooltip_name)
|
||||
|
||||
if escoria.action_manager.current_action != "use" \
|
||||
and escoria.action_manager.current_tool == null:
|
||||
if target_obj is ESCItem:
|
||||
verbs_menu.set_by_name(target_obj.default_action)
|
||||
match escoria.action_manager.action_state:
|
||||
# Don't change the tooltip if an action input is completed
|
||||
# (ie verb+item(+target)) because the action is now being executed
|
||||
# and the tooltip is already set because the item was focused
|
||||
# (see element_focused() and inventory_item_focused())
|
||||
ESCActionManager.ACTION_INPUT_STATE.COMPLETED:
|
||||
return
|
||||
|
||||
ESCActionManager.ACTION_INPUT_STATE.AWAITING_VERB_OR_ITEM, \
|
||||
ESCActionManager.ACTION_INPUT_STATE.AWAITING_ITEM:
|
||||
tooltip.set_target(target_obj.tooltip_name)
|
||||
|
||||
# Hovering an ESCItem highlights its default action
|
||||
if escoria.action_manager.current_action != "use" and target_obj is ESCItem:
|
||||
verbs_menu.set_by_name(target_obj.default_action)
|
||||
|
||||
ESCActionManager.ACTION_INPUT_STATE.AWAITING_TARGET_ITEM:
|
||||
tooltip.set_target2(target_obj.tooltip_name)
|
||||
|
||||
|
||||
func element_unfocused() -> void:
|
||||
tooltip.clear()
|
||||
match escoria.action_manager.action_state:
|
||||
# Don't change the tooltip if an action input is completed
|
||||
# (ie verb+item(+target)) because the action is now being executed
|
||||
# and the tooltip is already set because the item was focused
|
||||
# (see element_focused() and inventory_item_focused())
|
||||
ESCActionManager.ACTION_INPUT_STATE.COMPLETED:
|
||||
return
|
||||
|
||||
ESCActionManager.ACTION_INPUT_STATE.AWAITING_VERB_OR_ITEM, \
|
||||
ESCActionManager.ACTION_INPUT_STATE.AWAITING_ITEM:
|
||||
tooltip.set_target("")
|
||||
verbs_menu.unselect_actions()
|
||||
|
||||
ESCActionManager.ACTION_INPUT_STATE.AWAITING_TARGET_ITEM:
|
||||
tooltip.set_target2("")
|
||||
|
||||
|
||||
|
||||
## ITEMS ##
|
||||
func left_click_on_item(item_global_id: String, event: InputEvent) -> void:
|
||||
escoria.do("item_left_click", [item_global_id, event], true)
|
||||
|
||||
var target_obj = escoria.object_manager.get_object(
|
||||
item_global_id
|
||||
).node
|
||||
|
||||
match escoria.action_manager.action_state:
|
||||
# Don't change the tooltip if an action input is completed
|
||||
# (ie verb+item(+target)) because the action is now being executed
|
||||
# and the tooltip is already set because the item was focused
|
||||
# (see element_focused() and inventory_item_focused())
|
||||
ESCActionManager.ACTION_INPUT_STATE.COMPLETED:
|
||||
return
|
||||
|
||||
# Just clicked on the item
|
||||
ESCActionManager.ACTION_INPUT_STATE.AWAITING_VERB_OR_ITEM, \
|
||||
ESCActionManager.ACTION_INPUT_STATE.AWAITING_ITEM:
|
||||
tooltip.set_target(target_obj.tooltip_name)
|
||||
|
||||
# Clicked on item and now we're awaiting a target item
|
||||
# This means we clicked the tool and we now need a target
|
||||
ESCActionManager.ACTION_INPUT_STATE.AWAITING_TARGET_ITEM:
|
||||
tooltip.set_target(target_obj.tooltip_name, true)
|
||||
|
||||
|
||||
|
||||
func right_click_on_item(item_global_id: String, event: InputEvent) -> void:
|
||||
@@ -140,7 +195,29 @@ func left_double_click_on_item(item_global_id: String, event: InputEvent) -> voi
|
||||
## INVENTORY ##
|
||||
func left_click_on_inventory_item(inventory_item_global_id: String, event: InputEvent) -> void:
|
||||
escoria.do("item_left_click", [inventory_item_global_id, event])
|
||||
|
||||
|
||||
var target_obj = escoria.object_manager.get_object(
|
||||
inventory_item_global_id
|
||||
).node
|
||||
|
||||
match escoria.action_manager.action_state:
|
||||
# Don't change the tooltip if an action input is completed
|
||||
# (ie verb+item(+target)) because the action is now being executed
|
||||
# and the tooltip is already set because the item was focused
|
||||
# (see element_focused() and inventory_item_focused())
|
||||
ESCActionManager.ACTION_INPUT_STATE.COMPLETED:
|
||||
return
|
||||
|
||||
# Just clicked on the inventory item: do nothing special
|
||||
ESCActionManager.ACTION_INPUT_STATE.AWAITING_VERB_OR_ITEM, \
|
||||
ESCActionManager.ACTION_INPUT_STATE.AWAITING_ITEM:
|
||||
return
|
||||
|
||||
# Clicked on inventory item and now we're awaiting a target item
|
||||
# This means we clicked the tool and we now need a target
|
||||
ESCActionManager.ACTION_INPUT_STATE.AWAITING_TARGET_ITEM:
|
||||
tooltip.set_target(target_obj.tooltip_name, true)
|
||||
|
||||
|
||||
func right_click_on_inventory_item(inventory_item_global_id: String, event: InputEvent) -> void:
|
||||
escoria.action_manager.set_current_action(verbs_menu.selected_action)
|
||||
@@ -153,20 +230,45 @@ func left_double_click_on_inventory_item(_inventory_item_global_id: String, _eve
|
||||
|
||||
func inventory_item_focused(inventory_item_global_id: String) -> void:
|
||||
var target_obj = escoria.object_manager.get_object(
|
||||
inventory_item_global_id
|
||||
).node
|
||||
tooltip.set_target(target_obj.tooltip_name)
|
||||
|
||||
if escoria.action_manager.current_action != "use" \
|
||||
and escoria.action_manager.current_tool == null:
|
||||
if target_obj is ESCItem:
|
||||
verbs_menu.set_by_name(target_obj.default_action_inventory)
|
||||
inventory_item_global_id
|
||||
).node
|
||||
|
||||
match escoria.action_manager.action_state:
|
||||
# Don't change the tooltip if an action input is completed
|
||||
# (ie verb+item(+target)) because the action is now being executed
|
||||
# and the tooltip is already set because the item was focused
|
||||
# (see element_focused() and inventory_item_focused())
|
||||
ESCActionManager.ACTION_INPUT_STATE.COMPLETED:
|
||||
return
|
||||
|
||||
ESCActionManager.ACTION_INPUT_STATE.AWAITING_VERB_OR_ITEM, \
|
||||
ESCActionManager.ACTION_INPUT_STATE.AWAITING_ITEM:
|
||||
tooltip.set_target(target_obj.tooltip_name)
|
||||
|
||||
# Hovering an ESCItem highlights its default action
|
||||
if escoria.action_manager.current_action != "use" and target_obj is ESCItem:
|
||||
verbs_menu.set_by_name(target_obj.default_action)
|
||||
|
||||
ESCActionManager.ACTION_INPUT_STATE.AWAITING_TARGET_ITEM:
|
||||
tooltip.set_target2(target_obj.tooltip_name)
|
||||
|
||||
|
||||
func inventory_item_unfocused() -> void:
|
||||
tooltip.set_target("")
|
||||
verbs_menu.unselect_actions()
|
||||
|
||||
|
||||
match escoria.action_manager.action_state:
|
||||
ESCActionManager.ACTION_INPUT_STATE.COMPLETED:
|
||||
# Don't change the tooltip if an action input is completed
|
||||
# (ie verb+item(+target)) because the action is now being executed
|
||||
return
|
||||
|
||||
ESCActionManager.ACTION_INPUT_STATE.AWAITING_VERB_OR_ITEM, \
|
||||
ESCActionManager.ACTION_INPUT_STATE.AWAITING_ITEM:
|
||||
tooltip.set_target("")
|
||||
verbs_menu.unselect_actions()
|
||||
|
||||
ESCActionManager.ACTION_INPUT_STATE.AWAITING_TARGET_ITEM:
|
||||
tooltip.set_target2("")
|
||||
|
||||
|
||||
func open_inventory():
|
||||
pass
|
||||
@@ -237,3 +339,4 @@ func _on_MenuButton_pressed() -> void:
|
||||
|
||||
func _on_action_finished() -> void:
|
||||
verbs_menu.unselect_actions()
|
||||
tooltip.clear()
|
||||
|
||||
@@ -1,30 +1,6 @@
|
||||
[gd_scene load_steps=2 format=2]
|
||||
|
||||
[sub_resource type="GDScript" id=1]
|
||||
script/source = "extends ESCTooltip
|
||||
|
||||
|
||||
func update_tooltip_text():
|
||||
bbcode_text = \"[center]\"
|
||||
|
||||
if !current_action.empty():
|
||||
bbcode_text += current_action
|
||||
bbcode_text += \"\\t\"
|
||||
|
||||
bbcode_text += current_target
|
||||
|
||||
if waiting_for_target2 and current_target2.empty():
|
||||
bbcode_text += \"\\t\"
|
||||
bbcode_text += current_prep
|
||||
|
||||
if !current_target2.empty():
|
||||
bbcode_text += \"\\t\"
|
||||
bbcode_text += current_prep
|
||||
bbcode_text += \"\\t\"
|
||||
bbcode_text += current_target2
|
||||
|
||||
bbcode_text += \"[/center]\"
|
||||
"
|
||||
[ext_resource path="res://addons/escoria-ui-9verbs/tooltip/tooltip_action_target.gd" type="Script" id=1]
|
||||
|
||||
[node name="tooltip" type="RichTextLabel"]
|
||||
anchor_right = 1.0
|
||||
@@ -32,7 +8,7 @@ anchor_bottom = 1.0
|
||||
bbcode_enabled = true
|
||||
bbcode_text = "[center][/center]"
|
||||
scroll_active = false
|
||||
script = SubResource( 1 )
|
||||
script = ExtResource( 1 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user