Phazorknight / Cogito

Immersive Sim Template Project for GODOT 4
MIT License
865 stars 98 forks source link

Dropping a carried item while your cursor is hovering over another one activates the interact on said item #176

Closed aronand closed 5 months ago

aronand commented 5 months ago

Cogito and Godot Engine Version: Godot: 4.2.1 Cogito: 6d9f37e

Description: If the player is carrying an item/a carriable, and drops it in such a way that their cursor is hovering over another carriable with the same interaction key, the carried object is switched to a new one instead.

This is caused by the carried object dropping happening just before checking for interactions with a detected interactable in PlayerInteractionComponent.

Reproduction steps: This is easiest to reproduce in a place where multiple items are close by.

  1. Start carrying an item
  2. Move your cursor in such a way, that it hovers over another carriable, and without causing the carry to automatically stop
  3. Press the interaction key
  4. Notice how instead of dropping the item, a new one replaces it

Expected behavior: The item should be dropped and the input shouldn't fall through to the next interactable if one happens to be in view.

Screenshots: cogito_carriable_bug

Phazorknight commented 5 months ago

Please see https://github.com/Phazorknight/Cogito/commit/0264cd2dd2ce1e072ff3ecde4c74d93b80f6a108 if that fixes this for you.

The input event goes further down the tree, causing this behavior. A simple return should hopefully have fixed this for now.

aronand commented 5 months ago

That fixed it indeed 👍

How do you feel about one more slight change, moving the whole interaction handling block into its own function?

func _handle_interaction(action: String) -> void:
    # if carrying an object, drop it.
    if is_carrying:
        if is_instance_valid(carried_object) and carried_object.input_map_action == action:
            carried_object.throw(throw_power)
            return
        elif !is_instance_valid(carried_object):
            stop_carrying()
            return

    # Check if we have an interactable in view and are pressing the correct button
    if interactable != null and not is_carrying:
        for node: InteractionComponent in interactable.interaction_nodes:
            if node.input_map_action == action and not node.is_disabled:
                node.interact(self)
                # Update the prompts after an interaction. This is especially crucial for doors and switches.
                _rebuild_interaction_prompts()
                break
Phazorknight commented 5 months ago

Yeah that makes sense. Just added this in https://github.com/Phazorknight/Cogito/commit/4f0e4baf74ffe986b5813f8b2a5118cb68cf3d7d

I assume this issue can be closed now, but feel free to reopen if something comes up.