See my comment near the bottom for the updated script! Thank you!Hey everybody,
This script was originally made by
froggy77 (
http://forum.solarus-games.org/index.php/topic,520.msg7809.html) and they recently asked for help with updating the script to work with
Solarus 1.6. I took some time and got it working with the latest version and so I thought I would re-upload the script for the community. I hope this is okay; I didn't think posting it in the original forum would give it as much visibility and the original post contains some outdated information that is better left out. I did message the original author but after a few days without reply I decided I would post it here, with due credit. Not sure if messages even notify people on here.
Here is the script in it's entirety with
all the necessary extra functions and code included at the bottom and below the code is a download for the .lua file:
-- LEVEL (LVL) and EXPERIENCE (EXP) counters shown on the game screen.
-- LVL AND EXP version 1.6
-- from a script (for rupees) by christopho
-- Modified by froGgy for a Zelda-like (ZL) project.
-- v 1.0: First version posted. It is just a draft.
-- Modified by Kamigousu on 18/07/19.
-- v 1.6: Updated for use with Solarus 1.6; basic with lots of potential, mostly just froggy77's original draft.
--Additional code and notes are included at the bottom for convenience. Please read them before continuing.
local lvl_and_exp = {}
function lvl_and_exp:new(game)
local object = {}
setmetatable(object, self)
self.__index = self
object:initialize(game)
return object
end
function lvl_and_exp:initialize(game)
self.game = game
self.surface = sol.surface.create(112, 24)
self.digits_text_for_lvl = sol.text_surface.create{
font = "green_digits",
horizontal_alignment = "left",
}
self.digits_text_for_exp = sol.text_surface.create{
font = "white_digits",
horizontal_alignment = "left",
}
self.digits_text_for_exp_to_levelup = sol.text_surface.create{
font = "white_digits",
horizontal_alignment = "left",
}
self.digits_text_for_lvl:set_text(game:get_level())
self.digits_text_for_exp:set_text(game:get_exp())
self.lvl_icon_img = sol.surface.create("hud/lvl_and_exp_icon.png")
self.exp_icon_img = sol.surface.create("hud/lvl_and_exp_icon.png")
self.slash_icon_img = sol.surface.create("hud/lvl_and_exp_icon.png")
self.current_lvl_displayed = self.game:get_level()
self.current_exp_displayed = self.game:get_exp()
self.current_exp_displayed_length = string.len(self.current_exp_displayed)
self.t_exp_to_levelup = {100, 200, 300, 400, 500, 600, 700, 800}
self.max_level = #self.t_exp_to_levelup
self.digits_text_for_exp_to_levelup:set_text(self.t_exp_to_levelup[self.current_lvl_displayed])
self:check()
self:rebuild_surface()
end
function lvl_and_exp:check()
local need_rebuild = false
local current_level = self.game:get_level()
local current_exp = self.game:get_exp()
local exp_to_levelup = self.t_exp_to_levelup[current_level]
if exp_to_levelup == nil then
self.current_exp_displayed = self.t_exp_to_levelup[self.max_level]
self.current_exp_displayed_length = string.len(self.current_exp_displayed)
exp_to_levelup = self.t_exp_to_levelup[self.max_level]
end
local difference = 0
-- Current LVL.
if current_level <= self.max_level + 1 then
if current_level ~= self.current_lvl_displayed then
need_rebuild = true
local increment
if current_level > self.current_lvl_displayed then
increment = 1
else
increment = -1
end
self.current_lvl_displayed = self.current_lvl_displayed + increment
-- Play a sound if we have just reached the final value.
if self.current_lvl_displayed == current_level then
if increment == 1 then
sol.audio.play_sound("victory")
sol.audio.play_sound("treasure")
else
sol.audio.play_sound("switch")
sol.audio.play_sound("hero_falls")
end
end
end
end
-- Current XP.
if current_level <= self.max_level then
if current_exp ~= self.current_exp_displayed then
need_rebuild = true
local increment
if current_exp > self.current_exp_displayed then
increment = 1
else
increment = -1
end
self.current_exp_displayed = self.current_exp_displayed + increment
self.current_exp_displayed_length = string.len(self.current_exp_displayed)
end
-- Level up
if self.current_exp_displayed >= exp_to_levelup then
self.game:set_value("current_level", current_level + 1)
difference = current_exp - exp_to_levelup
self.game:set_value("current_exp", difference)
current_exp = self.game:get_value("current_exp")
self.current_exp_displayed = 0
self.current_exp_displayed_length = string.len(self.current_exp_displayed)
end
end
-- Redraw the surface only if something has changed.
if need_rebuild then
self:rebuild_surface()
end
-- Schedule the next check.
sol.timer.start(self.game, 40, function()
self:check()
end)
end
function lvl_and_exp:rebuild_surface()
self.surface:clear()
-- LVL (icon).
self.lvl_icon_img:draw_region(0, 0, 12, 12, self.surface)
-- XP (icon).
self.exp_icon_img:draw_region(12, 0, 12, 12, self.surface, 27, 0)
-- SLASH (icon).
self.slash_icon_img:draw_region(24, 0, 8, 12, self.surface, 35 + (8 * self.current_exp_displayed_length), 4)
-- Current LVL (counter).
if self.current_lvl_displayed > self.max_level then
self.digits_text_for_lvl:set_font("green_digits")
else
self.digits_text_for_lvl:set_font("white_digits")
end
self.digits_text_for_lvl:set_text(self.current_lvl_displayed)
self.digits_text_for_lvl:draw(self.surface, 12, 6)
-- Current XP (counter).
if self.current_lvl_displayed <= self.max_level then
self.digits_text_for_exp:set_font("white_digits")
self.digits_text_for_exp:set_text(self.current_exp_displayed)
self.digits_text_for_exp_to_levelup:set_font("white_digits")
self.digits_text_for_exp_to_levelup:set_text(self.t_exp_to_levelup[self.current_lvl_displayed])
else
self.digits_text_for_exp:set_font("green_digits")
self.digits_text_for_exp:set_text(self.current_exp_displayed)
self.digits_text_for_exp_to_levelup:set_font("green_digits")
self.digits_text_for_exp_to_levelup:set_text(self.t_exp_to_levelup[self.max_level])
end
self.digits_text_for_exp:draw(self.surface, 40, 6)
self.digits_text_for_exp_to_levelup:draw(self.surface, 40 + (8 * self.current_exp_displayed_length), 12)
end
function lvl_and_exp:set_dst_position(x, y)
self.dst_x = x
self.dst_y = y
end
function lvl_and_exp:on_draw(dst_surface)
local x, y = self.dst_x, self.dst_y
local width, height = dst_surface:get_size()
if x < 0 then
x = width + x
end
if y < 0 then
y = height + y
end
self.surface:draw(dst_surface, x, y)
end
return lvl_and_exp
--[[********************************NOTES and CODE********************************
--The segment of code below must go into your initial_game.lua in the initialise_new_savegame(game) function. Do not set the level to 0 or it will create a bug (it is my understanding that it is a bug). Also, you will need to add these values to any current savegame file you try to run the script on. Otherwise the script will not load properly
--Initialise player experience system.
game:set_level(1) --Initialise the player level value for new game.
game:set_exp(0) --Initialise the player experience value for new game.
--The following must be put into your hud_config script, in the table with the rest of your hud elements; unless you are putting the exp and lvl display in an inventory screen or some other menu, in which case you will have to require it in the proper lua file.
--Level and Experience Counter
{
menu_script = ("scripts/hud/lvl_and_xp"),
x = 210, --X and Y can be changed to wherever you would like the exp counter displayed.
y = 16,
},
Finally, you must also add the functions game:get_level/exp(), set_level/exp(), and add_level/exp(). In a seperate file named game.lua (or wherever you have a game metatable available) add the following functions. (This doesn't necessarily need to be in it's own file, but for the sake of organisation and tidy code, I find that defining all of my game_meta functions in one place makes things easier. (I do believe that is something I picked up from reading and learning from so many of the Solarus Team's scripts.)
--The following line can be omitted if you all ready have a file where you get the metatable.
local game_meta = sol.main.get_metatable("game")
function game_meta:get_level()
return self:get_value("current_level")
end
function game_meta:set_level(level)
return self:set_value("current_level", level)
end
function game_meta:add_level(level)
local level = level
local c_level = self:get_level()
local level_up = c_level + level
return self:set_value("current_level", level_up)
end
function game_meta:get_exp()
return self:get_value("current_exp")
end
function game_meta:set_exp(exp)
return self:set_value("current_exp", exp)
end
function game_meta:add_exp(exp)
local exp = exp
local c_exp = self:get_exp()
local exp_up = c_exp + exp
return self:set_value("current_exp", exp_up)
end
You may require this file in your main.lua somehow or use multi_events to call it. Whatever you prefer.
--]]
You will also need to put the
lvl_and_exp_icon.png (see attachments at bottom) into your
"sprites/hud" folder.
You can also modify the values of the
t_exp_to_levelup table to change the experience required to level up. The first index is the experience required to get from level 1 to level 2 and so on.
Hopefully my explanation was clear. I only know basic French or I would write this up in French as well. I have a few other features for it that I have been testing on my own project, one of which is an algorithm to populate the experience table. I may upload some of these changes in the future if they work out well.
Thanks again, froggy77, for this awesome script! I'm all ready putting it to good use!