feat: integrate inventory with cursor system, scene input, and GameScript
- ActionState: add ITEM action (value 4) to enum and get_action_name() - MainGame: right-click cycles through all 5 actions including ITEM; skips ITEM if nothing selected; clears selection when cycling away - Scene: guard _unhandled_input() against active inventory overlay; handle ITEM action for world-wide item use; add give_item(), remove_item(), strip_items() helper methods - SetPiece: handle ITEM action by calling scene's _use_item_on_setpiece() - GameScript: add GiveItem and GiveItemDeferred script step classes for item acquisition during cutscenes
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
extends Node
|
||||
|
||||
enum Action { WALK = 0, LOOK = 1, TOUCH = 2, TALK = 3 }
|
||||
enum Action { WALK = 0, LOOK = 1, TOUCH = 2, TALK = 3, ITEM = 4 }
|
||||
|
||||
var current_action: int = Action.WALK:
|
||||
set(value):
|
||||
@@ -22,6 +22,7 @@ func get_action_name() -> String:
|
||||
Action.LOOK: return "look"
|
||||
Action.TOUCH: return "touch"
|
||||
Action.TALK: return "talk"
|
||||
Action.ITEM: return "item"
|
||||
return "walk"
|
||||
|
||||
func get_action_enum() -> int:
|
||||
|
||||
@@ -476,5 +476,54 @@ func switch_camera(path):
|
||||
func reset_camera():
|
||||
var thing = ResetCamera.new()
|
||||
return thing
|
||||
|
||||
class GiveItem:
|
||||
extends ScriptNode
|
||||
var item_id: String = ""
|
||||
var text: String = ""
|
||||
var subject: Node2D = null
|
||||
var done = false
|
||||
var started = false
|
||||
|
||||
func step_type():
|
||||
return "GiveItem " + item_id
|
||||
|
||||
func init(scene):
|
||||
super(scene)
|
||||
|
||||
func do(delta):
|
||||
if not started:
|
||||
started = true
|
||||
if text:
|
||||
await scene.find_child("dialogue").say(text)
|
||||
InventoryManager.acquire_item(item_id)
|
||||
done = true
|
||||
|
||||
func is_done():
|
||||
return done
|
||||
|
||||
func interrupt():
|
||||
done = true
|
||||
|
||||
class GiveItemDeferred:
|
||||
extends GiveItem
|
||||
var subject_name: String = ""
|
||||
|
||||
func init(scene):
|
||||
super(scene)
|
||||
subject = scene.get_node(subject_name)
|
||||
|
||||
func give_item(item_id: String, text: String = ""):
|
||||
var step = GiveItem.new()
|
||||
step.item_id = item_id
|
||||
step.text = text
|
||||
return step
|
||||
|
||||
func give_item_deferred(item_id: String, subject_name: String, text: String = ""):
|
||||
var step = GiveItemDeferred.new()
|
||||
step.item_id = item_id
|
||||
step.subject_name = subject_name
|
||||
step.text = text
|
||||
return step
|
||||
|
||||
var current_script : ScriptGraph = null
|
||||
|
||||
14
MainGame.gd
14
MainGame.gd
@@ -78,5 +78,15 @@ func _input(event):
|
||||
if event.is_action_released("quit"):
|
||||
get_tree().quit()
|
||||
if event.is_action_released("right_click") and not is_cursor_locked:
|
||||
ActionState.current_action = (ActionState.current_action + 1) % 4
|
||||
Input.set_custom_mouse_cursor(cursors[ActionState.current_action], Input.CursorShape.CURSOR_ARROW, Vector2(0,0))
|
||||
var prev_action = ActionState.current_action
|
||||
ActionState.current_action = (ActionState.current_action + 1) % 5
|
||||
if ActionState.current_action == ActionState.Action.ITEM:
|
||||
if InventoryManager.selected_item:
|
||||
Input.set_custom_mouse_cursor(cursors[ActionState.current_action], Input.CursorShape.CURSOR_ARROW, Vector2(0,0))
|
||||
else:
|
||||
ActionState.current_action = (ActionState.current_action + 1) % 5
|
||||
Input.set_custom_mouse_cursor(cursors[ActionState.current_action], Input.CursorShape.CURSOR_ARROW, Vector2(0,0))
|
||||
else:
|
||||
if prev_action == ActionState.Action.ITEM:
|
||||
InventoryManager.clear_selection()
|
||||
Input.set_custom_mouse_cursor(cursors[ActionState.current_action], Input.CursorShape.CURSOR_ARROW, Vector2(0,0))
|
||||
|
||||
46
Scene.gd
46
Scene.gd
@@ -128,7 +128,12 @@ func _unhandled_input(event):
|
||||
if ScriptBuilder.current_script and not ScriptBuilder.current_script.can_interrupt:
|
||||
if ScriptBuilder.current_script.handle_input(event):
|
||||
return
|
||||
|
||||
|
||||
# Block input when inventory overlay is active
|
||||
var overlay = get_node_or_null("/root/Node2D/InventoryOverlay")
|
||||
if overlay and overlay is InventoryOverlay and overlay.is_active():
|
||||
return
|
||||
|
||||
var root = get_node("/root/Node2D")
|
||||
# If look cursor is active and we got here, no SetPiece handled the input
|
||||
# so this is a room-wide look
|
||||
@@ -138,7 +143,46 @@ func _unhandled_input(event):
|
||||
if ActionState.current_action == ActionState.Action.WALK:
|
||||
var path = NavigationServer2D.map_get_path(map, ego.position, pathfind.to_local(get_global_mouse_position()), true)
|
||||
start_main_script(ScriptBuilder.init(ScriptBuilder.walk_path(ego, path)).can_interrupt().build(self, "_on_script_complete"))
|
||||
if ActionState.current_action == ActionState.Action.ITEM:
|
||||
_on_item_use_in_world()
|
||||
|
||||
func _on_room_looked() -> void:
|
||||
# Default room look description - override in room scripts
|
||||
pass
|
||||
|
||||
func _on_item_use_in_world() -> void:
|
||||
if not InventoryManager.selected_item:
|
||||
return
|
||||
var item_id = InventoryManager.selected_item
|
||||
var top_piece = ActionState.get_top_hovered_setpiece()
|
||||
if top_piece:
|
||||
_use_item_on_setpiece(item_id, top_piece)
|
||||
else:
|
||||
_on_item_used_empty_space(item_id)
|
||||
|
||||
func _use_item_on_setpiece(item_id: String, piece: SetPiece) -> void:
|
||||
if piece.has_method("_on_item_used"):
|
||||
piece._on_item_used(item_id)
|
||||
else:
|
||||
var def = InventoryManager.get_item_definition(item_id)
|
||||
var item_name = item_id
|
||||
if def:
|
||||
item_name = def.name
|
||||
var piece_name = piece.label if piece.label else piece.name
|
||||
start_main_script(ScriptBuilder.init(ScriptBuilder.say(ego, "I can't use the %s on the %s." % [item_name, piece_name])).build(self, "_on_script_complete"))
|
||||
|
||||
func _on_item_used_empty_space(item_id: String) -> void:
|
||||
var def = InventoryManager.get_item_definition(item_id)
|
||||
var item_name = item_id
|
||||
if def:
|
||||
item_name = def.name
|
||||
start_main_script(ScriptBuilder.init(ScriptBuilder.say(ego, "There's nothing to use the %s on here." % [item_name])).build(self, "_on_script_complete"))
|
||||
|
||||
func give_item(item_id: String) -> void:
|
||||
InventoryManager.acquire_item(item_id)
|
||||
|
||||
func remove_item(item_id: String, quiet: bool = false) -> void:
|
||||
InventoryManager.remove_item(item_id, quiet)
|
||||
|
||||
func strip_items(event_items: Array[String], exempt_items: Array[String] = []) -> void:
|
||||
InventoryManager.bulk_strip_items(event_items, exempt_items)
|
||||
|
||||
@@ -75,3 +75,9 @@ func _input(event):
|
||||
ActionState.Action.TALK:
|
||||
if talked.get_connections().size() > 0:
|
||||
emit_signal("talked")
|
||||
ActionState.Action.ITEM:
|
||||
if InventoryManager.selected_item:
|
||||
var item_id = InventoryManager.selected_item
|
||||
var scene = get_node_or_null("/root/Node2D/SceneViewport/background")
|
||||
if scene and scene is Scene:
|
||||
scene._use_item_on_setpiece(item_id, self)
|
||||
|
||||
Reference in New Issue
Block a user