Solarus-Games English Forum

Solarus => Development => Topic started by: MetalZelda on July 13, 2016, 12:33:29 AM

Title: [SOLVED] Checking if the hero is overlapping an entity with a compatible name ?
Post by: MetalZelda on July 13, 2016, 12:33:29 AM
Hello !

So I was finalizing my Ocarina item and thought of something.

For my Water Temple (and other places) in my project, there are a lot of entities that need the ocarina to do some actions.
In the ocarina script, things goes like this

Code (lua) Select

-- these are example, h = hero
--ocarina_zelda_x = event id on the map

    -- for e in m:get_entities("ocarina_zelda") do
  -- if h:overlaps(e) then
    -- e:on_zelda_lullaby_interaction()
  -- else
    -- self:return_no_effect()
  -- end
-- end
-- end


If I playtest and play Zelda Lullaby (as shown above), it execute every entities with the name 'ocarina_zelda' present in the map, so it call both e:on_zelda_lullaby_interaction() because I am overlapping one of these entity, and it also execute return_no_effect(),  while the thing I want is execute the only entity Link is overlapping

Any clues ?
Title: Re: Checking if the hero is overlapping an entity with a compatible name ?
Post by: Satoh on July 13, 2016, 12:56:26 AM
Its doing both e:return_no_effect() and e:on_zelda_lullaby_interaction() because you're checking all entities that have those functions.
So say you have 5 possible entities 'e'
What's happening is
e:return_no_effect()                   --first e found
e:return_no_effect()                   --second e found
e:on_zelda_lullaby_interaction()--third e found
e:return_no_effect()                   --fourth e found
e:return_no_effect()                   --fifth e found

That's assuming you've programmed your ocarina_zelda entities correctly, and there's no problems with your search.

What I would do, is make the ocarina_zelda_whatever entities do a collision test, and in that collision test, check to see of the hero is using the ocarina.
There's a number of things that might be going wrong.

First of all, if return_no_effect() doesn't do anything, just remove your else altogether. I think most likely the Else is what's screwing you up, as I understand your statement.


But lets say you need to track the event that the Hero isn't overlapping ANY such entity, and return a message that says nothing happened.

What you would then do is
Code (lua) Select

    -- these are example, h = hero
    --ocarina_zelda_x = event id on the map
    local overlapping = false
        -- for e in m:get_entities("ocarina_zelda") do
              -- if h:overlaps(e) then
                -- e:on_zelda_lullaby_interaction()
                overlapping = true

               -------------No Else
              -- end
            -- end
   if not overlapping then
     -- display your 'not overlapping any valid entities' effect here
     overlapping = false
   end
            -- end

Title: Re: Checking if the hero is overlapping an entity with a compatible name ?
Post by: Diarandor on July 13, 2016, 08:32:43 AM
I agree with Satoh that the problem is probably that each time an entity that cannot interact is checked, then the method return_no_effect() is being called. So kudos to Satoh. (By the way, is it "e:return_no_effect()" or "self:return_no_effect()? Well, it does not matter.) I propose a similar code (using a return instead of using the "overlapping" variable), although this code would not allow to activate several interactive entities at the same time:

Code (Lua) Select

-- Ocarina script.
local item = ...
local m = item:get_map()
local h = m:get_hero()

function item:activate_ocarina_entities()
  for e in m:get_entities("ocarina_zelda") do
    if h:overlaps(e) then
      e:on_zelda_lullaby_interaction()
      return
    end
  end
  self:return_no_effect()
end
Title: Re: Checking if the hero is overlapping an entity with a compatible name ?
Post by: MetalZelda on July 13, 2016, 12:57:14 PM
Quote from: Diarandor on July 13, 2016, 08:32:43 AM
I agree with Satoh that the problem is probably that each time an entity that cannot interact is checked, then the method return_no_effect() is being called. So kudos to Satoh. (By the way, is it "e:return_no_effect()" or "self:return_no_effect()? Well, it does not matter.) I propose a similar code (using a return instead of using the "overlapping" variable), although this code would not allow to activate several interactive entities at the same time:

Code (Lua) Select

-- Ocarina script.
local item = ...
local m = item:get_map()
local h = m:get_hero()

function item:activate_ocarina_entities()
  for e in m:get_entities("ocarina_zelda") do
    if h:overlaps(e) then
      e:on_zelda_lullaby_interaction()
      return
    end
  end
  self:return_no_effect()
end


Looks like it is working, thanks!

Quote from: Satoh on July 13, 2016, 12:56:26 AM
Its doing both e:return_no_effect() and e:on_zelda_lullaby_interaction() because you're checking all entities that have those functions.
So say you have 5 possible entities 'e'
What's happening is
e:return_no_effect()                   --first e found
e:return_no_effect()                   --second e found
e:on_zelda_lullaby_interaction()--third e found
e:return_no_effect()                   --fourth e found
e:return_no_effect()                   --fifth e found

That's assuming you've programmed your ocarina_zelda entities correctly, and there's no problems with your search.

What I would do, is make the ocarina_zelda_whatever entities do a collision test, and in that collision test, check to see of the hero is using the ocarina.
There's a number of things that might be going wrong.

First of all, if return_no_effect() doesn't do anything, just remove your else altogether. I think most likely the Else is what's screwing you up, as I understand your statement.


But lets say you need to track the event that the Hero isn't overlapping ANY such entity, and return a message that says nothing happened.

What you would then do is
Code (lua) Select

    -- these are example, h = hero
    --ocarina_zelda_x = event id on the map
    local overlapping = false
        -- for e in m:get_entities("ocarina_zelda") do
              -- if h:overlaps(e) then
                -- e:on_zelda_lullaby_interaction()
                overlapping = true

               -------------No Else
              -- end
            -- end
   if not overlapping then
     -- display your 'not overlapping any valid entities' effect here
     overlapping = false
   end
            -- end



self:return_no_effect() is used when the overlapping condition isn't met or if we are in a place where the ocarina song is useless (inside a house for example), it only display a message and stop the ocarina.