From ca3f079015d4f51fe43533afe7b1e2a6b7833a96 Mon Sep 17 00:00:00 2001 From: dg <dg@51575b47-30f0-44d4-a5cc-537603b46e54> Date: Sat, 11 Jun 2011 21:58:21 +0000 Subject: [PATCH] working on tooltip git-svn-id: http://svn.net-core.org/repos/t-engine4@3636 51575b47-30f0-44d4-a5cc-537603b46e54 --- game/engines/default/engine/Tooltip.lua | 212 +++++++++ .../engine/interface/GameTargeting.lua | 21 - game/engines/default/engine/ui/Base.lua | 2 + .../default/engine/ui/TextzoneList.lua | 28 +- game/modules/tome/data/birth/worlds.lua | 25 + game/modules/tome/data/lore/orc-prides.lua | 2 +- game/modules/tome/data/quests/start-yeek.lua | 2 +- game/modules/tome/dialogs/LevelupDialog.lua | 35 +- .../tome/dialogs/LevelupStatsDialog.lua | 179 ------- .../tome/dialogs/LevelupTalentsDialog.lua | 440 ------------------ src/core_lua.c | 48 +- 11 files changed, 316 insertions(+), 678 deletions(-) delete mode 100644 game/modules/tome/dialogs/LevelupStatsDialog.lua delete mode 100644 game/modules/tome/dialogs/LevelupTalentsDialog.lua diff --git a/game/engines/default/engine/Tooltip.lua b/game/engines/default/engine/Tooltip.lua index 0174deb77b..7b0a4da518 100644 --- a/game/engines/default/engine/Tooltip.lua +++ b/game/engines/default/engine/Tooltip.lua @@ -17,6 +17,7 @@ -- Nicolas Casalini "DarkGod" -- darkgod@te4.org +--[[ require "engine.class" local Map = require "engine.Map" @@ -159,3 +160,214 @@ function _M:displayAtMap(tmx, tmy, mx, my, text) self.texture:toScreenFull(mx, my, self.w, self.h, self.texture_w, self.texture_h) end end +]] +-- TE4 - T-Engine 4 +-- Copyright (C) 2009, 2010, 2011 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" +local TextzoneList = require "engine.ui.TextzoneList" +local Map = require "engine.Map" +local Tiles = require "engine.Tiles" + +--- A generic tooltip +module(..., package.seeall, class.inherit(Base)) + +tiles = Tiles.new(16, 16) + +function _M:init(fontname, fontsize, color, bgcolor, max) + self.max = max or 300 + self.ui = "simple" + self.font = {fontname or "/data/font/Vera.ttf", fontsize or 12} + + local conf = self.ui_conf[self.ui] + self.frame = self.frame or { + b7 = "ui/dialogframe_7.png", + b9 = "ui/dialogframe_9.png", + b1 = "ui/dialogframe_1.png", + b3 = "ui/dialogframe_3.png", + b4 = "ui/dialogframe_4.png", + b6 = "ui/dialogframe_6.png", + b8 = "ui/dialogframe_8.png", + b2 = "ui/dialogframe_2.png", + b5 = "ui/dialogframe_5.png", + shadow = conf.frame_shadow, + a = conf.frame_alpha or 1, + } + self.frame.a = 0.85 + self.frame.ox1 = self.frame.ox1 or conf.frame_ox1 + self.frame.ox2 = self.frame.ox2 or conf.frame_ox2 + self.frame.oy1 = self.frame.oy1 or conf.frame_oy1 + self.frame.oy2 = self.frame.oy2 or conf.frame_oy2 + + self.default_ui = { TextzoneList.new{weakstore=true, width=self.max, height=500, variable_height=true, font=self.font, ui=self.ui} } + + self.uis = {} + self.w = self.max + (self.frame.ox2 - self.frame.ox1) + 10 + self.h = 200 + Base.init(self, {}) +end + +function _M:generate() + self.frame.w = self.w + self.frame.h = self.h + + self.b7 = self:getUITexture(self.frame.b7) + self.b9 = self:getUITexture(self.frame.b9) + self.b1 = self:getUITexture(self.frame.b1) + self.b3 = self:getUITexture(self.frame.b3) + self.b8 = self:getUITexture(self.frame.b8) + self.b4 = self:getUITexture(self.frame.b4) + self.b2 = self:getUITexture(self.frame.b2) + self.b6 = self:getUITexture(self.frame.b6) + self.b5 = self:getUITexture(self.frame.b5) +end + +--- Set the tooltip text +function _M:set(str, ...) + if type(str) == "string" then str = str:format(...):toTString() end + + if str.is_tstring then + self:erase() + self.default_ui[1]:switchItem(str, str) + else + if self.uids == self.default_ui then self.uids = {} end + self.uids[#self.uids+1] = str + end + + local uih = 0 + for i = 1, #self.uis do uih = uih + self.uis[i].h end + self.h = uih + (self.frame.oy2 - self.frame.oy1) + 10 + self.frame.h = self.h +end + +function _M:erase() + self.uis = self.default_ui + self.default_ui[1].list = nil +end + +function _M:display() end + +function _M:drawFrame(x, y, r, g, b, a) + x = x + self.frame.ox1 + y = y + self.frame.oy1 + + -- Corners + self.b7.t:toScreenFull(x, y, self.b7.w, self.b7.h, self.b7.tw, self.b7.th, r, g, b, a) + self.b1.t:toScreenFull(x, y + self.frame.h - self.b1.h, self.b1.w, self.b1.h, self.b1.tw, self.b1.th, r, g, b, a) + self.b9.t:toScreenFull(x + self.frame.w - self.b9.w, y, self.b9.w, self.b9.h, self.b9.tw, self.b9.th, r, g, b, a) + self.b3.t:toScreenFull(x + self.frame.w - self.b3.w, y + self.frame.h - self.b3.h, self.b3.w, self.b3.h, self.b3.tw, self.b3.th, r, g, b, a) + + -- Sides + self.b8.t:toScreenFull(x + self.b7.w, y, self.frame.w - self.b7.w - self.b9.w, self.b8.h, self.b8.tw, self.b8.th, r, g, b, a) + self.b2.t:toScreenFull(x + self.b7.w, y + self.frame.h - self.b3.h, self.frame.w - self.b7.w - self.b9.w, self.b2.h, self.b2.tw, self.b2.th, r, g, b, a) + self.b4.t:toScreenFull(x, y + self.b7.h, self.b4.w, self.frame.h - self.b7.h - self.b1.h, self.b4.tw, self.b4.th, r, g, b, a) + self.b6.t:toScreenFull(x + self.frame.w - self.b9.w, y + self.b7.h, self.b6.w, self.frame.h - self.b7.h - self.b1.h, self.b6.tw, self.b6.th, r, g, b, a) + + -- Body + self.b5.t:toScreenFull(x + self.b7.w, y + self.b7.h, self.frame.w - self.b7.w - self.b3.w , self.frame.h - self.b7.h - self.b3.h, self.b6.tw, self.b6.th, r, g, b, a) +end + +function _M:toScreen(x, y, nb_keyframes) + local zoom = 1 + + -- We translate and scale opengl matrix to make the popup effect easily + local ox, oy = x, y + local hw, hh = math.floor(self.w / 2), math.floor(self.h / 2) + local tx, ty = x + hw, y + hh + x, y = -hw, -hh + core.display.glTranslate(tx, ty, 0) + if zoom < 1 then core.display.glScale(zoom, zoom, zoom) end + + -- Draw the frame and shadow + self:drawFrame(x, y, 1, 1, 1, self.frame.a) + + -- UI elements + local uih = 0 + for i = 1, #self.uis do + local ui = self.uis[i] + ui:display(x + 5, y + 5 + uih, nb_keyframes, ox + 5, oy + 5 + uih) + uih = uih + ui.h + end + + -- Restiore normal opengl matrix + if zoom < 1 then core.display.glScale() end + core.display.glTranslate(-tx, -ty, 0) +end + +--- Displays the tooltip at the given map coordinates +-- @param tmx the map coordinate to get tooltip from +-- @param tmy the map coordinate to get tooltip from +-- @param mx the screen coordinate to display at, if nil it will be computed from tmx +-- @param my the screen coordinate to display at, if nil it will be computed from tmy +-- @param text a text to display, if nil it will interrogate the map under the mouse using the "tooltip" property +function _M:displayAtMap(tmx, tmy, mx, my, text) + if not mx then + mx, my = game.level.map:getTileToScreen(tmx, tmy) + end + + if text then + if text ~= self.old_text then + if type(text) == "string" then + self:set("%s", text) + else + self:set(text) + end + self:display() + self.old_text = text + end + else + if self.old_tmx ~= tmx or self.old_tmy ~= tmy or (game.paused and self.old_turn ~= game.turn) then + self.old_text = "" + self.old_tmx, self.old_tmy = tmx, tmy + self.old_turn = game.turn + local tt = {} + local seen = game.level.map.seens(tmx, tmy) + local remember = game.level.map.remembers(tmx, tmy) + tt[#tt+1] = seen and game.level.map:checkEntity(tmx, tmy, Map.PROJECTILE, "tooltip", game.level.map.actor_player) or nil + tt[#tt+1] = seen and game.level.map:checkEntity(tmx, tmy, Map.ACTOR, "tooltip", game.level.map.actor_player) or nil + tt[#tt+1] = (seen or remember) and game.level.map:checkEntity(tmx, tmy, Map.OBJECT, "tooltip", game.level.map.actor_player) or nil + tt[#tt+1] = (seen or remember) and game.level.map:checkEntity(tmx, tmy, Map.TRAP, "tooltip", game.level.map.actor_player) or nil + tt[#tt+1] = (seen or remember) and game.level.map:checkEntity(tmx, tmy, Map.TERRAIN, "tooltip", game.level.map.actor_player) or nil + if #tt > 0 then + local ts = tstring{} + for i = 1, #tt do + ts:merge(tt[i]:toTString()) + if i < #tt then ts:add(true, "---", true) end + end + self:set(ts) + self:display() + else + self:erase() + end + end + end + +-- if self.texture then +-- mx = mx - self.w / 2 + game.level.map.tile_w / 2 +-- my = my - self.h + if mx < 0 then mx = 0 end + if my < 0 then my = 0 end + if mx > game.w - self.w then mx = game.w - self.w end + if my > game.h - self.h then my = game.h - self.h end + self.last_display_x = mx + self.last_display_y = my + self:toScreen(mx, my) +-- end +end diff --git a/game/engines/default/engine/interface/GameTargeting.lua b/game/engines/default/engine/interface/GameTargeting.lua index b9cd67e49a..0de6c32219 100644 --- a/game/engines/default/engine/interface/GameTargeting.lua +++ b/game/engines/default/engine/interface/GameTargeting.lua @@ -70,27 +70,6 @@ function _M:targetDisplayTooltip(dx, dy) end self.old_tmx, self.old_tmy = tmx, tmy end - - if not self.tooltip2 then return end - - -- Tooltip is displayed over all else - if self.level and self.level.map and self.level.map.finished then - -- Display a tooltip if available - if self.tooltip2_x then - if type(self.tooltip2_x) == "table" then - self.tooltip2:toScreen(self.tooltip2.last_display_x, self.tooltip2.last_display_y) - else - local tmx, tmy = self.level.map:getMouseTile(self.tooltip2_x , self.tooltip2_y) - self.tooltip2:displayAtMap(tmx, tmy, dx, dy) - end - end - - -- Move target around - if self.old_tmx ~= tmx or self.old_tmy ~= tmy then - self.target.target.x, self.target.target.y = tmx, tmy - end - self.old_tmx, self.old_tmy = tmx, tmy - end end --- Enter/leave targeting mode diff --git a/game/engines/default/engine/ui/Base.lua b/game/engines/default/engine/ui/Base.lua index 38c96c8482..541e23bbdc 100644 --- a/game/engines/default/engine/ui/Base.lua +++ b/game/engines/default/engine/ui/Base.lua @@ -92,6 +92,8 @@ function _M:init(t, no_gen) end end + if t.ui then self.ui = t.ui end + if not no_gen then self:generate() end end diff --git a/game/engines/default/engine/ui/TextzoneList.lua b/game/engines/default/engine/ui/TextzoneList.lua index 3a32d6a8b2..24a35ddec8 100644 --- a/game/engines/default/engine/ui/TextzoneList.lua +++ b/game/engines/default/engine/ui/TextzoneList.lua @@ -21,24 +21,29 @@ require "engine.class" local Base = require "engine.ui.Base" local Focusable = require "engine.ui.Focusable" local Slider = require "engine.ui.Slider" +local Separator = require "engine.ui.Separator" --- A generic UI list module(..., package.seeall, class.inherit(Base, Focusable)) function _M:init(t) self.items = {} + if t.weakstore then setmetatable(self.items, {__mode="k"}) end self.cur_item = 0 self.w = assert(t.width, "no list width") if t.auto_height then t.height = 1 end self.h = assert(t.height, "no list height") self.scrollbar = t.scrollbar self.no_color_bleed = t.no_color_bleed + self.variable_height = t.variable_height if self.scrollbar then self.can_focus = true end Base.init(self, t) + + self.sep = Separator.new{dir="vertical", size=self.w, ui=self.ui} end function _M:generate() @@ -69,11 +74,15 @@ function _M:createItem(item, text) local old_style = self.font:getStyle() -- Handle normal text - if false and type(text) == "string" then + if type(text) == "string" then local list = text:splitLines(self.w, self.font) local scroll = 1 local max = #list local max_display = math.floor(self.h / self.fh) + if self.variable_height then + self.h = max * self.fh + max_display = max + end -- Draw the list items local gen = {} @@ -103,6 +112,10 @@ function _M:createItem(item, text) local scroll = 1 local max = #gen local max_display = math.floor(self.h / self.fh) + if self.variable_height then + self.h = max * self.fh + max_display = max + end self.items[item] = { list = gen, @@ -128,6 +141,11 @@ function _M:switchItem(item, create_if_needed) return true end +function _M:erase() + self.list = {} + self.items = {} +end + function _M:display(x, y) if not self.list then return end @@ -136,8 +154,12 @@ function _M:display(x, y) for i = self.scroll, max do local item = self.list[i] if not item then break end - if self.text_shadow then item._tex:toScreenFull(x+1, y+1, self.fw, self.fh, item._tex_w, item._tex_h, 0, 0, 0, self.text_shadow) end - item._tex:toScreenFull(x, y, self.fw, self.fh, item._tex_w, item._tex_h) + if item.is_separator then + self.sep:display(x, y + (self.fh - self.sep.h) / 2) + else + if self.text_shadow then item._tex:toScreenFull(x+1, y+1, self.fw, self.fh, item._tex_w, item._tex_h, 0, 0, 0, self.text_shadow) end + item._tex:toScreenFull(x, y, self.fw, self.fh, item._tex_w, item._tex_h) + end y = y + self.fh end diff --git a/game/modules/tome/data/birth/worlds.lua b/game/modules/tome/data/birth/worlds.lua index 6f50942fce..028031cb2c 100644 --- a/game/modules/tome/data/birth/worlds.lua +++ b/game/modules/tome/data/birth/worlds.lua @@ -81,9 +81,34 @@ newBirthDescriptor{ { "Play as your favorite race and class and venture into the infinite dungeon.", "The only limit to how far you can go is your own skill!", + "Inside the infinite dungeon you will yourself be limitless, you can levelup after level 50 and continue to gain stat and talent points (at a reduced rate).", + "Every levels after level 50 the maximun of stats will increase by one.", + "Every 10 levels after level 50 the maximun points of every talents will increase by one.", }, descriptor_choices = default_eyal_descriptors{ difficulty = { Tutorial = "never"} }, copy = { + -- Can levelup forever + resolvers.generic(function(e) e.max_level = nil end), + no_points_on_levelup = function(self) + if self.level <= 50 then + self.unused_stats = self.unused_stats + (self.stats_per_level or 3) + self:getRankStatAdjust() + self.unused_talents = self.unused_talents + 1 + self.unused_generics = self.unused_generics + 1 + if self.level % 5 == 0 then self.unused_talents = self.unused_talents + 1 end + if self.level % 5 == 0 then self.unused_generics = self.unused_generics - 1 end + if self.level == 10 or self.level == 20 or self.level == 30 or self.level == 40 then + self.unused_talents_types = self.unused_talents_types + 1 + end + else + self.unused_stats = self.unused_stats + 1 + if self.level % 2 == 0 then + self.unused_talents = self.unused_talents + 1 + elseif self.level % 3 == 0 then + self.unused_generics = self.unused_generics + 1 + end + end + end, + -- Give the orb of knowledge resolvers.inventory{ id=true, {defined="ORB_KNOWLEDGE"}}, resolvers.equip{ id=true, {name="iron pickaxe", ego_chance=-1000}}, diff --git a/game/modules/tome/data/lore/orc-prides.lua b/game/modules/tome/data/lore/orc-prides.lua index 41d1447bb8..34abd6360f 100644 --- a/game/modules/tome/data/lore/orc-prides.lua +++ b/game/modules/tome/data/lore/orc-prides.lua @@ -296,7 +296,7 @@ Some females have died during the procedures. I can only presume these were the newLore{ id = "orc-breeding-3", category = "orc prides", - name = "Clinician Korbek's experimental notes part tree", + name = "Clinician Korbek's experimental notes part three", lore = [[#{bold}#Clinician Korbek's experimental notes part three#{normal}# My work is continuing with tremendous success. All subjects now have multiple operational wombs, thanks to the corrupted blood infusions coupled with arcane regeneration fields to quickly repair the corrupted tissues. With greater advances in accelerating the foetal growth stage we are now seeing new orcs every few days! I believe this can be pushed even further. diff --git a/game/modules/tome/data/quests/start-yeek.lua b/game/modules/tome/data/quests/start-yeek.lua index 1c72487a72..2930c47c6f 100644 --- a/game/modules/tome/data/quests/start-yeek.lua +++ b/game/modules/tome/data/quests/start-yeek.lua @@ -28,7 +28,7 @@ desc = function(self, who) desc[#desc+1] = "#SLATE#* You must explore the underwater lair of Murgol.#WHITE#" end if self:isCompleted("ritch") then - desc[#desc+1] = "#LIGHT_GREEN#* You have explored the ritch'z tunnels and vanquished their queen.#WHITE#" + desc[#desc+1] = "#LIGHT_GREEN#* You have explored the ritch's tunnels and vanquished their queen.#WHITE#" else desc[#desc+1] = "#SLATE#* You must explore ritch's tunnels.#WHITE#" end diff --git a/game/modules/tome/dialogs/LevelupDialog.lua b/game/modules/tome/dialogs/LevelupDialog.lua index 6741586165..9f8f6479b5 100644 --- a/game/modules/tome/dialogs/LevelupDialog.lua +++ b/game/modules/tome/dialogs/LevelupDialog.lua @@ -420,6 +420,11 @@ function _M:getStatDescription(stat_id) return text, h * #lines end +function _M:getMaxTPoints(t) + if t.points == 1 then return 1 end + return t.points + math.max(0, math.floor((self.actor.level - 50) / 10)) +end + function _M:getStatNewTalents(stat_id) local text = "#LIGHT_BLUE#New available talents: #LAST#\n" local stats = { "str", "dex", "mag", "wil", "cun", "con" } @@ -427,7 +432,7 @@ function _M:getStatNewTalents(stat_id) if diff ~= 0 and self.talent_stats_req[stats[stat_id]] then for j=1,#self.talent_stats_req[stats[stat_id]] do local t = self.actor:getTalentFromId(self.talent_stats_req[stats[stat_id]][j][1].talent) - if self.actor:canLearnTalent(t) and not self.actor_dup:canLearnTalent(t) and t.points > self.actor:getTalentLevelRaw(t) then + if self.actor:canLearnTalent(t) and not self.actor_dup:canLearnTalent(t) and self:getMaxTPoints(t) > self.actor:getTalentLevelRaw(t) then text = text.."#GOLD# - "..t.name.."#LAST#\n" end end @@ -479,7 +484,7 @@ function _M:incStat(v) self:simplePopup("Stat is at the maximum for your level", "You cannot increase this stat further until next level!") return end - if self.actor:isStatMax(self.sel) or self.actor:getStat(self.sel, nil, nil, true) >= 60 then + if self.actor:isStatMax(self.sel) or self.actor:getStat(self.sel, 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!") return end @@ -635,11 +640,11 @@ function _M:learnTalent(t_id, v) self:simplePopup("Cannot learn talent", "Prerequisites not met!") return end - if self.actor:getTalentLevelRaw(t_id) >= t.points then + if self.actor:getTalentLevelRaw(t_id) >= self:getMaxTPoints(t) then self:simplePopup("Already known", "You already fully know this talent!") return end - self.actor:learnTalent(t_id) + self.actor:learnTalent(t_id, true) self.actor.unused_talents = self.actor.unused_talents - 1 self.talents_changed[t_id] = true self.talents_learned[t_id] = self.talents_learned[t_id] + 1 @@ -676,7 +681,7 @@ function _M:learnTalent(t_id, v) self:simplePopup("Cannot learn talent", "Prerequisites not met!") return end - if self.actor:getTalentLevelRaw(t_id) >= t.points then + if self.actor:getTalentLevelRaw(t_id) >= self:getMaxTPoints(t) then self:simplePopup("Already known", "You already fully know this talent!") return end @@ -792,10 +797,10 @@ function _M:onDrawItem(item) else local t = self.actor:getTalentFromId(item.talent) local traw = self.actor:getTalentLevelRaw(t.id) - local diff = function(i1, i2, res) + local diff = function(i2, i1, res) res:add({"color", "LIGHT_GREEN"}, i1, {"color", "LAST"}, " [->", {"color", "YELLOW_GREEN"}, i2, {"color", "LAST"}, "]") end - if traw == 0 and t.points >= 2 then + if traw == 0 and self:getMaxTPoints(t) >= 2 then local req = self.actor:getTalentReqDesc(item.talent, 1):toTString():tokenize(" ()[]") local req2 = self.actor:getTalentReqDesc(item.talent, 2):toTString():tokenize(" ()[]") text:add{"color","WHITE"} @@ -803,14 +808,14 @@ function _M:onDrawItem(item) text:add(true) text:merge(req:diffWith(req2, diff)) text:merge(self.actor:getTalentFullDescription(t, 1):diffWith(self.actor:getTalentFullDescription(t, 2), diff)) - elseif traw < t.points then + elseif traw < self:getMaxTPoints(t) then local req = self.actor:getTalentReqDesc(item.talent):toTString():tokenize(" ()[]") local req2 = self.actor:getTalentReqDesc(item.talent, 1):toTString():tokenize(" ()[]") text:add{"color","WHITE"} text:add({"font", "bold"}, traw == 0 and "Next talent level" or "Current talent level: ", tostring(traw), " [-> ", tostring(traw + 1), "]", {"font", "normal"}) text:add(true) - text:merge(req:diffWith(req2, diff)) - text:merge(self.actor:getTalentFullDescription(t):diffWith(self.actor:getTalentFullDescription(t, 1), diff)) + text:merge(req2:diffWith(req, diff)) + text:merge(self.actor:getTalentFullDescription(t, 1):diffWith(self.actor:getTalentFullDescription(t), diff)) else local req = self.actor:getTalentReqDesc(item.talent) text:add({"font", "bold"}, "Current talent level: "..traw, {"font", "normal"}) @@ -870,13 +875,13 @@ function _M:generateList() list[#list].status = function(item) local t = self.actor:getTalentFromId(item.talent) local ttknown = self.actor:knowTalentType(item._type) - if self.actor:getTalentLevelRaw(t.id) == t.points then - return tstring{{"color", 0x00, 0xFF, 0x00}, self.actor:getTalentLevelRaw(t.id).."/"..t.points} + if self.actor:getTalentLevelRaw(t.id) == self:getMaxTPoints(t) then + return tstring{{"color", 0x00, 0xFF, 0x00}, self.actor:getTalentLevelRaw(t.id).."/"..self:getMaxTPoints(t)} else if not self.actor:canLearnTalent(t) then - return tstring{(ttknown and {"color", 0xFF, 0x00, 0x00} or {"color", 0x80, 0x80, 0x80}), self.actor:getTalentLevelRaw(t.id).."/"..t.points} + return tstring{(ttknown and {"color", 0xFF, 0x00, 0x00} or {"color", 0x80, 0x80, 0x80}), self.actor:getTalentLevelRaw(t.id).."/"..self:getMaxTPoints(t)} else - return tstring{(ttknown and {"color", "WHITE"} or {"color", 0x80, 0x80, 0x80}), self.actor:getTalentLevelRaw(t.id).."/"..t.points} + return tstring{(ttknown and {"color", "WHITE"} or {"color", 0x80, 0x80, 0x80}), self.actor:getTalentLevelRaw(t.id).."/"..self:getMaxTPoints(t)} end end end @@ -1169,7 +1174,7 @@ function _M:drawDialog(kind) if self.talent_stats_req[stats[stat_id]] then for j=1,#self.talent_stats_req[stats[stat_id]] do local t = self.actor:getTalentFromId(self.talent_stats_req[stats[stat_id]][j][1].talent) - if self.actor:canLearnTalent(t) and not self.actor_dup:canLearnTalent(t) and t.points > self.actor:getTalentLevelRaw(t) and not talents_added[self.talent_stats_req[stats[stat_id]][j][1].talent] and not talents_learned[self.talent_stats_req[stats[stat_id]][j][1].talent] then + if self.actor:canLearnTalent(t) and not self.actor_dup:canLearnTalent(t) and self:getMaxTPoints(t) > self.actor:getTalentLevelRaw(t) and not talents_added[self.talent_stats_req[stats[stat_id]][j][1].talent] and not talents_learned[self.talent_stats_req[stats[stat_id]][j][1].talent] then talents_added[self.talent_stats_req[stats[stat_id]][j][1].talent] = true local desc = "#GOLD##{bold}#"..t.name.."#{normal}##WHITE#\n"..tostring(self.actor:getTalentFullDescription(t)) self:mouseTooltip(desc, s:drawColorStringBlended(self.font, ("#GOLD#%s"):format(t.name), w, h, 255, 255, 255, true)) h = h + self.font_h diff --git a/game/modules/tome/dialogs/LevelupStatsDialog.lua b/game/modules/tome/dialogs/LevelupStatsDialog.lua deleted file mode 100644 index cd2ed9bc9d..0000000000 --- a/game/modules/tome/dialogs/LevelupStatsDialog.lua +++ /dev/null @@ -1,179 +0,0 @@ --- ToME - Tales of Maj'Eyal --- Copyright (C) 2009, 2010, 2011 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 th+e 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 Dialog = require "engine.ui.Dialog" -local ListColumns = require "engine.ui.ListColumns" -local Textzone = require "engine.ui.Textzone" -local TextzoneList = require "engine.ui.TextzoneList" -local Separator = require "engine.ui.Separator" - -local LevelupTalentsDialog = require "mod.dialogs.LevelupTalentsDialog" - -module(..., package.seeall, class.inherit(Dialog)) - -local _points_text = "Stats points left: #00FF00#%d#WHITE#" - -function _M:init(actor, on_finish) - self.actor = actor - self.actor_dup = actor:clone() - self.unused_stats = self.actor.unused_stats - Dialog.init(self, "Stats Levelup: "..actor.name, 600, 500) - - self.sel = 1 - - self.c_tut = Textzone.new{width=math.floor(self.iw / 2 - 10), auto_height=true, no_color_bleed=true, text=[[ -Keyboard: #00FF00#up key/down key#FFFFFF# to select a stat; #00FF00#right key#FFFFFF# to increase stat; #00FF00#left key#FFFFFF# to decrease a stat. -Mouse: #00FF00#Left click#FFFFFF# to increase a stat; #00FF00#right click#FFFFFF# to decrease a stat. -]]} - self.c_desc = TextzoneList.new{width=math.floor(self.iw / 2 - 10), height=self.ih - self.c_tut.h - 20, no_color_bleed=true} - self.c_points = Textzone.new{width=math.floor(self.iw / 2 - 10), auto_height=true, no_color_bleed=true, text=_points_text:format(self.actor.unused_stats)} - - self.c_list = ListColumns.new{width=math.floor(self.iw / 2 - 10), height=self.ih - 10, all_clicks=true, columns={ - {name="Stat", width=50, display_prop="name"}, - {name="Base", width=25, display_prop="base"}, - {name="Value", width=25, display_prop="val"}, - }, list={ - {name="Strength", base=self.actor:getStr(nil, nil, true), val=self.actor:getStr(), stat_id=self.actor.STAT_STR}, - {name="Dexterity", base=self.actor:getDex(nil, nil, true), val=self.actor:getDex(), stat_id=self.actor.STAT_DEX}, - {name="Magic", base=self.actor:getMag(nil, nil, true), val=self.actor:getMag(), stat_id=self.actor.STAT_MAG}, - {name="Willpower", base=self.actor:getWil(nil, nil, true), val=self.actor:getWil(), stat_id=self.actor.STAT_WIL}, - {name="Cunning", base=self.actor:getCun(nil, nil, true), val=self.actor:getCun(), stat_id=self.actor.STAT_CUN}, - {name="Constitution", base=self.actor:getCon(nil, nil, true), val=self.actor:getCon(), stat_id=self.actor.STAT_CON}, - }, fct=function(item, _, v) - self:incStat(v == "left" and 1 or -1) - end, select=function(item, sel) self.sel = sel self.c_desc:switchItem(item, self.actor.stats_def[item.stat_id].description) end} - - self:loadUI{ - {left=0, top=0, ui=self.c_points}, - {left=5, top=self.c_points.h+5, ui=Separator.new{dir="vertical", size=math.floor(self.iw / 2) - 10}}, - {left=0, top=self.c_points.h+15, ui=self.c_list}, - - {hcenter=0, top=5, ui=Separator.new{dir="horizontal", size=self.ih - 10}}, - - {right=0, top=self.c_tut.h + 20, ui=self.c_desc}, - {right=0, top=0, ui=self.c_tut}, - } - self:setFocus(self.c_list) - self:setupUI() - - self:update() - - self.key:addBinds{ - EXIT = function() - game:unregisterDialog(self) - self:finish() - - -- if talents to spend, do it now - if self.actor.unused_generics > 0 or self.actor.unused_talents > 0 or self.actor.unused_talents_types > 0 then - local dt = LevelupTalentsDialog.new(self.actor, on_finish) - game:registerDialog(dt) - end - end, - } -end - -function _M:finish() - if self.actor.unused_stats == self.unused_stats then return end - local reset = {} - for tid, act in pairs(self.actor.sustain_talents) do - if act then - local t = self.actor:getTalentFromId(tid) - if t.no_sustain_autoreset then - game.logPlayer(self.actor, "#LIGHT_BLUE#Warning: You have increased some of your statistics. Talent %s is actually sustained; if it is dependent on one of the stats you changed, you need to re-use it for the changes to take effect.", t.name) - else - reset[#reset+1] = tid - end - end - end - for i, tid in ipairs(reset) do - self.actor:forceUseTalent(tid, {ignore_energy=true, ignore_cd=true, no_equilibrium_fail=true, no_paradox_fail=true}) - self.actor:forceUseTalent(tid, {ignore_energy=true, ignore_cd=true, no_equilibrium_fail=true, no_paradox_fail=true}) - end -end - -function _M:incStat(v) - if v == 1 then - if self.actor.unused_stats <= 0 then - self:simplePopup("Not enough stat points", "You have no stat points left!") - return - end - if self.actor:getStat(self.sel, 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!") - return - end - if self.actor:isStatMax(self.sel) or self.actor:getStat(self.sel, nil, nil, true) >= 60 then - self:simplePopup("Stat is at the maximum", "You cannot increase this stat further!") - return - end - else - if self.actor_dup:getStat(self.sel, nil, nil, true) == self.actor:getStat(self.sel, nil, nil, true) then - self:simplePopup("Impossible", "You cannot take out more points!") - return - end - end - - local sel = self.sel - self.actor:incStat(sel, v) - self.actor.unused_stats = self.actor.unused_stats - v - self.c_list.list[sel].base = self.actor:getStat(sel, nil, nil, true) - self.c_list.list[sel].val = self.actor:getStat(sel) - self.c_list:generate() - self.c_list.sel = sel - self.c_list:onSelect() - self.c_points.text = _points_text:format(self.actor.unused_stats) - self.c_points:generate() - self:update() -end - -function _M:update() - self.c_list.key:addBinds{ - ACCEPT = function() self.key:triggerVirtual("EXIT") end, - MOVE_LEFT = function() self:incStat(-1) end, - MOVE_RIGHT = function() self:incStat(1) end, - } -end - -function _M:drawDialog(s) - -- Description part - self:drawHBorder(s, self.iw / 2, 2, self.ih - 4) - local statshelp = ([[Keyboard: #00FF00#up key/down key#FFFFFF# to select a stat; #00FF00#right key#FFFFFF# to increase stat; #00FF00#left key#FFFFFF# to decrease a stat. -Mouse: #00FF00#Left click#FFFFFF# to increase a stat; #00FF00#right click#FFFFFF# to decrease a stat. -]]):splitLines(self.iw / 2 - 10, self.font) - local lines = self.actor.stats_def[self.sel].description:splitLines(self.iw / 2 - 10, self.font) - for i = 1, #statshelp do - s:drawColorStringBlended(self.font, statshelp[i], self.iw / 2 + 5, 2 + (i-1) * self.font:lineSkip()) - end - for i = 1, #lines do - s:drawColorStringBlended(self.font, lines[i], self.iw / 2 + 5, 2 + (i + #statshelp + 1) * self.font:lineSkip()) - end - - -- Stats - s:drawColorStringBlended(self.font, "Stats points left: #00FF00#"..self.actor.unused_stats, 2, 2) - self:drawWBorder(s, 2, 20, 200) - - self:drawSelectionList(s, 2, 25, self.font_h, { - "Strength", "Dexterity", "Magic", "Willpower", "Cunning", "Constitution" - }, self.sel) - self:drawSelectionList(s, 100, 25, self.font_h, { - self.actor:getStr(), self.actor:getDex(), self.actor:getMag(), self.actor:getWil(), self.actor:getCun(), self.actor:getCon(), - }, self.sel) - self.changed = false -end diff --git a/game/modules/tome/dialogs/LevelupTalentsDialog.lua b/game/modules/tome/dialogs/LevelupTalentsDialog.lua deleted file mode 100644 index db3b41d953..0000000000 --- a/game/modules/tome/dialogs/LevelupTalentsDialog.lua +++ /dev/null @@ -1,440 +0,0 @@ --- ToME - Tales of Maj'Eyal --- Copyright (C) 2009, 2010, 2011 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 Dialog = require "engine.ui.Dialog" -local TreeList = require "engine.ui.TreeList" -local Textzone = require "engine.ui.Textzone" -local TextzoneList = require "engine.ui.TextzoneList" -local Separator = require "engine.ui.Separator" - -module(..., package.seeall, class.inherit(Dialog)) - -local _points_left = [[ -Category points left: #00FF00#%d#WHITE# -Class talent points left: #00FF00#%d#WHITE# -Generic talent points left: #00FF00#%d#WHITE#]] - -function _M:init(actor, on_finish) - self.actor = actor - self.actor.__hidden_talent_types = self.actor.__hidden_talent_types or {} - self.actor.__increased_talent_types = self.actor.__increased_talent_types or {} - - self.actor_dup = actor:clone() - Dialog.init(self, "Talents Levelup: "..actor.name, math.max(game.w * 0.85, 800), math.max(game.h * 0.85, 600)) - - self.c_tut = Textzone.new{width=math.floor(self.iw / 2 - 10), height=1, auto_height=true, no_color_bleed=true, text=[[ -Keyboard: #00FF00#up key/down key#FFFFFF# to select a stat; #00FF00#right key#FFFFFF# to learn; #00FF00#left key#FFFFFF# to unlearn; #00FF00#+#FFFFFF# to expand a category; #00FF00#-#FFFFFF# to reduce a category. -Mouse: #00FF00#Left click#FFFFFF# to learn; #00FF00#right click#FFFFFF# to unlearn. -]]} - self.c_points = Textzone.new{width=math.floor(self.iw / 2 - 10), height=1, auto_height=true, no_color_bleed=true, text=_points_left:format(self.actor.unused_talents_types, self.actor.unused_talents, self.actor.unused_generics)} - self.c_desc = TextzoneList.new{width=math.floor(self.iw / 2 - 10), height=self.ih - self.c_tut.h - 20, scrollbar=true, no_color_bleed=true} - - self:generateList() - - self.c_tree = TreeList.new{width=math.floor(self.iw / 2 - 10), height=self.ih - 15 - self.c_points.h, all_clicks=true, scrollbar=true, columns={ - {width=80, display_prop="name"}, - {width=20, display_prop="status"}, - }, tree=self.tree, - fct=function(item, sel, v) self:treeSelect(item, sel, v) end, - select=function(item, sel) self:select(item) end, - on_expand=function(item) self.actor.__hidden_talent_types[item.type] = not item.shown end, - on_drawitem=function(item) if self.running then self:onDrawItem(item) end end, - } - - self:loadUI{ - {left=0, top=0, ui=self.c_points}, - {left=5, top=self.c_points.h+5, ui=Separator.new{dir="vertical", size=math.floor(self.iw / 2) - 10}}, - {left=0, top=self.c_points.h+20, ui=self.c_tree}, - - {hcenter=0, top=5, ui=Separator.new{dir="horizontal", size=self.ih - 10}}, - - {right=0, top=self.c_tut.h + 20, ui=self.c_desc}, - {right=0, top=0, ui=self.c_tut}, - } - self:setFocus(self.c_tree) - self:setupUI() - - self.talents_changed = {} - self.running = true - - self.key:addCommands{ - __TEXTINPUT = function(c) - local item = self.c_tree.list[self.c_tree.sel] - if not item or not item.type then return end - if c == "+" then - self.c_tree:treeExpand(true) - end - if c == "-" then - self.c_tree:treeExpand(false) - end - end, - } - self.c_tree.key:addBind("ACCEPT", function() self.key:triggerVirtual("EXIT") end) - self.key:addBinds{ - MOVE_LEFT = function() local item=self.c_tree.list[self.c_tree.sel] self:treeSelect(item, self.c_tree.sel, "right") end, - MOVE_RIGHT = function() local item=self.c_tree.list[self.c_tree.sel] self:treeSelect(item, self.c_tree.sel, "left") end, - ACCEPT = "EXIT", - EXIT = function() game:unregisterDialog(self) - -- Achievements checks - world:gainAchievement("ELEMENTALIST", self.actor) - world:gainAchievement("WARPER", self.actor) - - self:finish() - if on_finish then on_finish() end - end, - } -end - -function _M:computeDeps(t) - local d = {} - self.talents_deps[t.id] = d - - -- Check prerequisites - if rawget(t, "require") then - local req = t.require - if type(req) == "function" then req = req(self.actor, t) end - - if req.talent then - for _, tid in ipairs(req.talent) do - if type(tid) == "table" then - d[tid[1]] = true --- print("Talent deps: ", t.id, "depends on", tid[1]) - else - d[tid] = true --- print("Talent deps: ", t.id, "depends on", tid) - end - end - end - end - - -- Check number of talents - for id, nt in pairs(self.actor.talents_def) do - if nt.type[1] == t.type[1] then - d[id] = true --- print("Talent deps: ", t.id, "same category as", id) - end - end -end - -function _M:generateList() - self.actor.__show_special_talents = self.actor.__show_special_talents or {} - - -- Makes up the list - local tree = {} - self.talents_deps = {} - for i, tt in ipairs(self.actor.talents_types_def) do - if not tt.hide and not (self.actor.talents_types[tt.type] == nil) then - local cat = tt.type:gsub("/.*", "") - local ttknown = self.actor:knowTalentType(tt.type) - local isgeneric = self.actor.talents_types_def[tt.type].generic - local tshown = (self.actor.__hidden_talent_types[tt.type] == nil and ttknown) or (self.actor.__hidden_talent_types[tt.type] ~= nil and not self.actor.__hidden_talent_types[tt.type]) - local node = { - name=function(item) return tstring{{"font", "bold"}, cat:capitalize().." / "..tt.name:capitalize() ..(" (%s)"):format((isgeneric and "generic" or "class")), {"font", "normal"}} end, - rawname=function(item) return cat:capitalize().." / "..tt.name:capitalize() ..(" (%s, mastery %.2f)"):format((isgeneric and "generic" or "class"), self.actor:getTalentTypeMastery(item.type)) end, - type=tt.type, - color=function(item) - return ((self.actor:knowTalentType(item.type) ~= self.actor_dup:knowTalentType(item.type)) or ((self.actor.__increased_talent_types[item.type] or 0) ~= (self.actor_dup.__increased_talent_types[item.type] or 0))) and {255, 215, 0} or self.actor:knowTalentType(item.type) and {0,200,0} or {175,175,175} - end, - shown = tshown, - status = function(item) return self.actor:knowTalentType(item.type) and tstring{{"font", "bold"}, {"color", 0x00, 0xFF, 0x00}, ("%.2f"):format(self.actor:getTalentTypeMastery(item.type)), {"font", "normal"}} or tstring{{"color", 0xFF, 0x00, 0x00}, "unknown"} end, - nodes = {}, - } - tree[#tree+1] = node - - local list = node.nodes - - -- Find all talents of this school - for j, t in ipairs(tt.talents) do - if not t.hide or self.actor.__show_special_talents[t.id] then - self:computeDeps(t) - local isgeneric = self.actor.talents_types_def[tt.type].generic - list[#list+1] = { - __id=t.id, - name=t.name, - rawname=t.name..(isgeneric and " (generic talent)" or " (class talent)"), - talent=t.id, - _type=tt.type, - color=function(item) return ((self.actor.talents[item.talent] or 0) ~= (self.actor_dup.talents[item.talent] or 0)) and {255, 215, 0} or self.actor:knowTalentType(item._type) and {255,255,255} or {175,175,175} end, - } - list[#list].status = function(item) - local t = self.actor:getTalentFromId(item.talent) - local ttknown = self.actor:knowTalentType(item._type) - if self.actor:getTalentLevelRaw(t.id) == t.points then - return tstring{{"color", 0x00, 0xFF, 0x00}, self.actor:getTalentLevelRaw(t.id).."/"..t.points} - else - if not self.actor:canLearnTalent(t) then - return tstring{(ttknown and {"color", 0xFF, 0x00, 0x00} or {"color", 0x80, 0x80, 0x80}), self.actor:getTalentLevelRaw(t.id).."/"..t.points} - else - return tstring{(ttknown and {"color", "WHITE"} or {"color", 0x80, 0x80, 0x80}), self.actor:getTalentLevelRaw(t.id).."/"..t.points} - end - end - end - end - end - end - end - self.tree = tree -end - -function _M:finish() - -- Go through all sustained spells - local reset = {} - for tid, act in pairs(self.actor.sustain_talents) do - if act then - local t = self.actor:getTalentFromId(tid) - if self.actor:getTalentLevelRaw(tid) ~= self.actor_dup:getTalentLevelRaw(tid) then - if t.no_sustain_autoreset then - game.logPlayer(self.actor, "#LIGHT_BLUE#Warning: You have increased your level in %s, but it cannot be auto-reactivated. The new level will only take effect when you re-use it.", t.name) - else - reset[#reset+1] = tid - end - end - end - end - for i, tid in ipairs(reset) do - self.actor:forceUseTalent(tid, {ignore_energy=true, ignore_cd=true, no_equilibrium_fail=true, no_paradox_fail=true}) - self.actor:forceUseTalent(tid, {ignore_energy=true, ignore_cd=true, no_equilibrium_fail=true, no_paradox_fail=true}) - end -end - -function _M:onDrawItem(item) - if not item then return end - local text = tstring{} - - text:add({"color", "GOLD"}, {"font", "bold"}, util.getval(item.rawname, item), {"color", "LAST"}, {"font", "normal"}) - text:add(true, true) - - if item.type then - text:add({"color",0x00,0xFF,0xFF}, "Talent Category", true) - text:add({"color",0x00,0xFF,0xFF}, "A talent category allows you to learn talents of this category. You gain a talent category point at level 10, 20 and 30. You may also find trainers or artifacts that allow you to learn more.\nA talent category point can be used either to learn a new category or increase the mastery of a known one.", true, true, {"color", "WHITE"}) - - if self.actor.talents_types_def[item.type].generic then - text:add({"color",0x00,0xFF,0xFF}, "Generic talent tree", true) - text:add({"color",0x00,0xFF,0xFF}, "A generic talent allows you to perform various utility actions and improve your character. It represents talents anybody can learn (should they find a trainer for it). You gain one point every level (except every 5th level). You may also find trainers or artifacts that allow you to learn more.", true, true, {"color", "WHITE"}) - else - text:add({"color",0x00,0xFF,0xFF}, "Class talent tree", true) - text:add({"color",0x00,0xFF,0xFF}, "A class talent allows you to perform new combat moves, cast spells, and improve your character. It represents the core function of your class. You gain one point every level and two every 5th level. You may also find trainers or artifacts that allow you to learn more.", true, true, {"color", "WHITE"}) - end - - text:add(self.actor:getTalentTypeFrom(item.type).description) - - else - local t = self.actor:getTalentFromId(item.talent) - - if self.actor:getTalentLevelRaw(t.id) > 0 then - local req = self.actor:getTalentReqDesc(item.talent, 0) - text:add{"color","WHITE"} - text:add({"font", "bold"}, "Current talent level: "..(self.actor:getTalentLevelRaw(t.id)), {"font", "normal"}) - text:add(true) - text:merge(req) - text:merge(self.actor:getTalentFullDescription(t)) - text:add(true,true) - end - - if self.actor:getTalentLevelRaw(t.id) < t.points then - local req2 = self.actor:getTalentReqDesc(item.talent, 1) - text:add({"font", "bold"}, "Next talent level: "..(self.actor:getTalentLevelRaw(t.id)+1), {"font", "normal"}) - text:add(true) - text:merge(req2) - text:merge(self.actor:getTalentFullDescription(t, 1)) - end - end - - self.c_desc:createItem(item, text) - -end - -function _M:select(item) - if not item or not self.uis or not self.uis[5] then return end - - if not self.c_desc:switchItem(item) then - self:onDrawItem(item) - self.c_desc:switchItem(item) - end -end - -function _M:treeSelect(item, sel, v) - if not item then return end - self:learn(v == "left" and true) - if item.nodes then - item.shown = (self.actor.__hidden_talent_types[item.type] == nil and self.actor:knowTalentType(item.type)) or (self.actor.__hidden_talent_types[item.type] ~= nil and not self.actor.__hidden_talent_types[item.type]) - self.c_tree:drawItem(item) - for i, n in ipairs(item.nodes) do self.c_tree:drawItem(n) end - elseif item.talent then - for tid, _ in pairs(self.talents_deps[item.talent] or {}) do - local it = self.c_tree.items_by_key[tid] - if it then self.c_tree:drawItem(it) end - end - end - self.c_desc:switchItem(item) - self.c_tree:outputList() - - self.c_points.text = _points_left:format(self.actor.unused_talents_types, self.actor.unused_talents, self.actor.unused_generics) - self.c_points:generate() -end - -function _M:learn(v) - local item = self.c_tree.list[self.c_tree.sel] - if not item then return end - if item.type then - self:learnType(item.type, v) - else - self:learnTalent(item.talent, v) - end -end - -function _M:checkDeps() - local talents = "" - for t_id, _ in pairs(self.talents_changed) do - local t = self.actor:getTalentFromId(t_id) - if not self.actor:canLearnTalent(t, 0) and self.actor:knowTalent(t) then talents = talents.."\n#GOLD##{bold}# - "..t.name.."#{normal}##LAST#" end - end - if talents ~="" then - return false, talents - else - return true - end -end - -function _M:learnTalent(t_id, v) - local t = self.actor:getTalentFromId(t_id) - if not t.generic then - if v then - if self.actor.unused_talents < 1 then - self:simplePopup("Not enough class talent points", "You have no class talent points left!") - return - end - if not self.actor:canLearnTalent(t) then - self:simplePopup("Cannot learn talent", "Prerequisites not met!") - return - end - if self.actor:getTalentLevelRaw(t_id) >= t.points then - self:simplePopup("Already known", "You already fully know this talent!") - return - end - self.actor:learnTalent(t_id) - self.actor.unused_talents = self.actor.unused_talents - 1 - self.talents_changed[t_id] = true - else - if not self.actor:knowTalent(t_id) then - self:simplePopup("Impossible", "You do not know this talent!") - return - end - if self.actor_dup:getTalentLevelRaw(t_id) == self.actor:getTalentLevelRaw(t_id) then - self:simplePopup("Impossible", "You cannot unlearn talents!") - return - end - self.actor:unlearnTalent(t_id) - local ok, dep_miss = self:checkDeps() - if ok then - self.actor.unused_talents = self.actor.unused_talents + 1 - else - self:simpleLongPopup("Impossible", "You cannot unlearn this talent because of talent(s): "..dep_miss, game.w * 0.4) - self.actor:learnTalent(t_id) - return - end - end - else - if v then - if self.actor.unused_generics < 1 then - self:simplePopup("Not enough generic talent points", "You have no generic talent points left!") - return - end - if not self.actor:canLearnTalent(t) then - self:simplePopup("Cannot learn talent", "Prerequisites not met!") - return - end - if self.actor:getTalentLevelRaw(t_id) >= t.points then - self:simplePopup("Already known", "You already fully know this talent!") - return - end - self.actor:learnTalent(t_id) - self.actor.unused_generics = self.actor.unused_generics - 1 - self.talents_changed[t_id] = true - else - if not self.actor:knowTalent(t_id) then - self:simplePopup("Impossible", "You do not know this talent!") - return - end - if self.actor_dup:getTalentLevelRaw(t_id) == self.actor:getTalentLevelRaw(t_id) then - self:simplePopup("Impossible", "You cannot unlearn talents!") - return - end - self.actor:unlearnTalent(t_id) - local ok, dep_miss = self:checkDeps() - if ok then - self.actor.unused_generics = self.actor.unused_generics + 1 - else - self:simpleLongPopup("Impossible", "You can not unlearn this talent because of talent(s): "..dep_miss, game.w * 0.4) - self.actor:learnTalent(t_id) - return - end - end - end -end - -function _M:learnType(tt, v) - if v 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!") - return - end - if self.actor.unused_talents_types <= 0 then - self:simplePopup("Not enough talent category points", "You have no category points left!") - return - end - if not self.actor:knowTalentType(tt) then - self.actor:learnTalentType(tt) - else - self.actor.__increased_talent_types[tt] = (self.actor.__increased_talent_types[tt] or 0) + 1 - self.actor:setTalentTypeMastery(tt, self.actor:getTalentTypeMastery(tt) + 0.2) - end - self.actor.unused_talents_types = self.actor.unused_talents_types - 1 - 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 - self:simplePopup("Impossible", "You cannot take out more points!") - return - 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 - self:simplePopup("Impossible", "You cannot unlearn this category!") - return - end - if not self.actor:knowTalentType(tt) then - self:simplePopup("Impossible", "You do not know this category!") - return - end - - if (self.actor.__increased_talent_types[tt] or 0) > 0 then - self.actor.__increased_talent_types[tt] = (self.actor.__increased_talent_types[tt] or 0) - 1 - self.actor:setTalentTypeMastery(tt, self.actor:getTalentTypeMastery(tt) - 0.2) - self.actor.unused_talents_types = self.actor.unused_talents_types + 1 - else - self.actor:unlearnTalentType(tt) - local ok, dep_miss = self:checkDeps() - if ok then - self.actor.unused_talents_types = self.actor.unused_talents_types + 1 - else - self:simpleLongPopup("Impossible", "You cannot unlearn this category because of: "..dep_miss, game.w * 0.4) - self.actor:learnTalentType(tt) - return - end - end - end -end diff --git a/src/core_lua.c b/src/core_lua.c index b60ac0b6eb..92fbfa8fa2 100644 --- a/src/core_lua.c +++ b/src/core_lua.c @@ -369,10 +369,10 @@ static int sdl_font_style_get(lua_State *L) TTF_Font **f = (TTF_Font**)auxiliar_checkclass(L, "sdl{font}", 1); int style = TTF_GetFontStyle(*f); - if (style & TTF_STYLE_BOLD) lua_pushstring(L, "bold"); - else if (style & TTF_STYLE_ITALIC) lua_pushstring(L, "italic"); - else if (style & TTF_STYLE_UNDERLINE) lua_pushstring(L, "underline"); - else lua_pushstring(L, "normal"); + if (style & TTF_STYLE_BOLD) lua_pushliteral(L, "bold"); + else if (style & TTF_STYLE_ITALIC) lua_pushliteral(L, "italic"); + else if (style & TTF_STYLE_UNDERLINE) lua_pushliteral(L, "underline"); + else lua_pushliteral(L, "normal"); return 1; } @@ -486,11 +486,11 @@ static int sdl_surface_drawstring_newsurface_aa(lua_State *L) return 1; } -static font_make_texture_line(lua_State *L, SDL_Surface *s, int id) +static font_make_texture_line(lua_State *L, SDL_Surface *s, int id, bool is_separator) { lua_createtable(L, 0, 5); - lua_pushstring(L, "_tex"); + lua_pushliteral(L, "_tex"); GLuint *t = (GLuint*)lua_newuserdata(L, sizeof(GLuint)); auxiliar_setclass(L, "gl{texture}", -1); lua_rawset(L, -3); @@ -501,20 +501,27 @@ static font_make_texture_line(lua_State *L, SDL_Surface *s, int id) make_texture_for_surface(s, &fw, &fh); copy_surface_to_texture(s); - lua_pushstring(L, "_tex_w"); + lua_pushliteral(L, "_tex_w"); lua_pushnumber(L, fw); lua_rawset(L, -3); - lua_pushstring(L, "_tex_h"); + lua_pushliteral(L, "_tex_h"); lua_pushnumber(L, fh); lua_rawset(L, -3); - lua_pushstring(L, "w"); + lua_pushliteral(L, "w"); lua_pushnumber(L, s->w); lua_rawset(L, -3); - lua_pushstring(L, "h"); + lua_pushliteral(L, "h"); lua_pushnumber(L, s->h); lua_rawset(L, -3); + if (is_separator) + { + lua_pushliteral(L, "is_separator"); + lua_pushboolean(L, TRUE); + lua_rawset(L, -3); + } + lua_rawseti(L, -2, id); } @@ -545,6 +552,7 @@ static int sdl_font_draw(lua_State *L) char *start = (char*)str, *stop = (char*)str, *next = (char*)str; int max_size = 0; int size = 0; + bool is_separator = FALSE; int i; bool force_nl = FALSE; SDL_Surface *txt = NULL; @@ -572,7 +580,8 @@ static int sdl_font_draw(lua_State *L) if (!no_linefeed && (force_nl || (txt && (size + txt->w > max_width)))) { // Push it & reset the surface - font_make_texture_line(L, s, nb_lines); + font_make_texture_line(L, s, nb_lines, is_separator); + is_separator = FALSE; SDL_FillRect(s, NULL, SDL_MapRGBA(s->format, 0, 0, 0, 0)); // printf("Ending previous line at size %d\n", size); if (size > max_size) max_size = size; @@ -583,6 +592,9 @@ static int sdl_font_draw(lua_State *L) if (txt) { + // Detect separators + if ((*start == '-') && (*(start+1) == '-') && (*(start+2) == '-') && !(*(start+3))) is_separator = TRUE; + // printf("Drawing word '%s'\n", start); SDL_SetAlpha(txt, 0, 0); sdlDrawImage(s, txt, size, 0); @@ -642,13 +654,13 @@ static int sdl_font_draw(lua_State *L) g = color.g; b = color.b; - lua_pushstring(L, "r"); + lua_pushliteral(L, "r"); lua_rawget(L, -2); color.r = lua_tonumber(L, -1); - lua_pushstring(L, "g"); + lua_pushliteral(L, "g"); lua_rawget(L, -3); color.g = lua_tonumber(L, -1); - lua_pushstring(L, "b"); + lua_pushliteral(L, "b"); lua_rawget(L, -4); color.b = lua_tonumber(L, -1); lua_pop(L, 3); @@ -703,7 +715,7 @@ static int sdl_font_draw(lua_State *L) next++; } - font_make_texture_line(L, s, nb_lines); + font_make_texture_line(L, s, nb_lines, is_separator); if (size > max_size) max_size = size; if (txt) SDL_FreeSurface(txt); @@ -1809,11 +1821,11 @@ static int sdl_get_modes_list(lua_State *L) lua_pushnumber(L, nb++); lua_newtable(L); - lua_pushstring(L, "w"); + lua_pushliteral(L, "w"); lua_pushnumber(L, modes[i]->w); lua_settable(L, -3); - lua_pushstring(L, "h"); + lua_pushliteral(L, "h"); lua_pushnumber(L, modes[i]->h); lua_settable(L, -3); @@ -2411,7 +2423,7 @@ int luaopen_core(lua_State *L) luaL_openlib(L, "core.zlib", zliblib, 0); luaL_openlib(L, "core.game", gamelib, 0); - lua_pushstring(L, "VERSION"); + lua_pushliteral(L, "VERSION"); lua_pushnumber(L, TE4CORE_VERSION); lua_settable(L, -3); -- GitLab