Seach for an entity?

Started by ponderitus, August 09, 2019, 11:13:20 AM

Previous topic - Next topic
Hey, long time. I was working on an item the other day and wondered if there is a way to check for entities on the map on use..I was trying to make something that would freeze an enemy if it exists

ie.

function item:on_using()
  item:check_enemy()
  if entity type enemy then
    enemy:freeze()
    --function of item, function()
     enemy:unfreeze()
    end)
  else
    --function of item
  end
  self:set_finished()
end

function item:check_enemy()
--check map for enemies
end

I think you could do something like
```local map = item:get_map()
for enemy in map:get_entities_by_type("enemy") do
   enemy:freeze()
end```

August 10, 2019, 02:11:55 AM #2 Last Edit: August 10, 2019, 02:21:36 AM by Kamigousu
If you don't mind naming your entities with a prefix you can use map:has_entities(prefix)/map:get_entities(prefix). Here is a link to the API page for the former: https://www.solarus-games.org/doc/latest/lua_api_map.html#lua_api_map_has_entities

then just run your for loop on the results and freeze what ever you need to.

EDIT: realising now you may have wanted to freeze any given enemy/all enemies on the map. In this case, you could use the code provided by Max.
Build a man a fire, he will be warm for the night. Set a man on fire, he will be warm for the rest of his life.
a.k.a. Kamigousu, Xejk, Sr Xejk

cheers for the help guys, the code max gave kinda works, it finds them...but the enemy:freeze() gives me

"attempt to call method 'freeze' (a nil value)"

i tried using enemy:immobilize() but that pushes the enemy away from the hero so it looks kinda weird.

Oh, you had been typing enemy:freeze(), so I assumed that was a method you'd added yourself to the metatable or something.

Depending on how simple you enemies are, you might be able to add an enemy:freeze() method, as long as you remember to deal with the fact that all when an enemy is damaged, all timers and stopped on them and enemy:restart() is called.

If you don't want to do that, unfortunately enemy:immobilize() is the only option, and you can't set the length of time they're frozen and there's no way to unfreeze them.

yeah i just wrote that as an example of what i wanted to happen and then realised that no such thing exists and i didnt have another way of explaining what i wanted to happen. I honestly have no idea how to perform what you suggested in adding it to the enemy_meta but ill be looking into it.

my enemies are pretty simple, I havent made any new ones that dont basically mimic something from the past...other than that deku scrub that you made for me lol.

I thought it would open up for being able to use like a magic attack, like a little "cutscene" could happen and some things could appear on screen, then any enemy within a radius get damaged by it or are turned into something like a pot or a flower...I was just messing around making a little ocarina item though lol. just so at any point you could whip out an ocarina and play it. i got it working all fine but then realised i hadnt put anything in to stop things moving and wondered what would happen if an enemy was present...and surely enough they just kept moving. so i set game:set_suspended(true) on using and false on finish...which works for the enemies...but also stops the hero...which means the correct animation loads but it just stays at frame 1.

it could also be used for some kinda fast travel applications aswell, eg. item loads a dialog, answer leads to cutscene of being picked up and then teleport happens....like the flute and the bird in link to the past

just incase anyone is wondering. i got around this by making the enemies walk an empty path and then enemy:restart() at the end. technically does freeze them lol

August 14, 2019, 12:49:19 AM #7 Last Edit: August 14, 2019, 12:52:03 AM by Max
Oooh, I see. I'd argue that you're trying to solve the wrong problem. The issue isn't that you need to stop enemies from moving, you really SHOULD be suspending the game for this, and you need to figure out how to show the animation you want anyway.

Which is pretty simple:
hero:get_sprite():set_ignore_suspend(true)

I mean, your solution technically works so it's not wrong, and maybe should is a strong word. But effectively what you're describing is you do want the game to suspend. You don't want enemies moving, or starting attacks, you wouldn't want NPCs to keep walking around, you wouldn't want some timer you've set to go off, etc. If you don't suspend the game you leave yourself open to a lot of potential conflicts I think

you know whats funny,  that was the first thing i tried and the original plan but i couldnt find a way to get hero to ignore suspended so i gave up and tried another route, I could only figure out how to make an NPC or timer ignore suspended...when that didnt work i thought its time i ask for help...should have just asked straight a way lol. would have saved me a lot of time, i wasn't adding :get_sprite() originally so it didnt work. That one line of code has made everything better...and made me have to erase another 300 lines lmao! Thanks as always