diff --git a/game/modules/tome/class/Object.lua b/game/modules/tome/class/Object.lua index f0ae2465802f23afd616ff672e65a4e567edae28..9305598c68b2909555e3f4fe028c0dff478c7b28 100644 --- a/game/modules/tome/class/Object.lua +++ b/game/modules/tome/class/Object.lua @@ -149,21 +149,9 @@ function _M:getName(t) end end ---- Gets the full desc of the object -function _M:getDesc() - local _, c = self:getDisplayColor() - local desc - if not self:isIdentified() then - desc = { c..self:getName().."#FFFFFF#" } - else - desc = { c..self:getName().."#FFFFFF#", self.desc } - end - - local reqs = self:getRequirementDesc(game.player) - if reqs then - desc[#desc+1] = reqs - end - +--- Gets the full textual desc of the object without the name and requirements +function _M:getTextualDesc() + local desc = {} if self.encumber then desc[#desc+1] = ("#67AD00#%0.2f Encumbrance."):format(self.encumber) end @@ -287,7 +275,27 @@ function _M:getDesc() local use_desc = self:getUseDesc() if use_desc then desc[#desc+1] = use_desc end - return table.concat(desc, "\n") + return table.concat(desc, "\n ") +end + +--- Gets the full desc of the object +function _M:getDesc() + local _, c = self:getDisplayColor() + local desc + if not self:isIdentified() then + desc = { c..self:getName().."#FFFFFF#" } + else + desc = { c..self:getName().."#FFFFFF#", self.desc } + end + + local reqs = self:getRequirementDesc(game.player) + if reqs then + desc[#desc+1] = reqs + end + + local textdesc = self:getTextualDesc() + + return table.concat(desc, "\n").."\n"..textdesc end local type_sort = { diff --git a/game/modules/tome/class/PlayerDisplay.lua b/game/modules/tome/class/PlayerDisplay.lua index d05036b60d8f3601df506605ab83d55a13ec0162..0100ece545ed4a7f5154e6927055c734528c2e06 100644 --- a/game/modules/tome/class/PlayerDisplay.lua +++ b/game/modules/tome/class/PlayerDisplay.lua @@ -96,5 +96,18 @@ function _M:display() self.surface:drawColorStringBlended(self.font, ("#7fffd4#Negative:#ffffff#%d/%d"):format(game.player:getNegative(), game.player.max_negative), 0, h, 255, 255, 255) h = h + self.font_h end + h = h + self.font_h + for tid, act in pairs(game.player.sustain_talents) do + if act then self.surface:drawColorStringBlended(self.font, ("#LIGHT_GREEN#%s"):format(game.player:getTalentFromId(tid).name), 0, h, 255, 255, 255) h = h + self.font_h end + end + for eff_id, p in pairs(game.player.tmp) do + local e = game.player.tempeffect_def[eff_id] + if e.status == "detrimental" then + self.surface:drawColorStringBlended(self.font, ("#LIGHT_RED#%s"):format(e.desc), 0, h, 255, 255, 255) h = h + self.font_h + else + self.surface:drawColorStringBlended(self.font, ("#LIGHT_GREEN#%s"):format(e.desc), 0, h, 255, 255, 255) h = h + self.font_h + end + end + return self.surface end diff --git a/game/modules/tome/class/interface/Combat.lua b/game/modules/tome/class/interface/Combat.lua index 827023adac1da82b2fe2b5f5987ceaab27897a60..c05f2feff1fcc7f282e19b7844ebf8f9107dfdac 100644 --- a/game/modules/tome/class/interface/Combat.lua +++ b/game/modules/tome/class/interface/Combat.lua @@ -467,7 +467,7 @@ function _M:combatDamage(weapon) end local talented_mod = math.sqrt(self:combatCheckTraining(weapon) / 10) + 1 - local power = self.combat_dam + (weapon.dam or 1) + add + local power = math.min(self.combat_dam + (weapon.dam or 1) + add, 1) power = (math.sqrt(power / 10) - 1) * 0.8 + 1 print(("[COMBAT DAMAGE] power(%f) totstat(%f) talent_mod(%f)"):format(power, totstat, talented_mod)) return totstat / 1.5 * power * talented_mod diff --git a/game/modules/tome/dialogs/CharacterSheet.lua b/game/modules/tome/dialogs/CharacterSheet.lua index ecbce7a1993b099b036b5eeeffd307e6372f19f4..0b199e67327d469426d302b57d7ca795914c4c5d 100644 --- a/game/modules/tome/dialogs/CharacterSheet.lua +++ b/game/modules/tome/dialogs/CharacterSheet.lua @@ -164,54 +164,82 @@ function _M:dump() fs.mkdir("/character-dumps") 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 + --prepare label and value + local makelabel = function(s,r) while s:len() < labelwidth do s = s.." " end return ("%s: %s"):format(s, r) end - nl("Sex: "..game.player.descriptor.sex) - nl("Race: "..game.player.descriptor.subrace) - nl("Class: "..game.player.descriptor.subclass) - nl("Level: "..game.player.level) - - nl() local cur_exp, max_exp = game.player.exp, game.player:getExpChart(game.player.level+1) - nl(("Exp: %2d%%"):format(100 * cur_exp / max_exp)) - nl(("Gold: %0.2f"):format(game.player.money)) + nl(" [Tome 4.00 @ www.te4.org Character Dump]") + nl() + + nnl(("%-32s"):format(makelabel("Sex", game.player.descriptor.sex))) + nl(("STR: %d"):format(game.player:getStr())) + + nnl(("%-32s"):format(makelabel("Race", game.player.descriptor.subrace))) + nl(("DEX: %d"):format(game.player:getDex())) + + nnl(("%-32s"):format(makelabel("Class", game.player.descriptor.subclass))) + nl(("MAG: %d"):format(game.player:getMag())) + + nnl(("%-32s"):format(makelabel("Level", ("%d"):format(game.player.level)))) + nl(("WIL: %d"):format(game.player:getWil())) + + 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)))) + nl(("CON: %d"):format(game.player:getCon())) + + -- All weapons in main hands + + local strings = {} + for i = 1, 5 do strings[i]="" end + if self.actor:getInven(self.actor.INVEN_MAINHAND) then + for i, o in ipairs(self.actor:getInven(self.actor.INVEN_MAINHAND)) do + if o.combat then + strings[1] = ("Attack(Main Hand): %3d"):format(game.player:combatAttack(o.combat)) + strings[2] = ("Damage(Main Hand): %3d"):format(game.player:combatDamage(o.combat)) + strings[3] = ("APR (Main Hand): %3d"):format(game.player:combatAPR(o.combat)) + strings[4] = ("Crit (Main Hand): %3d%%"):format(game.player:combatCrit(o.combat)) + strings[5] = ("Speed (Main Hand): %0.2f"):format(game.player:combatSpeed(o.combat)) + end + end + end + + local enc, max = game.player:getEncumbrance(), game.player:getMaxEncumbrance() nl() - nl(("Life: %d/%d"):format(game.player.life, game.player.max_life)) + nnl(("%-32s"):format(strings[1])) + nnl(("%-32s"):format(makelabel("Life", (" %d/%d"):format(game.player.life, game.player.max_life)))) + nl(makelabel("Encumbrance", enc .. "/" .. max)) + + nnl(("%-32s"):format(strings[2])) if game.player:knowTalent(game.player.T_STAMINA_POOL) then - nl(("Stamina: %d/%d"):format(game.player:getStamina(), game.player.max_stamina)) + nnl(("%-32s"):format(makelabel("Stamina", (" %d/%d"):format(game.player:getStamina(), game.player.max_stamina)))) + else + nnl(("%-32s"):format(" ")) end + nl(makelabel("Difficulty", game.player.descriptor.difficulty)) + + nnl(("%-32s"):format(strings[3])) if game.player:knowTalent(game.player.T_MANA_POOL) then - nl(("Mana: %d/%d"):format(game.player:getMana(), game.player.max_mana)) + nl(makelabel("Mana", (" %d/%d"):format(game.player:getMana(), game.player.max_mana))) + else + nl() end + nnl(("%-32s"):format(strings[4])) if game.player:knowTalent(game.player.T_SOUL_POOL) then - nl(("Soul: %d/%d"):format(game.player:getSoul(), game.player.max_soul)) + nl(makelabel("Soul", (" %d/%d"):format(game.player:getSoul(), game.player.max_soul))) + else + nl() end + nnl(("%-32s"):format(strings[5])) if game.player:knowTalent(game.player.T_EQUILIBRIUM_POOL) then - nl(("Equi: %d"):format(game.player:getEquilibrium())) - end - - nl() - nl(("STR: %3d"):format(game.player:getStr())) - nl(("DEX: %3d"):format(game.player:getDex())) - nl(("MAG: %3d"):format(game.player:getMag())) - nl(("WIL: %3d"):format(game.player:getWil())) - nl(("CUN: %3d"):format(game.player:getCun())) - nl(("CON: %3d"):format(game.player:getCon())) - - -- All weapons in main hands - if self.actor:getInven(self.actor.INVEN_MAINHAND) then - for i, o in ipairs(self.actor:getInven(self.actor.INVEN_MAINHAND)) do - if o.combat then - nl() - nl(("Attack(Main Hand): %3d"):format(game.player:combatAttack(o.combat))) - nl(("Damage(Main Hand): %3d"):format(game.player:combatDamage(o.combat))) - nl(("APR (Main Hand): %3d"):format(game.player:combatAPR(o.combat))) - nl(("Crit (Main Hand): %3d%%"):format(game.player:combatCrit(o.combat))) - nl(("Speed (Main Hand): %0.2f"):format(game.player:combatSpeed(o.combat))) - end - end + nl((makelabel("Equilibrium", (" %d"):format(game.player:getEquilibrium())))) + else + nl() end -- All wpeaons in off hands @@ -226,35 +254,34 @@ function _M:dump() nl() nl(("Attack (Off Hand): %3d"):format(game.player:combatAttack(o.combat))) nl(("Damage (Off Hand): %3d"):format(game.player:combatDamage(o.combat) * offmult)) - nl(("APR (Off Hand): %3d"):format(game.player:combatAPR(o.combat))) - nl(("Crit (Off Hand): %3d%%"):format(game.player:combatCrit(o.combat))) + nl(("APR (Off Hand): %3d"):format(game.player:combatAPR(o.combat))) + nl(("Crit (Off Hand): %3d%%"):format(game.player:combatCrit(o.combat))) nl(("Speed (Off Hand): %0.2f"):format(game.player:combatSpeed(o.combat))) end end end nl() - nl(("Spellpower: %3d"):format(game.player:combatSpellpower())) - nl(("Spell Crit: %3d%%"):format(game.player:combatSpellCrit())) - nl(("Spell Speed: %3d"):format(game.player:combatSpellSpeed())) + nnl(("%-32s"):format(makelabel("Fatigue", game.player.fatigue .. "%"))) + nl(makelabel("Spellpower", game.player:combatSpellpower() .."")) + nnl(("%-32s"):format(makelabel("Armor", game.player:combatArmor() .. ""))) + nl(makelabel("Spell Crit", game.player:combatSpellCrit() .."%")) + nnl(("%-32s"):format(makelabel("Class", game.player:combatDefense() .. ""))) + nl(makelabel("Spell Speed", game.player:combatSpellSpeed() .."")) + nnl(("%-32s"):format(makelabel("Class", game.player:combatDefenseRanged() .. ""))) + nl() nl() for i, t in ipairs(DamageType.dam_def) do if self.actor.inc_damage[DamageType[t.type]] and self.actor.inc_damage[DamageType[t.type]] ~= 0 then - nl(("%s damage: %3d%%"):format(t.name:capitalize(), self.actor.inc_damage[DamageType[t.type]])) + nl(makelabel(t.name:capitalize().." damage", self.actor.inc_damage[DamageType[t.type]].."%")) end end nl() - nl(("Fatigue: %3d%%"):format(game.player.fatigue)) - nl(("Armor: %3d"):format(game.player:combatArmor())) - nl(("Defense: %3d"):format(game.player:combatDefense())) - nl(("Ranged Defense: %3d"):format(game.player:combatDefenseRanged())) - - nl() - nl(("Physical Resist: %3d"):format(game.player:combatPhysicalResist())) - nl(("Spell Resist: %3d"):format(game.player:combatSpellResist())) - nl(("Mental Resist: %3d"):format(game.player:combatMentalResist())) + nl(makelabel("Physical Resist",game.player:combatPhysicalResist() .."")) + nl(makelabel("Spell Resist",game.player:combatSpellResist() .."")) + nl(makelabel("Mental Resist",game.player:combatMentalResist() .."")) nl() for i, t in ipairs(DamageType.dam_def) do @@ -273,6 +300,112 @@ function _M:dump() nl(("Number of NPC killed: %s"):format(total_kill)) nl(("Most killed NPC: %s (%d)"):format(most_kill, most_kill_max)) + --Talents and skills + nl() + nl(" [Talents/Skills Chart]") + nl() + + for i, tt in ipairs(self.actor.talents_types_def) do + local ttknown = self.actor:knowTalentType(tt.type) + if not (self.actor.talents_types[tt.type] == nil) and ttknown then + local cat = tt.type:gsub("/.*", "") + local catname = ("%s / %s"):format(cat:capitalize(), tt.name:capitalize()) + nl((" - %-35s(mastery %.02f)"):format(catname, self.actor:getTalentTypeMastery(tt.type))) + + -- Find all talents of this school + if (ttknown) then + for j, t in ipairs(tt.talents) do + if not t.hide then + local typename = "talent" + if t.skill then typename = "skill" end + local skillname = (" %s (%s)"):format(t.name, typename) + nl(("%-37s %d/%d"):format(skillname, self.actor:getTalentLevelRaw(t.id), t.points)) + end + end + end + end + end + + -- Current Effects + + nl() + nl(" [Current Effects]") + nl() + + for tid, act in pairs(game.player.sustain_talents) do + if act then nl("- "..game.player:getTalentFromId(tid).name) end + end + for eff_id, p in pairs(game.player.tmp) do + local e = game.player.tempeffect_def[eff_id] + if e.status == "detrimental" then + nl("+ "..e.desc) + else + nl("- "..e.desc) + end + end + + -- Quests, Active and Completed + + 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("#.-#", " ")) + end + end + + first=true + for id, q in pairs(self.actor.quests or {}) do + if not q:isEnded() then + if first then + first=false + nl() + nl(" [Active Quests]") + nl() + end + nl(" -- ".. q.name) + nl(q:desc(self.actor):gsub("#.-#", " ")) + end + end + + + --All Equipment + nl() + nl(" [Character Equipment]") + nl() + local index = 0 + for inven_id = 1, #self.actor.inven_def do + if self.actor.inven[inven_id] and self.actor.inven_def[inven_id].is_worn then + nl((" %s"):format(self.actor.inven_def[inven_id].name)) + + for item, o in ipairs(self.actor.inven[inven_id]) do + if not self.filter or self.filter(o) then + local char = string.char(string.byte('a') + index) + nl(("%s) %s"):format(char, o:getName{force_id=true})) + nl((" %s"):format(o:getTextualDesc())) + index = index + 1 + end + end + end + end + + nl() + nl(" [Character Inventory]") + nl() + for item, o in ipairs(self.actor:getInven("INVEN")) do + if not self.filter or self.filter(o) then + local char = string.char(string.byte('a') + item - 1) + nl(("%s) %s"):format(char, o:getName{force_id=true})) + nl((" %s"):format(o:getTextualDesc())) + end + end + fff:close() Dialog:simplePopup("Character dump complete", "File: "..fs.getRealPath(file))