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

SyF

  • Newbie
  • *
  • Posts: 13
    • 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) [Select]
local entity = ...

function entity:on_created()
  entity:set_size(32, 24)
  entity:set_origin(16, 21)
  entity:set_traversable_by(false)
  entity:set_drawn_in_y_order(true)
end

entity:add_collision_test("touching", function(entity, other_entity)

  local type = other_entity:get_type()
  local switch_state = entity:get_sprite():get_animation()
    local check = type == "boomerang" and switch_state == "stop_off"

  if check then
    entity:get_sprite():set_animation("activated")
    sol.timer.start(1000, function()
      sol.audio.play_sound("secret")
      entity:get_sprite():set_animation("stop_on")
      entity:clear_collision_tests()
      end)
  end
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) [Select]
local item = ...

function item:on_created()
  item:set_savegame_variable("possession_boomerang")
  item:set_assignable(true)
end

function item:on_using()
  local hero = item:get_map():get_hero()
  hero:start_boomerang(64,160,"boomerang","entities/boomerang")
end
« Last Edit: April 06, 2017, 09:47:46 am by SyF »

Christopho

  • Administrator
  • Hero Member
  • *****
  • Posts: 1176
    • 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) [Select]
sol.timer.start(1000, function()
  sol.audio.play_sound("secret")
  if entity.on_activated ~= nil then
    entity:on_activated()
  end
  ...
[code]
As you can see, switches could actually be reimplemented in Lua as custom entities.

Zefk

  • Hero Member
  • *****
  • Posts: 536
  • Just helping Solarus
    • View Profile
    • Zelzec
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) [Select]
local hero = map:get_hero()

--Create on_activated
sol.timer.start(500, function()
  if entity.on_activated ~= nil then
    entity:on_activated()
 return true
  end
end)

--if hero's position is equal to entity's position, then hero is damaged when stepping on entity.
function entity:on_activated()
local x1,y1 = hero:get_position()
local x2,y2 = entity:get_position()
print("Entity: "..x2..","..y2)
print("Hero: "..x1..","..y1)
  if x1 == x2 and y1 == y2 then
    sol.audio.play_sound("secret")
    hero:start_hurt(240,277,6)
  end
end

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

Code: ( lua) [Select]
--if hero's position is equal to entity's position, then hero is damaged when stepping on entity.
function entity:on_activated()
local x1,y1 = hero:get_position()
print("Hero: "..x1..","..y1)
  if (x1 > 240 and x1 < 256) and (y1 > 272 and y1 < 288) then
    sol.audio.play_sound("secret")
    hero:start_hurt(240,277,6)
  end
end

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

Code: ( lua) [Select]
function entity:on_activated()
  if hero:overlaps(entity) then
    sol.audio.play_sound("secret")
    hero:start_hurt(240,277,6)
  end
end

SyF

  • Newbie
  • *
  • Posts: 13
    • 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

  • Hero Member
  • *****
  • Posts: 536
  • Just helping Solarus
    • View Profile
    • Zelzec
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) [Select]
sol.timer.start(400, function()
  if entity.on_activated ~= nil then
    entity:on_activated()
 return true
  end
end)

function entity:on_activated()
  if hero:overlaps(entity) then
    sol.audio.play_sound("secret")
    hero:start_hurt(240,277,6)
  end
end