Hello, I have a problem with an enemy I made. I 've done a Skulltula (like in OoT) falling from the ceiling, turning, etc... and after many days of coding, I finished it. It works as I would, but when I adding a second Skulltula, both of them doesn't work! I had the same problem when I made custom wizzrobe (before the release of ROTH, otherwise I didn't lost my time on it) and I've solved it somehow, but I don't remember how today! I think it's a problem with "self", but not sure! Here is the code. (And if it can help some dev to make a skulltula!)
local enemy = ...
-- Skulltula :
local fallen = false
local vulnerable = false
local shadow_x, shadow_y, shadow_z = enemy:get_position()
local m = sol.movement.create("straight")
local angle = math.pi/2
local angle_inverse = 3*math.pi/2
function enemy:on_created()
self:set_life(4)
self:set_damage(2)
self:set_optimization_distance(160)
self:set_size(16, 16)
self:set_origin(8, 13)
self:set_can_attack(false)
self:set_pushed_back_when_hurt(false)
self:set_attack_consequence("sword", "custom")
self:set_attack_consequence("hookshot", "ignored")
self:set_attack_consequence("boomerang", "ignored")
self:set_attack_consequence("explosion", "ignored")
self:set_obstacle_behavior("flying")
self:set_layer_independent_collisions(true)
sprite = self:create_sprite("enemies/skulltula")
end
function enemy:on_restarted()
if not fallen then
sprite:set_animation("shadow")
self:check_hero()
else
self:turning()
end
end
function enemy:check_hero()
local hero = self:get_map():get_entity("hero")
local x, y, z = self:get_position()
local hero_x, hero_y, hero_z = hero:get_position()
if self:get_distance(hero) <= 32 then
local direction = self:get_direction4_to(hero)
sprite:set_direction(direction)
if direction == 0 then
angle = 2*math.pi/2
angle_inverse = 0
end
if direction == 1 then
angle = 3*math.pi/2
angle_inverse = math.pi/2
end
if direction == 2 then
angle = 0
angle_inverse = 2*math.pi/2
end
if direction == 3 then
angle = math.pi/2
angle_inverse = 3*math.pi/2
end
self:falling()
end
sol.timer.stop_all(self)
sol.timer.start(self, 500, function() self:check_hero() end)
end
function enemy:falling()
sol.audio.play_sound("jump")
sprite:set_animation("walking")
self:set_position(shadow_x, shadow_y - 120, 2)
self:set_can_attack(true)
m:set_speed(320)
m:set_angle(3*math.pi/2)
m:set_max_distance(120)
m:start(self)
end
function enemy:on_movement_finished()
if fallen == false then
fallen = true
self:set_position(shadow_x, shadow_y, shadow_z)
self:restart()
end
end
function enemy:turn_anim()
if vulnerable == false then
sprite:set_animation("vulnerable")
vulnerable = true
else
sprite:set_animation("walking")
vulnerable = false
end
end
function enemy:turning()
sol.timer.start(self, 2000, function() -- Shaking
if vulnerable == false then
sprite:set_animation("shaking")
else
sprite:set_animation("vulnerable_shaking")
end
sol.timer.start(self, 2000, function() -- Turning
self:turn_anim()
sol.timer.start(self, 2000, function() self:turning() end)
end)
end)
end
function enemy:on_custom_attack_received(attack, sprite)
if fallen == true then
m:set_angle(angle)
m:set_speed(128)
m:start(self)
sol.timer.start(self, 200, function()
m:set_angle(angle_inverse)
sol.timer.start(self, 400, function()
m:set_angle(angle)
sol.timer.start(self, 200, function() m:stop() end)
end)
end)
if vulnerable == false then
sol.audio.play_sound("sword_tapping")
else
sprite:set_animation("hurt")
sol.audio.play_sound("enemy_hurt")
self:remove_life(1)
sol.timer.start(self, 200, function() self:turn_anim() end)
end
end
end
You forgot to declare sprite as a local variable to the script. Therefore, it is a global variable shared by all skulltulas.
Bugs that appear as soon as there are two instances of the same script are typically this kind of error.
Ok! I knew it was just a little mistake like that, but I didn't figure what! What a dumb I am ! Well, thank you for this help and another question : what do you think about the code, is there a way to improve it, or I just let it like that ?
Hard to say, it is quite long, but nothing shocked me when reading it quickly :)