Wall entities behaving strangely

Started by the bread, January 04, 2016, 12:14:40 AM

Previous topic - Next topic
Hello there  ;D
For some kind of bow-shooting minigame I wanted to keep the hero from moving. I wanted to do this by blocking all directions with wall entities. I disable them, when the map starts and enable them, when the hero activates a walkable switch.
However, the wall entities are kind of acting in a weird way...
(I got no clue how to insert screenshots in the text so I am going to attach them to the post)
At first I tried to use only one big wall entity and position the switch on top of this entity (see first screenshot). This didn't work at all, I could leave the switch and go wherever I want. But the wall entity was activated because it's impossible to go back to the switch again once you leave it.
Afterwards I tried to block the way using four different wall entities (as seen in screenshot 2). This is very strange, sometimes I can leave the switch and go anywhere, sometimes not. Returning to the switch is always impossible. I came to think that it depends on whether the hero overlaps the switch completely.
Finally I extended the four entities (screenshot 3), now it is acting similar to screenshot 2 but even stranger... Sometimes I end up blocked beneath the switch and sometimes I can slip through a wall entity as I did with the four smaller ones but this breaks the disabling of the wall entities; usually the wall entities should be disabled again after some time but now the wall entity I glitched through stays activated while the other ones are disabled correctly.
Does anyone know why the walls behave like this? Is this intended?

Hi! I don't know much about how the engine creates the walls, but this could be a bug (I have not tried to reproduce it because I am lazy  ::)). I think that what is happening is that you cannot enable a wall which is overlapping the bounding box of the hero, so one solution could be to center the hero on the position of the switch with something like: hero:set_position(switch:get_position)
and enable the wall after that, but I have not tested this solution.
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."

Yes, it works now ;D
This is the code line:
Code ( lua) Select
hero:set_position(switch_x + 8, switch_y + 13)
(It's plus 8 and 13 because the origin point of the hero is at those coordinates)
Anyway, I'd still appreciate an explanation why wall entities are behaving like this. Your explanation makes kinda sense but I'd rather expect the hero to be stuck in the wall entity than to ignore it when they overlap each other. And still this
Quote from: the bread on January 04, 2016, 12:14:40 AM
At first I tried to use only one big wall entity and position the switch on top of this entity (see first screenshot). This didn't work at all, I could leave the switch and go wherever I want. But the wall entity was activated because it's impossible to go back to the switch again once you leave it.
and this
Quoteusually the wall entities should be disabled again after some time but now the wall entity I glitched through stays activated while the other ones are disabled correctly.
are a mystery to me.
But thanks anyways :D

Christopho is the only one who can solve this mystery. We have to wait for his answer.
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."

When entity:set_enabled(true) would result in having the hero stuck in an obstacle, the engine delays the enable operation until the hero leaves. It is an historical choice from years ago. Now that scripts can easily do the same thing if necessary, it is clearly wrong to have this behavior in the engine side. It is not even documented because I see it as a bug.

I just opened an issue: https://github.com/christopho/solarus/issues/817

This weird behavior is specific to entity:set_enabled(true). So for your use case, an easy workaround is to use a solution other than entity:set_enabled(true). For example, you can create/destroy the wall from the script instead of from the editor. Or create it from the editor, but outside of the map, and change its position from the script.

Thanks for solving the mystery  :)
It works, I can create the wall entity like this:
Code ( lua) Select
local wall = map:create_wall{
    x = switch_x - 8,
    y = switch_y - 8,
    layer = switch_layer,
    width = 32,
    height = 32,
    stops_hero = true,
    stops_npcs = true,
    stops_enemies = true,
    stops_blocks = true,
    stops_projectiles = true
}

Another little remark: Wouldn't it be better to set the boolean properties of the wall (e.g. stops_hero, stops_npcs, ...) to true by default. Because a wall that blocks everything is probably more common and rather the expected result than a wall that blocks nothing.