From 9bf34c6ae0055fa0272f2ecf2386394bb12259fe Mon Sep 17 00:00:00 2001 From: dg <dg@51575b47-30f0-44d4-a5cc-537603b46e54> Date: Sat, 4 Sep 2010 12:28:17 +0000 Subject: [PATCH] Fix character sheet for controlled summmons git-svn-id: http://svn.net-core.org/repos/t-engine4@1140 51575b47-30f0-44d4-a5cc-537603b46e54 --- game/modules/tome/dialogs/CharacterSheet.lua | 341 ++++++++++--------- ideas/worlds.ods | Bin 8198 -> 8438 bytes 2 files changed, 172 insertions(+), 169 deletions(-) diff --git a/game/modules/tome/dialogs/CharacterSheet.lua b/game/modules/tome/dialogs/CharacterSheet.lua index 5744d85b56..751c1ac6dd 100644 --- a/game/modules/tome/dialogs/CharacterSheet.lua +++ b/game/modules/tome/dialogs/CharacterSheet.lua @@ -43,135 +43,136 @@ function _M:init(actor) end function _M:drawDialog(s) - local cur_exp, max_exp = game.player.exp, game.player:getExpChart(game.player.level+1) + local player = self.actor + local cur_exp, max_exp = player.exp, player:getExpChart(player.level+1) local h = 0 local w = 0 - s:drawStringBlended(self.font, "Sex: "..game.player.descriptor.sex, w, h, 0, 200, 255) h = h + self.font_h - s:drawStringBlended(self.font, "Race: "..game.player.descriptor.subrace, w, h, 0, 200, 255) h = h + self.font_h - s:drawStringBlended(self.font, "Class: "..game.player.descriptor.subclass, w, h, 0, 200, 255) h = h + self.font_h + s:drawStringBlended(self.font, "Sex: "..(player.descriptor.sex or (player.female and "Female" or "Male")), w, h, 0, 200, 255) h = h + self.font_h + s:drawStringBlended(self.font, "Race: "..(player.descriptor.subrace or player.type:capitalize()), w, h, 0, 200, 255) h = h + self.font_h + s:drawStringBlended(self.font, "Class: "..(player.descriptor.subclass or player.subtype:capitalize()), w, h, 0, 200, 255) h = h + self.font_h h = h + self.font_h - s:drawColorStringBlended(self.font, "Level: #00ff00#"..game.player.level, w, h, 255, 255, 255) h = h + self.font_h + s:drawColorStringBlended(self.font, "Level: #00ff00#"..player.level, w, h, 255, 255, 255) h = h + self.font_h s:drawColorStringBlended(self.font, ("Exp: #00ff00#%2d%%"):format(100 * cur_exp / max_exp), w, h, 255, 255, 255) h = h + self.font_h - s:drawColorStringBlended(self.font, ("Gold: #00ff00#%0.2f"):format(game.player.money), w, h, 255, 255, 255) h = h + self.font_h + s:drawColorStringBlended(self.font, ("Gold: #00ff00#%0.2f"):format(player.money), w, h, 255, 255, 255) h = h + self.font_h h = h + self.font_h - s:drawColorStringBlended(self.font, ("#c00000#Life: #00ff00#%d/%d"):format(game.player.life, game.player.max_life), w, h, 255, 255, 255) h = h + self.font_h - if game.player:knowTalent(game.player.T_STAMINA_POOL) then - s:drawColorStringBlended(self.font, ("#ffcc80#Stamina: #00ff00#%d/%d"):format(game.player:getStamina(), game.player.max_stamina), w, h, 255, 255, 255) h = h + self.font_h + s:drawColorStringBlended(self.font, ("#c00000#Life: #00ff00#%d/%d"):format(player.life, player.max_life), w, h, 255, 255, 255) h = h + self.font_h + if player:knowTalent(player.T_STAMINA_POOL) then + s:drawColorStringBlended(self.font, ("#ffcc80#Stamina: #00ff00#%d/%d"):format(player:getStamina(), player.max_stamina), w, h, 255, 255, 255) h = h + self.font_h end - 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 + if player:knowTalent(player.T_MANA_POOL) then + s:drawColorStringBlended(self.font, ("#7fffd4#Mana: #00ff00#%d/%d"):format(player:getMana(), player.max_mana), w, h, 255, 255, 255) h = h + self.font_h end - 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 + if player:knowTalent(player.T_POSITIVE_POOL) then + s:drawColorStringBlended(self.font, ("#7fffd4#Positive:#00ff00#%d/%d"):format(player:getPositive(), 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 + if player:knowTalent(player.T_NEGATIVE_POOL) then + s:drawColorStringBlended(self.font, ("#7fffd4#Negative:#00ff00#%d/%d"):format(player:getNegative(), 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 + if player:knowTalent(player.T_VIM_POOL) then + s:drawColorStringBlended(self.font, ("#904010#Vim: #00ff00#%d/%d"):format(player:getVim(), 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 + if player:knowTalent(player.T_EQUILIBRIUM_POOL) then + s:drawColorStringBlended(self.font, ("#00ff74#Equi: #00ff00#%d"):format(player:getEquilibrium()), w, h, 255, 255, 255) h = h + self.font_h end h = h + self.font_h - s:drawColorStringBlended(self.font, ("STR: #00ff00#%3d"):format(game.player:getStr()), w, h, 255, 255, 255) h = h + self.font_h - s:drawColorStringBlended(self.font, ("DEX: #00ff00#%3d"):format(game.player:getDex()), w, h, 255, 255, 255) h = h + self.font_h - s:drawColorStringBlended(self.font, ("MAG: #00ff00#%3d"):format(game.player:getMag()), w, h, 255, 255, 255) h = h + self.font_h - s:drawColorStringBlended(self.font, ("WIL: #00ff00#%3d"):format(game.player:getWil()), w, h, 255, 255, 255) h = h + self.font_h - s:drawColorStringBlended(self.font, ("CUN: #00ff00#%3d"):format(game.player:getCun()), w, h, 255, 255, 255) h = h + self.font_h - s:drawColorStringBlended(self.font, ("CON: #00ff00#%3d"):format(game.player:getCon()), w, h, 255, 255, 255) h = h + self.font_h + s:drawColorStringBlended(self.font, ("STR: #00ff00#%3d"):format(player:getStr()), w, h, 255, 255, 255) h = h + self.font_h + s:drawColorStringBlended(self.font, ("DEX: #00ff00#%3d"):format(player:getDex()), w, h, 255, 255, 255) h = h + self.font_h + s:drawColorStringBlended(self.font, ("MAG: #00ff00#%3d"):format(player:getMag()), w, h, 255, 255, 255) h = h + self.font_h + s:drawColorStringBlended(self.font, ("WIL: #00ff00#%3d"):format(player:getWil()), w, h, 255, 255, 255) h = h + self.font_h + s:drawColorStringBlended(self.font, ("CUN: #00ff00#%3d"):format(player:getCun()), w, h, 255, 255, 255) h = h + self.font_h + s:drawColorStringBlended(self.font, ("CON: #00ff00#%3d"):format(player:getCon()), w, h, 255, 255, 255) h = h + self.font_h h = 0 w = 200 -- 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 player:getInven(player.INVEN_MAINHAND) then + for i, o in ipairs(player:getInven(player.INVEN_MAINHAND)) do if o.combat then - s:drawColorStringBlended(self.font, ("Attack(Main Hand): #00ff00#%3d"):format(game.player:combatAttack(o.combat)), w, h, 255, 255, 255) h = h + self.font_h - s:drawColorStringBlended(self.font, ("Damage(Main Hand): #00ff00#%3d"):format(game.player:combatDamage(o.combat)), w, h, 255, 255, 255) h = h + self.font_h - s:drawColorStringBlended(self.font, ("APR (Main Hand): #00ff00#%3d"):format(game.player:combatAPR(o.combat)), w, h, 255, 255, 255) h = h + self.font_h - s:drawColorStringBlended(self.font, ("Crit (Main Hand): #00ff00#%3d%%"):format(game.player:combatCrit(o.combat)), w, h, 255, 255, 255) h = h + self.font_h - s:drawColorStringBlended(self.font, ("Speed (Main Hand): #00ff00#%0.2f"):format(game.player:combatSpeed(o.combat)), w, h, 255, 255, 255) h = h + self.font_h + s:drawColorStringBlended(self.font, ("Attack(Main Hand): #00ff00#%3d"):format(player:combatAttack(o.combat)), w, h, 255, 255, 255) h = h + self.font_h + s:drawColorStringBlended(self.font, ("Damage(Main Hand): #00ff00#%3d"):format(player:combatDamage(o.combat)), w, h, 255, 255, 255) h = h + self.font_h + s:drawColorStringBlended(self.font, ("APR (Main Hand): #00ff00#%3d"):format(player:combatAPR(o.combat)), w, h, 255, 255, 255) h = h + self.font_h + s:drawColorStringBlended(self.font, ("Crit (Main Hand): #00ff00#%3d%%"):format(player:combatCrit(o.combat)), w, h, 255, 255, 255) h = h + self.font_h + s:drawColorStringBlended(self.font, ("Speed (Main Hand): #00ff00#%0.2f"):format(player:combatSpeed(o.combat)), w, h, 255, 255, 255) h = h + self.font_h end end end h = h + self.font_h -- All wpeaons in off hands -- Offhand atatcks are with a damage penality, taht can be reduced by talents - if self.actor:getInven(self.actor.INVEN_OFFHAND) then + if player:getInven(player.INVEN_OFFHAND) then local offmult = (mult or 1) / 2 - if self.actor:knowTalent(Talents.T_DUAL_WEAPON_TRAINING) then - offmult = (mult or 1) / (2 - (self.actor:getTalentLevel(Talents.T_DUAL_WEAPON_TRAINING) / 6)) + if player:knowTalent(Talents.T_DUAL_WEAPON_TRAINING) then + offmult = (mult or 1) / (2 - (player:getTalentLevel(Talents.T_DUAL_WEAPON_TRAINING) / 6)) end - for i, o in ipairs(self.actor:getInven(self.actor.INVEN_OFFHAND)) do + for i, o in ipairs(player:getInven(player.INVEN_OFFHAND)) do if o.combat then - s:drawColorStringBlended(self.font, ("Attack (Off Hand): #00ff00#%3d"):format(game.player:combatAttack(o.combat)), w, h, 255, 255, 255) h = h + self.font_h - s:drawColorStringBlended(self.font, ("Damage (Off Hand): #00ff00#%3d"):format(game.player:combatDamage(o.combat) * offmult), w, h, 255, 255, 255) h = h + self.font_h - s:drawColorStringBlended(self.font, ("APR (Off Hand): #00ff00#%3d"):format(game.player:combatAPR(o.combat)), w, h, 255, 255, 255) h = h + self.font_h - s:drawColorStringBlended(self.font, ("Crit (Off Hand): #00ff00#%3d%%"):format(game.player:combatCrit(o.combat)), w, h, 255, 255, 255) h = h + self.font_h - s:drawColorStringBlended(self.font, ("Speed (Off Hand): #00ff00#%0.2f"):format(game.player:combatSpeed(o.combat)), w, h, 255, 255, 255) h = h + self.font_h + s:drawColorStringBlended(self.font, ("Attack (Off Hand): #00ff00#%3d"):format(player:combatAttack(o.combat)), w, h, 255, 255, 255) h = h + self.font_h + s:drawColorStringBlended(self.font, ("Damage (Off Hand): #00ff00#%3d"):format(player:combatDamage(o.combat) * offmult), w, h, 255, 255, 255) h = h + self.font_h + s:drawColorStringBlended(self.font, ("APR (Off Hand): #00ff00#%3d"):format(player:combatAPR(o.combat)), w, h, 255, 255, 255) h = h + self.font_h + s:drawColorStringBlended(self.font, ("Crit (Off Hand): #00ff00#%3d%%"):format(player:combatCrit(o.combat)), w, h, 255, 255, 255) h = h + self.font_h + s:drawColorStringBlended(self.font, ("Speed (Off Hand): #00ff00#%0.2f"):format(player:combatSpeed(o.combat)), w, h, 255, 255, 255) h = h + self.font_h end end end h = h + self.font_h - s:drawColorStringBlended(self.font, ("Spellpower: #00ff00#%3d"):format(game.player:combatSpellpower()), w, h, 255, 255, 255) h = h + self.font_h - s:drawColorStringBlended(self.font, ("Spell Crit: #00ff00#%3d%%"):format(game.player:combatSpellCrit()), w, h, 255, 255, 255) h = h + self.font_h - s:drawColorStringBlended(self.font, ("Spell Speed: #00ff00#%3d"):format(game.player:combatSpellSpeed()), w, h, 255, 255, 255) h = h + self.font_h + s:drawColorStringBlended(self.font, ("Spellpower: #00ff00#%3d"):format(player:combatSpellpower()), w, h, 255, 255, 255) h = h + self.font_h + s:drawColorStringBlended(self.font, ("Spell Crit: #00ff00#%3d%%"):format(player:combatSpellCrit()), w, h, 255, 255, 255) h = h + self.font_h + s:drawColorStringBlended(self.font, ("Spell Speed: #00ff00#%3d"):format(player:combatSpellSpeed()), w, h, 255, 255, 255) h = h + self.font_h h = h + self.font_h - if self.actor.inc_damage.all then s:drawColorStringBlended(self.font, ("All damage: #00ff00#%3d%%"):format(self.actor.inc_damage.all), w, h, 255, 255, 255) h = h + self.font_h end + if player.inc_damage.all then s:drawColorStringBlended(self.font, ("All damage: #00ff00#%3d%%"):format(player.inc_damage.all), w, h, 255, 255, 255) h = h + self.font_h end 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 - s:drawColorStringBlended(self.font, ("%s damage: #00ff00#%3d%%"):format(t.name:capitalize(), self.actor.inc_damage[DamageType[t.type]]), w, h, 255, 255, 255) h = h + self.font_h + if player.inc_damage[DamageType[t.type]] and player.inc_damage[DamageType[t.type]] ~= 0 then + s:drawColorStringBlended(self.font, ("%s damage: #00ff00#%3d%%"):format(t.name:capitalize(), player.inc_damage[DamageType[t.type]]), w, h, 255, 255, 255) h = h + self.font_h end end h = 0 w = 400 - s:drawColorStringBlended(self.font, ("Fatigue: #00ff00#%3d%%"):format(game.player.fatigue), w, h, 255, 255, 255) h = h + self.font_h - s:drawColorStringBlended(self.font, ("Armor: #00ff00#%3d"):format(game.player:combatArmor()), w, h, 255, 255, 255) h = h + self.font_h - s:drawColorStringBlended(self.font, ("Defense: #00ff00#%3d"):format(game.player:combatDefense()), w, h, 255, 255, 255) h = h + self.font_h - s:drawColorStringBlended(self.font, ("Ranged Defense: #00ff00#%3d"):format(game.player:combatDefenseRanged()), w, h, 255, 255, 255) h = h + self.font_h + s:drawColorStringBlended(self.font, ("Fatigue: #00ff00#%3d%%"):format(player.fatigue), w, h, 255, 255, 255) h = h + self.font_h + s:drawColorStringBlended(self.font, ("Armor: #00ff00#%3d"):format(player:combatArmor()), w, h, 255, 255, 255) h = h + self.font_h + s:drawColorStringBlended(self.font, ("Defense: #00ff00#%3d"):format(player:combatDefense()), w, h, 255, 255, 255) h = h + self.font_h + s:drawColorStringBlended(self.font, ("Ranged Defense: #00ff00#%3d"):format(player:combatDefenseRanged()), w, h, 255, 255, 255) h = h + self.font_h h = h + self.font_h - s:drawColorStringBlended(self.font, ("Physical Save: #00ff00#%3d"):format(game.player:combatPhysicalResist()), w, h, 255, 255, 255) h = h + self.font_h - s:drawColorStringBlended(self.font, ("Spell Save: #00ff00#%3d"):format(game.player:combatSpellResist()), w, h, 255, 255, 255) h = h + self.font_h - s:drawColorStringBlended(self.font, ("Mental Save: #00ff00#%3d"):format(game.player:combatMentalResist()), w, h, 255, 255, 255) h = h + self.font_h + s:drawColorStringBlended(self.font, ("Physical Save: #00ff00#%3d"):format(player:combatPhysicalResist()), w, h, 255, 255, 255) h = h + self.font_h + s:drawColorStringBlended(self.font, ("Spell Save: #00ff00#%3d"):format(player:combatSpellResist()), w, h, 255, 255, 255) h = h + self.font_h + s:drawColorStringBlended(self.font, ("Mental Save: #00ff00#%3d"):format(player:combatMentalResist()), w, h, 255, 255, 255) h = h + self.font_h h = h + self.font_h - if self.actor.resists.all then s:drawColorStringBlended(self.font, ("All Resists: #00ff00#%3d%%"):format(self.actor.resists.all), w, h, 255, 255, 255) h = h + self.font_h end + if player.resists.all then s:drawColorStringBlended(self.font, ("All Resists: #00ff00#%3d%%"):format(player.resists.all), w, h, 255, 255, 255) h = h + self.font_h end for i, t in ipairs(DamageType.dam_def) do - if self.actor.resists[DamageType[t.type]] and self.actor.resists[DamageType[t.type]] ~= 0 then - s:drawColorStringBlended(self.font, ("%s Resist: #00ff00#%3d%%"):format(t.name:capitalize(), self.actor.resists[DamageType[t.type]]), w, h, 255, 255, 255) h = h + self.font_h + if player.resists[DamageType[t.type]] and player.resists[DamageType[t.type]] ~= 0 then + s:drawColorStringBlended(self.font, ("%s Resist: #00ff00#%3d%%"):format(t.name:capitalize(), player.resists[DamageType[t.type]]), w, h, 255, 255, 255) h = h + self.font_h 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 + immune_type = "poison_immune" immune_name = "Poison Resistance" if player:attr(immune_type) then s:drawColorStringBlended(self.font, ("%s: #00ff00#%3d%%"):format(immune_name, util.bound(player: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 player:attr(immune_type) then s:drawColorStringBlended(self.font, ("%s: #00ff00#%3d%%"):format(immune_name, util.bound(player: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 player:attr(immune_type) then s:drawColorStringBlended(self.font, ("%s: #00ff00#%3d%%"):format(immune_name, util.bound(player: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 player:attr(immune_type) then s:drawColorStringBlended(self.font, ("%s: #00ff00#%3d%%"):format(immune_name, util.bound(player: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 player:attr(immune_type) then s:drawColorStringBlended(self.font, ("%s: #00ff00#%3d%%"):format(immune_name, util.bound(player: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 player:attr(immune_type) then s:drawColorStringBlended(self.font, ("%s: #00ff00#%3d%%"):format(immune_name, util.bound(player: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 player:attr(immune_type) then s:drawColorStringBlended(self.font, ("%s: #00ff00#%3d%%"):format(immune_name, util.bound(player: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 player:attr(immune_type) then s:drawColorStringBlended(self.font, ("%s: #00ff00#%3d%%"):format(immune_name, util.bound(player: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 player:attr(immune_type) then s:drawColorStringBlended(self.font, ("%s: #00ff00#%3d%%"):format(immune_name, util.bound(player: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 player:attr(immune_type) then s:drawColorStringBlended(self.font, ("%s: #00ff00#%3d%%"):format(immune_name, util.bound(player: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 player:attr(immune_type) then s:drawColorStringBlended(self.font, ("%s: #00ff00#%3d%%"):format(immune_name, util.bound(player: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 player:attr(immune_type) then s:drawColorStringBlended(self.font, ("%s: #00ff00#%3d%%"):format(immune_name, util.bound(player: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 player:attr(immune_type) then s:drawColorStringBlended(self.font, ("%s: #00ff00#%3d%%"):format(immune_name, util.bound(player: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 - for tid, act in pairs(game.player.sustain_talents) do - if act then s:drawColorStringBlended(self.font, ("#LIGHT_GREEN#%s"):format(game.player:getTalentFromId(tid).name), w, h, 255, 255, 255) h = h + self.font_h end + for tid, act in pairs(player.sustain_talents) do + if act then s:drawColorStringBlended(self.font, ("#LIGHT_GREEN#%s"):format(player:getTalentFromId(tid).name), w, 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] + for eff_id, p in pairs(player.tmp) do + local e = player.tempeffect_def[eff_id] if e.status == "detrimental" then s:drawColorStringBlended(self.font, ("#LIGHT_RED#%s"):format(e.desc), w, h, 255, 255, 255) h = h + self.font_h else @@ -183,8 +184,10 @@ function _M:drawDialog(s) end function _M:dump() + local player = self.actor + 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 file = "/character-dumps/"..(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) s = s or "" fff:write(s:removeColorCodes()) fff:write("\n") end @@ -192,169 +195,169 @@ function _M:dump() --prepare label and value local makelabel = function(s,r) while s:len() < labelwidth do s = s.." " end return ("%s: %s"):format(s, r) end - local cur_exp, max_exp = game.player.exp, game.player:getExpChart(game.player.level+1) + local cur_exp, max_exp = player.exp, player:getExpChart(player.level+1) 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("Sex", player.descriptor.sex or (player.female and "Female" or "Male")))) + nl(("STR: %d"):format(player:getStr())) - nnl(("%-32s"):format(makelabel("Race", game.player.descriptor.subrace))) - nl(("DEX: %d"):format(game.player:getDex())) + nnl(("%-32s"):format(makelabel("Race", player.descriptor.subrace or player.type:capitalize()))) + nl(("DEX: %d"):format(player:getDex())) - nnl(("%-32s"):format(makelabel("Class", game.player.descriptor.subclass))) - nl(("MAG: %d"):format(game.player:getMag())) + nnl(("%-32s"):format(makelabel("Class", player.descriptor.subclass or player.subtype:capitalize()))) + nl(("MAG: %d"):format(player:getMag())) - nnl(("%-32s"):format(makelabel("Level", ("%d"):format(game.player.level)))) - nl(("WIL: %d"):format(game.player:getWil())) + nnl(("%-32s"):format(makelabel("Level", ("%d"):format(player.level)))) + nl(("WIL: %d"):format(player:getWil())) nnl(("%-32s"):format(makelabel("Exp", ("%d%%"):format(100 * cur_exp / max_exp)))) - nl(("CUN: %d"):format(game.player:getCun())) + nl(("CUN: %d"):format(player:getCun())) - nnl(("%-32s"):format(makelabel("Gold", ("%.2f"):format(game.player.money)))) - nl(("CON: %d"):format(game.player:getCon())) + nnl(("%-32s"):format(makelabel("Gold", ("%.2f"):format(player.money)))) + nl(("CON: %d"):format(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 player:getInven(player.INVEN_MAINHAND) then + for i, o in ipairs(player:getInven(player.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)) + strings[1] = ("Attack(Main Hand): %3d"):format(player:combatAttack(o.combat)) + strings[2] = ("Damage(Main Hand): %3d"):format(player:combatDamage(o.combat)) + strings[3] = ("APR (Main Hand): %3d"):format(player:combatAPR(o.combat)) + strings[4] = ("Crit (Main Hand): %3d%%"):format(player:combatCrit(o.combat)) + strings[5] = ("Speed (Main Hand): %0.2f"):format(player:combatSpeed(o.combat)) end end end - local enc, max = game.player:getEncumbrance(), game.player:getMaxEncumbrance() + local enc, max = player:getEncumbrance(), player:getMaxEncumbrance() nl() nnl(("%-32s"):format(strings[1])) - nnl(("%-32s"):format(makelabel("Life", (" %d/%d"):format(game.player.life, game.player.max_life)))) + nnl(("%-32s"):format(makelabel("Life", (" %d/%d"):format(player.life, player.max_life)))) nl(makelabel("Encumbrance", enc .. "/" .. max)) nnl(("%-32s"):format(strings[2])) - if game.player:knowTalent(game.player.T_STAMINA_POOL) then - nnl(("%-32s"):format(makelabel("Stamina", (" %d/%d"):format(game.player:getStamina(), game.player.max_stamina)))) + if player:knowTalent(player.T_STAMINA_POOL) then + nnl(("%-32s"):format(makelabel("Stamina", (" %d/%d"):format(player:getStamina(), player.max_stamina)))) else nnl(("%-32s"):format(" ")) end - nl(makelabel("Difficulty", game.player.descriptor.difficulty)) + nl(makelabel("Difficulty", player.descriptor.difficulty)) nnl(("%-32s"):format(strings[3])) - if game.player:knowTalent(game.player.T_MANA_POOL) then - nl(makelabel("Mana", (" %d/%d"):format(game.player:getMana(), game.player.max_mana))) + if player:knowTalent(player.T_MANA_POOL) then + nl(makelabel("Mana", (" %d/%d"):format(player:getMana(), player.max_mana))) else nl() end nnl(("%-32s"):format(strings[4])) - if game.player:knowTalent(game.player.T_POSITIVE_POOL) then - nl(makelabel("Positive", (" %d/%d"):format(game.player:getPositive(), game.player.max_positive))) + if player:knowTalent(player.T_POSITIVE_POOL) then + nl(makelabel("Positive", (" %d/%d"):format(player:getPositive(), 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))) + if player:knowTalent(player.T_NEGATIVE_POOL) then + nl(makelabel("Negative", (" %d/%d"):format(player:getNegative(), 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))) + if player:knowTalent(player.T_VIM_POOL) then + nl(makelabel("Vim", (" %d/%d"):format(player:getVim(), player.max_vim))) else nl() end nnl(("%-32s"):format(strings[5])) - if game.player:knowTalent(game.player.T_EQUILIBRIUM_POOL) then - nl((makelabel("Equilibrium", (" %d"):format(game.player:getEquilibrium())))) + if player:knowTalent(player.T_EQUILIBRIUM_POOL) then + nl((makelabel("Equilibrium", (" %d"):format(player:getEquilibrium())))) else nl() end -- All wpeaons in off hands -- Offhand atatcks are with a damage penality, taht can be reduced by talents - if self.actor:getInven(self.actor.INVEN_OFFHAND) then + if player:getInven(player.INVEN_OFFHAND) then local offmult = (mult or 1) / 2 - if self.actor:knowTalent(Talents.T_DUAL_WEAPON_TRAINING) then - offmult = (mult or 1) / (2 - (self.actor:getTalentLevel(Talents.T_DUAL_WEAPON_TRAINING) / 6)) + if player:knowTalent(Talents.T_DUAL_WEAPON_TRAINING) then + offmult = (mult or 1) / (2 - (player:getTalentLevel(Talents.T_DUAL_WEAPON_TRAINING) / 6)) end - for i, o in ipairs(self.actor:getInven(self.actor.INVEN_OFFHAND)) do + for i, o in ipairs(player:getInven(player.INVEN_OFFHAND)) do if o.combat then 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(("Speed (Off Hand): %0.2f"):format(game.player:combatSpeed(o.combat))) + nl(("Attack (Off Hand): %3d"):format(player:combatAttack(o.combat))) + nl(("Damage (Off Hand): %3d"):format(player:combatDamage(o.combat) * offmult)) + nl(("APR (Off Hand): %3d"):format(player:combatAPR(o.combat))) + nl(("Crit (Off Hand): %3d%%"):format(player:combatCrit(o.combat))) + nl(("Speed (Off Hand): %0.2f"):format(player:combatSpeed(o.combat))) end end end nl() - 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("Defense", game.player:combatDefense() .. ""))) - nl(makelabel("Spell Speed", game.player:combatSpellSpeed() .."")) - nnl(("%-32s"):format(makelabel("Ranged Defense", game.player:combatDefenseRanged() .. ""))) + nnl(("%-32s"):format(makelabel("Fatigue", player.fatigue .. "%"))) + nl(makelabel("Spellpower", player:combatSpellpower() .."")) + nnl(("%-32s"):format(makelabel("Armor", player:combatArmor() .. ""))) + nl(makelabel("Spell Crit", player:combatSpellCrit() .."%")) + nnl(("%-32s"):format(makelabel("Defense", player:combatDefense() .. ""))) + nl(makelabel("Spell Speed", player:combatSpellSpeed() .."")) + nnl(("%-32s"):format(makelabel("Ranged Defense", player:combatDefenseRanged() .. ""))) nl() nl() - if self.actor.inc_damage.all then nl(makelabel("All damage", self.actor.inc_damage.all.."%")) end + if player.inc_damage.all then nl(makelabel("All damage", player.inc_damage.all.."%")) end 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(makelabel(t.name:capitalize().." damage", self.actor.inc_damage[DamageType[t.type]].."%")) + if player.inc_damage[DamageType[t.type]] and player.inc_damage[DamageType[t.type]] ~= 0 then + nl(makelabel(t.name:capitalize().." damage", player.inc_damage[DamageType[t.type]].."%")) end end nl() - nl(makelabel("Physical Save",game.player:combatPhysicalResist() .."")) - nl(makelabel("Spell Save",game.player:combatSpellResist() .."")) - nl(makelabel("Mental Save",game.player:combatMentalResist() .."")) + nl(makelabel("Physical Save",player:combatPhysicalResist() .."")) + nl(makelabel("Spell Save",player:combatSpellResist() .."")) + nl(makelabel("Mental Save",player:combatMentalResist() .."")) nl() - if self.actor.resists.all then nl(("All Resists: %3d%%"):format(self.actor.resists.all)) end + if player.resists.all then nl(("All Resists: %3d%%"):format(player.resists.all)) end for i, t in ipairs(DamageType.dam_def) do - if self.actor.resists[DamageType[t.type]] and self.actor.resists[DamageType[t.type]] ~= 0 then - nl(("%s Resist: %3d%%"):format(t.name:capitalize(), self.actor.resists[DamageType[t.type]])) + if player.resists[DamageType[t.type]] and player.resists[DamageType[t.type]] ~= 0 then + nl(("%s Resist: %3d%%"):format(t.name:capitalize(), player.resists[DamageType[t.type]])) 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 + immune_type = "poison_immune" immune_name = "Poison Resistance" if player:attr(immune_type) then nl(("%s: %3d%%"):format(immune_name, util.bound(player:attr(immune_type) * 100, 0, 100))) end + immune_type = "cut_immune" immune_name = "Bleed Resistance" if player:attr(immune_type) then nl(("%s: %3d%%"):format(immune_name, util.bound(player:attr(immune_type) * 100, 0, 100))) end + immune_type = "confusion_immune" immune_name = "Confusion Resistance" if player:attr(immune_type) then nl(("%s: %3d%%"):format(immune_name, util.bound(player:attr(immune_type) * 100, 0, 100))) end + immune_type = "blind_immune" immune_name = "Blind Resistance" if player:attr(immune_type) then nl(("%s: %3d%%"):format(immune_name, util.bound(player:attr(immune_type) * 100, 0, 100))) end + immune_type = "silence_immune" immune_name = "Silence Resistance" if player:attr(immune_type) then nl(("%s: %3d%%"):format(immune_name, util.bound(player:attr(immune_type) * 100, 0, 100))) end + immune_type = "disarm_immune" immune_name = "Disarm Resistance" if player:attr(immune_type) then nl(("%s: %3d%%"):format(immune_name, util.bound(player:attr(immune_type) * 100, 0, 100))) end + immune_type = "pin_immune" immune_name = "Pinning Resistance" if player:attr(immune_type) then nl(("%s: %3d%%"):format(immune_name, util.bound(player:attr(immune_type) * 100, 0, 100))) end + immune_type = "stun_immune" immune_name = "Stun Resistance" if player:attr(immune_type) then nl(("%s: %3d%%"):format(immune_name, util.bound(player:attr(immune_type) * 100, 0, 100))) end + immune_type = "fear_immune" immune_name = "Fear Resistance" if player:attr(immune_type) then nl(("%s: %3d%%"):format(immune_name, util.bound(player:attr(immune_type) * 100, 0, 100))) end + immune_type = "knockback_immune" immune_name = "Knockback Resistance" if player:attr(immune_type) then nl(("%s: %3d%%"):format(immune_name, util.bound(player:attr(immune_type) * 100, 0, 100))) end + immune_type = "stone_immune" immune_name = "Stoning Resistance" if player:attr(immune_type) then nl(("%s: %3d%%"):format(immune_name, util.bound(player:attr(immune_type) * 100, 0, 100))) end + immune_type = "instakill_immune" immune_name = "Instadeath Resistance" if player:attr(immune_type) then nl(("%s: %3d%%"):format(immune_name, util.bound(player:attr(immune_type) * 100, 0, 100))) end + immune_type = "teleport_immune" immune_name = "Teleport Resistance" if player:attr(immune_type) then nl(("%s: %3d%%"):format(immune_name, util.bound(player:attr(immune_type) * 100, 0, 100))) end nl() local most_kill, most_kill_max = "none", 0 local total_kill = 0 - for name, nb in pairs(game.player.all_kills or {}) do + for name, nb in pairs(player.all_kills or {}) do if nb > most_kill_max then most_kill_max = nb most_kill = name end total_kill = total_kill + nb end 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 + if player.winner then nl() nl(" [Winner!]") nl() - for i, line in ipairs(self.actor.winner_text) do + for i, line in ipairs(player.winner_text) do nl(("%s"):format(line:removeColorCodes())) end end @@ -364,12 +367,12 @@ function _M:dump() nl(" [Talents 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 + for i, tt in ipairs(player.talents_types_def) do + local ttknown = player:knowTalentType(tt.type) + if not (player.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))) + nl((" - %-35s(mastery %.02f)"):format(catname, player:getTalentTypeMastery(tt.type))) -- Find all talents of this school if (ttknown) then @@ -378,7 +381,7 @@ function _M:dump() local typename = "class" 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)) + nl(("%-37s %d/%d"):format(skillname, player:getTalentLevelRaw(t.id), t.points)) end end end @@ -391,11 +394,11 @@ function _M:dump() nl(" [Current Effects]") nl() - for tid, act in pairs(game.player.sustain_talents) do - if act then nl("- "..game.player:getTalentFromId(tid).name) end + for tid, act in pairs(player.sustain_talents) do + if act then nl("- "..player:getTalentFromId(tid).name) end end - for eff_id, p in pairs(game.player.tmp) do - local e = game.player.tempeffect_def[eff_id] + for eff_id, p in pairs(player.tmp) do + local e = player.tempeffect_def[eff_id] if e.status == "detrimental" then nl("+ "..e.desc) else @@ -406,7 +409,7 @@ function _M:dump() -- Quests, Active and Completed local first = true - for id, q in pairs(self.actor.quests or {}) do + for id, q in pairs(player.quests or {}) do if q:isEnded() then if first then nl() @@ -415,12 +418,12 @@ function _M:dump() first=false end nl(" -- ".. q.name) - nl(q:desc(self.actor):gsub("#.-#", " ")) + nl(q:desc(player):gsub("#.-#", " ")) end end first=true - for id, q in pairs(self.actor.quests or {}) do + for id, q in pairs(player.quests or {}) do if not q:isEnded() then if first then first=false @@ -429,7 +432,7 @@ function _M:dump() nl() end nl(" -- ".. q.name) - nl(q:desc(self.actor):gsub("#.-#", " ")) + nl(q:desc(player):gsub("#.-#", " ")) end end @@ -439,11 +442,11 @@ function _M:dump() 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 inven_id = 1, #player.inven_def do + if player.inven[inven_id] and player.inven_def[inven_id].is_worn then + nl((" %s"):format(player.inven_def[inven_id].name)) - for item, o in ipairs(self.actor.inven[inven_id]) do + for item, o in ipairs(player.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})) @@ -461,7 +464,7 @@ function _M:dump() nl(" [Player Achievements]") nl() local achs = {} - for id, data in pairs(self.actor.achievements or {}) do + for id, data in pairs(player.achievements or {}) do local a = world:getAchievementFromId(id) achs[#achs+1] = {id=id, data=data, name=a.name} end @@ -474,7 +477,7 @@ function _M:dump() nl() nl(" [Character Inventory]") nl() - for item, o in ipairs(self.actor:getInven("INVEN")) do + for item, o in ipairs(player: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})) diff --git a/ideas/worlds.ods b/ideas/worlds.ods index e194fa6fd38d279a3374a38cba265b773d3ccf28..254265917247eab4bfd33bbfc1bbea9c80c2a1c7 100644 GIT binary patch delta 6700 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 delta 6570 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 M1z{t>k^Rd44`J1tBLDyZ -- GitLab