Solarus-Games English Forum

Solarus => Development => Topic started by: wizard_wizzle (aka ZeldaHistorian) on November 08, 2015, 12:47:47 AM

Title: Menu help
Post by: wizard_wizzle (aka ZeldaHistorian) on November 08, 2015, 12:47:47 AM
At the request of my brother, I've created a new warp menu for my game. Everything basically works, but I have a couple things that aren't working as well as they could, and I was hoping I could get some help.

1) The caption (the last part of on_draw) is not displaying, and I don't know why. This is based off of christopho's map submenu. I've checked that there is text in the variables (and there is) and I've tried to change the draw coordinates to no avail.

2) I can't figure out how to change the HUD icons. I've frozen the hero when the menu starts so you don't move around when trying to interact with the menu, but that's also frozen the HUD. I would like the attack icon to be "Confirm" (validate) and the pause icon to be "Back".

Code (lua) Select

local game = ...
local warp_menu = {}  -- The warp menu.
local initial_point
local initial_y = 10
local index

-- Warp point name, Companion point, Warp to map, Coordinate x on minimap, Coordinate y on minimap, Name of warp.
warp_points = {         -- Intentionally Global!
  b1500 = { "b1501", "133", 166, 102, "Old Kasuto" },
  b1501 = { "b1500", "46", 178, 220, "Hidden Village" },
  b1502 = { "b1503", "51", 90, 194, "Kakariko City" },
  b1503 = { "b1502", "11", 162, 372, "Ordon Village" },
  b1504 = { "b1505", "72", 2, 228, "Gerudo Camp" },
  b1505 = { "b1504", "66", 208, 178, "Goron City" },
  b1506 = { "b1507", "82", 50, 346, "Beach" },
  b1507 = { "b1506", "37", 218, 266, "Lost Woods" },
  b1508 = { "b1509", "60", 4, 180, "Snowpeak" },
  b1509 = { "b1508", "88", 15, 25, "Calatia Peaks" },
  b1510 = { "b1511", "56", 160, 150, "Septen Heights" },
  b1511 = { "b1510", "139", 178, 126, "Three Eye Rock" },
  b1512 = { "b1513", "57", 184, 150, "Zora's Domain" },
  b1513 = { "b1512", "93", 34, 40, "Rito Town" },
  b1514 = { "b1515", "34", 120, 258, "Lake Hylia" },
  b1515 = { "b1514", "13", 210, 365, "Floria Peninsula" }
}

function game:on_warp_started(point)
  initial_point = point
  if not sol.menu.is_started(warp_menu) then sol.menu.start(game:get_map(), warp_menu) end
end

function warp_menu:on_started()
  game:get_map():get_hero():freeze()
  self.hero_head_sprite = sol.sprite.create("menus/hero_head")
  self.hero_head_sprite:set_animation("tunic" .. game:get_item("tunic"):get_variant())
  self.background_surfaces = sol.surface.create("pause_submenus.png", true)
  self.background_surfaces:set_opacity(192)
  self.cursor_sprite = sol.sprite.create("menus/pause_cursor")
  self.caption_text_1 = sol.text_surface.create{
    horizontal_alignment = "center",
    vertical_alignment = "middle",
    font = "fixed",
    font = menu_font,
    font_size = menu_font_size,
  }
  self.caption_text_2 = sol.text_surface.create{
    horizontal_alignment = "center",
    vertical_alignment = "middle",
    font = "fixed",
    font = menu_font,
    font_size = menu_font_size,
  }

  -- Show a world map.
  self.caption_text_1:set_text(sol.language.get_string("map.caption.warp"))
  self.outside_world_minimap_size = { width = 225, height = 399 }
  self.world_minimap_img = sol.surface.create("menus/warp_map.png")
  self.world_minimap_movement = nil

  -- Initialize the cursor and scroll map to initial point.
  for k, v in pairs(warp_points) do
    if k == initial_point then
      index = k
      self:set_cursor_position(v[3], v[4])
      if v[4] >= 133 then initial_y = v[4] - 133 + 10 else initial_y = 0 end
      self.world_minimap_visible_xy = {x = 0, y = initial_y }
    end
  end
end

function warp_menu:on_command_pressed(command)
  if command == "left" or command == "up" then
    self:previous_warp_point()
    handled = true
  elseif command == "right" or command == "down" then
    self:next_warp_point()
    handled = true
  elseif command == "action" or command == "attack" then
    for k, v in pairs(warp_points) do
      if k == index and game:get_value(v[1]) then
        game:start_dialog("warp.to_"..v[2], function(answer)
          if answer == 1 then
            sol.menu.stop(warp_menu)
            game:get_map():get_hero():set_animation("ocarina")
            sol.audio.play_sound("ocarina_wind")
            game:get_map():get_entity("hero"):teleport(v[2], "ocarina_warp", "fade")
          end
        end)
      end
    end
  elseif command == "pause" then
    sol.menu.stop(warp_menu)
  end

  return true
end

function warp_menu:next_warp_point()
  if index == "b1500" then index = "b1501"
  elseif index == "b1501" then index = "b1502"
  elseif index == "b1502" then index = "b1503"
  elseif index == "b1503" then index = "b1504"
  elseif index == "b1504" then index = "b1505"
  elseif index == "b1505" then index = "b1506"
  elseif index == "b1506" then index = "b1507"
  elseif index == "b1507" then index = "b1508"
  elseif index == "b1508" then index = "b1509"
  elseif index == "b1509" then index = "b1510"
  elseif index == "b1510" then index = "b1511"
  elseif index == "b1511" then index = "b1512"
  elseif index == "b1512" then index = "b1513"
  elseif index == "b1513" then index = "b1514"
  elseif index == "b1514" then index = "b1515"
  elseif index == "b1515" then index = "b1500" end

  -- Move cursor and scroll map to new warp point.
  for k, v in pairs(warp_points) do
    if k == index and game:get_value(v[1]) then
      self:set_cursor_position(v[3], v[4])
      if v[4] >= 133 then initial_y = v[4] - 133 + 10 else initial_y = 0 end
      self.world_minimap_visible_xy = {x = 0, y = initial_y }
    end
  end
end

function warp_menu:previous_warp_point()
  if index == "b1500" then index = "b1515"
  elseif index == "b1501" then index = "b1500"
  elseif index == "b1502" then index = "b1501"
  elseif index == "b1503" then index = "b1502"
  elseif index == "b1504" then index = "b1503"
  elseif index == "b1505" then index = "b1504"
  elseif index == "b1506" then index = "b1505"
  elseif index == "b1507" then index = "b1506"
  elseif index == "b1508" then index = "b1507"
  elseif index == "b1509" then index = "b1508"
  elseif index == "b1510" then index = "b1509"
  elseif index == "b1511" then index = "b1510"
  elseif index == "b1512" then index = "b1511"
  elseif index == "b1513" then index = "b1512"
  elseif index == "b1514" then index = "b1513"
  elseif index == "b1515" then index = "b1514" end

  -- Move cursor and scroll map to new warp point.
  for k, v in pairs(warp_points) do
    if k == index and game:get_value(v[1]) then
      self:set_cursor_position(v[3], v[4])
      if v[4] >= 133 then initial_y = v[4] - 133 + 10 else initial_y = 0 end
      self.world_minimap_visible_xy = {x = 0, y = initial_y }
    end
  end
end

function warp_menu:set_cursor_position(x, y)
  self.cursor_x = x
  self.cursor_y = y
  if y > 133 then
    if y <399 then self.world_minimap_visible_xy.y = y - 51 else self.world_minimap_visible_xy.y = 399 end
  end

  -- Update the caption text.
  for k, v in pairs(warp_points) do
    if k == initial_point then self.caption_text_2:set_text(sol.language.get_string(v[5])) end
  end
end

function warp_menu:on_draw(dst_surface)
  -- Draw background.
  local width, height = dst_surface:get_size()
  self.background_surfaces:draw_region(320, 0, 320, 240, dst_surface, (width - 320) / 2, (height - 240) / 2)

  -- Draw the minimap.
  self.world_minimap_img:draw_region(self.world_minimap_visible_xy.x, self.world_minimap_visible_xy.y, 255, 133, dst_surface, 48, 59)

  -- Draw the warp points.
  for k, v in pairs(warp_points) do
    if game:get_value(v[1]) then -- Only those that have been discovered are shown.
      local point_visible_y = v[4] - self.world_minimap_visible_xy.y
      if point_visible_y >= 10 and point_visible_y <= 133 then self.hero_head_sprite:draw(dst_surface, v[3] + 40, point_visible_y + 51) end
    end
  end

  -- Draw the cursor.
  if self.cursor_y >= (10 + self.world_minimap_visible_xy.y) and self.cursor_y <= (133 + self.world_minimap_visible_xy.y) then
    self.cursor_sprite:draw(dst_surface, self.cursor_x + 48, self.cursor_y + 55 - self.world_minimap_visible_xy.y)
  end

  -- Draw caption (Not working currently for some reason).
  local width, height = dst_surface:get_size()
  self.caption_text_1:draw(dst_surface, width / 2, 200)
  self.caption_text_2:draw(dst_surface, width / 2, 213)
end

function warp_menu:on_finished()
  game:get_map():get_hero():unfreeze()
end
Title: Re: Menu help
Post by: Diarandor on November 08, 2015, 03:15:05 AM
Hi. This seems hard...

For (1), I would first try to set some explicit text with
Code (Lua) Select

self.caption_text_1:set_text("TESTING TEXT")
self.caption_text_2:set_text("TESTING AGAIN")

just to be sure that there is some text different from the empty string ("") or something like that. If the string is not the problem, then I have no idea, it is very strange.

For (2) it should not be too hard, but maybe long. If I am not wrong, in "Zelda: Mystery of Solarus", when you open the weapon menu, the behaviour and text of the HUD changes. So I would study Christopho's scripts and try to adapt them to your menu. You will probably need to add some casewise functions to the scripts of the attack and action icons, I mean, you will need to check if the warp menu is open or not, to display the correct icons.
Title: Re: Menu help
Post by: MetalZelda on November 08, 2015, 02:12:58 PM
Quote2) I can't figure out how to change the HUD icons. I've frozen the hero when the menu starts so you don't move around when trying to interact with the menu, but that's also frozen the HUD. I would like the attack icon to be "Confirm" (validate) and the pause icon to be "Back".

Have you tried game:set_custom_command_effect("pause", "back") game:set_custom_command_effect("attack", "confirm")  in warp_menu:on_started()

For the 1 : Is there any errors ?
Title: Re: Menu help
Post by: wizard_wizzle (aka ZeldaHistorian) on November 08, 2015, 07:07:13 PM
Diarandor, setting explicit text didn't work. I had already run a check to see that the correct string was in the caption, and I've tried moving it around the screen. Nothing has worked. I even tried moving where the code is in the drawing function, and it doesn't seem to matter.

I did base this off of the map and inventory pause submenus from ZSDX, where Christopho uses set_custom_command_effect (as Username mentions) to change the HUD icons. I have tried to include these commands, both in the on_started and in a cursor update function like Christopho does, and neither appears to have any effect on the HUD.

There are no errors. I've basically finished the menu and eliminated all errors, and these are the odd things that are left to iron out. I'm stumped.
Title: Re: Menu help
Post by: Christopho on November 08, 2015, 07:41:50 PM
get/set_custom_command_effect are not in the Solarus API, there are added in pure in Lua in game_manager.lua in ZSDX. If I remember correctly, the HUD silently does nothing if get_custom_command_effect does not exist. Maybe this is why there is no result and no error?
Title: Re: Menu help
Post by: MetalZelda on November 08, 2015, 08:35:23 PM
Quote from: Christopho on November 08, 2015, 07:41:50 PM
get/set_custom_command_effect are not in the Solarus API, there are added in pure in Lua in game_manager.lua in ZSDX. If I remember correctly, the HUD silently does nothing if get_custom_command_effect does not exist. Maybe this is why there is no result and no error?


I do used BoM source when I started my project, set_custom_command works properly (I use it for some custom entity interraction), maybe the culprit is the hud script itself since he now use another hud script (Mercuris Chest)

He does have set/get_custom_command_effect and his hud script seems to have no problem, I don't know why it don't work actually
https://github.com/wrightmat/zbom/blob/master/data/scripts/game_manager.lua#L102
Title: Re: Menu help
Post by: Diarandor on November 08, 2015, 10:19:44 PM
I think there are no custom commands called "confirm" or "back" in the list effects_indexes of your attack icon script, here:
https://github.com/wrightmat/zbom/blob/master/data/scripts/hud/attack_icon.lua

However, there are already custom commands called "validate" and "return", so you can use them instead (or define new ones in the list, which is probably unnecessary and you would also need to add them to the png image).

Edit: he has the functions "get/set_custom_command_effect" defined in his game manager, here:
https://github.com/wrightmat/zbom/blob/master/data/scripts/game_manager.lua
so it is strange that the hud shows nothing.
Title: Re: Menu help
Post by: wizard_wizzle (aka ZeldaHistorian) on November 08, 2015, 11:13:42 PM
Great research everyone, thanks!

Diarandor, I've tried "validate" and "return" as well, but still no luck. The HUD continues to display what was there before the menu appears.

Anyone who has more experience with menus - does the structure of my menu script look okay? Maybe it's something unrelated to get/set_custom_command_effect and something wrong with the menu itself?
Title: Re: Menu help
Post by: MetalZelda on November 08, 2015, 11:51:15 PM
Quote from: wrightmat on November 08, 2015, 11:13:42 PM
Great research everyone, thanks!

Diarandor, I've tried "validate" and "return" as well, but still no luck. The HUD continues to display what was there before the menu appears.

Anyone who has more experience with menus - does the structure of my menu script look okay? Maybe it's something unrelated to get/set_custom_command_effect and something wrong with the menu itself?

If you have a early version of you game, you might try if this work, if yesn then that should be :
- the hud script or your script
- https://github.com/christopho/zelda_mercuris_chest/blob/master/data/scripts/hud/hud.lua#L21
https://github.com/wrightmat/zbom/blob/master/data/scripts/hud/hud.lua#L15
Mercuri's Chest Hud.lua have get/set_custom_command declared on it and use the hud_manager.game: , while your game manager use game:, and since you changed the hud script, the game:get/set_blabla in game_manager might be obsolete

This is confusing  :o
Title: Re: Menu help
Post by: wizard_wizzle (aka ZeldaHistorian) on November 09, 2015, 12:13:52 AM
Every other script that I have (such as the pause submenus) which changes the HUD icons works though, so I'm reticent to go changes a bunch of stuff for one menu.
Title: Re: Menu help
Post by: MetalZelda on November 09, 2015, 12:30:36 AM
Quote from: wrightmat on November 09, 2015, 12:13:52 AM
Every other script that I have (such as the pause submenus) which changes the HUD icons works though, so I'm reticent to go changes a bunch of stuff for one menu.


If that work for others then this is not the thing I described above, hmmmm, that's a strange issue.
Title: Re: Menu help
Post by: Diarandor on November 09, 2015, 02:32:55 AM
In the code of your warp menu, above, I don't see any call to the set_custom_command_effect function. You shoould have something like
Code (Lua) Select
game:set_custom_command_effect("attack","validate")
Where have you written it?
Title: Re: Menu help
Post by: Diarandor on November 09, 2015, 02:40:23 AM
By the way, I found a possible bug which happens when changing map while the game is paused. When you do so, custom entities of the new map seem not to be paused (they move and their animations are not stopped). Could you check if you have this problem too? Just to confirm it. Just use your teleport menu (set it semitransparent to see the entities of the map), and check if the custom entities of the new map are moving (after teleporting without closing the menu, so the game is still paused).

EDIT: to confirm the bug, you need not closing the menu (to keep the pause of the game) after teleporting.

I have opened an issue on github for this:
https://github.com/christopho/solarus/issues/789
Title: Re: Menu help
Post by: MetalZelda on November 09, 2015, 09:24:23 AM
Oh, yeah, that might be this, "confirm" doesn't exist as a action, so validate might be right thing

https://github.com/wrightmat/zbom/blob/master/data/scripts/hud/action_icon.lua#L41
Edit : Oh he does already have these.

Edit 2 : The custom_interraction script is called each frame when the hero step on the ocarina patch or any custom entity, so it can't call "validate" from the menu since it is immediately replaced by the custom entity's interraction one(check).

The problem is : Your warp script isn't a real menu, judging by how it is called in ocarina_patch, you should consider using http://www.solarus-games.org/doc/latest/lua_api_menu.html#lua_api_menu_start, game:on_warp_started() doesn't halt upcoming map update and thus entities are still updating since it runs at the same time, unlike a menu.

If you put a print("blabla") after game:add_collision_test in custom_interraction and another print in your on_called menu, you will see what i'm talking about, if you "regular pause", the interaction is halted because sol.menu take the advantage. (Am I right ?)

Title: Re: Menu help
Post by: wizard_wizzle (aka ZeldaHistorian) on November 10, 2015, 12:16:44 AM
Username - that makes sense, but I'm not sure how to fix it. I use game:on_warp_started() to call sol.menu.start() because I pass a variable - initial_point (from self:get_name() of the custom entity) to the menu and I couldn't figure how to do that from sol.menu.start() directly. Is that possible?

Diarandor - is it possible to change maps while paused? Have you seen an instance of this in my game, or another game?

As for the set_custom_command_effect lines, I didn't have them in there yet, sorry. Updated code is below!

Code (lua) Select

local game = ...
local warp_menu = {}  -- The warp menu.
local initial_point
local initial_y = 10
local initial_volume
local index

-- Warp point name, Companion point, Warp to map, Coordinate x on minimap, Coordinate y on minimap, Name of warp.
warp_points = {         -- Intentionally Global!
  b1500 = { "b1501", "133", 166, 102, "Old Kasuto" },
  b1501 = { "b1500", "46", 178, 220, "Hidden Village" },
  b1502 = { "b1503", "51", 90, 194, "Kakariko City" },
  b1503 = { "b1502", "11", 162, 372, "Ordon Village" },
  b1504 = { "b1505", "72", 2, 228, "Gerudo Camp" },
  b1505 = { "b1504", "66", 208, 178, "Goron City" },
  b1506 = { "b1507", "82", 50, 346, "Beach" },
  b1507 = { "b1506", "37", 218, 266, "Lost Woods" },
  b1508 = { "b1509", "60", 4, 180, "Snowpeak" },
  b1509 = { "b1508", "88", 15, 25, "Calatia Peaks" },
  b1510 = { "b1511", "56", 160, 150, "Septen Heights" },
  b1511 = { "b1510", "139", 178, 126, "Three Eye Rock" },
  b1512 = { "b1513", "57", 184, 150, "Zora's Domain" },
  b1513 = { "b1512", "93", 34, 40, "Rito Town" },
  b1514 = { "b1515", "34", 120, 258, "Lake Hylia" },
  b1515 = { "b1514", "13", 210, 365, "Floria Peninsula" }
}

function game:on_warp_started(point)
  initial_point = point
  if not sol.menu.is_started(warp_menu) then sol.menu.start(game, warp_menu) end
end

function warp_menu:on_started()
  self.hero_head_sprite = sol.sprite.create("menus/hero_head")
  self.hero_head_sprite:set_animation("tunic" .. game:get_item("tunic"):get_variant())
  self.background_surfaces = sol.surface.create("pause_submenus.png", true)
  self.background_surfaces:set_opacity(192)
  self.cursor_sprite = sol.sprite.create("menus/pause_cursor")
  self.caption_text_1 = sol.text_surface.create{
    horizontal_alignment = "center",
    vertical_alignment = "middle",
    font = "fixed",
    font = menu_font,
    font_size = menu_font_size,
  }
  self.caption_text_2 = sol.text_surface.create{
    horizontal_alignment = "center",
    vertical_alignment = "middle",
    font = "fixed",
    font = menu_font,
    font_size = menu_font_size,
  }

  -- Show a world map.
  self.caption_text_1:set_text(sol.language.get_string("map.caption.warp"))
  self.outside_world_minimap_size = { width = 225, height = 399 }
  self.world_minimap_img = sol.surface.create("menus/warp_map.png")
  self.world_minimap_movement = nil

  -- Initialize the cursor and scroll map to initial point.
  for k, v in pairs(warp_points) do
    if k == initial_point then
      index = k
      self:set_cursor_position(v[3], v[4])
      if v[4] >= 133 then initial_y = v[4] - 133 + 10 else initial_y = 0 end
      self.world_minimap_visible_xy = {x = 0, y = initial_y }
    end
  end

  -- Update HUD icons (not working).
  game:set_custom_command_effect("action", nil)
  game:set_custom_command_effect("attack", "validate")
  game:set_custom_command_effect("pause", "return")

  -- Ensure the hero can't move.
  game:get_map():get_hero():freeze()

  -- Lower the volume (so ocarina sound can be heard when point selected).
  initial_volume = sol.audio.get_music_volume()
  sol.audio.set_music_volume(initial_volume/3)
end

function warp_menu:on_command_pressed(command)
  if command == "left" or command == "up" then
    self:previous_warp_point()
    handled = true
  elseif command == "right" or command == "down" then
    self:next_warp_point()
    handled = true
  elseif command == "action" or command == "attack" then
    for k, v in pairs(warp_points) do
      if k == index and game:get_value(v[1]) then
        game:start_dialog("warp.to_"..v[2], function(answer)
          if answer == 1 then
            sol.menu.stop(warp_menu)
            game:get_map():get_hero():set_animation("ocarina")
            sol.audio.play_sound("ocarina_wind")
            game:get_map():get_entity("hero"):teleport(v[2], "ocarina_warp", "fade")
          end
        end)
      end
    end
  elseif command == "pause" then
    sol.menu.stop(warp_menu)
  end

  return true
end

function warp_menu:next_warp_point()
  if index == "b1500" then index = "b1501"
  elseif index == "b1501" then index = "b1502"
  elseif index == "b1502" then index = "b1503"
  elseif index == "b1503" then index = "b1504"
  elseif index == "b1504" then index = "b1505"
  elseif index == "b1505" then index = "b1506"
  elseif index == "b1506" then index = "b1507"
  elseif index == "b1507" then index = "b1508"
  elseif index == "b1508" then index = "b1509"
  elseif index == "b1509" then index = "b1510"
  elseif index == "b1510" then index = "b1511"
  elseif index == "b1511" then index = "b1512"
  elseif index == "b1512" then index = "b1513"
  elseif index == "b1513" then index = "b1514"
  elseif index == "b1514" then index = "b1515"
  elseif index == "b1515" then index = "b1500" end

  -- Move cursor and scroll map to new warp point.
  for k, v in pairs(warp_points) do
    if k == index and game:get_value(v[1]) then
      self:set_cursor_position(v[3], v[4])
      if v[4] >= 133 then initial_y = v[4] - 133 + 10 else initial_y = 0 end
      self.world_minimap_visible_xy = {x = 0, y = initial_y }
    end
  end
end

function warp_menu:previous_warp_point()
  if index == "b1500" then index = "b1515"
  elseif index == "b1501" then index = "b1500"
  elseif index == "b1502" then index = "b1501"
  elseif index == "b1503" then index = "b1502"
  elseif index == "b1504" then index = "b1503"
  elseif index == "b1505" then index = "b1504"
  elseif index == "b1506" then index = "b1505"
  elseif index == "b1507" then index = "b1506"
  elseif index == "b1508" then index = "b1507"
  elseif index == "b1509" then index = "b1508"
  elseif index == "b1510" then index = "b1509"
  elseif index == "b1511" then index = "b1510"
  elseif index == "b1512" then index = "b1511"
  elseif index == "b1513" then index = "b1512"
  elseif index == "b1514" then index = "b1513"
  elseif index == "b1515" then index = "b1514" end

  -- Move cursor and scroll map to new warp point.
  for k, v in pairs(warp_points) do
    if k == index and game:get_value(v[1]) then
      self:set_cursor_position(v[3], v[4])
      if v[4] >= 133 then initial_y = v[4] - 133 + 10 else initial_y = 0 end
      self.world_minimap_visible_xy = {x = 0, y = initial_y }
    end
  end
end

function warp_menu:set_cursor_position(x, y)
  self.cursor_x = x
  self.cursor_y = y
  if y > 133 then
    if y <399 then self.world_minimap_visible_xy.y = y - 51 else self.world_minimap_visible_xy.y = 399 end
  end

  -- Update the caption text.
  for k, v in pairs(warp_points) do
    if k == initial_point then self.caption_text_2:set_text(sol.language.get_string(v[5])) end
  end
end

function warp_menu:on_draw(dst_surface)
  -- Draw background.
  local width, height = dst_surface:get_size()
  self.background_surfaces:draw_region(320, 0, 320, 240, dst_surface, (width - 320) / 2, (height - 240) / 2)

  -- Draw caption (Not working currently for some reason).
  local width, height = dst_surface:get_size()
  self.caption_text_1:draw(dst_surface, width / 2, height / 2 + 83)
  self.caption_text_2:draw(dst_surface, width / 2, height / 2 + 95)

  -- Draw the minimap.
  self.world_minimap_img:draw_region(self.world_minimap_visible_xy.x, self.world_minimap_visible_xy.y, 255, 133, dst_surface, 48, 59)

  -- Draw the warp points.
  for k, v in pairs(warp_points) do
    if game:get_value(v[1]) then -- Only those that have been discovered are shown.
      local point_visible_y = v[4] - self.world_minimap_visible_xy.y
      if point_visible_y >= 10 and point_visible_y <= 133 then self.hero_head_sprite:draw(dst_surface, v[3] + 40, point_visible_y + 51) end
    end
  end

  -- Draw the cursor.
  if self.cursor_y >= (10 + self.world_minimap_visible_xy.y) and self.cursor_y <= (133 + self.world_minimap_visible_xy.y) then
    self.cursor_sprite:draw(dst_surface, self.cursor_x + 48, self.cursor_y + 55 - self.world_minimap_visible_xy.y)
  end
end

function warp_menu:on_finished()
  sol.audio.set_music_volume(initial_volume)
  game:get_map():get_hero():unfreeze()
end
Title: Re: Menu help
Post by: MetalZelda on November 10, 2015, 12:34:05 AM
Quote from: wrightmat on November 10, 2015, 12:16:44 AM
Username - that makes sense, but I'm not sure how to fix it. I use game:on_warp_started() to call sol.menu.start() because I pass a variable - initial_point (from self:get_name() of the custom entity) to the menu and I couldn't figure how to do that from sol.menu.start() directly. Is that possible?

Diarandor - is it possible to change maps while paused? Have you seen an instance of this in my game, or another game?

As for the set_custom_command_effect lines, I didn't have them in there yet, sorry. Updated code is below!

Code (lua) Select

local game = ...
local warp_menu = {}  -- The warp menu.
local initial_point
local initial_y = 10
local initial_volume
local index

-- Warp point name, Companion point, Warp to map, Coordinate x on minimap, Coordinate y on minimap, Name of warp.
warp_points = {         -- Intentionally Global!
  b1500 = { "b1501", "133", 166, 102, "Old Kasuto" },
  b1501 = { "b1500", "46", 178, 220, "Hidden Village" },
  b1502 = { "b1503", "51", 90, 194, "Kakariko City" },
  b1503 = { "b1502", "11", 162, 372, "Ordon Village" },
  b1504 = { "b1505", "72", 2, 228, "Gerudo Camp" },
  b1505 = { "b1504", "66", 208, 178, "Goron City" },
  b1506 = { "b1507", "82", 50, 346, "Beach" },
  b1507 = { "b1506", "37", 218, 266, "Lost Woods" },
  b1508 = { "b1509", "60", 4, 180, "Snowpeak" },
  b1509 = { "b1508", "88", 15, 25, "Calatia Peaks" },
  b1510 = { "b1511", "56", 160, 150, "Septen Heights" },
  b1511 = { "b1510", "139", 178, 126, "Three Eye Rock" },
  b1512 = { "b1513", "57", 184, 150, "Zora's Domain" },
  b1513 = { "b1512", "93", 34, 40, "Rito Town" },
  b1514 = { "b1515", "34", 120, 258, "Lake Hylia" },
  b1515 = { "b1514", "13", 210, 365, "Floria Peninsula" }
}

function game:on_warp_started(point)
  initial_point = point
  if not sol.menu.is_started(warp_menu) then sol.menu.start(game, warp_menu) end
end

function warp_menu:on_started()
  self.hero_head_sprite = sol.sprite.create("menus/hero_head")
  self.hero_head_sprite:set_animation("tunic" .. game:get_item("tunic"):get_variant())
  self.background_surfaces = sol.surface.create("pause_submenus.png", true)
  self.background_surfaces:set_opacity(192)
  self.cursor_sprite = sol.sprite.create("menus/pause_cursor")
  self.caption_text_1 = sol.text_surface.create{
    horizontal_alignment = "center",
    vertical_alignment = "middle",
    font = "fixed",
    font = menu_font,
    font_size = menu_font_size,
  }
  self.caption_text_2 = sol.text_surface.create{
    horizontal_alignment = "center",
    vertical_alignment = "middle",
    font = "fixed",
    font = menu_font,
    font_size = menu_font_size,
  }

  -- Show a world map.
  self.caption_text_1:set_text(sol.language.get_string("map.caption.warp"))
  self.outside_world_minimap_size = { width = 225, height = 399 }
  self.world_minimap_img = sol.surface.create("menus/warp_map.png")
  self.world_minimap_movement = nil

  -- Initialize the cursor and scroll map to initial point.
  for k, v in pairs(warp_points) do
    if k == initial_point then
      index = k
      self:set_cursor_position(v[3], v[4])
      if v[4] >= 133 then initial_y = v[4] - 133 + 10 else initial_y = 0 end
      self.world_minimap_visible_xy = {x = 0, y = initial_y }
    end
  end

  -- Update HUD icons (not working).
  game:set_custom_command_effect("action", nil)
  game:set_custom_command_effect("attack", "validate")
  game:set_custom_command_effect("pause", "return")

  -- Ensure the hero can't move.
  game:get_map():get_hero():freeze()

  -- Lower the volume (so ocarina sound can be heard when point selected).
  initial_volume = sol.audio.get_music_volume()
  sol.audio.set_music_volume(initial_volume/3)
end

function warp_menu:on_command_pressed(command)
  if command == "left" or command == "up" then
    self:previous_warp_point()
    handled = true
  elseif command == "right" or command == "down" then
    self:next_warp_point()
    handled = true
  elseif command == "action" or command == "attack" then
    for k, v in pairs(warp_points) do
      if k == index and game:get_value(v[1]) then
        game:start_dialog("warp.to_"..v[2], function(answer)
          if answer == 1 then
            sol.menu.stop(warp_menu)
            game:get_map():get_hero():set_animation("ocarina")
            sol.audio.play_sound("ocarina_wind")
            game:get_map():get_entity("hero"):teleport(v[2], "ocarina_warp", "fade")
          end
        end)
      end
    end
  elseif command == "pause" then
    sol.menu.stop(warp_menu)
  end

  return true
end

function warp_menu:next_warp_point()
  if index == "b1500" then index = "b1501"
  elseif index == "b1501" then index = "b1502"
  elseif index == "b1502" then index = "b1503"
  elseif index == "b1503" then index = "b1504"
  elseif index == "b1504" then index = "b1505"
  elseif index == "b1505" then index = "b1506"
  elseif index == "b1506" then index = "b1507"
  elseif index == "b1507" then index = "b1508"
  elseif index == "b1508" then index = "b1509"
  elseif index == "b1509" then index = "b1510"
  elseif index == "b1510" then index = "b1511"
  elseif index == "b1511" then index = "b1512"
  elseif index == "b1512" then index = "b1513"
  elseif index == "b1513" then index = "b1514"
  elseif index == "b1514" then index = "b1515"
  elseif index == "b1515" then index = "b1500" end

  -- Move cursor and scroll map to new warp point.
  for k, v in pairs(warp_points) do
    if k == index and game:get_value(v[1]) then
      self:set_cursor_position(v[3], v[4])
      if v[4] >= 133 then initial_y = v[4] - 133 + 10 else initial_y = 0 end
      self.world_minimap_visible_xy = {x = 0, y = initial_y }
    end
  end
end

function warp_menu:previous_warp_point()
  if index == "b1500" then index = "b1515"
  elseif index == "b1501" then index = "b1500"
  elseif index == "b1502" then index = "b1501"
  elseif index == "b1503" then index = "b1502"
  elseif index == "b1504" then index = "b1503"
  elseif index == "b1505" then index = "b1504"
  elseif index == "b1506" then index = "b1505"
  elseif index == "b1507" then index = "b1506"
  elseif index == "b1508" then index = "b1507"
  elseif index == "b1509" then index = "b1508"
  elseif index == "b1510" then index = "b1509"
  elseif index == "b1511" then index = "b1510"
  elseif index == "b1512" then index = "b1511"
  elseif index == "b1513" then index = "b1512"
  elseif index == "b1514" then index = "b1513"
  elseif index == "b1515" then index = "b1514" end

  -- Move cursor and scroll map to new warp point.
  for k, v in pairs(warp_points) do
    if k == index and game:get_value(v[1]) then
      self:set_cursor_position(v[3], v[4])
      if v[4] >= 133 then initial_y = v[4] - 133 + 10 else initial_y = 0 end
      self.world_minimap_visible_xy = {x = 0, y = initial_y }
    end
  end
end

function warp_menu:set_cursor_position(x, y)
  self.cursor_x = x
  self.cursor_y = y
  if y > 133 then
    if y <399 then self.world_minimap_visible_xy.y = y - 51 else self.world_minimap_visible_xy.y = 399 end
  end

  -- Update the caption text.
  for k, v in pairs(warp_points) do
    if k == initial_point then self.caption_text_2:set_text(sol.language.get_string(v[5])) end
  end
end

function warp_menu:on_draw(dst_surface)
  -- Draw background.
  local width, height = dst_surface:get_size()
  self.background_surfaces:draw_region(320, 0, 320, 240, dst_surface, (width - 320) / 2, (height - 240) / 2)

  -- Draw caption (Not working currently for some reason).
  local width, height = dst_surface:get_size()
  self.caption_text_1:draw(dst_surface, width / 2, height / 2 + 83)
  self.caption_text_2:draw(dst_surface, width / 2, height / 2 + 95)

  -- Draw the minimap.
  self.world_minimap_img:draw_region(self.world_minimap_visible_xy.x, self.world_minimap_visible_xy.y, 255, 133, dst_surface, 48, 59)

  -- Draw the warp points.
  for k, v in pairs(warp_points) do
    if game:get_value(v[1]) then -- Only those that have been discovered are shown.
      local point_visible_y = v[4] - self.world_minimap_visible_xy.y
      if point_visible_y >= 10 and point_visible_y <= 133 then self.hero_head_sprite:draw(dst_surface, v[3] + 40, point_visible_y + 51) end
    end
  end

  -- Draw the cursor.
  if self.cursor_y >= (10 + self.world_minimap_visible_xy.y) and self.cursor_y <= (133 + self.world_minimap_visible_xy.y) then
    self.cursor_sprite:draw(dst_surface, self.cursor_x + 48, self.cursor_y + 55 - self.world_minimap_visible_xy.y)
  end
end

function warp_menu:on_finished()
  sol.audio.set_music_volume(initial_volume)
  game:get_map():get_hero():unfreeze()
end


Yeah that's the one I tested, I didn't see that there were sol.menu.start, which make the thing a lot weirder  :o
That's a tough issue
Title: Re: Menu help
Post by: MetalZelda on November 10, 2015, 12:53:03 AM
For the text I found the culprit

  self.caption_text_(1 and 2) = sol.text_surface.create{
    horizontal_alignment = "center",
    vertical_alignment = "middle",
    font = "fixed",
    font = menu_font,
    font_size = menu_font_size,


There is no menu_font, menu_font_size declared so the game cannot render the text with nothing, plus, there is 2 fonts section

You should replaced "fixed" (nil) by an existing fonts in /font folder and font_size is up to you

(I do tested with font = "lttp" and font_size = 12, here's the result, text caption 2 display nothing for some reasons, maybe the variable isn't correct ?)

Edit  : for caption_text 2, there is no value for them in strings.dat.
Please test caption 2

(http://i.imgur.com/EjvWa80.png)

Now let's see about custom action
Title: Re: Menu help
Post by: wizard_wizzle (aka ZeldaHistorian) on November 10, 2015, 01:27:21 AM
You're a genius, great find! Thanks!

That fix definitely worked. The weird thing is that I copied that code from another of my menus, and it didn't cause a problem (that I noticed) in that one. *shrugs* I fixed it in the other menu too, just in case.
Title: Re: Menu help
Post by: Diarandor on November 10, 2015, 08:02:29 AM
For the attack_icon issue, I think what could be causing the problem, in this file
https://github.com/wrightmat/zbom/blob/master/data/scripts/hud/attack_icon.lua
I was using a modified version of Christopho's script where I changed two parts that had this code
game:get_custom_command_effect("attack") or game:get_command_effect("attack")
for this new one
game:get_command_effect("attack") or game:get_custom_command_effect("attack")
(see the "attack_icon:initialize(game)" and "attack_icon:check()" functions) and since you used some of my scripts (for carrying custom entities), you have this part different too. So if you have some command_effect for the attack icon (value different from nil), then the script will not change the hud (this was the behaviour I wanted to make my own interactions compatible with the hud, because I wanted to give priority to built-in command effects). If that was the problem, then it was my fault (sorry for the inconvenience!). I also modified the action_icon script in the same way.

If that solves the problem, that could create a new one since my script custom_interactions.lua might not work correctly, but I am not sure at all. (The custom_command_effect attack is not used there, but the custom_command_effect action is used, so if you change back the modified script of the action_icon, then the "lift" caption might not be shown fof portable entities. On the other hand, I was using the attack icon to show the "throw" label of "portable_entities", which might not work correctly if you change back the atack_icon script.)

Quote from: wrightmat on November 10, 2015, 12:16:44 AM
Diarandor - is it possible to change maps while paused? Have you seen an instance of this in my game, or another game?

Yes, I made a menu to switch heroes from one map to a different map, which uses a teleport function, and it worked. The map changed with the usual transition, with the menu open and game paused all the time (even after teleporting). As I said, there seems to be a bug, so if there are custom entities in the new map, they won't be suspended (they can move and their animations are not stopped) although the game is paused (this only seems to affect custom entities). As a workaround for the bug, I closed the menu and unpaused the game after switching hero (after teleporting).
Title: Re: Menu help
Post by: Diarandor on November 10, 2015, 08:54:39 AM
The reason why I changed those lines of code was to allow talking with npcs while carrying custom entities (to allow giving them objects of type "portable_entity"), so I needed to give priority to the built-in action effect. (In an older version of my script I used the action button to throw the entity, which is also used to talk with normal npcs, so I changed the priority for the built-in talking effect.) But probably you are not using that feature. Anyway, it should be possible to modify the scripts to make everything work correctly with the original code (but that would mean to remove this feature, although that may be fine for your purposes if you don't plan to use it).

In case you change back that code, there might happen that you open the pause menu while carrying a portable_entity, so the custom_command_effects change during the menu, and hence after closing the menu you cannot throw the entity because the custom_command_effects have been changed. The solution should be easy: just store the value of the custom_command_effects in some variables when you open some menu and restore those values after closing the menu.
Title: Re: Menu help
Post by: MetalZelda on November 10, 2015, 10:22:54 AM
Quote from: Diarandor on November 10, 2015, 08:54:39 AM
The reason why I changed those lines of code was to allow talking with npcs while carrying custom entities (to allow giving them objects of type "portable_entity"), so I needed to give priority to the built-in action effect. (In an older version of my script I used the action button to throw the entity, which is also used to talk with normal npcs, so I changed the priority for the built-in talking effect.) But probably you are not using that feature. Anyway, it should be possible to modify the scripts to make everything work correctly with the original code (but that would mean to remove this feature, although that may be fine for your purposes if you don't plan to use it).

In case you change back that code, there might happen that you open the pause menu while carrying a portable_entity, so the custom_command_effects change during the menu, and hence after closing the menu you cannot throw the entity because the custom_command_effects have been changed. The solution should be easy: just store the value of the custom_command_effects in some variables when you open some menu and restore those values after closing the menu.

Hmmm, strange thing is that you can't set the custom effect from the debug console in-game, it always return that set_custom_command_effect doesn't exist
Title: Re: Menu help
Post by: Diarandor on November 10, 2015, 10:30:08 AM
Quote from: Username on November 10, 2015, 10:22:54 AM
Hmmm, strange thing is that you can't set the custom effect from the debug console in-game, it always return that set_custom_command_effect doesn't exist

I don't understand what exactly you mean. The function set_custom_command_effect is not a built-in function as Christopho said, it is fully scripted in Lua (in this case it is in the game_manager script); if you get an error is because you have not written it in your scripts. The command_effect is the built-in one, which cannot be changed directly.
Title: Re: Menu help
Post by: MetalZelda on November 10, 2015, 11:04:54 AM
Quote from: Diarandor on November 10, 2015, 10:30:08 AM
Quote from: Username on November 10, 2015, 10:22:54 AM
Hmmm, strange thing is that you can't set the custom effect from the debug console in-game, it always return that set_custom_command_effect doesn't exist

I don't understand what exactly you mean. The function set_custom_command_effect is not a built-in function as Christopho said, it is fully scripted in Lua (in this case it is in the game_manager script); if you get an error is because you have not written it in your scripts. The command_effect is the built-in one, which cannot be changed directly.

Right !
For this issue, There must be in newer releases of Solarus a game:freeze_all(bool), just like when you press "d", because, interestingly , you can move while you're in the menu and trigger an error, the menu would still work.
My guess is, at the moment, that the menu isn't halting/freezing stuffs (only the hero is freez'd), so the engine might still consider that it need to update some values (and, it still update the ocarina patch's custom interraction while you're in the warp menu), other than that, I don't know what is causing this issue, that's quite strange honestly


Title: Re: Menu help
Post by: Diarandor on November 10, 2015, 11:22:44 AM
Username- If you want to suspend all entities, you can use game:set_paused(true) when you open the menu, and game:set_paused(false) to unpause the game. A menu can be used during the pause.
Title: Re: Menu help
Post by: wizard_wizzle (aka ZeldaHistorian) on November 10, 2015, 02:29:13 PM
Username, I tried moving the hero away from the ocarina patch before freezing, and the "Check" action does go away (as your previous comments would suggest), but any new action is not represented. I'm sure Diarandor's fix would work, but I don't think I want to break something else at this time. For now I think I'll just keep the hero moved, which dims the HUD, and everything else works great!

Thanks all for the help!
Title: Re: Menu help
Post by: Diarandor on November 10, 2015, 11:51:44 PM
wrightmat- I found a better and easy solution. First define two new methods
"game:get_menu_command_effect(command)" and "game:set_menu_command_effect(command, effect)"
and we will use them only for effects during menus. Then, we give more priority to these menu command effects. To do this, just write
game:get_menu_command_effect("attack") or  game:get_command_effect("attack") or game:get_custom_command_effect("attack")
instead of
game:get_command_effect("attack") or game:get_custom_command_effect("attack")
in the attack_icon script (and similarly for the action effect in the action_icon script). Also, don't forget to set the menu_command_effects to nil when you close the menu. With this you will not need to move the hero before teleporting, and everything will work as before.
Title: Re: Menu help
Post by: wizard_wizzle (aka ZeldaHistorian) on November 11, 2015, 03:42:54 AM
Diarandor - I did a quick test, and I think that your solution would work with enough tweaking, but I don't think I want to make the requisite changes at this time. For now I'll stick with greying out the HUD, and will refer to this topic later if I decide to do something differently.

You guys have been an amazing help and I greatly appreciate it!!!