Item command held on item?

Started by Porksteak, June 19, 2017, 04:12:22 PM

Previous topic - Next topic
Hi I wanted to try and make some kind of energy blast attack that gets stronger the longer you hold it. Is there a way in the item to check if the specific item key that the item is assigned to is being held down?

What you'll probably want to do is create a timer (or a set of timers) that count for how long you want the difference of time between the instances of charge.

So doing something like this:
Code ( lua) Select

-- At beinging of code
local timer = nil

--  Code before timers
local function start_timer()
  timer = sol.timer.start(item, 1000, function()
    --code relating to when timer reaches max time
  end) -- This timer lasts 1 sec and belongs to "context" item if defined. To increase the time, change the 2nd value to desired time in milliseconds.

end

local function end_timer()
  local time_remaining = timer:get_remaining_time()
  --code relating to translating time into charge
  --I.E. Total charge value / (time_remaining * -1)
  --return charge_strength
end



See http://www.solarus-games.org/doc/latest/lua_api_timer.html for more details relating to timers.

For checking if the item is being held down, I would look to these sets of events: http://www.solarus-games.org/doc/latest/lua_api_game.html#lua_api_game_on_key_pressed
This signature was way too long before, but now it's short!
Also, I am Still Alive!
On ad Off I go!

Do you ever get the feeling that the fandom of a product(s) ruin the potential that you could have had to enjoy the product?

I started the item, but I can't get the command released function to work so the hero stays frozen

This is function:on_using()
Code ( lua) Select
function item:on_using()
local map = game:get_map()
local hero = game:get_hero()

local direction = hero:get_direction()




  if game:is_command_pressed("item_1") or game:is_command_pressed("item_2") then
  state = 1
      if blastlevel < 4 then
    timer = sol.timer.start(2000, function()
      blastlevel = blastlevel + 1
    return true
    end)
  end
  end



    if game:get_item_assigned(2) == "blast" and not game:is_command_pressed("item_2") and state == 1 then
      game:simulate_command_released("item_2")
    end

    if game:get_item_assigned(1) == "blast" and not game:is_command_pressed("item_1") and state == 1 then
      game:simulate_command_released("item_1")
    end


end


function game:on_command_released(command)
  if command == "item_1" or "item_2" then
    timer:stop()
    hero:unfreeze()
    item:fire_blast()
  end
end


To make the hero controllable just call item:set_fiinished()

But, you might want to control the hero and having the item to work. I would link a menu to this item and control everrything from this menu, you will have access to on_command_pressed / released.

That's what I do for my bow, hookshot and other stuffs

Quote from: MetalZelda on June 21, 2017, 12:34:22 PM
To make the hero controllable just call item:set_fiinished()

But, you might want to control the hero and having the item to work.

You can directly unfreeze the hero (which allows to control him) before calling item:set_finished(), which is probably what he needs. This is what I use for my "custom jump", which allows to control the hero during the jump. But don't forget to call item:set_finished() when you finish using the item! :)
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."

Yeah, but the problem is the unfreeze() is in the on_command_released function, but when the key is released nothing happens and the hero stays frozen

Quote from: Porksteak on June 20, 2017, 05:20:58 PM
I started the item, but I can't get the command released function to work so the hero stays frozen

This is function:on_using()
Code ( lua) Select
function item:on_using()
local map = game:get_map()
local hero = game:get_hero()

local direction = hero:get_direction()




  if game:is_command_pressed("item_1") or game:is_command_pressed("item_2") then
  state = 1
      if blastlevel < 4 then
    timer = sol.timer.start(2000, function()
      blastlevel = blastlevel + 1
    return true
    end)
  end
  end



    if game:get_item_assigned(2) == "blast" and not game:is_command_pressed("item_2") and state == 1 then
      game:simulate_command_released("item_2")
    end

    if game:get_item_assigned(1) == "blast" and not game:is_command_pressed("item_1") and state == 1 then
      game:simulate_command_released("item_1")
    end


end


function game:on_command_released(command)
  if command == "item_1" or "item_2" then
    timer:stop()
    hero:unfreeze()
    item:fire_blast()
  end
end


Are you aware of the fact that defining "game" events inside an item script is a bad idea and that one event definition will override other previous definitions of that event in other scripts? I am talking about game.on_command_released.
"If you make people think they're thinking, they'll love you. But if you really make them think, they'll hate you."

September 25, 2018, 08:51:16 PM #7 Last Edit: September 25, 2018, 09:03:20 PM by alexgleason
Here's how I achieved this.

In main.lua, within the sol.main:start_savegame(game) function:

Code (lua) Select

-- ♡ Copying is an act of love. Please copy and share.

-- Returns an item for item_ command strings
function get_item_for_command(command)

  local slot = tonumber(string.match(command, "^item_([12])$"))

  if slot then
    local item = game:get_item_assigned(slot)
    return item
  else
    return nil
  end
end


function game:on_command_pressed(command)

  -- Handle items with item:on_command_pressed()
  local item = get_item_for_command(command)
  if item and item.on_command_pressed ~= nil then
    item:on_command_pressed(command)
    return true
  else
    -- Fall back to item:on_using()
    return false
  end

end

function game:on_command_released(command)

  -- Handle items with item:on_command_released()
  local item = get_item_for_command(command)
  if item and item.on_command_released ~= nil then
    item:on_command_released(command)
    return true
  else
    return false
  end

end


Then within the item itself, simply implement item:on_command_pressed() and item:on_command_released().

Code ( lua) Select

-- ♡ Copying is an act of love. Please copy and share.

function item:on_command_pressed(command)
  print(string.format("%s command pressed", item:get_name()))
end

function item:on_command_released(command)
  print(string.format("%s command released", item:get_name()))
end


In this case, item:on_using() is never called. If you choose not to implement item:on_command_pressed() for a particular item, it will fall back to item:on_using().

I'm a bit afraid I've missed something which I'll discover later, but this works in normal circumstances.
RIP Aaron Swartz