Small keys

Started by Dragon_noir, May 19, 2015, 07:23:30 PM

Previous topic - Next topic
Thanks! I found the problem. We forgot to set the maximum amount of our counter, and by default the maximum is zero (which is probably stupid, and I will change that in Solarus 1.5).

Here is the updated code:

dungeon_1_small_key_counter.lua:

local item = ...

function item:on_created()
  item:set_savegame_variable("dungeon_1_small_key_counter_possession")
  item:set_amount_savegame_variable("dungeon_1_small_key_counter_amount")
  item:set_max_amount(999)
end


dungeon_1_small_key.lua:

function item:on_created()
  item:set_shadow("small")
  item:set_brandish_when_picked(false)
  item:set_sound_when_picked("picked_small_key")
end

function item:on_obtaining(variant, savegame_variable)

  local counter = item:get_game():get_item("dungeon_1_small_key_counter")
  counter:set_variant(1)
  counter:add_amount(1)
end


Also, in dungeon_1_small_key.lua, don't forget to remove the set_savegame_variable() line. It is the counter that saves its possession state, not each individual key.

Now, to make the HUD, this is a completely different matter. You can use the same as ZSDX, except that you have to retrieve the counter value differently.

You can implement helper functions game:get_num_small_keys(), game:get_dungeon(), etc like in ZSDX.
In get_num_small_keys(), get the small key counter of the current dungeon with something like

local dungeon_number = game:get_dungeon()
local counter = game:get_item("dungeon_" .. dungeon_number .. "_small_key_counter")

and then the value is counter:get_amount().

No, still doesn't work :(

If I don't use the line "item:set_savegame_variable()" in the dungeon_1_small_key.lua file, I get the error:

"Error: In create_door: bad argument #1 to ? (Bad field 'opening_condition' (equipment item 'dungeon_1_small_key' is not saved))"

As I've said in the beginning i'm just a beginner and I don't really know what I'm doing.

The HUD script for the key counter is almost the same as ZeldaDX

Your doors need to require the small key counter item, not the small key item. The code I pasted above works, I tested it on your data.
The small key item is a treasure whose only effect is to increment the small key counter item. The logic is that a door can be opened if small key counter > 0.

Items with counters are not trivial. I recommend you to watch the tutorial video (in French) about the bow and arrows because it works the same way. There is a bow item (the counter) and an arrow item (the one that increments the counter). I understand that it can be more confusing for small keys.

If you prefer, you can rename "small key counter" to "bunch of keys" (trousseau de clés en français), maybe it will be easier to undertand the difference.

Yes! That was my error. I used the small key item instead of the counter :D.

One more question: How do I make it so that a map shows the key counter.

I can get it to show up when I set

"small_keys.visible = false" to "small_keys.visible =  true" in the file small_keys.lua (script/hud/small_keys.lua)

PS: Thanks for your patience ;)

But you don't want to set it visible all the time, you want it only in dungeons.

This visible property is set from the result of game:are_small_keys_enabled() in ZSDX. This function is defined in equipment.lua. It could look like this:


-- Returns whether a small key counter exists on the current map.
function game:are_small_keys_enabled()
  return game:get_small_keys_counter_item() ~= nil
end

-- Returns the item that stores the number
-- of small keys for the current map, or nil.
function game:get_small_keys_counter_item()

  local map = game:get_map()

  if map ~= nil then
    -- Are we in a dungeon?
    local dungeon_index = game:get_dungeon_index()
    if dungeon_index ~= nil then
      local item_name = "dungeon_" .. dungeon_index .. "_small_key_counter"
      return game:get_item(item_name)
    end
  end

  -- No small keys on this map.
  return nil
end

-- Returns whether the player has at least one small key.
-- Raises an error is small keys are not enabled in the current map.
function game:has_small_key()

  return game:get_num_small_keys() > 0
end

-- Returns the number of small keys of the player.
-- Raises an error is small keys are not enabled in the current map.
function game:get_num_small_keys()

  if not self:are_small_keys_enabled() then
    error("Small keys are not enabled in the current map")
  end

  local item = self:get_small_keys_counter_item()
  if item == nil then
    return 0
  end

  return item:get_amount()
end


In equipment.lua from ZSDX, replace all functions related to small keys by this code. Then you should not have to change anything in the HUD code.
Your small key counter item has to be named exactly dungeon_1_small_key_counter.
To make get_small_keys_counter_item() detect that you are in a dungeon, you have to set the world of your map to "dungeon_1".

Doesn't work :(

I've looked around the code and i think there's something wrong within the function small_keys:check() . A variable never gets set to "true".

I've also added the dungeon.lua file to my data.

But did you even call dungeons.lua and equipment.lua at some point?
It does work, I just tested it ;)

You should really learn Lua to be able make your own scripts. I recommend this book: http://www.lua.org/pil/contents.html

I got it to work :D

Thanks :)