Skip to content
Snippets Groups Projects
Commit ee2bf948 authored by DarkGod's avatar DarkGod
Browse files

Merge branch 'levelup_annoyances' into 'master'

LevelupDialog status box

Many users have expressed their frustration that appears when clicking too fast on a talent or stat to level it up pops up a message, forcing them to click "Ok". This commit adds a simple status line on top of the window, always clearly visible, that communicates these short messages in aesthetically pleasing colours. For important messages (e.g. the player somehow created an impossible talent loadout), the modal dialog usage was retained.
parents 9852d519 b4e9634c
No related branches found
No related tags found
No related merge requests found
...@@ -26,6 +26,7 @@ local Textzone = require "engine.ui.Textzone" ...@@ -26,6 +26,7 @@ local Textzone = require "engine.ui.Textzone"
local TextzoneList = require "engine.ui.TextzoneList" local TextzoneList = require "engine.ui.TextzoneList"
local UIContainer = require "engine.ui.UIContainer" local UIContainer = require "engine.ui.UIContainer"
local TalentTrees = require "mod.dialogs.elements.TalentTrees" local TalentTrees = require "mod.dialogs.elements.TalentTrees"
local StatusBox = require "mod.dialogs.elements.StatusBox"
local Separator = require "engine.ui.Separator" local Separator = require "engine.ui.Separator"
local DamageType = require "engine.DamageType" local DamageType = require "engine.DamageType"
local FontPackage = require "engine.FontPackage" local FontPackage = require "engine.FontPackage"
...@@ -152,6 +153,15 @@ function _M:getMaxTPoints(t) ...@@ -152,6 +153,15 @@ function _M:getMaxTPoints(t)
return t.points + math.max(0, math.floor((self.actor.level - 50) / 10)) + (self.actor.talents_inc_cap and self.actor.talents_inc_cap[t.id] or 0) return t.points + math.max(0, math.floor((self.actor.level - 50) / 10)) + (self.actor.talents_inc_cap and self.actor.talents_inc_cap[t.id] or 0)
end end
function _M:subtleMessage(title, message, color)
if not self.t_messages then return self:simplePopup(title, message) end
return self.t_messages:setTextColor(message, color)
end
-- Some common colors
local subtleMessageErrorColor = {r=255, g=100, b=100}
local subtleMessageWarningColor = {r=255, g=255, b=80}
function _M:finish() function _M:finish()
local ok, dep_miss = self:checkDeps(true, true) local ok, dep_miss = self:checkDeps(true, true)
if not ok then if not ok then
...@@ -215,20 +225,20 @@ end ...@@ -215,20 +225,20 @@ end
function _M:incStat(sid, v) function _M:incStat(sid, v)
if v == 1 then if v == 1 then
if self.actor.unused_stats <= 0 then if self.actor.unused_stats <= 0 then
self:simplePopup("Not enough stat points", "You have no stat points left!") self:subtleMessage("Not enough stat points", "You have no stat points left!", subtleMessageErrorColor)
return return
end end
if self.actor:getStat(sid, nil, nil, true) >= self.actor.level * 1.4 + 20 then if self.actor:getStat(sid, nil, nil, true) >= self.actor.level * 1.4 + 20 then
self:simplePopup("Stat is at the maximum for your level", "You cannot increase this stat further until next level!") self:subtleMessage("Stat is at the maximum for your level", "You cannot increase this stat further until next level!", 255, 215, 0)
return return
end end
if self.actor:isStatMax(sid) or self.actor:getStat(sid, nil, nil, true) >= 60 + math.max(0, (self.actor.level - 50)) then if self.actor:isStatMax(sid) or self.actor:getStat(sid, nil, nil, true) >= 60 + math.max(0, (self.actor.level - 50)) then
self:simplePopup("Stat is at the maximum", "You cannot increase this stat further!") self:subtleMessage("Stat is at the maximum", "You cannot increase this stat further!", subtleMessageWarningColor)
return return
end end
else else
if self.actor_dup:getStat(sid, nil, nil, true) == self.actor:getStat(sid, nil, nil, true) then if self.actor_dup:getStat(sid, nil, nil, true) == self.actor:getStat(sid, nil, nil, true) then
self:simplePopup("Impossible", "You cannot take out more points!") self:subtleMessage("Impossible", "You cannot take out more points!", subtleMessageErrorColor)
return return
end end
end end
...@@ -332,15 +342,15 @@ function _M:learnTalent(t_id, v) ...@@ -332,15 +342,15 @@ function _M:learnTalent(t_id, v)
if t.generic then t_type, t_index = "generic", "unused_generics" end if t.generic then t_type, t_index = "generic", "unused_generics" end
if v then if v then
if self.actor[t_index] < 1 then if self.actor[t_index] < 1 then
self:simplePopup("Not enough "..t_type.." talent points", "You have no "..t_type.." talent points left!") self:subtleMessage("Not enough "..t_type.." talent points", "You have no "..t_type.." talent points left!", subtleMessageErrorColor)
return return
end end
if not self.actor:canLearnTalent(t) then if not self.actor:canLearnTalent(t) then
self:simplePopup("Cannot learn talent", "Prerequisites not met!") self:subtleMessage("Cannot learn talent", "Prerequisites not met!", subtleMessageErrorColor)
return return
end end
if self.actor:getTalentLevelRaw(t_id) >= self:getMaxTPoints(t) then if self.actor:getTalentLevelRaw(t_id) >= self:getMaxTPoints(t) then
self:simplePopup("Already known", "You already fully know this talent!") self:subtleMessage("Already known", "You already fully know this talent!", subtleMessageWarningColor)
return return
end end
self.actor:learnTalent(t_id, true) self.actor:learnTalent(t_id, true)
...@@ -350,15 +360,15 @@ function _M:learnTalent(t_id, v) ...@@ -350,15 +360,15 @@ function _M:learnTalent(t_id, v)
self.new_talents_changed = true self.new_talents_changed = true
else else
if not self.actor:knowTalent(t_id) then if not self.actor:knowTalent(t_id) then
self:simplePopup("Impossible", "You do not know this talent!") self:subtleMessage("Impossible", "You do not know this talent!", subtleMessageErrorColor)
return return
end end
if not self:isUnlearnable(t, true) and self.actor_dup:getTalentLevelRaw(t_id) >= self.actor:getTalentLevelRaw(t_id) then if not self:isUnlearnable(t, true) and self.actor_dup:getTalentLevelRaw(t_id) >= self.actor:getTalentLevelRaw(t_id) then
local _, could = self:isUnlearnable(t, true) local _, could = self:isUnlearnable(t, true)
if could then if could then
self:simplePopup("Impossible here", "You could unlearn this talent in a quiet place, like a #{bold}#town#{normal}#.") self:subtleMessage("Impossible here", "You could unlearn this talent in a quiet place, like a #{bold}#town#{normal}#.", {r=200, g=200, b=255})
else else
self:simplePopup("Impossible", "You cannot unlearn this talent!") self:subtleMessage("Impossible", "You cannot unlearn this talent!", subtleMessageErrorColor)
end end
return return
end end
...@@ -384,11 +394,11 @@ function _M:learnType(tt, v) ...@@ -384,11 +394,11 @@ function _M:learnType(tt, v)
self.talent_types_learned[tt] = self.talent_types_learned[tt] or {} self.talent_types_learned[tt] = self.talent_types_learned[tt] or {}
if v then if v then
if self.actor:knowTalentType(tt) and self.actor.__increased_talent_types[tt] and self.actor.__increased_talent_types[tt] >= 1 then if self.actor:knowTalentType(tt) and self.actor.__increased_talent_types[tt] and self.actor.__increased_talent_types[tt] >= 1 then
self:simplePopup("Impossible", "You can only improve a category mastery once!") self:subtleMessage("Impossible", "You can only improve a category mastery once!", subtleMessageWarningColor)
return return
end end
if self.actor.unused_talents_types <= 0 then if self.actor.unused_talents_types <= 0 then
self:simplePopup("Not enough talent category points", "You have no category points left!") self:subtleMessage("Not enough talent category points", "You have no category points left!", subtleMessageErrorColor)
return return
end end
if not self.actor.talents_types_def[tt] or (self.actor.talents_types_def[tt].min_lev or 0) > self.actor.level then if not self.actor.talents_types_def[tt] or (self.actor.talents_types_def[tt].min_lev or 0) > self.actor.level then
...@@ -408,15 +418,15 @@ function _M:learnType(tt, v) ...@@ -408,15 +418,15 @@ function _M:learnType(tt, v)
self.new_talents_changed = true self.new_talents_changed = true
else else
if self.actor_dup:knowTalentType(tt) == true and self.actor:knowTalentType(tt) == true and (self.actor_dup.__increased_talent_types[tt] or 0) >= (self.actor.__increased_talent_types[tt] or 0) then if self.actor_dup:knowTalentType(tt) == true and self.actor:knowTalentType(tt) == true and (self.actor_dup.__increased_talent_types[tt] or 0) >= (self.actor.__increased_talent_types[tt] or 0) then
self:simplePopup("Impossible", "You cannot take out more points!") self:subtleMessage("Impossible", "You cannot take out more points!", subtleMessageErrorColor)
return return
end end
if self.actor_dup:knowTalentType(tt) == true and self.actor:knowTalentType(tt) == true and (self.actor.__increased_talent_types[tt] or 0) == 0 then if self.actor_dup:knowTalentType(tt) == true and self.actor:knowTalentType(tt) == true and (self.actor.__increased_talent_types[tt] or 0) == 0 then
self:simplePopup("Impossible", "You cannot unlearn this category!") self:subtleMessage("Impossible", "You cannot unlearn this category!", subtleMessageWarningColor)
return return
end end
if not self.actor:knowTalentType(tt) then if not self.actor:knowTalentType(tt) then
self:simplePopup("Impossible", "You do not know this category!") self:subtleMessage("Impossible", "You do not know this category!", subtleMessageErrorColor)
return return
end end
...@@ -674,6 +684,7 @@ function _M:createDisplay() ...@@ -674,6 +684,7 @@ function _M:createDisplay()
on_use = function(item, inc) self:onUseTalent(item, inc) end, on_use = function(item, inc) self:onUseTalent(item, inc) end,
on_expand = function(item) self.actor.__hidden_talent_types[item.type] = not item.shown end, on_expand = function(item) self.actor.__hidden_talent_types[item.type] = not item.shown end,
scrollbar = true, no_tooltip = self.no_tooltip, scrollbar = true, no_tooltip = self.no_tooltip,
message_box = self.t_
} }
self.c_gtree = TalentTrees.new{ self.c_gtree = TalentTrees.new{
...@@ -757,6 +768,15 @@ function _M:createDisplay() ...@@ -757,6 +768,15 @@ function _M:createDisplay()
end end
end} end}
-- align it with Category Points button, to be nice
local btypes_center = 330 + self.b_types.w / 2
local msg_halfwidth = math.min(btypes_center, self.iw - btypes_center)
local msg_leftedge = btypes_center - msg_halfwidth
self.t_messages = StatusBox.new{
font = core.display.newFont("/data/font/DroidSans.ttf", 16),
width = msg_halfwidth * 2, delay = 1,
}
local ret = { local ret = {
{left=-10, top=0, ui=self.b_stat}, {left=-10, top=0, ui=self.b_stat},
...@@ -775,6 +795,8 @@ function _M:createDisplay() ...@@ -775,6 +795,8 @@ function _M:createDisplay()
{left=330, top=0, ui=self.b_types}, {left=330, top=0, ui=self.b_types},
{right=0, bottom=0, ui=self.b_prodigies}, {right=0, bottom=0, ui=self.b_prodigies},
{left=msg_leftedge, top=-self.t_messages.h, ui=self.t_messages},
} }
if self.b_inscriptions then table.insert(ret, {right=self.b_prodigies.w, bottom=0, ui=self.b_inscriptions}) end if self.b_inscriptions then table.insert(ret, {right=self.b_prodigies.w, bottom=0, ui=self.b_inscriptions}) end
......
-- ToME - Tales of Maj'Eyal
-- Copyright (C) 2009 - 2014 Nicolas Casalini
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
--
-- Nicolas Casalini "DarkGod"
-- darkgod@te4.org
require "engine.class"
local Base = require "engine.ui.Base"
--- A talent trees display
module(..., package.seeall, class.inherit(Base))
-- A status box.
-- width : sets width
-- delay: if not nil, the text will disappear after that much seconds
-- text and color can be set, that updates frame counter
function _M:init(t)
self.w = t.width
self.text = ""
self.color = t.color or {r=255,g=255,b=255}
self.delay = t.delay
self.frame_delay = t.delay * (config.settings.display_fps or 60)
self.frame_decay = 0
Base.init(self, t)
end
function _M:generate()
self.mouse:reset()
self.key:reset()
self.h = self.font_h
self.text_surf = core.display.newSurface(self.w, self.h)
self.text_surf:erase(0, 0, 0, 0)
self.text_tex = {self.text_surf:glTexture()}
self.iw, self.ih = self.w, self.h
self.w = self.w + 6
self.h = self.h + 6
end
function _M:setTextColor(text, color)
self.text = text or self.text
self.color = color or self.color
self.text_surf:erase(0, 0, 0, 0)
self.text_surf:drawColorStringCentered(self.font, self.text, 0, 0, self.iw, self.ih, self.color.r, self.color.g, self.color.b)
self.text_surf:updateTexture(self.text_tex[1])
self.frame_decay = 0
end
function _M:display(x, y, nb_keyframes)
local alpha = 1
if self.frame_delay then
self.frame_decay = self.frame_decay + nb_keyframes
if self.frame_decay > self.frame_delay then
-- ease out over 0.5 s
local easetime = (config.settings.display_fps or 60) / 2
alpha = 1 - (self.frame_decay - self.frame_delay) / easetime
end
end
self.text_tex[1]:toScreenFull(x + 3, y + 3, self.iw, self.ih, self.text_tex[2], self.text_tex[3], 1, 1, 1, alpha)
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment