Author Topic: [Solved]How to add an "opening" animation for chests?  (Read 524 times)

froggy77

  • Jr. Member
  • **
  • Posts: 82
    • View Profile
[Solved]How to add an "opening" animation for chests?
« on: May 07, 2017, 08:06:50 pm »
Hello,

I would like to add an intermediate animation for chests. "closed" and "open" are the basic animations. I added, in the .dat files, an "opening" animation which it could be in 1 or 2 frames according the size of the chests.

How woud you proceed in lua scripts?


Sorry, I have lost a lot of skills in lua and even about Solarus in general, because I have not worked on it for several months.
Moreover, there are now in the last versions, scripts "features" and "multi_events" which is all the more new and difficult for me.
But instead, I improved my pixel art skills a bit  ;) . I will soon update my topic on the project.
« Last Edit: June 19, 2017, 12:55:56 am by froggy77 »

Zefk

  • Sr. Member
  • ****
  • Posts: 492
  • Just helping Solarus
    • View Profile
    • Zelzec Business
Re: How to add an "opening" animation for chests?
« Reply #1 on: May 07, 2017, 08:20:25 pm »
If you mean opening as in lifting the lid of the chest, then try changing the number of frames for the "open" animation.


MetalZelda

  • Sr. Member
  • ****
  • Posts: 499
    • View Profile
Re: How to add an "opening" animation for chests?
« Reply #2 on: May 07, 2017, 09:23:01 pm »
you have to go through custom entity

Or, maybe this could help ?
http://www.solarus-games.org/doc/latest/lua_api_chest.html#lua_api_chest_on_opened

Zefk

  • Sr. Member
  • ****
  • Posts: 492
  • Just helping Solarus
    • View Profile
    • Zelzec Business
Re: How to add an "opening" animation for chests?
« Reply #3 on: May 07, 2017, 10:00:54 pm »
@froggy77

MetalZelda is correct. I made a super quick chest opening animation and apparently the chest sprite vanishes with more than one frame.

froggy77

  • Jr. Member
  • **
  • Posts: 82
    • View Profile
Re: How to add an "opening" animation for chests?
« Reply #4 on: May 07, 2017, 11:09:37 pm »
@Zefk > I had already tried to change the number of frames for the "open" animation. Yes, " the chest sprite vanishes with more than one frame."  :(

@MetalZelda >  OK, I also think I have to go through custom entity :'(
http://www.solarus-games.org/doc/latest/lua_api_chest.html#lua_api_chest_on_opened is when the chest is already opened. It is above all to choose the treasure.

Thanks for your help!

Zefk

  • Sr. Member
  • ****
  • Posts: 492
  • Just helping Solarus
    • View Profile
    • Zelzec Business
Re: How to add an "opening" animation for chests?
« Reply #5 on: May 10, 2017, 09:16:20 am »
@froggy77

If you do not mind, I'd like to discuss features for a custom chest with you.

So far my thought process led me to the following. I will be coding this sometime for my Lib. What more features would it need?

Code: Lua
  1. entity:custom_chest(treasure, treasure_variant, save_variable, sprite_directory, traversable, closed_animation, open_animation, opening_animation, key)

With default settings it could be called inside a custom entity like this.

Code: Lua
  1. entity:custom_chest()

With custom settings it would be more readable like this:

Code: Lua
  1. entity:custom_chest(
  2. treasure, --treasure
  3. treasure_variant, --treasure_variant
  4. save_variable, --save_variable
  5. sprite_directory, --sprite_directory
  6. traversable, --traversable
  7. closed_animation, --closed_animation
  8. open_animation, --open_animation
  9. opening_animation, --opening_animation
  10. key) --key

Maybe something like....

Opening mode:

-By hero
-By hero with save variable
-By hero with item required
-increment/decrement item

and maybe these...
http://forum.solarus-games.org/index.php/topic,971.msg5646.html#msg5646

-By entity
-By entity with save variable
-By entity with dummy item required
-increment/decrement dummy item
-By entity overlap

Dialog:

-fail dialog
« Last Edit: May 11, 2017, 07:53:28 am by Zefk »

Diarandor

  • Hero Member
  • *****
  • Posts: 745
  • Cats are cool! (ΦωΦ)
    • View Profile
Re: How to add an "opening" animation for chests?
« Reply #6 on: May 10, 2017, 12:31:01 pm »
For your purposes with chests, I recommend to use normal chests in the map editor, just to have compatibility with the map editor. There are several ways to do this:
-Use a script that replaces chests with custom entities when a map is created, or when chests are created. This can be done directly by defining chest_metatable:on_created().
-Another way is to define chest_metatable:on_created() in order to define some events on the sprite of the chest, which would allow that animation to appear.

Diarandor

  • Hero Member
  • *****
  • Posts: 745
  • Cats are cool! (ΦωΦ)
    • View Profile
Re: How to add an "opening" animation for chests?
« Reply #7 on: May 10, 2017, 12:45:11 pm »
Remark: using custom entities takes a bit more of work than using the chest metatable, since you would need to define the functions and events of the chest Lua API. On the other hand that solution allows much more customization on chests: for instance, you can make chests that can only be opened by one of the heroes and not by the others, or make chests that can be opened by throwing a pot.

Zefk

  • Sr. Member
  • ****
  • Posts: 492
  • Just helping Solarus
    • View Profile
    • Zelzec Business
Re: How to add an "opening" animation for chests?
« Reply #8 on: May 10, 2017, 07:14:17 pm »
By entity overlap is a good idea Diarandor. I am guessing a specific entity would be best because not one wants any entity to open a chest.

Aha! I did it. I made an on_interaction function. Of course, it will need some tweaking to actually work for the chest, but it allows me to interact with many entities.

Code: Lua
  1. function metatable_entity:on_entity_interaction()
  2.   local map = self:get_map()
  3.   local hero = map:get_hero()
  4.   local game = map:get_game()
  5.   local dialog_activation_distance = 20
  6.  
  7.     sol.timer.start(2000, function()
  8.       local distance_check = hero:get_distance(self)
  9.       if distance_check <= dialog_activation_distance then -- dialog_activation_distance
  10.        function map:on_key_pressed(key)
  11.          if key == "y" then
  12.            print("pressed")
  13.          end
  14.        end
  15.      end
  16.     return true  -- To call the timer again (with the same delay).
  17.   end)
  18. end

It can be called in an entity like this:

Code: Lua
  1. entity:on_entity_interaction()
« Last Edit: May 11, 2017, 07:54:16 am by Zefk »

Diarandor

  • Hero Member
  • *****
  • Posts: 745
  • Cats are cool! (ΦωΦ)
    • View Profile
Re: How to add an "opening" animation for chests?
« Reply #9 on: May 10, 2017, 09:07:50 pm »
I think you are complicating things too much. You should just define custom_entity:on_interaction() for your custom chest. There is no need of checking distances and timers, or using the event on_key_pressed().

MetalZelda

  • Sr. Member
  • ****
  • Posts: 499
    • View Profile
Re: How to add an "opening" animation for chests?
« Reply #10 on: May 10, 2017, 09:11:25 pm »
I like Diarandor's solution, overwriting a chest to replace it with a custom entity.

For the custom entity script, simple trick is to use add_collision_test to do HUD stuffs and simply add an animation in on_interaction. Thn call hero:start_treasure from there

MetalZelda

  • Sr. Member
  • ****
  • Posts: 499
    • View Profile
Re: How to add an "opening" animation for chests?
« Reply #11 on: May 10, 2017, 10:28:50 pm »
You need 3 things.

1) the metatable modification
2) a chest entity
3) a chest on a map, where you need to define
    - it's spriteset
    - it's treasure
    - it's variant
    - the savegame variable

1) * Keep note that it is from my project so you might need to modify things to fit your needs
And, with this script you can only set a treasure that you can open if you press Action, other chest action cannot be done without more complex modifications
Also to set a direction for your chest (if needed), put the desired direction as the chest name.

Code: Lua
  1. local chest_meta = sol.main.get_metatable("chest")
  2.  
  3. function chest_meta:on_created()
  4.   local treasure, variant, savegame = self:get_treasure()
  5.   local x, y, layer = self:get_position()
  6.   local graphic = self:get_sprite():get_animation_set()
  7.  
  8.   local setup = {
  9.     x = x,
  10.         y = y,
  11.         layer = layer,
  12.         model = "chest/chest",
  13.         width = 16,
  14.         height = 16,
  15.         direction = 3,
  16.         sprite = graphic
  17.   }
  18.  
  19.   local entity = self:get_map():create_custom_entity(setup)
  20.   entity:set_treasure(treasure, variant, savegame)
  21.   entity:create()
  22.  
  23.   -- You might need to customize this chest.
  24.   function self:get_chest()
  25.     return entity
  26.   end
  27.   self:remove()
  28. end

2)

Code: Lua
  1. local entity = ...
  2. entity.data = {}
  3.  
  4. function entity:set_treasure(treasure, variant, savegame)
  5.   self.data.treasure = treasure
  6.   self.data.variant  = variant
  7.   self.data.savegame = savegame
  8. end
  9.  
  10. local game = entity:get_game()
  11. local hero = game:get_hero()
  12.  
  13. function entity:is_open()
  14.   return game:get_value(self.data.savegame)
  15. end
  16.  
  17. function entity:create()
  18.   self:set_drawn_in_y_order(true)
  19.   self:set_can_traverse("hero", false)
  20.   self:set_traversable_by("hero", false)
  21.   self:set_traversable_by("custom_entity", false)
  22.  
  23.   if self:is_open() then
  24.     self:get_sprite():set_animation("open")
  25.     return
  26.   end
  27.  
  28.   -- Hud notification
  29.   self:add_collision_test("facing", function(_, other)
  30.     if other:get_type() == "hero" then
  31.       if not self:is_open() then
  32.             self.action_effect = other:get_direction() == self:get_direction() and "open" or "look"
  33.           else
  34.             self:clear_collision_tests()
  35.           end
  36.     end
  37.   end)
  38. end
  39.  
  40. function entity:on_interaction()
  41.   -- This is where you will play your animation, set the savegame value to true and give the hero the treasure
  42.   -- savegame value is stored in entity.data.savegame
  43.  
  44.   if self:is_open() then
  45.     return
  46.   end
  47.  
  48.   hero:freeze()
  49.   game:set_pause_allowed(false)
  50.   self:get_sprite():set_animation("opening", function()
  51.     self:get_sprite():set_animation("open")
  52.     hero:start_treasure(self.data.treasure, self.data.variant, self.data.savegame, function()
  53.       -- After the treasure has been obtained
  54.       hero:unfreeze()
  55.       game:set_pause_allowed(true)
  56.     end)
  57.   end)
  58.  
  59.   self.action_effect = nil
  60. end
« Last Edit: May 11, 2017, 11:38:41 am by MetalZelda »

Zefk

  • Sr. Member
  • ****
  • Posts: 492
  • Just helping Solarus
    • View Profile
    • Zelzec Business
Re: How to add an "opening" animation for chests?
« Reply #12 on: May 11, 2017, 05:31:15 am »
I think you are complicating things too much. You should just define custom_entity:on_interaction() for your custom chest. There is no need of checking distances and timers, or using the event on_key_pressed().

I think only custom_entity:on_interaction() works for a hero. It would not work for a player 2 custom entity as far as I know, but I guess I could just make that a second custom chest function.

Diarandor

  • Hero Member
  • *****
  • Posts: 745
  • Cats are cool! (ΦωΦ)
    • View Profile
Re: How to add an "opening" animation for chests?
« Reply #13 on: May 11, 2017, 07:40:20 am »
Ok, if you allow to do that then you are right, I did not think on that case.

Zefk

  • Sr. Member
  • ****
  • Posts: 492
  • Just helping Solarus
    • View Profile
    • Zelzec Business
Re: How to add an "opening" animation for chests?
« Reply #14 on: May 11, 2017, 08:16:23 am »
I am still debating on it though because first my main goal is to just get a fully function ally AI system working. A custom entity chest for the hero is far easier.