On_interaction error?

Started by Zefk, May 08, 2017, 12:08:12 PM

Previous topic - Next topic
May 08, 2017, 12:08:12 PM Last Edit: May 09, 2017, 05:13:31 AM by Zefk
I did the following with a custom entity, but the dialog is still called (if I keep pressing the spacebar) when the entity is far away unless I move the hero. How can I fix this?

Edit: This is probably a bug. A quick solaution is to check the distance with on_interaction() Here

Code ( lua) Select
  function self:on_interaction()
    if hero:get_direction() == 0 then
      self:set_direction(2)
      map:get_game():start_dialog(dialog)
    end
    if hero:get_direction() == 1 then
      self:set_direction(3)
      map:get_game():start_dialog(dialog)
    end
    if hero:get_direction() == 2 then
      self:set_direction(0)
      map:get_game():start_dialog(dialog)
    end
    if hero:get_direction() == 3 then
      self:set_direction(1)
      map:get_game():start_dialog(dialog)
    end
  end




May 08, 2017, 03:51:26 PM #2 Last Edit: May 08, 2017, 03:55:52 PM by Zefk
Code ( lua) Select
function metatable_entity:wander(speed, traversable, ignore_obstacles, movement_type, sprite_directory, dialog)

  local map = self:get_map()
  local hero = map:get_hero()
  local sprite
  local quick_movement

  function self:on_created()
     sprite = self:create_sprite(sprite_directory)
     self:set_can_traverse("hero", traversable)
     self:set_traversable_by("hero", false)
     self:set_drawn_in_y_order(true)

     quick_movement = sol.movement.create(movement_type)
     quick_movement:set_ignore_obstacles(ignore_obstacles)
     quick_movement:set_speed(speed)
     quick_movement:start(self)
  end

  function self:on_interaction()
    if hero:get_direction() == 0 then
      self:set_direction(2)
      map:get_game():start_dialog(dialog)
    end
    if hero:get_direction() == 1 then
      self:set_direction(3)
      map:get_game():start_dialog(dialog)
    end
    if hero:get_direction() == 2 then
      self:set_direction(0)
      map:get_game():start_dialog(dialog)
    end
    if hero:get_direction() == 3 then
      self:set_direction(1)
      map:get_game():start_dialog(dialog)
    end
  end

  function self:on_movement_changed()
     sprite:set_direction(quick_movement:get_direction4())   
  end
end


I declared it in a custom entity like this:

Code ( lua) Select
entity:wander(80, false, false, "random_path", "citizens/village_woman_6", "welcome_sign")

In my opinion....It might be a bug. I did the following instead of on_interaction().

Code ( lua) Select
  --Create timer on check
  timer = sol.timer.start(300, function()
    if self.on_check ~= nil then
      self:on_check()
   return true
    end
  end)

  local test = false 
  --check entity front and back layer and correct it.
  function self:on_check()
    local distance_check = hero:get_distance(self)

    if distance_check <= 16  and test == true then
    print("pressed")
    print(distance_check)
      if hero:get_direction() == 0 then
        self:set_direction(2)
        map:get_game():start_dialog(dialog)
      end
      if hero:get_direction() == 1 then
        self:set_direction(3)
        map:get_game():start_dialog(dialog)
      end
      if hero:get_direction() == 2 then
        self:set_direction(0)
        map:get_game():start_dialog(dialog)
      end
      if hero:get_direction() == 3 then
        self:set_direction(1)
        map:get_game():start_dialog(dialog)
      end
    end

    function map:on_key_pressed(key)   
      if key == "y" then
        test = true
      print("true")
      else
        test = false
      end
    end 

May 08, 2017, 08:06:03 PM #4 Last Edit: May 08, 2017, 08:08:29 PM by Zefk
A better solution and one that will work for more than one of the same entity is to check the distance with on_interaction().


Code ( lua) Select
  --Create timer on check
  timer = sol.timer.start(300, function()
    if self.on_check ~= nil then
      self:on_check()
   return true
    end
  end)

  --check entity front and back layer and correct it.
  function self:on_check()
    local distance_check = hero:get_distance(self)
   function self:on_interaction()
    if distance_check <= 20 then
      if hero:get_direction() == 0 then
        self:set_direction(2)
        map:get_game():start_dialog(dialog)
      end
      if hero:get_direction() == 1 then
        self:set_direction(3)
        map:get_game():start_dialog(dialog)
      end
      if hero:get_direction() == 2 then
        self:set_direction(0)
        map:get_game():start_dialog(dialog)
      end
      if hero:get_direction() == 3 then
        self:set_direction(1)
        map:get_game():start_dialog(dialog)
      end
    end
   end
end

Which is the custom entity in your image above?
If it is a sign, maybe you should check if the hero is facing it, but I am not sure if that is really necessary.
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."

May 08, 2017, 08:54:47 PM #6 Last Edit: May 09, 2017, 01:40:42 AM by Zefk
@Diarandor

The pink sprite in the upper left corner. Actually, it traveled all the way across the map and I was still able to activate the dialog as long as the hero did not move. I tested this in more than one place on the map.  Edit: I had to go up to the entity and interact with it before this error started.

Calculating the distance in the post above fixed the problem, but is the on_interaction() function suppose to work that way?

Code ( lua) Select
  function self:on_interaction()
    local distance_check = hero:get_distance(self)

    if distance_check <= 20 then
      if hero:get_direction() == 0 then
        self:set_direction(2)
        map:get_game():start_dialog(dialog)
      end
      if hero:get_direction() == 1 then
        self:set_direction(3)
        map:get_game():start_dialog(dialog)
      end
      if hero:get_direction() == 2 then
        self:set_direction(0)
        map:get_game():start_dialog(dialog)
      end
      if hero:get_direction() == 3 then
        self:set_direction(1)
        map:get_game():start_dialog(dialog)
      end
    end
  end

I am quite sure that on_interaction does not work in that way. I think that the hero must be facing the bounding box of the custom entity, and if that is the case, maybe the origin point of your custom entity sprite is wrong. Could you check if that is the problem?
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."

May 09, 2017, 05:10:15 AM #8 Last Edit: May 09, 2017, 05:15:56 AM by Zefk
The origin was the first thing I checked. Everything is fine in that area and on_interaction() works with my sprites as a NPC entity. (Just tested it again.)

I honestly think this is a bug, but it might not be related to distance or it could be. All I know is that a distance check prevents the bug from occurring for my custom_entity functions.

how big is your custom entity if you do entity:get_size()?

The output is 16 x 16

That was the second thing I checked.  ;D

I even tried manually setting it with self:set_size and self:set_origin. Same exact issue.

 

Just to be sure, have you checked both origin points? (There are 2, the one of the sprite and the one of the entity.)
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."

May 09, 2017, 06:28:09 PM #12 Last Edit: May 09, 2017, 06:33:39 PM by Zefk
Indeed, I did check that. Also, the problem is not only with my sprite. It happens to other sprites as well in the sample_quest. 

As I mentioned before all sprites work with the NPC entity's on_interaction() function. I will point out what we covered.

Custom Entity On_interaction bug:

Solarus version: 1.5.0

If the hero interacts with a custom entity with the function on_interaction(), then the hero can activate the custom entity as long as the hero does not move. The custom entity can be 10,000+ pixels away and the hero can still activate it. If the hero moves, then this bug cancels.

Problems it is not: (I triple checked)

  • Not Origin
  • Not sprite size
  • Not second origin
  • Not second sprite size
  • Not a problem with set_size() and set_origin()
  • Not Code
  • Not Sprites

Current solution is a distance check while using the on_interaction() function for a custom entity.

Code ( lua) Select
  function self:on_interaction()
    local distance_check = hero:get_distance(self)

    if distance_check <= 20 then
      if hero:get_direction() == 0 then
        self:set_direction(2)
        map:get_game():start_dialog(dialog)
      end
      if hero:get_direction() == 1 then
        self:set_direction(3)
        map:get_game():start_dialog(dialog)
      end
      if hero:get_direction() == 2 then
        self:set_direction(0)
        map:get_game():start_dialog(dialog)
      end
      if hero:get_direction() == 3 then
        self:set_direction(1)
        map:get_game():start_dialog(dialog)
      end
    end
  end

So you are using Solarus v1.5.0. Try to use version 1.5.3, does it happen too?
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."

May 10, 2017, 01:00:55 AM #14 Last Edit: May 10, 2017, 05:26:18 AM by Zefk
I just checked and it still happens in Solarus version 1.5.3.

Edit: I reported the bug: https://github.com/solarus-games/solarus/issues/1056

On another note. I think I found another bug unrelated to this post.