Hello ! I have a strange problem with my code. I want to enable my custom entitiy "light" after a timer, it works but I have an error message in the consol... I really don't understand what this is about
Here's the code :
local map = ...
local game = map:get_game()
-- Explode the door and Kimos enter the room
local function animation()
sol.timer.start(4000, function()
map:create_explosion({
name = "ex",
layer = 2,
x = 160,
y = 208})
sol.audio.play_sound("explosion")
light_door:set_enabled(true)
door:set_enabled(false)
end)
end
-- Event called at initialization time, as soon as this map is loaded.
function map:on_started()
game:set_value("dark_room",true)
light_door:set_enabled(false)
game:set_hud_enabled(false)
game:set_pause_allowed(false)
hero:set_visible(false)
animation()
end
And here's the error message :
Error: In on_enabled: scripts/multi_events.lua:41: attempt to call upvalue 'callback' (a boolean value)
stack traceback:
[C]: in function 'callback'
scripts/multi_events.lua:41: in function 'previous_callbacks'
scripts/multi_events.lua:41: in function <scripts/multi_events.lua:40>
[C]: in function 'set_enabled'
maps/cutscenes/intro_1.lua:14: in function <maps/cutscenes/intro_1.lua:7>
I know how to read error message but I don't understand why this happen only with my custom entity.. No probleme with the door:set_enabled(false)
Thank you
Can you also show the code of your light_door entity?
Does it register an event on_enabled()? If yes, make sure it is a function.
This is the code for the light :
local light = ...
local game = light:get_game()
local map = light:get_map()
local light_mgr = require('scripts/lights/light_manager')
local radius = tonumber(light:get_property('radius')) or 120
local size = radius*2
local color_str = light:get_property('color') or '255,255,255'
local color = {color_str:match('(%d+),(%d+),(%d+)')}
for i,k in ipairs(color) do
color[i] = k/256.0
end
local sqrt2radius = 1.41 * radius
light:set_can_traverse(true)
--set light properties
light.radius = radius
light.color = color
light.excluded_occs = {}
light.halo = tonumber(light:get_property('halo'))
local dir_str = light:get_property('direction')
if dir_str then
light.direction = {dir_str:match('(-?%d+),(-?%d+)')}
for i,k in ipairs(light.direction) do
light.direction[i] = k*1
end
end
light.cut = tonumber(light:get_property('cut'))
light.aperture = tonumber(light:get_property('aperture'))
local angle = light:get_property('angle')
if angle then
light.aperture = math.cos((math.pi/180)* tonumber(angle))
end
local x,y = light:get_position()
local fire_dist = sol.shader.create('fire_dist')
local fire_sprite = light:get_sprite()
if fire_sprite then
light:remove_sprite(fire_sprite)
fire_sprite:set_shader(fire_dist)
end
-- Event called when the custom light is initialized.
function light:on_created()
-- Initialize the properties of your custom light here,
-- like the sprite, the size, and whether it can traverse other
-- entities and be traversed by them.
light_mgr:add_light(self,light:get_name())
light:set_origin(radius,radius)
local size8 = math.ceil(size/8)*8
light:set_size(size8,size8)
end
function light:draw_visual(dst,drawable,x,y)
local cx,cy = map:get_camera():get_position()
drawable:draw(dst,x-cx,y-cy)
end
function light:get_topleft()
local lx,ly,ll = self:get_position()
return lx-radius,ly-radius,ll
end
function light:draw_light(dst, camera)
--dont draw light if disabled
if not self:is_enabled() then
return
end
--dont draw light if outside of the camera
camera:set_layer(self:get_layer()) --TODO verify if this is not a shitty idea
if not camera:overlaps(self) then
return
end
-- get the shadow_map for this light
local shad_map = light_mgr:compute_light_shadow_map(light)
--draw 1D shadow as additive shadows
self:draw_visual(dst,shad_map, self:get_topleft())
end
function light:draw_disturb(dst)
self:draw_visual(dst,fire_sprite,self:get_position())
end
function light:track_entity(ent,dx,dy,dl)
ent:register_event("on_position_changed",function(ent,x,y,l)
light:set_position(x+(dx or 0),y+(dy or 0), l+(dl or 0))
end)
end
This is the one from "Le defi de Zeldo"
Here's how you can pinpoint the line of code giving you problems:
Edit your multi-events script to add the following line after line 72 (extra lines shown for context)
local function register_event(object, event_name, callback, first) --line 72
assert(type(callback)=="function", "callback must be a function!") --add this new line
local events = get_events(object) --line 73
if (not events[event_name]) and safe_rawget(object,event_name) then --line 74
This will give you an error pointing you to the line with bad syntax for the register_event() function. Then revert the multi-events script back to how it was originally.
Thank you for the answer !
Here's the new error message
Error: In on_map_changed: scripts/multi_events.lua:39: callback must be a function!
stack traceback:
[C]: at 0x017de150
[C]: in function 'assert'
scripts/multi_events.lua:39: in function 'register_event'
scripts/fsa_effect.lua:210: in function 'setup_inside_lights'
scripts/fsa_effect.lua:225: in function 'on_map_changed'
scripts/effect_manager.lua:7: in function 'apply_effect'
scripts/effect_manager.lua:22: in function 'callback'
scripts/multi_events.lua:42: in function <scripts/multi_events.lua:41>
Looks like your fsa_effect script or maybe effect_manager are causing the issue. Could you post those, or link them, looks pretty long.
I don't know how to link scripts... :/
Your problem is line 210 of scripts/fsa_effect.lua
I'm guessing the line is something like:
light_entity:register_event("on_enabled", true)
or perhaps:
light_entity:register_event("on_enabled", light_entity:is_enabled())
where basically what you are passing as the second argument to register_event() is a boolean value, where it should be a function. Like so:
light_entity:register_event("on_enabled", function()
--do the things that should happen when the light is enabled here
end)
If you still need help then paste the code of your setup_inside_lights() function in your fsa_effect.lua script and indicate which line is line 210.