From fdae9c6030a835a31bcf8bdfdb9c05334aa71648 Mon Sep 17 00:00:00 2001 From: dg <dg@51575b47-30f0-44d4-a5cc-537603b46e54> Date: Sat, 28 Aug 2010 12:03:47 +0000 Subject: [PATCH] Improved character sheet (displays some more resistances and betetr char dump) git-svn-id: http://svn.net-core.org/repos/t-engine4@1090 51575b47-30f0-44d4-a5cc-537603b46e54 --- game/engine/utils.lua | 8 +- game/modules/tome/class/Actor.lua | 2 +- game/modules/tome/class/Player.lua | 3 +- game/modules/tome/class/PlayerDisplay.lua | 4 +- game/modules/tome/data/texts/win.lua | 5 + .../tome/data/zones/grushnak-pride/npcs.lua | 5 +- .../tome/data/zones/high-peak/grids.lua | 1 + game/modules/tome/dialogs/CharacterSheet.lua | 107 ++++++++++++++---- ideas/quests.ods | Bin 11050 -> 11398 bytes 9 files changed, 104 insertions(+), 31 deletions(-) diff --git a/game/engine/utils.lua b/game/engine/utils.lua index 69bc2f099b..0bec443bec 100644 --- a/game/engine/utils.lua +++ b/game/engine/utils.lua @@ -164,6 +164,10 @@ local Pcode = (lpeg.R"af" + lpeg.R"09" + lpeg.R"AF") local Pcolorcode = Pcode * Pcode local Pcolorcodefull = Pcolorcode * Pcolorcode * Pcolorcode +function string.removeColorCodes(str) + return str:lpegSub("#" * (Puid + Pcolorcodefull + Pcolorname) * "#", "") +end + function string.splitLine(str, max_width, font) local space_w = font:size(" ") local lines = {} @@ -263,7 +267,7 @@ getmetatable(tmps).__index.drawColorString = function(s, font, str, x, y, r, g, oldr, oldg, oldb = r, g, b r, g, b = colors[col].r, colors[col].g, colors[col].b end - elseif uid and mo then + elseif uid and mo and game.level then uid = tonumber(uid) mo = tonumber(mo) local e = __uids[uid] @@ -312,7 +316,7 @@ getmetatable(tmps).__index.drawColorStringBlended = function(s, font, str, x, y, oldr, oldg, oldb = r, g, b r, g, b = colors[col].r, colors[col].g, colors[col].b end - elseif uid and mo then + elseif uid and mo and game.level then uid = tonumber(uid) mo = tonumber(mo) local e = __uids[uid] diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua index 9543a40127..21e1306c6f 100644 --- a/game/modules/tome/class/Actor.lua +++ b/game/modules/tome/class/Actor.lua @@ -642,7 +642,7 @@ function _M:die(src) end -- Increase vim - if src and src:attr("vim_on_death") and not self:attr("undead") then src:incVim(src:attr("vim_on_death")) end + if src and src.attr and src:attr("vim_on_death") and not self:attr("undead") then src:incVim(src:attr("vim_on_death")) end if src and src.resolveSource and src:resolveSource().player then -- Achievements diff --git a/game/modules/tome/class/Player.lua b/game/modules/tome/class/Player.lua index 43611b7075..fca5e77902 100644 --- a/game/modules/tome/class/Player.lua +++ b/game/modules/tome/class/Player.lua @@ -589,6 +589,7 @@ function _M:useOrbPortal(portal) local ok = false self:restInit(20, "using the portal", "used the poral", function(cnt, max) if cnt > max then ok = true end + print("*********** portaling one turn", ok) coroutine.resume(co) end) coroutine.yield() @@ -598,7 +599,7 @@ function _M:useOrbPortal(portal) end return true end --- if not wait() then return end + if not wait() then return end if portal.teleport_level then local x, y = util.findFreeGrid(portal.teleport_level.x, portal.teleport_level.y, 2, true, {[Map.ACTOR]=true}) diff --git a/game/modules/tome/class/PlayerDisplay.lua b/game/modules/tome/class/PlayerDisplay.lua index 30967e803c..ab1283c070 100644 --- a/game/modules/tome/class/PlayerDisplay.lua +++ b/game/modules/tome/class/PlayerDisplay.lua @@ -104,8 +104,8 @@ function _M:display() self.surface:drawColorStringBlended(self.font, ("#7fffd4#Negative:#ffffff#%d/%d"):format(player:getNegative(), player.max_negative), 0, h, 255, 255, 255) h = h + self.font_h end if player:knowTalent(player.T_VIM_POOL) then - self.surface:erase(0xff / 6, 0xcc / 6, 0x80 / 6, 255, self.bars_x, h, self.bars_w, self.font_h) - self.surface:erase(0xff / 3, 0xcc / 3, 0x80 / 3, 255, self.bars_x, h, self.bars_w * player:getVim() / player.max_vim, self.font_h) + self.surface:erase(0x90 / 6, 0x40 / 6, 0x10 / 6, 255, self.bars_x, h, self.bars_w, self.font_h) + self.surface:erase(0x90 / 3, 0x40 / 3, 0x10 / 3, 255, self.bars_x, h, self.bars_w * player:getVim() / player.max_vim, self.font_h) self.surface:drawColorStringBlended(self.font, ("#904010#Vim: #ffffff#%d/%d"):format(player:getVim(), player.max_vim), 0, h, 255, 255, 255) h = h + self.font_h end diff --git a/game/modules/tome/data/texts/win.lua b/game/modules/tome/data/texts/win.lua index e6edae43f7..f3c4bd48f0 100644 --- a/game/modules/tome/data/texts/win.lua +++ b/game/modules/tome/data/texts/win.lua @@ -34,6 +34,9 @@ end if game.player:isQuestStatus("high-peak", engine.Quest.COMPLETED, "gates-of-morning-destroyed") then desc[#desc+1] = "" desc[#desc+1] = "The Gates of Morning have been destroyed and the Sunwall has fallen, the last remnants of the free people in the Far East will surely disminish and soon only orcs will inhabit this land." +else + desc[#desc+1] = "" + desc[#desc+1] = "The orc presence in the Far East has greatly been disminished by the loss of their leaders and the destruction of the Istari. The free people of the Sunwall will be able to prosper and thrive on this land." end desc[#desc+1] = "" @@ -44,4 +47,6 @@ if game.player.winner ~= "self-sacrifice" then desc[#desc+1] = "You may continue playing and enjoy the rest of the world." end +game.player.winner_text = desc + return table.concat(desc, "\n") diff --git a/game/modules/tome/data/zones/grushnak-pride/npcs.lua b/game/modules/tome/data/zones/grushnak-pride/npcs.lua index 30a88e259c..578dd75220 100644 --- a/game/modules/tome/data/zones/grushnak-pride/npcs.lua +++ b/game/modules/tome/data/zones/grushnak-pride/npcs.lua @@ -51,8 +51,9 @@ newEntity{ base="BASE_NPC_ORC_GRUSHNAK", define_as = "GRUSHNAK", {type="armor", subtype="massive", ego_chance=100, autoreq=true}, {type="armor", subtype="head", ego_chance=100, autoreq=true}, {type="armor", subtype="feet", ego_chance=100, autoreq=true}, - {type="jewelry", subtype="amulet", ego_chance=100, autoreq=true}, - {type="jewelry", subtype="ring", ego_chance=100, autoreq=true}, +-- Commented because this can generate rings of invis or amulets of telepathy and drain the life of the boss +-- {type="jewelry", subtype="amulet", ego_chance=100, autoreq=true}, +-- {type="jewelry", subtype="ring", ego_chance=100, autoreq=true}, {type="jewelry", subtype="ring", defined="PRIDE_GLORY", autoreq=true}, }, resolvers.drops{chance=100, nb=5, {ego_chance=100} }, diff --git a/game/modules/tome/data/zones/high-peak/grids.lua b/game/modules/tome/data/zones/high-peak/grids.lua index b8e1190ef7..9599b81964 100644 --- a/game/modules/tome/data/zones/high-peak/grids.lua +++ b/game/modules/tome/data/zones/high-peak/grids.lua @@ -75,6 +75,7 @@ This one seems to go to an unknown place, seemingly out of this world. You dare } local invocation_close = function(self, who) + if not who:hasQuest("high-peak") or who:hasQuest("high-peak"):isCompleted() then return end game.logPlayer(who, "#LIGHT_BLUE#You use the orb on the portal, shutting it down easily.") -- Remove the level spot local spot = game.level:pickSpot{type="portal", subtype=self.summon} diff --git a/game/modules/tome/dialogs/CharacterSheet.lua b/game/modules/tome/dialogs/CharacterSheet.lua index 1565624384..5744d85b56 100644 --- a/game/modules/tome/dialogs/CharacterSheet.lua +++ b/game/modules/tome/dialogs/CharacterSheet.lua @@ -64,8 +64,14 @@ function _M:drawDialog(s) if game.player:knowTalent(game.player.T_MANA_POOL) then s:drawColorStringBlended(self.font, ("#7fffd4#Mana: #00ff00#%d/%d"):format(game.player:getMana(), game.player.max_mana), w, h, 255, 255, 255) h = h + self.font_h end - if game.player:knowTalent(game.player.T_SOUL_POOL) then - s:drawColorStringBlended(self.font, ("#777777#Soul: #00ff00#%d/%d"):format(game.player:getSoul(), game.player.max_soul), w, h, 255, 255, 255) h = h + self.font_h + if game.player:knowTalent(game.player.T_POSITIVE_POOL) then + s:drawColorStringBlended(self.font, ("#7fffd4#Positive:#00ff00#%d/%d"):format(game.player:getPositive(), game.player.max_positive), w, h, 255, 255, 255) h = h + self.font_h + end + if game.player:knowTalent(game.player.T_NEGATIVE_POOL) then + s:drawColorStringBlended(self.font, ("#7fffd4#Negative:#00ff00#%d/%d"):format(game.player:getNegative(), game.player.max_negative), w, h, 255, 255, 255) h = h + self.font_h + end + if game.player:knowTalent(game.player.T_VIM_POOL) then + s:drawColorStringBlended(self.font, ("#904010#Vim: #00ff00#%d/%d"):format(game.player:getVim(), game.player.max_vim), w, h, 255, 255, 255) h = h + self.font_h end if game.player:knowTalent(game.player.T_EQUILIBRIUM_POOL) then s:drawColorStringBlended(self.font, ("#00ff74#Equi: #00ff00#%d"):format(game.player:getEquilibrium()), w, h, 255, 255, 255) h = h + self.font_h @@ -144,6 +150,20 @@ function _M:drawDialog(s) end end + immune_type = "poison_immune" immune_name = "Poison Resistance" if self.actor:attr(immune_type) then s:drawColorStringBlended(self.font, ("%s: #00ff00#%3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100)), w, h, 255, 255, 255) h = h + self.font_h end + immune_type = "cut_immune" immune_name = "Bleed Resistance" if self.actor:attr(immune_type) then s:drawColorStringBlended(self.font, ("%s: #00ff00#%3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100)), w, h, 255, 255, 255) h = h + self.font_h end + immune_type = "confusion_immune" immune_name = "Confusion Resistance" if self.actor:attr(immune_type) then s:drawColorStringBlended(self.font, ("%s: #00ff00#%3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100)), w, h, 255, 255, 255) h = h + self.font_h end + immune_type = "blind_immune" immune_name = "Blind Resistance" if self.actor:attr(immune_type) then s:drawColorStringBlended(self.font, ("%s: #00ff00#%3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100)), w, h, 255, 255, 255) h = h + self.font_h end + immune_type = "silence_immune" immune_name = "Silence Resistance" if self.actor:attr(immune_type) then s:drawColorStringBlended(self.font, ("%s: #00ff00#%3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100)), w, h, 255, 255, 255) h = h + self.font_h end + immune_type = "disarm_immune" immune_name = "Disarm Resistance" if self.actor:attr(immune_type) then s:drawColorStringBlended(self.font, ("%s: #00ff00#%3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100)), w, h, 255, 255, 255) h = h + self.font_h end + immune_type = "pin_immune" immune_name = "Pinning Resistance" if self.actor:attr(immune_type) then s:drawColorStringBlended(self.font, ("%s: #00ff00#%3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100)), w, h, 255, 255, 255) h = h + self.font_h end + immune_type = "stun_immune" immune_name = "Stun Resistance" if self.actor:attr(immune_type) then s:drawColorStringBlended(self.font, ("%s: #00ff00#%3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100)), w, h, 255, 255, 255) h = h + self.font_h end + immune_type = "fear_immune" immune_name = "Fear Resistance" if self.actor:attr(immune_type) then s:drawColorStringBlended(self.font, ("%s: #00ff00#%3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100)), w, h, 255, 255, 255) h = h + self.font_h end + immune_type = "knockback_immune" immune_name = "Knockback Resistance" if self.actor:attr(immune_type) then s:drawColorStringBlended(self.font, ("%s: #00ff00#%3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100)), w, h, 255, 255, 255) h = h + self.font_h end + immune_type = "stone_immune" immune_name = "Stoning Resistance" if self.actor:attr(immune_type) then s:drawColorStringBlended(self.font, ("%s: #00ff00#%3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100)), w, h, 255, 255, 255) h = h + self.font_h end + immune_type = "instakill_immune" immune_name = "Instadeath Resistance" if self.actor:attr(immune_type) then s:drawColorStringBlended(self.font, ("%s: #00ff00#%3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100)), w, h, 255, 255, 255) h = h + self.font_h end + immune_type = "teleport_immune" immune_name = "Teleport Resistance" if self.actor:attr(immune_type) then s:drawColorStringBlended(self.font, ("%s: #00ff00#%3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100)), w, h, 255, 255, 255) h = h + self.font_h end + h = 0 w = 600 s:drawColorStringBlended(self.font, "#LIGHT_BLUE#Current effects:", w, h, 255, 255, 255) h = h + self.font_h @@ -167,8 +187,8 @@ function _M:dump() local file = "/character-dumps/"..(game.player.name:gsub("[^a-zA-Z0-9_-.]", "_")).."-"..os.date("%Y%m%d-%H%M%S")..".txt" local fff = fs.open(file, "w") local labelwidth = 17 - local nl = function(s) fff:write(s or "") fff:write("\n") end - local nnl = function(s) fff:write(s or "") end + local nl = function(s) s = s or "" fff:write(s:removeColorCodes()) fff:write("\n") end + local nnl = function(s) s = s or "" fff:write(s:removeColorCodes()) end --prepare label and value local makelabel = function(s,r) while s:len() < labelwidth do s = s.." " end return ("%s: %s"):format(s, r) end @@ -191,7 +211,7 @@ function _M:dump() nnl(("%-32s"):format(makelabel("Exp", ("%d%%"):format(100 * cur_exp / max_exp)))) nl(("CUN: %d"):format(game.player:getCun())) - nnl(("%-32s"):format(makelabel("Gold", ("%.2f"):format(game.player.money)))) + nnl(("%-32s"):format(makelabel("Gold", ("%.2f"):format(game.player.money)))) nl(("CON: %d"):format(game.player:getCon())) -- All weapons in main hands @@ -232,9 +252,21 @@ function _M:dump() nl() end nnl(("%-32s"):format(strings[4])) - if game.player:knowTalent(game.player.T_SOUL_POOL) then - nl(makelabel("Soul", (" %d/%d"):format(game.player:getSoul(), game.player.max_soul))) - else + if game.player:knowTalent(game.player.T_POSITIVE_POOL) then + nl(makelabel("Positive", (" %d/%d"):format(game.player:getPositive(), game.player.max_positive))) + else + nl() + end + nnl(("%-32s"):format(strings[4])) + if game.player:knowTalent(game.player.T_NEGATIVE_POOL) then + nl(makelabel("Negative", (" %d/%d"):format(game.player:getNegative(), game.player.max_negative))) + else + nl() + end + nnl(("%-32s"):format(strings[4])) + if game.player:knowTalent(game.player.T_VIM_POOL) then + nl(makelabel("Vim", (" %d/%d"):format(game.player:getVim(), game.player.max_vim))) + else nl() end nnl(("%-32s"):format(strings[5])) @@ -294,6 +326,20 @@ function _M:dump() end end + immune_type = "poison_immune" immune_name = "Poison Resistance" if self.actor:attr(immune_type) then nl(("%s: %3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100))) end + immune_type = "cut_immune" immune_name = "Bleed Resistance" if self.actor:attr(immune_type) then nl(("%s: %3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100))) end + immune_type = "confusion_immune" immune_name = "Confusion Resistance" if self.actor:attr(immune_type) then nl(("%s: %3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100))) end + immune_type = "blind_immune" immune_name = "Blind Resistance" if self.actor:attr(immune_type) then nl(("%s: %3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100))) end + immune_type = "silence_immune" immune_name = "Silence Resistance" if self.actor:attr(immune_type) then nl(("%s: %3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100))) end + immune_type = "disarm_immune" immune_name = "Disarm Resistance" if self.actor:attr(immune_type) then nl(("%s: %3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100))) end + immune_type = "pin_immune" immune_name = "Pinning Resistance" if self.actor:attr(immune_type) then nl(("%s: %3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100))) end + immune_type = "stun_immune" immune_name = "Stun Resistance" if self.actor:attr(immune_type) then nl(("%s: %3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100))) end + immune_type = "fear_immune" immune_name = "Fear Resistance" if self.actor:attr(immune_type) then nl(("%s: %3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100))) end + immune_type = "knockback_immune" immune_name = "Knockback Resistance" if self.actor:attr(immune_type) then nl(("%s: %3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100))) end + immune_type = "stone_immune" immune_name = "Stoning Resistance" if self.actor:attr(immune_type) then nl(("%s: %3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100))) end + immune_type = "instakill_immune" immune_name = "Instadeath Resistance" if self.actor:attr(immune_type) then nl(("%s: %3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100))) end + immune_type = "teleport_immune" immune_name = "Teleport Resistance" if self.actor:attr(immune_type) then nl(("%s: %3d%%"):format(immune_name, util.bound(self.actor:attr(immune_type) * 100, 0, 100))) end + nl() local most_kill, most_kill_max = "none", 0 local total_kill = 0 @@ -304,6 +350,15 @@ function _M:dump() nl(("Number of NPC killed: %s"):format(total_kill)) nl(("Most killed NPC: %s (%d)"):format(most_kill, most_kill_max)) + if self.actor.winner then + nl() + nl(" [Winner!]") + nl() + for i, line in ipairs(self.actor.winner_text) do + nl(("%s"):format(line:removeColorCodes())) + end + end + -- Talents nl() nl(" [Talents Chart]") @@ -321,7 +376,7 @@ function _M:dump() for j, t in ipairs(tt.talents) do if not t.hide then local typename = "class" - if t.skill then typename = "generic" end + if t.generic then typename = "generic" end local skillname = (" %s (%s)"):format(t.name, typename) nl(("%-37s %d/%d"):format(skillname, self.actor:getTalentLevelRaw(t.id), t.points)) end @@ -353,14 +408,14 @@ function _M:dump() local first = true for id, q in pairs(self.actor.quests or {}) do if q:isEnded() then - if first then - nl() - nl(" [Completed Quests]") - nl() - first=false - end - nl(" -- ".. q.name) - nl(q:desc(self.actor):gsub("#.-#", " ")) + if first then + nl() + nl(" [Completed Quests]") + nl() + first=false + end + nl(" -- ".. q.name) + nl(q:desc(self.actor):gsub("#.-#", " ")) end end @@ -368,13 +423,13 @@ function _M:dump() for id, q in pairs(self.actor.quests or {}) do if not q:isEnded() then if first then - first=false - nl() + first=false + nl() nl(" [Active Quests]") - nl() + nl() end - nl(" -- ".. q.name) - nl(q:desc(self.actor):gsub("#.-#", " ")) + nl(" -- ".. q.name) + nl(q:desc(self.actor):gsub("#.-#", " ")) end end @@ -405,9 +460,15 @@ function _M:dump() nl() nl(" [Player Achievements]") nl() + local achs = {} for id, data in pairs(self.actor.achievements or {}) do local a = world:getAchievementFromId(id) - nl(("%s Was Achieved for %s At %s"):format(a.name,a.desc,data.when)) + achs[#achs+1] = {id=id, data=data, name=a.name} + end + table.sort(achs, function(a, b) return a.name < b.name end) + for i, d in ipairs(achs) do + local a = world:getAchievementFromId(d.id) + nl(("'%s' was wchieved for %s At %s"):format(a.name, a.desc, d.data.when)) end nl() diff --git a/ideas/quests.ods b/ideas/quests.ods index f25186fb83d30b7eec9d446a221eb99835a12174..629365d1c26c7860d211a1c30782846c8a0f47d9 100644 GIT binary patch delta 8219 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 MVL}c9|M~2H0PI_kb^rhX delta 7870 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 URyH#D40?zm8{-QG#=lAb4>hQ#BLDyZ -- GitLab