Solarus-Games English Forum

Solarus => Development => Topic started by: zutokaza on April 12, 2017, 12:16:54 AM

Title: [Solved]Disable spin Attack?
Post by: zutokaza on April 12, 2017, 12:16:54 AM
is it possible to disable the spin attack?
Title: Re: Disable spin Attack?
Post by: MetalZelda on April 15, 2017, 02:08:38 PM
You can, by overwriting the spin attack loading state in hero:on_state_changed

just unfreeze the hero and that would work
Title: Re: Disable spin Attack?
Post by: zutokaza on April 16, 2017, 07:22:12 AM
Could I get an example?

I tried this, but is fails...
Code ( lua) Select
function hero:on_state_changed("sword spin attack")
  hero:unfreeze()
end
Title: Re: Disable spin Attack?
Post by: zutokaza on April 16, 2017, 10:18:40 AM
I got it somewhat working now, but it does not disable anything. It just unfreezes the player after a spin attack.

Code ( lua) Select
function hero:on_state_changed(state)

  if state == "sword spin attack" then
    hero:unfreeze()
  end
end

Title: Re: Disable spin Attack?
Post by: Zefk on April 27, 2017, 06:53:58 PM
In game_manager.lua.

You will need to require Christopho's multi_events script. (http://forum.solarus-games.org/index.php/topic,784.0.html)

Code ( lua) Select
require("scripts/multi_events")

That way you register the script.

Code ( lua) Select
game:register_event("on_started", function()

end


Add the following inside the register event. Basically, it is a timer called on_activated and I use MetalZelda's clever hack (http://forum.solarus-games.org/index.php/topic,431.msg2287.html#msg2287). It works for me.

Code ( lua) Select
game:register_event("on_started", function()
--Create on_activated
sol.timer.start(100, function()
  if game.on_activated ~= nil then
    game:on_activated()
return true
  end
end)

--timer function
function game:on_activated()
--MetalZelda's clever hack
  if game:get_hero():get_state() == "sword loading" then
   if not game:get_value("skill_spin_attack") then
   game:simulate_command_released("attack")
   end
end
end

  end) -- end of game:register_event
Title: [Solved]Disable spin Attack?
Post by: zutokaza on April 27, 2017, 07:05:28 PM
That works perfectly. I was able to activate it with set_value. Thanks again zefk!
Title: Re: [Solved]Disable spin Attack?
Post by: MetalZelda on April 28, 2017, 01:11:52 AM
Just rewrite hero:on_state_changed.
To disable the spin attack, the state we need to unfreeze the hero is called "sword loading"
You can still access game function through.
This way, it is more convenient since you rewrite the function it belongs to

Code (lua) Select
hero:register_event("on_state_changed", function(hero, state)
  if state == "sword loading" then
    local game = hero:get_game()
    if not game:get_value("skill_spin_attack") then
      game:simulate_command_released("attack")
    end
  end
end
Title: Re: [Solved]Disable spin Attack?
Post by: Zefk on April 28, 2017, 01:50:31 AM
@MetalZelda
I am not sure why, but I get an error.
[2770] Error: In on_started: [string "scripts/game_manager.lua"]:17: attempt to index global 'hero' (a nil value)

This is basically identical to your code and works for me. I thank you for the tip. This actually functions better than my suggestion.

Code ( lua) Select

game:register_event("on_started", function()

  local hero = game:get_hero()

  hero:register_event("on_state_changed", function(hero, state)
    if state == "sword loading" then
      if not game:get_value("skill_spin_attack") then
        game:simulate_command_released("attack")
      end
    end
  end) -- end of hero:register
end) -- end of game:register
Title: Re: [Solved]Disable spin Attack?
Post by: MetalZelda on April 28, 2017, 12:26:56 PM
You can do the following.

using metatable.
http://www.solarus-games.org/doc/latest/lua_api_main.html#lua_api_main_get_metatable


You need
1 file, called hero.lua, if you like organisation, put it in a new folder called "meta"

In main.lua, in the begining, require this file
Code (lua) Select
require("meta/hero")

in hero.lua
Code (lua) Select
local hero_meta = sol.main.get_metatable("hero")

function hero_meta:on_state_changed(state)
  if state == "sword loading" then
    local game = self:get_game()
    if not game:get_value("skill_spin_attack") then
      game:simulate_command_released("attack")
    end
  end
end


Your solution works as well, but this one is more efficient, the new state is already defined when the game starts, not applied when the game starts