Author Topic: [Solved] Create a custom switch  (Read 125 times)

SyF

  • Newbie
  • *
  • Posts: 10
    • View Profile
[Solved] Create a custom switch
« on: April 05, 2017, 03:40:30 pm »
Hi everyone,
I would like to create a custom switch. In fact, I have an idea but I prefer ask if there is a better way to script it.
This is my idea: The hero throws a boomerang and activate the switch (which keeps the item). After the switch animation, the boomerang returns to the hero and something happens (for example, opening a door).

I already create a custom entity for the switch and it works when I throw my boomerang. Now, I need to indicate in the game that this custom entity is a switch, because I want to use the function "switch:on_activated" and the other.

Does someone have an idea ?

----------------------------------------------------
Switch code :
Code: Lua
  1. local entity = ...
  2.  
  3. function entity:on_created()
  4.   entity:set_size(32, 24)
  5.   entity:set_origin(16, 21)
  6.   entity:set_traversable_by(false)
  7.   entity:set_drawn_in_y_order(true)
  8. end
  9.  
  10. entity:add_collision_test("touching", function(entity, other_entity)
  11.  
  12.   local type = other_entity:get_type()
  13.   local switch_state = entity:get_sprite():get_animation()
  14.     local check = type == "boomerang" and switch_state == "stop_off"
  15.  
  16.   if check then
  17.     entity:get_sprite():set_animation("activated")
  18.     sol.timer.start(1000, function()
  19.       sol.audio.play_sound("secret")
  20.       entity:get_sprite():set_animation("stop_on")
  21.       entity:clear_collision_tests()
  22.       end)
  23.   end
  24. end)
States :
  # stop_off : the switch is not activated
  # activated : the switch is beins activated (loop animation)
  # stop_on : the switch is activated and unusable

Boomerang code:
Code: Lua
  1. local item = ...
  2.  
  3. function item:on_created()
  4.   item:set_savegame_variable("possession_boomerang")
  5.   item:set_assignable(true)
  6. end
  7.  
  8. function item:on_using()
  9.   local hero = item:get_map():get_hero()
  10.   hero:start_boomerang(64,160,"boomerang","entities/boomerang")
  11. end
« Last Edit: April 06, 2017, 09:47:46 am by SyF »

Christopho

  • Administrator
  • Hero Member
  • *****
  • Posts: 1001
    • View Profile
Re: Create a custom switch
« Reply #1 on: April 05, 2017, 04:29:25 pm »
switch:on_activated() won't be called by the engine ever because your entity is of type "custom_entity" and not "switch".
But in your entity:add_collision_test callback, you can manually call a function of your choice if it exists. You can call it on_activated, just like for built-in switches, or something different.
Code: Lua
  1. sol.timer.start(1000, function()
  2.   sol.audio.play_sound("secret")
  3.   if entity.on_activated ~= nil then
  4.     entity:on_activated()
  5.   end
  6.   ...
  7. [code]
  8. As you can see, switches could actually be reimplemented in Lua as custom entities.

Zefk

  • Sr. Member
  • ****
  • Posts: 414
  • Just helping Solarus
    • View Profile
    • Zelzec Business
Re: Create a custom switch
« Reply #2 on: April 05, 2017, 09:51:00 pm »
@Christopho
That is interesting, so a simple step switch would be like this:

Code: Lua
  1. local hero = map:get_hero()
  2.  
  3. --Create on_activated
  4. sol.timer.start(500, function()
  5.   if entity.on_activated ~= nil then
  6.     entity:on_activated()
  7.  return true
  8.   end
  9. end)
  10.  
  11. --if hero's position is equal to entity's position, then hero is damaged when stepping on entity.
  12. function entity:on_activated()
  13. local x1,y1 = hero:get_position()
  14. local x2,y2 = entity:get_position()
  15. print("Entity: "..x2..","..y2)
  16. print("Hero: "..x1..","..y1)
  17.   if x1 == x2 and y1 == y2 then
  18.     sol.audio.play_sound("secret")
  19.     hero:start_hurt(240,277,6)
  20.   end
  21. end

Although, it will be hard to get the hero exactly on the point without doing some manual range calculations.

Code: Lua
  1. --if hero's position is equal to entity's position, then hero is damaged when stepping on entity.
  2. function entity:on_activated()
  3. local x1,y1 = hero:get_position()
  4. print("Hero: "..x1..","..y1)
  5.   if (x1 > 240 and x1 < 256) and (y1 > 272 and y1 < 288) then
  6.     sol.audio.play_sound("secret")
  7.     hero:start_hurt(240,277,6)
  8.   end
  9. end

The easiest way to do this is by using the overlap function.

Code: Lua
  1. function entity:on_activated()
  2.   if hero:overlaps(entity) then
  3.     sol.audio.play_sound("secret")
  4.     hero:start_hurt(240,277,6)
  5.   end
  6. end
« Last Edit: April 07, 2017, 03:28:21 am by Zefk »

SyF

  • Newbie
  • *
  • Posts: 10
    • View Profile
Create a custom switch
« Reply #3 on: April 06, 2017, 09:47:24 am »
Ahah okay  ;D
Thanks you Christopho and Zefk !

Zefk

  • Sr. Member
  • ****
  • Posts: 414
  • Just helping Solarus
    • View Profile
    • Zelzec Business
Re: [Solved] Create a custom switch
« Reply #4 on: April 07, 2017, 01:00:05 am »
I edited my example above to be a working example, but it only works for the exact point and it might be some time before the hero walks on that exact point unless you manually calculate the range.


It might be easier to use the overlap function because there is no need for calculations.

Code: Lua
  1. sol.timer.start(400, function()
  2.   if entity.on_activated ~= nil then
  3.     entity:on_activated()
  4.  return true
  5.   end
  6. end)
  7.  
  8. function entity:on_activated()
  9.   if hero:overlaps(entity) then
  10.     sol.audio.play_sound("secret")
  11.     hero:start_hurt(240,277,6)
  12.   end
  13. end
« Last Edit: April 07, 2017, 03:29:43 am by Zefk »