Removed ESCController and greatly reworked ESCActionManager (#480)

This commit is contained in:
Julian Murgia
2021-12-13 14:06:43 +01:00
committed by GitHub
parent 5d581df79e
commit a0f15af10b
6 changed files with 468 additions and 319 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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("")

View File

@@ -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]

View File

@@ -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()

View File

@@ -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
}