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 :
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:
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
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.
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.
@Christopho
That is interesting, so a simple step switch would be like this:
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.
--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.
function entity:on_activated()
if hero:overlaps(entity) then
sol.audio.play_sound("secret")
hero:start_hurt(240,277,6)
end
end
Ahah okay ;D
Thanks you Christopho and Zefk !
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.
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