Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - Maxs

Development / Re: Trouble porting a script
June 25, 2017, 06:35:43 PM
I don't think that there are a Lua equivalent to the next statement of Ruby, but you can easily reproduce this with a variable.

For example :

Code (ruby) Select

for i in 0...@xy_pos.size
  if (condition)
  # rest of the code

becomes :

Code (lua) Select

for i = 1, #items do
  local to_next = false
  if (condition) then
     to_next = true

  if not to_next then
    -- rest of the code
Your projects / Re: Path to Official Debian Package
September 15, 2016, 06:27:55 PM
Quote from: Nate-Devv on September 15, 2016, 07:43:54 AM
because there was no .desktop file.

There are already a .desktop file in the solarus-quest-editor repo. ;)

I use it for the ArchLinux package in PKGBUILD.
If you choose LaTex (or something else that uses files that can be read in clear), it will be a good idea to create a git repository.
So the book could be maintained more easily (branch for manage versions, issues, team work, etc ...).
Development / Re: Question about dynamic tiles
September 05, 2015, 03:50:34 PM
If you want to use my script with solarus 1.4, you can remove the code that check for entities in the game:can_dig(x, y, layer) method. (line 116)

But you need to add code to update the mask when you dig, to not be able to dig in the same place twice.
With something like this (in the game:dig(x, y, layer) method):
Code (lua) Select

function game:dig(x, y, layer)

  -- Check if can dig
  -- Create the dynamic tile

  digable_mask[mask_layer][mask_x .. ";" .. mask_y] = nil
  return true
Development / Re: Question about dynamic tiles
September 05, 2015, 07:32:32 AM
I wrote a script to manage the digging ! ;D (but solarus 1.5 is needed)

It provides two methods for the game:

  • game:can_dig(x, y, layer) to check if can digging at the specified position
  • game:dig(x, y, layer) to create a hole with a dynamic tile
And the method digger:on_map_changed(map) that must be called in the game:on_map_changed(map) method.

It uses a 16x16 grid and allows to have different tiles for holes (e.g. for the grass and the sand). To do that you need to specify for each tiles of each tilesets (that allows digging) which tile to use for hole; and you can use the _default value to allow digging where there are no tile. (see the definition of the variable digging_rules in the script)

So here's the script (digging_manager.lua):
Code (lua) Select

-- Script that manages digable positions and makes holes for the shovel.

-- Usage:
-- local digging_manager = require("scripts/digging_manager")
-- digging_manager:create(game)

local digging_manager = {}

-- Rules for each tilesets that allows to dig.
local digging_rules = {
  ["light_world"] = {
    _default = "grass.under_stone",
    ["grass.soil"] = "grass.under_stone",
    ["grass.weed"] = "grass.under_stone",
    ["grass.weed_big"] = "grass.under_stone",
    ["grass.flower"] = "grass.under_stone",
    ["grass.flower_double"] = "grass.under_stone",
    ["grass.soil.diag.1b"] = "grass.under_stone",
    ["grass.soil.diag.2b"] = "grass.under_stone",
    ["grass.soil.diag.3b"] = "grass.under_stone",
    ["grass.soil.diag.4b"] = "grass.under_stone",
    ["sand.soil"] = "sand.under_stone",
    ["sand.weed"] = "sand.under_stone",
    ["sand.flower"] = "sand.under_stone",
    ["sand.soil.diag.1b"] = "sand.under_stone",
    ["sand.soil.diag.2b"] = "sand.under_stone",
    ["sand.soil.diag.3b"] = "sand.under_stone",
    ["sand.soil.diag.4b"] = "sand.under_stone",

-- Creates a digger for the specified game.
function digging_manager:create(game)

  local digger = {}
  local current_map = nil
  local digable_mask = {[1] = {}, [2] = {}, [3] = {}}

  -- Loads the digable mask from the current map.
  local function load_digable_mask()

    digable_mask = {[1] = {}, [2] = {}, [3] = {}}

    -- Check the map.
    if current_map == nil then return end

    -- Get the tileset.
    local tileset = current_map:get_tileset()
    if digging_rules[tileset] == nil then

    -- Set default rule for the low layer.
    if digging_rules[tileset]._default then

      local width, height = current_map:get_size()
      width, height = math.floor(width / 16), math.floor(height / 16)

      for x = 0, width do
        for y = 0, height do
          digable_mask[1][x .. ";" .. y] = digging_rules[tileset]._default

    -- Setup an environment to load map tiles.
    local environment = {
      tile = function(tile_properties)

        local layer = tile_properties.layer + 1
        local x = math.floor(tile_properties.x / 8)
        local y = math.floor(tile_properties.y / 8)
        local width = math.floor(tile_properties.width / 8)
        local height = math.floor(tile_properties.height / 8)

        local tile = digging_rules[tileset][tile_properties.pattern]

        for i = 1, width do
          for j = 1, height do
            local mask_x = math.floor((x + i - 1) / 2)
            local mask_y = math.floor((y + j - 1) / 2)
            digable_mask[layer][mask_x .. ";" .. mask_y] = tile

    setmetatable(environment, {
      __index = function()
        return function() end

    -- Load the map.
    local chunk = sol.main.load_file("maps/" .. current_map:get_id() .. ".dat")
    setfenv(chunk, environment)

  -- Call this function to notify the digger that the current map has changed.
  function digger:on_map_changed(map)

    current_map = map

  -- Checks whether the specified position can be dug in the current map.
  function game:can_dig(x, y, layer)

    if digable_mask == nil then
      return false

    x, y = x - (x % 16), y - (y % 16)

    for entity in current_map:get_entities_in_rectangle(x, y, 16, 16) do
      if entity:get_type() == "dynamic_tile" and entity:is_enabled() then
        return false

    x, y, layer = math.floor(x / 16), math.floor(y / 16), layer + 1

    return digable_mask[layer][x .. ";" .. y] ~= nil

  -- Digs a hole at the specified position in the current map.
  function game:dig(x, y, layer)

    if not self:can_dig(x, y, layer) then
      return false

    local mask_layer = layer + 1
    local mask_x, mask_y = math.floor(x / 16), math.floor(y / 16)
    local tile = digable_mask[mask_layer][mask_x .. ";" .. mask_y]

      layer = layer,
      x = mask_x * 16,
      y = mask_y * 16,
      width = 16,
      height = 16,
      pattern = tile,
      enabled_at_start = true

    return true

  return digger

return digging_manager

The digging_rules of this script is an example based on the alltp pack but you need to modify the light_world.tiles image to add "grass" and "sand" of tiles grass.under_stone and sand.under_stone. (have no transparency to override flowers)

Now, it remains only to write the script of the shovel.  :P

meanwhile here's the script that I've used for my tests (main.lua):
Code (lua) Select

local digging_manager = require("digging_manager")

function sol.main:on_started()

  local game ="save")
  local digger = digging_manager:create(game)

  function game:on_map_changed(map)

  function game:on_key_pressed(key)

    local map = self:get_map()
    if map and key == "t" then
      local x, y, layer = map:get_hero():get_position()
      self:dig(x, y, layer)


Development / Re: Trouble making a bridge.
July 30, 2015, 02:54:38 AM
Do you have put sensors on good layers? And have you noticed that he uses invisible tiles placed on the upper layer to allow the transition?
Development / Re: Trouble making a bridge.
July 30, 2015, 01:23:55 AM
Christopho made a bridge in zelda mercuris chest (under development).

You can see an example in `the forest_store` map. He use sensors named `layer_up_sensor` and `layer_down_sensor`, you can find the code to make that in the quest_manager.lua script.
Ok, the `hero` variable isn't defined here, you need to get it like that:
Code (lua) Select


So you can replace the line 11 by:
Code (lua) Select

If you have any problems with the error.txt file, you can always start the engine or editor from a console. If you're on Windows there is an option in the editor settings to display a console at launch.

This way you see all the error messages directly into the console.
It is already planned (see issue #39)
I haven't tested this but I think it should work better like this (you made a few mistakes explained in comments) :
Code (lua) Select

local item = ...
local game = item:get_game() -- not map:get_game(), map isn't defined here

function item:on_created()


function item:on_using()
  hero:set_animation("book") -- this method get a string as parameter, book doesn't exists here
  game:start_dialog("book.test", nil, function ()  -- use the callback function of the dialog to finish after this one

You should see the messages in the error.txt file and learn to determine what it really mean to fix that yourself. ;)
There is a problem with the `game` variable and I cannot help you more than that with the infos you gave me.

Could you give me a link with all the data of your quest? (Github, Drive, Dropbox, or something else)
I don't understand why the method `get_item` isn't defined in your script, but you can try with this code (in the map script) :
Code (lua) Select

function map:on_obtained_treasure(item)
  if item:get_name() == "book" then
    game:set_item_assigned(1, item)

This way the item will be automatically assigned when you retrieve it.
It's weird, it means that this method is not defined in game. However, it is in the API and for me it works very well.

But I have even so a bug because it is necessary to possess an item before assigning it.

I suggest you do it in another way to get your item directly with the map editor, placing it in a chest or on the ground.
Replace (in your map script)
Code (lua) Select
local game = ...
Code (lua) Select
local game = map:get_game()

The `...` allow to get the arguments passed to the script, so you can only get the map from a map script by this way (the item from an item script, etc).

And for the `equipBook:on_activated` method, I think you need to write something like this :
Code (lua) Select

function equipBook:on_activated()
  game:set_item_assigned(1, game:get_item("book"))

You have defined the method instead of call it and the variable `book` isn't defined, you need to get it by the method `game:get_item`.