Skip to content

Implement NPC investigation state logic#508

Open
luiscarloscontreirassilvestre-art wants to merge 11 commits into
Phazorknight:1.1.5-rcfrom
luiscarloscontreirassilvestre-art:patch-4
Open

Implement NPC investigation state logic#508
luiscarloscontreirassilvestre-art wants to merge 11 commits into
Phazorknight:1.1.5-rcfrom
luiscarloscontreirassilvestre-art:patch-4

Conversation

@luiscarloscontreirassilvestre-art

Copy link
Copy Markdown
Contributor

This script defines the NPC investigation state, including timers for observing and moving, handling NPC interactions, and managing investigation status.

This script defines the NPC investigation state, including timers for observing and moving, handling NPC interactions, and managing investigation status.
@Phazorknight Phazorknight self-requested a review January 2, 2026 17:12

@Phazorknight Phazorknight left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks promising but could you update this PR with an example implementation of this state?

Also please see other comments/questions. Thank you!

# Send signal or command to nearby NPC to investigate
if npc.has_method("set_investigate_target"):
npc.set_investigate_target(investigate_location)
elif npc.has_meta("state_machine"):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cogito_npc has a direct reference to it's state machine.
Whats your reasoning for using get_meta / set_meta for this?

var all_npcs = get_tree().get_nodes_in_group("npc")

for npc in all_npcs:
if npc == Host:

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this makes sense. Host is basically the parent node of the state machine, but the way this is written, it implies that it only looks for this statemachines host npc.


func _call_nearby_npcs():
# Find all NPCs in the scene
var all_npcs = get_tree().get_nodes_in_group("npc")

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR doesn't add or set an "npc" group so this line won't do what it's intended to do.

enum InvestigateStatus{ OBSERVING, MOVING_TO_LOCATION, INVESTIGATING, COMPLETE = 3 }
var current_investigate_status : InvestigateStatus = InvestigateStatus.OBSERVING

@export var investigate_animation : String = "alert"

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you're setting a default string, could you set it to an animation that exists?
I know there's no matching animation included but maybe we can repurpose a different one, like the talk or dance one, just so this can be tested.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Items are dropped to trigger the investigated state.

inventory_interface.gd to notify nearby NPCs after a drop — searching for NPCs in the "npc" group and calling their npc_state_machine.goto("investigate").

dropped_item.find_interaction_nodes()
for node in dropped_item.interaction_nodes:
if node.has_method("get_item_type"):
node.slot_data = slot_data

# Notify nearby NPCs to investigate this drop
var investigate_radius := 8.0
var drop_pos := dropped_item.global_position
var all_npcs := get_tree().get_nodes_in_group("npc")
for npc in all_npcs:
	if npc == null:
		continue
	if not npc.has_method("global_position"):
		# assume it's a Node3D-like with property
		pass
	var dist := npc.global_position.distance_to(drop_pos)
	if dist <= investigate_radius:
		# Provide investigate target and switch state if possible
		if npc.has_method("set_investigate_target"):
			npc.set_investigate_target(drop_pos)
		else:
			# set meta for state to read
			npc.set_meta("investigate_location", drop_pos)
			if npc.has("npc_state_machine") and npc.npc_state_machine and npc.npc_state_machine.has("investigate"):
				npc.npc_state_machine.goto("investigate")
			elif npc.npc_state_machine and npc.npc_state_machine.has("investigate"):
				npc.npc_state_machine.goto("investigate")

return true

This class provides a method to notify nearby NPCs to investigate a specified location within a given radius. It sets the investigate location meta key and transitions NPCs into the investigate state if applicable.
@luiscarloscontreirassilvestre-art

Copy link
Copy Markdown
Contributor Author
inventory_interface.gd


   # Notify nearby NPCs to investigate this drop via InvestigateSoundManager
#
# This call broadcasts a simple investigate request to all NPCs in the
# group "npc" within the given radius. Notified NPCs receive a meta key
# `investigate_location` and will be asked to transition into their
# `investigate` state (if available). Use this for gameplay events such as
# dropped items producing attention from nearby NPCs.
var drop_pos: Vector3 = dropped_item.global_position
var InvestigateSoundManager = preload("res://addons/cogito/InvestigateSoundManager.gd")
InvestigateSoundManager.broadcast_investigate(drop_pos, 8.0)

@luiscarloscontreirassilvestre-art

Copy link
Copy Markdown
Contributor Author

"Investigate" Status Implemented
Main Features:
Observation Phase - The NPC stands still observing for 2 seconds
Movement for Investigation - Moves towards the location/sound at 80% of normal speed
Investigation - Remains at the location observing for up to 15 seconds
Cooperation with Nearby NPCs - Automatically calls other NPCs within an 8m radius to investigate together

@luiscarloscontreirassilvestre-art

Copy link
Copy Markdown
Contributor Author
Screenshot_20260103_094530 Screenshot_20260103_094539 Screenshot_20260103_095235

@luiscarloscontreirassilvestre-art

Copy link
Copy Markdown
Contributor Author
Screenshot_20260103_093430

@luiscarloscontreirassilvestre-art

Copy link
Copy Markdown
Contributor Author

I know the code has some errors, but from my point of view it works. It works for me. But I also know it needs improvement. Now the community has better options.

There are other alternatives.

This system below hasn't been created yet, it's just an idea.

For example, an item drop within a 3D area initiates an investigation.

Another option is to have a global location of the active NPC looter position.

To create another system, add LootComponent to a box, spawn items.

Place NPC on patrol.
Valuable item within radius → NPC stops, goes to, picks it up, returns to patrol.
NPC inventory: check in the Inspector or add HUD debug.

This makes the NPC looters smarter!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactor NPC investigate state logic

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logi

@luiscarloscontreirassilvestre-art

Copy link
Copy Markdown
Contributor Author

The code was very confusing. Please clean up the code to make it simpler. There are no longer distance limits or animations required for it to work. There needs to be an NPC scene group, but it can be changed to another name. The PR is working without bugs.
Good luck.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants