Solarus-Games English Forum

Solarus => Development => Topic started by: Realguigui on February 08, 2017, 07:22:54 PM

Title: Event function linked to a dynamically created item
Post by: Realguigui on February 08, 2017, 07:22:54 PM
Hello.
Is it possible to code an on_obtaining () event function related to an item created during code execution ?
I know this is possible in item.lua but I want to code specific actions in this event function.

Thank you.
Title: Re: Event function linked to a dynamically created item
Post by: MetalZelda on February 08, 2017, 09:35:57 PM
In your item script, you just need

Code (lua) Select

function item:on_obtaining(variant, savegame_variable)
  your_code
end


But, on_obtaining is called when you get that treasure, that is, before the treasure text begins.

You should use item:on_obtained() instead, or item:on_using()
Title: Re: Event function linked to a dynamically created item
Post by: Realguigui on February 08, 2017, 10:17:12 PM
Thanks, but this solution works only with the actions performed each time. My goal is to cut the music when I get a large key but only on this map.

Quote from: MetalZelda on February 08, 2017, 09:35:57 PM
In your item script, you just need

Code (lua) Select

function item:on_obtaining(variant, savegame_variable)
  your_code
end


But, on_obtaining is called when you get that treasure, that is, before the treasure text begins.

You should use item:on_obtained() instead, or item:on_using()
Title: Re: Event function linked to a dynamically created item
Post by: MetalZelda on February 08, 2017, 10:40:35 PM
Quote from: Realguigui on February 08, 2017, 10:17:12 PM
Thanks, but this solution works only with the actions performed each time. My goal is to cut the music when I get a large key but only on this map.


Oh, you want to set the music volume to 0 when you got an item and restore the volume after the text ?

Simple method

Code (lua) Select

local volume

function item:on_obtaining(variant, savegame_variable)
  volume = sol.audio.get_music_volume()
  sol.audio.set_music_volume(0)
end

function item:on_obtained(variant, savegame_variable)
  sol.audio.set_music_volume(volume)
end


if you want to make the volume to be muted only for a specific map, just add a condition

Code (lua) Select

local volume

function item:on_obtaining(variant, savegame_variable)
  volume = sol.audio.get_music_volume()
  if item:get_map():get_id() == your_map then
    sol.audio.set_music_volume(0)
  end
end

function item:on_obtained(variant, savegame_variable)
  sol.audio.set_music_volume(volume)
end

Title: Re: Event function linked to a dynamically created item
Post by: Realguigui on February 09, 2017, 09:23:39 AM
It works.
I had thought of this solution but it seemed to me not logical to code specific behavior in the general event function.

Thank you.
Title: Re: Event function linked to a dynamically created item
Post by: Diarandor on February 09, 2017, 03:39:59 PM
Quote from: Realguigui on February 09, 2017, 09:23:39 AM
It works.
I had thought of this solution but it seemed to me not logical to code specific behavior in the general event function.

Thank you.

And probably it is not logical or good to do this in this way in the item script. But since you are not explaining how the key is obtained (maybe from a chest?) it is impossible to be sure if this is the best and cleaner solution for your particular case.
Title: Re: Event function linked to a dynamically created item
Post by: Christopho on February 09, 2017, 04:00:15 PM
There are also events map:on_obtaining_treasure() and map:on_obtained_treasure() if your logic is more related to the map than to the item.
Title: Re: Event function linked to a dynamically created item
Post by: MetalZelda on February 09, 2017, 04:30:12 PM
Oh I was not aware of the map related events for items
Title: Re: Event function linked to a dynamically created item
Post by: Diarandor on February 09, 2017, 06:59:34 PM
In case the key is obtained as a pickable only in that map, Christopho's suggestion is probably the best. But if it is obtained from a chest, the event chest.on_opened should be the best option, probably. We still don't know how the key is obtained so we cannot know yet. But in any case, the map script is the best place for something so particular.
Title: Re: Event function linked to a dynamically created item
Post by: Realguigui on February 10, 2017, 10:50:47 AM
I create when  the game is running a pickable big key that drop from the ceiling.
My difficulty is to refer in my code to an object that does not yet exist. I get nil errors in the console at launch.

My function/script "falling_item" which is called uses a custom entity for the fall and a map:create_pickable when there is contact with the ground.

The solution I think to implement:
Title: Re: Event function linked to a dynamically created item
Post by: Realguigui on February 10, 2017, 11:10:05 AM
Quote from: Realguigui on February 10, 2017, 10:50:47 AM
The solution I think to implement:

  • Create the big key in the editor and disable it.
  • Transmit to my function "fall" the var "large key" to reactivate it rather than create it.

There is a problem with this solution because I use my function "fall" intensively to make a random bomb rain down. I'm brave but I do not want to create dozens of bombs in the editor.
Title: Re: Event function linked to a dynamically created item
Post by: Diarandor on February 10, 2017, 11:27:20 AM
Ok, thanks for the info!

Your solution for the key seems good enough. But a cleaner solution could be to use "map.on_obtaining_treasure", as Chris has suggested before. You don't need an instance of the pickable to define that event, so you can define it directly in the map script before the pickable key is created.
Title: Re: Event function linked to a dynamically created item
Post by: Diarandor on February 10, 2017, 11:36:28 AM
You should create bombs dynamically (from some script), and then initialize them with your fall function. If that falling function is something general, you probably should define it in some metatable script (for maps or pickables, idk). Then call that function just after the creation of the bomb, to make them fall. A way to do this is:
-disable the falling entity,
-create a custom entity with same sprite and make the falling effect,
-remove the custom entity and enable the bombs or pickables in the correct position.
Your falling function could take as parameters the falling entity (and the falling position as optionally, with the current position as default falling position).

Edit: in any case, you don't need to create the bombs before in the editor. If you get errors that means you are doing it in a bad way. Share your code if necessary, so we can help you more.
Title: Re: Event function linked to a dynamically created item
Post by: Realguigui on February 10, 2017, 12:24:38 PM
Thank all of you for your help.

the event map:on_obtaining_treasure() is the solution !

It's my fault. I always forget that parameters in events are "alredy fill" at the moment of the event contrary of functions. Obviously i tried to pass the item variable of my big key in the first parameter of "on_obtainig" event in order to have an event specific to my big key and I obtained an error message.