Avoid pickables to be ... picked ?

Started by MetalZelda, December 28, 2016, 01:00:51 AM

Previous topic - Next topic
December 28, 2016, 01:00:51 AM Last Edit: December 28, 2016, 02:02:55 AM by MetalZelda
Hi.

So today I was working on streams (fan & water stream), so it implied also reworking an item: the Roc's Cape.
The roc's cape is a simple, yet complex item, script-wise.

The Hero's sprite coordinate are always changing while using the roc's cape, but it's collision stays (see bellow) on ground, which means, teleporters and switches are disabled if the player use this item, as well as being invincible to avoid any collision with enemies.



All works fine, but picking an item while flying is weird, and there is no pickable:set_obtainable(boolean) or whatever to avoid the hero to pick any items

Any workaround or solution ?

Hello. I didn't come here since a long time, but I visit the forum this morning and saw your post. I think that maybe with layer, and transparent tile, you should do something. i.e put your item on the tile in the upper layer, and make the layer change when the hero jump. I don't know if it works, but it's an idea I had.

Hi!

@Yosha: Yeah, that is probably the easiest solution to code the custom jump, and the one I have been using until now. But the layer of the hero should not be changed during the jump, that is unnecessary and would produce big problems. You can just make a custom entitity of size 8x8, with traversable ground, no sprite, and following the hero; and that works fine. For the tunic animation, MetalZelda can use the animation fix script, so that the hero is not returned to the walking or stopped animations. All of this has been tested and works, as can be seen in some videos of my youtube channel.

There is a quite old thread about the custom jump: http://forum.solarus-games.org/index.php/topic,354.0.html


@MetalZelda: I found the same problems when scripting the jump: teleporters should not be activated, pickables should not be picked and switches/buttons should not be pushed while the hero is jumping. At first, I used the workaround of disabling teleporters, but later I realized that this was a bad idea and too dirty way of coding this (if teleporters have sprites they would disappear, and other problems or script bugs may appear, so don't do this). The final solution I used was to use a replacement script for teleporters, and use custom entities as teleporters. I did the same with custom pickables and buttons (you can jump over them and no collision is activated). I recommed that you do it in this way. You will only need to re-make these 3 types of entities and override some methods (for their metatables, override the method "on_created", and for the "map" metatable, override the method "create_*"; note that this is a clean solution that does not bring incompatibilities with code or the built-in entities of maps.


There is already a thread with the code for the teleporters (replacement script and custom entity teleporter script). But you should modify it and adapt it for your game. Don't forget to modify the code to make it compatible with the multi-event script that Christopho made, which will make these scripts easier to use for others. Also, some of the teleporter functions may not be defined in the scripts yet (because I did not need them yet or I forgot to write them), but you can code them easily. Make sure that all the necesssary functions of the Lua API of teleporters are coded in the script. This is the link of the old thread:
http://forum.solarus-games.org/index.php/topic,484.0.html

For custom pickables and custom buttons, just make the same. There are some scripts for these entities in my old repository (you can take a look if that helps you), but I don't recommend to use them since the code is too old and far from good. You can adapt them or make your own scripts.
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."

Another solution would be to ask Christopho if he can implement new methods "get/set_collision_test" for these entities (teleporters, pickables and switches) to change the collision test to a different one, or maybe "get/set_collision_test_condition" to add some necessary conditions to activate these collision tests.

However, if we make all of this scripted, we have the advantage of allowing full customization for other features that we may need in the future (who knows?), so I will stay with the solution of scripted custom entities.
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."

Maybe you can open an issue about adding a function like entity:set_collisions_enabled().

December 28, 2016, 11:24:56 AM #5 Last Edit: December 28, 2016, 11:33:43 AM by Diarandor
Note that using "entity:get/set_collisions_enabled()" for all entities (or entities near the hero) during the jump could bring problems since ALL collision tests would be disabled for these entities. This would affect custom entities and enemies. Since you plan to make hero invincible, that should not be a big problem for enemies (but it still may affect the behavior of enemies that use collision test). But in case we wanted flying enemies to hurt the hero during the jump we would have problems. There could also be problems with other collision tests between two entities that are not the hero, but that also depends on the mechanics and functions used in the game. If some enemy that throws fire against you is used in a puzzle to lit torches, that would not work while jumping close to the torch. Another problematic example: if we code the custom boots which allow to be used with the custom jump and also to crash against trees (that may throw items), that collision against trees would not be detected if the hero crashes while jumping, which is a bit weird. All these problems (or at least most of them), can be solved with a function that checks, case by case, the types of the entities (and subtypes in case of custom entities); hence a bit of delicate extra work would be necessary to avoid little problems like this. From my point of view, it would be cleaner to replace entities, but that also adds a bit more of scripting work (well,not so much, actually). In any case, the functions "entity:get/set_collisions_enabled()" could still be useful for many other purposes.

EDIT: well, it should be actually easy to code that with that function, if that is only applied to pickables, teleporters and switches, so forget what I wrote above.
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."