Author Topic: Problem w global go value  (Read 1977 times)

Starlock

  • Jr. Member
  • **
  • Posts: 82
    • View Profile
Problem w global go value
« on: August 26, 2015, 03:01:44 am »
I'm trying to make a crab that throws a stone using the roth code for an octorok but everytime I run it the sprite disappears during the "shooting" animation with the error:

Error: In timer callback: [string "enemies/crab.lua"]:53: attempt to call global 'go' (a nil value)

Diarandor

  • Hero Member
  • *****
  • Posts: 805
  • Cats are cool! (ΦωΦ)
    • View Profile
Re: Problem w global go value
« Reply #1 on: August 26, 2015, 03:19:57 am »
Your errors says that you have an error in line 53 because the function go is not defined before (in other words, it is equal to nil). If you still have problems with this, post the code here, so we can help you.

Starlock

  • Jr. Member
  • **
  • Posts: 82
    • View Profile
Re: Problem w global go value
« Reply #2 on: August 26, 2015, 03:25:58 am »
Here is the code:

Code: Lua
  1. local enemy = ...
  2.  
  3. local can_shoot = true
  4.  
  5. function enemy:on_created()
  6.  
  7.   enemy:set_life(3)
  8.   enemy:set_damage(2)
  9.   enemy:create_sprite("enemies/" .. enemy:get_breed())
  10. end
  11.  
  12. local function go_hero()
  13.  
  14.   local sprite = enemy:get_sprite()
  15.   sprite:set_animation("walking")
  16.   local movement = sol.movement.create("target")
  17.   movement:set_speed(64)
  18.   movement:start(enemy)
  19. end
  20.  
  21. local function shoot()
  22.  
  23.   local map = enemy:get_map()
  24.   local hero = map:get_hero()
  25.   if not enemy:is_in_same_region(hero) then
  26.     return true  -- Repeat the timer.
  27.   end
  28.  
  29.   local sprite = enemy:get_sprite()
  30.   local x, y, layer = enemy:get_position()
  31.   local direction = sprite:get_direction()
  32.  
  33.   -- Where to create the projectile.
  34.   local dxy = {
  35.     {  8,  -4 },
  36.     {  0, -13 },
  37.     { -8,  -4 },
  38.     {  0,   0 },
  39.   }
  40.  
  41.   sprite:set_animation("shooting")
  42.   enemy:stop_movement()
  43.   sol.timer.start(enemy, 300, function()
  44.     sol.audio.play_sound("stone")
  45.     local stone = enemy:create_enemy({
  46.       breed = "crab_stone",
  47.       x = dxy[direction + 1][1],
  48.       y = dxy[direction + 1][2],
  49.     })
  50.  
  51.     go(direction)
  52.  
  53.     sol.timer.start(enemy, 500, go_hero)
  54.   end)
  55. end
  56.  
  57. function enemy:on_restarted()
  58.  
  59.   local map = enemy:get_map()
  60.   local hero = map:get_hero()
  61.  
  62.   go_hero()
  63.  
  64.   can_shoot = true
  65.  
  66.   sol.timer.start(enemy, 100, function()
  67.  
  68.     local hero_x, hero_y = hero:get_position()
  69.     local x, y = enemy:get_center_position()
  70.  
  71.     if can_shoot then
  72.       local aligned = (math.abs(hero_x - x) < 16 or math.abs(hero_y - y) < 16)
  73.       if aligned and enemy:get_distance(hero) < 200 then
  74.         shoot()
  75.         can_shoot = false
  76.         sol.timer.start(enemy, 1500, function()
  77.           can_shoot = true
  78.         end)
  79.       end
  80.     end
  81.     return true  -- Repeat the timer.
  82.   end)
  83. end
  84.  
  85. function enemy:on_movement_changed(movement)
  86.  
  87.   local direction4 = movement:get_direction4()
  88.   local sprite = self:get_sprite()
  89.   sprite:set_direction(direction4)
  90. end

Diarandor

  • Hero Member
  • *****
  • Posts: 805
  • Cats are cool! (ΦωΦ)
    • View Profile
Re: Problem w global go value
« Reply #3 on: August 26, 2015, 03:42:39 am »
Do you still get an error or does it work now? And, in case you get an error or something is wrong, what is it?

Starlock

  • Jr. Member
  • **
  • Posts: 82
    • View Profile
Re: Problem w global go value
« Reply #4 on: August 26, 2015, 03:49:05 am »
The error is still

Error: In timer callback: [string "enemies/crab.lua"]:53: attempt to call global 'go' (a nil value)

which is what I dont understand since the go value is supposed to be based on direction as far as I know... The sprite just disappears when its supposed to shoot the rock

Diarandor

  • Hero Member
  • *****
  • Posts: 805
  • Cats are cool! (ΦωΦ)
    • View Profile
Re: Problem w global go value
« Reply #5 on: August 26, 2015, 03:56:54 am »
You have a 'go' function in line 51 which is not defined in the script.

Starlock

  • Jr. Member
  • **
  • Posts: 82
    • View Profile
Re: Problem w global go value
« Reply #6 on: August 26, 2015, 04:11:25 am »
Ahh I see what you mean now.. I was able to get it work now thanks   :)

ffomega

  • Full Member
  • ***
  • Posts: 212
    • View Profile
    • Solarus Resource & Tutorial Site
Re: Problem w global go value
« Reply #7 on: April 01, 2017, 11:58:57 pm »
I'm receiving a similar error message from the octorok script, only instead it is giving an error for method 'go' instead of global 'go'.  Also in my case, the octorok moves as it should until the hero gets close to it, then it stops moving.  It continues to animate the walking animation, but it is unable to move.  It also does not shoot a projectile, but the stone sound can be heard.  The hero can even kill it like a normal enemy.

Here's the code:

Code: Lua
  1. -- Octorok: shoots stones.
  2.  
  3. local enemy = ...
  4.  
  5. local children = {}
  6.  
  7. local can_shoot = true
  8.  
  9. function enemy:on_created()
  10.  
  11.   enemy:set_life(3)
  12.   enemy:set_damage(2)
  13.   enemy:create_sprite("enemies/" .. enemy:get_breed())
  14. end
  15.  
  16. local function go_hero()
  17.  
  18.   local sprite = enemy:get_sprite()
  19.   sprite:set_animation("walking")
  20.   local movement = sol.movement.create("target")
  21.   movement:set_speed(64)
  22.   movement:start(enemy)
  23. end
  24.  
  25. local function shoot()
  26.  
  27.   local map = enemy:get_map()
  28.   local hero = map:get_hero()
  29.   if not enemy:is_in_same_region(hero) then
  30.     return true  -- Repeat the timer.
  31.   end
  32.  
  33.   local sprite = enemy:get_sprite()
  34.   local x, y, layer = enemy:get_position()
  35.   local direction = sprite:get_direction()
  36.  
  37.   -- Where to create the projectile.
  38.   local dxy = {
  39.     {  8,  -4 },
  40.     {  0, -13 },
  41.     { -8,  -4 },
  42.     {  0,   0 },
  43.   }
  44.  
  45.   sprite:set_animation("shooting")
  46.   enemy:stop_movement()
  47.   sol.timer.start(enemy, 300, function()
  48.     sol.audio.play_sound("stone")
  49.     local stone = enemy:create_enemy({
  50.       breed = "octorok_stone",
  51.       x = dxy[direction + 1][1],
  52.       y = dxy[direction + 1][2],
  53.     })
  54.     children[#children + 1] = stone
  55.     stone:go(direction)
  56.  
  57.     sol.timer.start(enemy, 500, go_hero)
  58.   end)
  59. end
  60.  
  61. function enemy:on_restarted()
  62.  
  63.   local map = enemy:get_map()
  64.   local hero = map:get_hero()
  65.  
  66.   go_hero()
  67.  
  68.   can_shoot = true
  69.  
  70.   sol.timer.start(enemy, 100, function()
  71.  
  72.     local hero_x, hero_y = hero:get_position()
  73.     local x, y = enemy:get_center_position()
  74.  
  75.     if can_shoot then
  76.       local aligned = (math.abs(hero_x - x) < 16 or math.abs(hero_y - y) < 16)
  77.       if aligned and enemy:get_distance(hero) < 200 then
  78.         shoot()
  79.         can_shoot = false
  80.         sol.timer.start(enemy, 1500, function()
  81.           can_shoot = true
  82.         end)
  83.       end
  84.     end
  85.     return true  -- Repeat the timer.
  86.   end)
  87. end
  88.  
  89. function enemy:on_movement_changed(movement)
  90.  
  91.   local direction4 = movement:get_direction4()
  92.   local sprite = self:get_sprite()
  93.   sprite:set_direction(direction4)
  94. end
  95.  
  96. local previous_on_removed = enemy.on_removed
  97. function enemy:on_removed()
  98.  
  99.   if previous_on_removed then
  100.     previous_on_removed(enemy)
  101.   end
  102.  
  103.   for _, child in ipairs(children) do
  104.     child:remove()
  105.   end
  106. end
  107.  

In a previous message, it was mentioned that 'go' has to be defined.  Is this the case here as well? If so, I do not know how to do this
My tilesets page can be found here:
http://absolute-hyrule-tutorials.solarus-games.org/

Diarandor

  • Hero Member
  • *****
  • Posts: 805
  • Cats are cool! (ΦωΦ)
    • View Profile
Re: Problem w global go value
« Reply #8 on: April 02, 2017, 01:30:18 am »
I'm receiving a similar error message from the octorok script, only instead it is giving an error for method 'go' instead of global 'go'.  Also in my case, the octorok moves as it should until the hero gets close to it, then it stops moving.  It continues to animate the walking animation, but it is unable to move.  It also does not shoot a projectile, but the stone sound can be heard.  The hero can even kill it like a normal enemy.

Here's the code:

Code: Lua
  1. -- Octorok: shoots stones.
  2.  
  3. local enemy = ...
  4.  
  5. local children = {}
  6.  
  7. local can_shoot = true
  8.  
  9. function enemy:on_created()
  10.  
  11.   enemy:set_life(3)
  12.   enemy:set_damage(2)
  13.   enemy:create_sprite("enemies/" .. enemy:get_breed())
  14. end
  15.  
  16. local function go_hero()
  17.  
  18.   local sprite = enemy:get_sprite()
  19.   sprite:set_animation("walking")
  20.   local movement = sol.movement.create("target")
  21.   movement:set_speed(64)
  22.   movement:start(enemy)
  23. end
  24.  
  25. local function shoot()
  26.  
  27.   local map = enemy:get_map()
  28.   local hero = map:get_hero()
  29.   if not enemy:is_in_same_region(hero) then
  30.     return true  -- Repeat the timer.
  31.   end
  32.  
  33.   local sprite = enemy:get_sprite()
  34.   local x, y, layer = enemy:get_position()
  35.   local direction = sprite:get_direction()
  36.  
  37.   -- Where to create the projectile.
  38.   local dxy = {
  39.     {  8,  -4 },
  40.     {  0, -13 },
  41.     { -8,  -4 },
  42.     {  0,   0 },
  43.   }
  44.  
  45.   sprite:set_animation("shooting")
  46.   enemy:stop_movement()
  47.   sol.timer.start(enemy, 300, function()
  48.     sol.audio.play_sound("stone")
  49.     local stone = enemy:create_enemy({
  50.       breed = "octorok_stone",
  51.       x = dxy[direction + 1][1],
  52.       y = dxy[direction + 1][2],
  53.     })
  54.     children[#children + 1] = stone
  55.     stone:go(direction)
  56.  
  57.     sol.timer.start(enemy, 500, go_hero)
  58.   end)
  59. end
  60.  
  61. function enemy:on_restarted()
  62.  
  63.   local map = enemy:get_map()
  64.   local hero = map:get_hero()
  65.  
  66.   go_hero()
  67.  
  68.   can_shoot = true
  69.  
  70.   sol.timer.start(enemy, 100, function()
  71.  
  72.     local hero_x, hero_y = hero:get_position()
  73.     local x, y = enemy:get_center_position()
  74.  
  75.     if can_shoot then
  76.       local aligned = (math.abs(hero_x - x) < 16 or math.abs(hero_y - y) < 16)
  77.       if aligned and enemy:get_distance(hero) < 200 then
  78.         shoot()
  79.         can_shoot = false
  80.         sol.timer.start(enemy, 1500, function()
  81.           can_shoot = true
  82.         end)
  83.       end
  84.     end
  85.     return true  -- Repeat the timer.
  86.   end)
  87. end
  88.  
  89. function enemy:on_movement_changed(movement)
  90.  
  91.   local direction4 = movement:get_direction4()
  92.   local sprite = self:get_sprite()
  93.   sprite:set_direction(direction4)
  94. end
  95.  
  96. local previous_on_removed = enemy.on_removed
  97. function enemy:on_removed()
  98.  
  99.   if previous_on_removed then
  100.     previous_on_removed(enemy)
  101.   end
  102.  
  103.   for _, child in ipairs(children) do
  104.     child:remove()
  105.   end
  106. end
  107.  

In a previous message, it was mentioned that 'go' has to be defined.  Is this the case here as well? If so, I do not know how to do this

Ahoy there! I am not sure of what could be wrong (I haven't tested the script). Could you post the message error (explicitly) so that we can know in which line it happens?

With the given info I can only say that the problem might be happening in line 55, "stone:go(direction)", so make sure that the "go" function is defined in your stone script.

I am not sure if you have this problem now but, if you see that your "shooting" animation is not started, then try to swap lines 45 and 46, in this order:
Code: Lua
  1. enemy:stop_movement()
  2. sprite:set_animation("shooting")
(If an enemy is walking the engine might change its animation to the "walking" animation, so I would stop the movement before changing the animation, just in case.)

ffomega

  • Full Member
  • ***
  • Posts: 212
    • View Profile
    • Solarus Resource & Tutorial Site
Re: Problem w global go value
« Reply #9 on: April 02, 2017, 01:50:36 am »
I tried swapping lines 45 and 46 and no changed happened.  Here is the exact error message.  It only appears when the hero gets close enough to the octorok to trigger it to shoot at him.

Error: In timer callback: [string "enemies/Octoroks/octorok.lua"]:55: attempt to call method 'go' (a nil value)
My tilesets page can be found here:
http://absolute-hyrule-tutorials.solarus-games.org/

Diarandor

  • Hero Member
  • *****
  • Posts: 805
  • Cats are cool! (ΦωΦ)
    • View Profile
Re: Problem w global go value
« Reply #10 on: April 02, 2017, 07:03:59 am »
I tried swapping lines 45 and 46 and no changed happened.  Here is the exact error message.  It only appears when the hero gets close enough to the octorok to trigger it to shoot at him.

Error: In timer callback: [string "enemies/Octoroks/octorok.lua"]:55: attempt to call method 'go' (a nil value)

-The swap of lines was to make sure that the change of animation is performed, not for your current problem.
-Your error in line 55 confirms what I said. So open your "octorok_stone.lua" enemy spript (the one for the stone, not the octorok) and take a look inside. The "enemy:go()" function has to be missing there, or has a different name.

ffomega

  • Full Member
  • ***
  • Posts: 212
    • View Profile
    • Solarus Resource & Tutorial Site
Re: Problem w global go value
« Reply #11 on: April 02, 2017, 02:33:59 pm »
Here's the code for the octorok stone:

Code: Lua
  1. -- Stone shot by Octorok.
  2.  
  3. local enemy = ...
  4.  
  5. function enemy:on_created()
  6.  
  7.   enemy:set_life(1)
  8.   enemy:set_damage(2)
  9.   enemy:create_sprite("enemies/" .. enemy:get_breed())
  10.   enemy:set_size(8, 8)
  11.   enemy:set_origin(4, 4)
  12.   enemy:set_invincible()
  13.   enemy:set_obstacle_behavior("flying")
  14. end
  15.  
  16. function enemy:on_obstacle_reached()
  17.  
  18.   enemy:remove()
  19. end
  20.  
  21. function enemy:go(direction4)
  22.  
  23.   local angle = direction4 * math.pi / 2
  24.   local movement = sol.movement.create("straight")
  25.   movement:set_speed(192)
  26.   movement:set_angle(angle)
  27.   movement:set_smooth(false)
  28.   movement:start(enemy)
  29.  
  30.   enemy:get_sprite():set_direction(direction4)
  31. end
  32.  
  33.  
My tilesets page can be found here:
http://absolute-hyrule-tutorials.solarus-games.org/

MetalZelda

  • Hero Member
  • *****
  • Posts: 511
    • View Profile
Re: Problem w global go value
« Reply #12 on: April 02, 2017, 03:42:23 pm »
You are trying to  call go() from another script.

You can access the other entities' code as soon as they are created.

Code: Lua
  1. local stone = enemy:create_enemy({
  2.       breed = "crab_stone",
  3.       x = dxy[direction + 1][1],
  4.       y = dxy[direction + 1][2],
  5.     })

Good point, the enemy here is stone, so
 
Code: Lua
  1. go(direction)

is wrong. Because in the rock script, this is what appear
Code: Lua
  1. enemy:go(direction4)
It's not global and it is also not local, it is proper to this entity

The solution:
Just call

Code: Lua
  1. stone:go(direction)

If the error persists, then it is related to a line in enemy:go(), yet for what I've seen the enemy:go looks ok
« Last Edit: April 02, 2017, 03:47:41 pm by MetalZelda »

Diarandor

  • Hero Member
  • *****
  • Posts: 805
  • Cats are cool! (ΦωΦ)
    • View Profile
Re: Problem w global go value
« Reply #13 on: April 02, 2017, 06:19:46 pm »
@MetalZelda: I think you have read the original post by Starlock and not the last one by ffomega by mistake (in ffomega's script there is no "crab_stone" enemy). Better to point this out before all of us become crazy XD.

@ffomega: I have not been able yet to find the problem and all the code seems correct to me, but there has to be something that we have not found yet. Another possibility is that your enemy is not correctly created because some properties were missing in the property list:
Code: Lua
  1. local stone = enemy:create_enemy({
  2.       breed = "octorok_stone",
  3.       x = dxy[direction + 1][1],
  4.       y = dxy[direction + 1][2],
  5.     })
You did not define the "direction" and "layer", which are mandatory to create the enemy (if the Lua API is right); probably there is an engine bug if the engine did not give you another bug telling that these properties were missing. So try to add these properties and tell us if this solves the bug or not.

I am getting out of ideas, so let's hope that this fixes the problem :-[
« Last Edit: April 02, 2017, 06:22:00 pm by Diarandor »

ffomega

  • Full Member
  • ***
  • Posts: 212
    • View Profile
    • Solarus Resource & Tutorial Site
Re: Problem w global go value
« Reply #14 on: April 02, 2017, 06:48:45 pm »
I may have figured out the problem.

I want to create ten different versions of this enemy (and all others for my enemy package)  As of right now, the scripts for both enemies (octorok and the stone) have not been rewritten.

To keep all enemies sorted neatly, however, I want to place them all in their own separate folders--in this case, a folder named "Octoroks".  It is when I place the enemy script for both the octorok and the stone in its own directory when I begin seeing this problem.  If I move the enemy script outside of the Octoroks folder (leaving it in the root directory of "enemies"), it works as intended, so the problem lies in the location of the octorok script.  Any ideas on how I can resolve this problem?
« Last Edit: April 02, 2017, 06:51:10 pm by ffomega »
My tilesets page can be found here:
http://absolute-hyrule-tutorials.solarus-games.org/