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))