Problems with "get_facing_entity()" being a one time use?

Started by Argeus, May 16, 2022, 03:46:21 AM

Previous topic - Next topic
This may be user error and not a bug because I am not a programmer by trade or experience.  Apologies in advance.

I have a side project in which I am having a problem where "get_facing_entity()" only works once.  In the project I have a custom entity that follows the hero around.  This custom entity needs to be able to detect certain map entities, namely movement entities like "stairs" and "jumpers."  The relevant code is below:

--ALLOWING THE CUSTOM_ENTITY TO INTERACT WITH "JUMPER" ENTITIES
custom_entity:set_can_traverse("jumper", jumper_found)

--FUNCTION SETUPS

--TO END ANY CURRENT MOVEMENTS IF APPLICABLE
function end_movement()
  custom_entity:stop_movement()
  alt_movement = false
  object = nil
end

--ACTIVATES WHEN THE CUSTOM_ENTITY RUNS INTO A "JUMPER"
function jumper_found()
    --ENDS ANY MOVEMENT
    end_movement()

    --ASSIGNS THE ENCOUNTERED "JUMPER" SO I CAN PULL PROPERTIES FROM IT
    object = custom_entity:get_facing_entity()

    --CREATES THE JUMP MOVEMENT
    jump = sol.movement.create("jump")

    jump:set_ignore_obstacles(true)

    --PULLS A CUSTOM "DIR" PROPERTY WHICH TELLS THE CUSTOM ENTITY WHICH WAY TO JUMP
    jump:set_direction8(object:get_property("dir"))

    --PULLS A CUSTOM "DIST" PROPERTY WHICH TELLS THE CUSTOM ENTITY HOW FAR TO JUMP
    jump:set_distance(object:get_property("dist"))

    --STARTS THE JUMP AND ENDS THE JUMP SO STANDARD MOVEMENT CAN RESUME
    jump:start(custom_entity, end_movement)
   
    --CUSTOM VARIABLE USED ELSEWHERE TO PREVENT STANDARD MOVEMENTS FROM ACTIVATING WHILE JUMPING
    alt_movement = true
end

--RUNTIME MONITORING
function custom_entity:on_update()

  print(object)

end


The problem is that "get_facing_entity()" will only work on the first entity it encounters.  For instance, I have a "chest" entity and a "jumper" entity; if I bump the custom entity into the "jumper," then "get_facing_entity()" assigns that entity to "object."  I can manually set "object" back to "nil" using a debug key command, but if I proceed to bump the custom entity into the "chest," then "get_facing_entity()" still returns the id of the "jumper" that it touched earlier, and the "jump" movement will activate.

What's even more strange is if I bump into the "chest" first, then the "chest" entity is assigned to "object" even though according to my understanding of the above code, my custom "jumper_found()" function should only be activating when the custom entity explicitly encounters a "jumper" entity.

I've moved my "jumper_found()" function declaration into the "on_created()" function to ensure it doesn't run unless called.  No change.

I've attempted making "object" local.  No change.

I've attempted embedding "get_facing_entity()" into the "on_update()" function so it constantly runs.  No change.

I'm sure I am probably just using "get_facing_entity()" wrong, but I've been stumped for 3 days now on this one task.

Hopefully you've fixed this already, but I've had a look and I'm getting the same problem with get_facing_entity just returning the same entity each time.

I'm just a beginner with Solarus but it definitely looks like a bug?

However, when my custom entity collides with a chest, my function isn't triggering, only jumpers - so that might be a problem with part of your code that isn't shown.

You might want to post the problem with get_facing_entity on the gitlab as an Issue, I don't expect that to happen.

Anyway, I've found a workaround that will hopefully do what you want:

Change the line:

function jumper_found():
to
function jumper_found(self, object):

self will be the custom_entity, and object will be the same as your object variable - you won't need to assign it, just delete the 'object = get_facing_entity()' line.

I worked this out from reading the docs on set_can_traverse, it mentions that the function you assign can take 2 parameters, the entity and the one you're colliding with.

Hopefully that helps if you haven't already fixed it.  :D

Quote from: ultidonki on May 30, 2022, 10:34:33 PM
Hopefully that helps if you haven't already fixed it.  :D

Nope, I never fixed it.  I've been addressing other aspects of the project while waiting for potential feedback/input about this.

Quote from: ultidonki on May 30, 2022, 10:34:33 PM
Anyway, I've found a workaround that will hopefully do what you want:

Change the line:

function jumper_found():
to
function jumper_found(self, object):

self will be the custom_entity, and object will be the same as your object variable - you won't need to assign it, just delete the 'object = get_facing_entity()' line.

I worked this out from reading the docs on set_can_traverse, it mentions that the function you assign can take 2 parameters, the entity and the one you're colliding with.

Hopefully that helps if you haven't already fixed it.  :D

Thanks for the workaround!  This method seems to be working.  I will know for sure once I start adding other interactions for other entity types using a similar method.