From 2164e465f24c9f837191ce87904aca743a0987fd Mon Sep 17 00:00:00 2001
From: dg <dg@51575b47-30f0-44d4-a5cc-537603b46e54>
Date: Sat, 13 Nov 2010 01:16:55 +0000
Subject: [PATCH] improved randarts

git-svn-id: http://svn.net-core.org/repos/t-engine4@1891 51575b47-30f0-44d4-a5cc-537603b46e54
---
 game/engines/default/engine/Entity.lua        |   2 +-
 .../default/engine/interface/ActorFOV.lua     |   2 +-
 game/engines/default/engine/utils.lua         |   6 +
 game/modules/tome/class/GameState.lua         |  51 ++-
 .../data/general/objects/random-artifacts.lua | 301 ++++++++++++------
 game/modules/tome/resolvers.lua               |   8 +
 6 files changed, 260 insertions(+), 110 deletions(-)

diff --git a/game/engines/default/engine/Entity.lua b/game/engines/default/engine/Entity.lua
index 40c1a40114..395ca80197 100644
--- a/game/engines/default/engine/Entity.lua
+++ b/game/engines/default/engine/Entity.lua
@@ -290,7 +290,7 @@ function _M:resolve(t, last, on_entity)
 	t = t or self
 	for k, e in pairs(t) do
 		if type(e) == "table" and e.__resolver and (not e.__resolve_last or last) then
-			t[k] = resolvers.calc[e.__resolver](e, on_entity or self, self)
+			t[k] = resolvers.calc[e.__resolver](e, on_entity or self, self, t, k)
 		elseif type(e) == "table" and not e.__CLASSNAME then
 			self:resolve(e, last, on_entity)
 		end
diff --git a/game/engines/default/engine/interface/ActorFOV.lua b/game/engines/default/engine/interface/ActorFOV.lua
index 4cf32e9357..232838a3e3 100644
--- a/game/engines/default/engine/interface/ActorFOV.lua
+++ b/game/engines/default/engine/interface/ActorFOV.lua
@@ -82,7 +82,7 @@ function _M:computeFOV(radius, block, apply, force, no_store, cache)
 				fov.actors_dist[#fov.actors_dist+1] = a
 				a.__sqdist = sqdist
 				a:check("seen_by", self)
---				a:updateFOV(self, t.sqdist)
+				a:updateFOV(self, t.sqdist)
 			end
 		end, cache and game.level.map._fovcache[block])
 
diff --git a/game/engines/default/engine/utils.lua b/game/engines/default/engine/utils.lua
index c67a552457..1d73b0bfca 100644
--- a/game/engines/default/engine/utils.lua
+++ b/game/engines/default/engine/utils.lua
@@ -108,6 +108,12 @@ function table.listify(t)
 	return tt
 end
 
+function table.keys(t)
+	local tt = {}
+	for k, e in pairs(t) do tt[#tt+1] = k end
+	return tt
+end
+
 function table.update(dst, src, deep)
 	for k, e in pairs(src) do
 		if deep and dst[k] and type(e) == "table" and type(dst[k]) == "table" and not e.__CLASSNAME then
diff --git a/game/modules/tome/class/GameState.lua b/game/modules/tome/class/GameState.lua
index 8b05f9cd48..50d6b87b9e 100644
--- a/game/modules/tome/class/GameState.lua
+++ b/game/modules/tome/class/GameState.lua
@@ -144,12 +144,11 @@ function _M:generateRandart(add)
 	o.no_unique_lore = true
 	o.rarity = rng.range(200, 290)
 
+	local allthemes = {'misc','psionic','sorcerous','nature','brawny','lightning','arcane','light','physical','def','tireless','unyielding','dark','nimble','spell','cold','fire','venom','attack'}
 	local pthemes = table.listify(o.randart_able)
-	local themes = {}
-	local no_theme = true
+	local themes = {[rng.table(allthemes)] = true}
 	for i = 1, #pthemes do if rng.percent(pthemes[i][2]) then themes[pthemes[i][1]] = true no_theme = false end end
 	local themes_fct = function(e)
-		if no_theme then return true end
 		for theme, _ in pairs(e.theme) do if themes[theme] then return true end end
 		return false
 	end
@@ -159,6 +158,7 @@ function _M:generateRandart(add)
 	local nb_powers = 2 + rng.dice(math.max(1, lev / 10), 2)
 	local powers = {}
 	print("Creating randart "..o.name.." with level "..lev)
+	print(" == using themes", table.concat(table.keys(themes), ','))
 
 	-- Select some powers
 	for i = 1, nb_powers do
@@ -170,6 +170,26 @@ function _M:generateRandart(add)
 		end
 	end
 
+	local function merger(dst, src)
+		for k, e in pairs(src) do
+			if type(e) == "table" then
+				if e.__resolver and e.__resolver == "randartmax" then
+					dst[k] = (dst[k] or 0) + e.v
+					if dst[k] > e.max then
+						dst[k] = e.max
+					end
+				else
+					if not dst[k] then dst[k] = {} end
+					merger(dst[k], e)
+				end
+			elseif type(e) == "number" then
+				dst[k] = (dst[k] or 0) + e
+			else
+				error("Type "..type(e).. " for randart property unsupported!")
+			end
+		end
+	end
+
 	-- Distribute points
 	local hpoints = math.ceil(points / 2)
 	local i = 0
@@ -178,13 +198,16 @@ function _M:generateRandart(add)
 
 		local p = powers[i]:clone()
 		if p.points <= hpoints then
-			p:resolve(nil, nil, o)
-			p.__CLASSNAME = nil
-			table.mergeAddAppendArray(o, p, true)
-			print(" * adding power: "..p.name)
+			if p.wielder then
+				o.wielder = o.wielder or {}
+				merger(o.wielder, p.wielder)
+			end
+			if p.copy then merger(o, p.copy) end
+--			print(" * adding power: "..p.name)
 		end
 		hpoints = hpoints - p.points
 	end
+	o:resolve() o:resolve(nil, true)
 
 	-- Bias toward some powers
 	local bias_powers = {}
@@ -196,13 +219,15 @@ function _M:generateRandart(add)
 		i = util.boundWrap(i + 1, 1, #bias_powers)
 
 		local p = bias_powers[i]:clone()
-		if p.points <= hpoints then
-			p:resolve(nil, nil, o)
-			p.__CLASSNAME = nil
-			table.mergeAddAppendArray(o, p, true)
-			print(" * adding power: "..p.name)
+		if p.points <= hpoints * 2 then
+			if p.wielder then
+				o.wielder = o.wielder or {}
+				merger(o.wielder, p.wielder)
+			end
+			if p.copy then merger(o, p.copy) end
+--			print(" * adding power: "..p.name)
 		end
-		hpoints = hpoints - p.points
+		hpoints = hpoints - p.points * 2
 	end
 
 	-- Setup the name
diff --git a/game/modules/tome/data/general/objects/random-artifacts.lua b/game/modules/tome/data/general/objects/random-artifacts.lua
index 52514c0fe1..996c7013c3 100644
--- a/game/modules/tome/data/general/objects/random-artifacts.lua
+++ b/game/modules/tome/data/general/objects/random-artifacts.lua
@@ -23,178 +23,289 @@ local Talents = require "engine.interface.ActorTalents"
 ----------------------------------------------------------------
 -- Spellcasting
 ----------------------------------------------------------------
-newEntity{ theme={spell=true}, name="spellpower", points = 1, rarity = 8, level_range = {1, 50},
-	wielder = { combat_spellpower = 2, },
+newEntity{ theme={spell=true, sorcerous=true}, name="spellpower", points = 1, rarity = 8, level_range = {1, 50},
+	wielder = { combat_spellpower = resolvers.randartmax(2, 50), },
 }
-newEntity{ theme={spell=true}, name="spellcrit", points = 1, rarity = 10, level_range = {1, 50},
-	wielder = { combat_spellcrit = 1, },
+newEntity{ theme={spell=true, sorcerous=true}, name="spellcrit", points = 1, rarity = 10, level_range = {1, 50},
+	wielder = { combat_spellcrit = resolvers.randartmax(1, 15), },
+}
+newEntity{ theme={spell=true, sorcerous=true}, name="spell crit magnitude", points = 1, rarity = 15, level_range = {1, 50},
+	wielder = { combat_critical_power = resolvers.randartmax(3, 30), },
 }
 
 ----------------------------------------------------------------
 -- Physical damage
 ----------------------------------------------------------------
-newEntity{ theme={physical=true}, name="phys dam", points = 1, rarity = 8, level_range = {1, 50},
-	wielder = { combat_dam = 1, },
+newEntity{ theme={physical=true, brawny=true}, name="phys dam", points = 1, rarity = 8, level_range = {1, 50},
+	wielder = { combat_dam = resolvers.randartmax(1, 20), },
+}
+newEntity{ theme={physical=true, nimble=true}, name="phys apr", points = 1, rarity = 10, level_range = {1, 50},
+	wielder = { combat_apr = resolvers.randartmax(1, 15), },
+}
+newEntity{ theme={physical=true, brawny=true, nimble=true}, name="phys crit", points = 1, rarity = 10, level_range = {1, 50},
+	wielder = { combat_physcrit = resolvers.randartmax(1, 15), },
+}
+newEntity{ theme={physical=true, nimble=true}, name="phys atk", points = 1, rarity = 10, level_range = {1, 50},
+	wielder = { combat_atk = resolvers.randartmax(1, 15), },
+}
+newEntity{ theme={physical=true, brawny=true}, name="phys crit magnitude", points = 1, rarity = 15, level_range = {1, 50},
+	wielder = { combat_critical_power = resolvers.randartmax(3, 30),   },
+}
+
+----------------------------------------------------------------
+-- Melee damage projection
+----------------------------------------------------------------
+newEntity{ theme={attack=true, venom=true}, name="acid melee", points = 1, rarity = 8, level_range = {1, 50},
+	wielder = { melee_project = {[DamageType.ACID] = resolvers.randartmax(3, 45), }, },
+}
+newEntity{ theme={attack=true, lightning=true}, name="lightning melee", points = 1, rarity = 8, level_range = {1, 50},
+	wielder = { melee_project = {[DamageType.LIGHTNING] = resolvers.randartmax(3, 45), }, },
+}
+newEntity{ theme={attack=true, fire=true}, name="fire melee", points = 1, rarity = 8, level_range = {1, 50},
+	wielder = { melee_project = {[DamageType.FIRE] = resolvers.randartmax(3, 45), }, },
+}
+newEntity{ theme={attack=true, cold=true}, name="cold melee", points = 1, rarity = 8, level_range = {1, 50},
+	wielder = { melee_project = {[DamageType.COLD] = resolvers.randartmax(3, 45), }, },
 }
-newEntity{ theme={physical=true}, name="phys apr", points = 1, rarity = 10, level_range = {1, 50},
-	wielder = { combat_apr = 1, },
+newEntity{ theme={attack=true, light=true}, name="light melee", points = 1, rarity = 8, level_range = {1, 50},
+	wielder = { melee_project = {[DamageType.LIGHT] = resolvers.randartmax(3, 45), }, },
 }
-newEntity{ theme={physical=true}, name="phys crit", points = 1, rarity = 10, level_range = {1, 50},
-	wielder = { combat_physcrit = 1, },
+newEntity{ theme={attack=true, dark=true}, name="dark melee", points = 1, rarity = 8, level_range = {1, 50},
+	wielder = { melee_project = {[DamageType.DARKNESS] = resolvers.randartmax(3, 45), }, },
 }
+newEntity{ theme={attack=true, venom=true}, name="blight melee", points = 1, rarity = 8, level_range = {1, 50},
+	wielder = { melee_project = {[DamageType.BLIGHT] = resolvers.randartmax(3, 45), }, },
+}
+newEntity{ theme={attack=true, nature=true}, name="nature melee", points = 1, rarity = 8, level_range = {1, 50},
+	wielder = { melee_project = {[DamageType.NATURE] = resolvers.randartmax(3, 45), }, },
+}
+newEntity{ theme={attack=true, arcane=true}, name="arcane melee", points = 1, rarity = 8, level_range = {1, 50},
+	wielder = { melee_project = {[DamageType.ARCANE] = resolvers.randartmax(3, 45), }, },
+}
+newEntity{ theme={attack=true, venom=true}, name="poison melee", points = 1, rarity = 8, level_range = {1, 50},
+	wielder = { melee_project = {[DamageType.POISON] = resolvers.randartmax(3, 45), }, },
+}
+
 
 ----------------------------------------------------------------
 -- Defence
 ----------------------------------------------------------------
 newEntity{ theme={def=true}, name="def", points = 2, rarity = 8, level_range = {1, 50},
-	wielder = { combat_def = 1, },
+	wielder = { combat_def = resolvers.randartmax(1, 15), },
 }
 newEntity{ theme={def=true}, name="rdef", points = 1.5, rarity = 12, level_range = {1, 50},
-	wielder = { combat_def_ranged = 1, },
+	wielder = { combat_def_ranged = resolvers.randartmax(1, 15), },
 }
 newEntity{ theme={def=true}, name="armor", points = 2, rarity = 8, level_range = {1, 50},
-	wielder = { combat_armor = 1, },
+	wielder = { combat_armor = resolvers.randartmax(1, 15), },
 }
 
 ----------------------------------------------------------------
 -- Stats
 ----------------------------------------------------------------
-newEntity{ theme={misc=true}, name="stat str", points = 2, rarity = 7, level_range = {1, 50},
-	wielder = { inc_stats = { [Stats.STAT_STR] = 1 }, },
+newEntity{ theme={misc=true, brawny=true}, name="stat str", points = 2, rarity = 7, level_range = {1, 50},
+	wielder = { inc_stats = { [Stats.STAT_STR] = resolvers.randartmax(1, 10), }, },
 }
-newEntity{ theme={misc=true}, name="stat dex", points = 2, rarity = 7, level_range = {1, 50},
-	wielder = { inc_stats = { [Stats.STAT_DEX] = 1 }, },
+newEntity{ theme={misc=true, nimble=true}, name="stat dex", points = 2, rarity = 7, level_range = {1, 50},
+	wielder = { inc_stats = { [Stats.STAT_DEX] = resolvers.randartmax(1, 10), }, },
 }
-newEntity{ theme={misc=true}, name="stat mag", points = 2, rarity = 7, level_range = {1, 50},
-	wielder = { inc_stats = { [Stats.STAT_MAG] = 1 }, },
+newEntity{ theme={misc=true, sorcerous=true}, name="stat mag", points = 2, rarity = 7, level_range = {1, 50},
+	wielder = { inc_stats = { [Stats.STAT_MAG] = resolvers.randartmax(1, 10), }, },
 }
-newEntity{ theme={misc=true}, name="stat wil", points = 2, rarity = 7, level_range = {1, 50},
-	wielder = { inc_stats = { [Stats.STAT_WIL] = 1 }, },
+newEntity{ theme={misc=true, sorcerous=true, psionic=true}, name="stat wil", points = 2, rarity = 7, level_range = {1, 50},
+	wielder = { inc_stats = { [Stats.STAT_WIL] = resolvers.randartmax(1, 10), }, },
 }
-newEntity{ theme={misc=true}, name="stat cun", points = 2, rarity = 7, level_range = {1, 50},
-	wielder = { inc_stats = { [Stats.STAT_CUN] = 1 }, },
+newEntity{ theme={misc=true, nimble=true, psionic=true}, name="stat cun", points = 2, rarity = 7, level_range = {1, 50},
+	wielder = { inc_stats = { [Stats.STAT_CUN] = resolvers.randartmax(1, 10), }, },
 }
-newEntity{ theme={misc=true}, name="stat con", points = 2, rarity = 7, level_range = {1, 50},
-	wielder = { inc_stats = { [Stats.STAT_CON] = 1 }, },
+newEntity{ theme={misc=true, brawny=true}, name="stat con", points = 2, rarity = 7, level_range = {1, 50},
+	wielder = { inc_stats = { [Stats.STAT_CON] = resolvers.randartmax(1, 10), }, },
 }
 
 ----------------------------------------------------------------
 -- Damage %
 ----------------------------------------------------------------
-newEntity{ theme={attack=true}, name="inc damage physical", points = 1, rarity = 11, level_range = {1, 50},
-	wielder = { inc_damage = { [DamageType.PHYSICAL] = 1 }, },
+newEntity{ theme={attack=true, brawny=true}, name="inc damage physical", points = 1, rarity = 11, level_range = {1, 50},
+	wielder = { inc_damage = { [DamageType.PHYSICAL] = resolvers.randartmax(2, 30), }, },
 }
-newEntity{ theme={attack=true}, name="inc damage fire", points = 1, rarity = 11, level_range = {1, 50},
-	wielder = { inc_damage = { [DamageType.FIRE] = 1 }, },
+newEntity{ theme={attack=true, fire=true}, name="inc damage fire", points = 1, rarity = 11, level_range = {1, 50},
+	wielder = { inc_damage = { [DamageType.FIRE] = resolvers.randartmax(2, 30),  }, },
 }
-newEntity{ theme={attack=true}, name="inc damage cold", points = 1, rarity = 11, level_range = {1, 50},
-	wielder = { inc_damage = { [DamageType.COLD] = 1 }, },
+newEntity{ theme={attack=true, cold=true}, name="inc damage cold", points = 1, rarity = 11, level_range = {1, 50},
+	wielder = { inc_damage = { [DamageType.COLD] = resolvers.randartmax(2, 30),  }, },
 }
-newEntity{ theme={attack=true}, name="inc damage acid", points = 1, rarity = 11, level_range = {1, 50},
-	wielder = { inc_damage = { [DamageType.ACID] = 1 }, },
+newEntity{ theme={attack=true, venom=true}, name="inc damage acid", points = 1, rarity = 11, level_range = {1, 50},
+	wielder = { inc_damage = { [DamageType.ACID] = resolvers.randartmax(2, 30),  }, },
 }
-newEntity{ theme={attack=true}, name="inc damage lightning", points = 1, rarity = 11, level_range = {1, 50},
-	wielder = { inc_damage = { [DamageType.LIGHTNING] = 1 }, },
+newEntity{ theme={attack=true, lightning=true}, name="inc damage lightning", points = 1, rarity = 11, level_range = {1, 50},
+	wielder = { inc_damage = { [DamageType.LIGHTNING] = resolvers.randartmax(2, 30),  }, },
 }
-newEntity{ theme={attack=true}, name="inc damage arcane", points = 1, rarity = 11, level_range = {1, 50},
-	wielder = { inc_damage = { [DamageType.ARCANE] = 1 }, },
+newEntity{ theme={attack=true, arcane=true, sorcerous=true}, name="inc damage arcane", points = 1, rarity = 11, level_range = {1, 50},
+	wielder = { inc_damage = { [DamageType.ARCANE] = resolvers.randartmax(2, 30),  }, },
 }
-newEntity{ theme={attack=true}, name="inc damage nature", points = 1, rarity = 11, level_range = {1, 50},
-	wielder = { inc_damage = { [DamageType.NATURE] = 1 }, },
+newEntity{ theme={attack=true, nature=true}, name="inc damage nature", points = 1, rarity = 11, level_range = {1, 50},
+	wielder = { inc_damage = { [DamageType.NATURE] = resolvers.randartmax(2, 30),  }, },
 }
-newEntity{ theme={attack=true}, name="inc damage blight", points = 1, rarity = 11, level_range = {1, 50},
-	wielder = { inc_damage = { [DamageType.BLIGHT] = 1 }, },
+newEntity{ theme={attack=true, venom=true}, name="inc damage blight", points = 1, rarity = 11, level_range = {1, 50},
+	wielder = { inc_damage = { [DamageType.BLIGHT] = resolvers.randartmax(2, 30),  }, },
 }
-newEntity{ theme={attack=true}, name="inc damage light", points = 1, rarity = 11, level_range = {1, 50},
-	wielder = { inc_damage = { [DamageType.LIGHT] = 1 }, },
+newEntity{ theme={attack=true, light=true}, name="inc damage light", points = 1, rarity = 11, level_range = {1, 50},
+	wielder = { inc_damage = { [DamageType.LIGHT] = resolvers.randartmax(2, 30),  }, },
 }
-newEntity{ theme={attack=true}, name="inc damage darkness", points = 1, rarity = 11, level_range = {1, 50},
-	wielder = { inc_damage = { [DamageType.DARKNESS] = 1 }, },
+newEntity{ theme={attack=true, dark=true}, name="inc damage darkness", points = 1, rarity = 11, level_range = {1, 50},
+	wielder = { inc_damage = { [DamageType.DARKNESS] = resolvers.randartmax(2, 30),  }, },
 }
-newEntity{ theme={attack=true}, name="inc damage mind", points = 1, rarity = 11, level_range = {1, 50},
-	wielder = { inc_damage = { [DamageType.MIND] = 1 }, },
+newEntity{ theme={attack=true, psionic=true}, name="inc damage mind", points = 1, rarity = 11, level_range = {1, 50},
+	wielder = { inc_damage = { [DamageType.MIND] = resolvers.randartmax(2, 30),  }, },
 }
 
 ----------------------------------------------------------------
 -- Immunes
 ----------------------------------------------------------------
-newEntity{ theme={def=true}, name="immune stun", points = 2, rarity = 14, level_range = {1, 50},
-	wielder = { stun_immune = 0.05 },
+newEntity{ theme={def=true, unyielding=true}, name="immune stun", points = 1, rarity = 7, level_range = {1, 50},
+	wielder = { stun_immune = resolvers.randartmax(0.05, 1), },
 }
-newEntity{ theme={def=true}, name="immune knockback", points = 2, rarity = 14, level_range = {1, 50},
-	wielder = { knockback_immune = 0.05 },
+newEntity{ theme={def=true, brawny=true, unyielding=true}, name="immune knockback", points = 1, rarity = 14, level_range = {1, 50},
+	wielder = { knockback_immune = resolvers.randartmax(0.05, 1), },
 }
-newEntity{ theme={def=true}, name="immune blind", points = 2, rarity = 14, level_range = {1, 50},
-	wielder = { blind_immune = 0.05 },
+newEntity{ theme={def=true, sorcerous=true}, name="immune blind", points = 1, rarity = 14, level_range = {1, 50},
+	wielder = { blind_immune = resolvers.randartmax(0.05, 1), },
 }
-newEntity{ theme={def=true}, name="immune confusion", points = 2, rarity = 14, level_range = {1, 50},
-	wielder = { confusion_immune = 0.05 },
+newEntity{ theme={def=true, psionic=true}, name="immune confusion", points = 1, rarity = 14, level_range = {1, 50},
+	wielder = { confusion_immune = resolvers.randartmax(0.05, 1), },
 }
-newEntity{ theme={def=true}, name="immune pin", points = 2, rarity = 14, level_range = {1, 50},
-	wielder = { pin_immune = 0.05 },
+newEntity{ theme={def=true, brawny=true}, name="immune pin", points = 1, rarity = 14, level_range = {1, 50},
+	wielder = { pin_immune = resolvers.randartmax(0.05, 1), },
 }
-newEntity{ theme={def=true}, name="immune poison", points = 2, rarity = 14, level_range = {1, 50},
-	wielder = { poison_immune = 0.05 },
+newEntity{ theme={def=true, venom=true, nature=true}, name="immune poison", points = 1, rarity = 14, level_range = {1, 50},
+	wielder = { poison_immune = resolvers.randartmax(0.05, 1), },
 }
-newEntity{ theme={def=true}, name="immune disease", points = 2, rarity = 14, level_range = {1, 50},
-	wielder = { disease_immune = 0.05 },
+newEntity{ theme={def=true, venom=true, nature=true}, name="immune disease", points = 1, rarity = 14, level_range = {1, 50},
+	wielder = { disease_immune = resolvers.randartmax(0.05, 1), },
 }
-newEntity{ theme={def=true}, name="immune silence", points = 2, rarity = 14, level_range = {1, 50},
-	wielder = { silence_immune = 0.05 },
+newEntity{ theme={def=true, sorcerous=true}, name="immune silence", points = 1, rarity = 11, level_range = {1, 50},
+	wielder = { silence_immune = resolvers.randartmax(0.05, 1), },
 }
-newEntity{ theme={def=true}, name="immune disarm", points = 2, rarity = 14, level_range = {1, 50},
-	wielder = { disarm_immune = 0.05 },
+newEntity{ theme={def=true, nimble=true, unyielding=true}, name="immune disarm", points = 1, rarity = 11, level_range = {1, 50},
+	wielder = { disarm_immune = resolvers.randartmax(0.05, 1), },
 }
-newEntity{ theme={def=true}, name="immune cut", points = 2, rarity = 14, level_range = {1, 50},
-	wielder = { cut_immune = 0.05 },
+newEntity{ theme={def=true, nimble=true}, name="immune cut", points = 1, rarity = 14, level_range = {1, 50},
+	wielder = { cut_immune = resolvers.randartmax(0.05, 1), },
 }
 
 ----------------------------------------------------------------
 -- Resists %
 ----------------------------------------------------------------
-newEntity{ theme={def=true}, name="resist physical", points = 1, rarity = 11, level_range = {1, 50},
-	wielder = { resists = { [DamageType.PHYSICAL] = 1 }, },
+newEntity{ theme={def=true, brawny=true}, name="resist physical", points = 2, rarity = 15, level_range = {1, 50},
+	wielder = { resists = { [DamageType.PHYSICAL] = resolvers.randartmax(1, 15), }, },
 }
-newEntity{ theme={def=true}, name="resist fire", points = 1, rarity = 11, level_range = {1, 50},
-	wielder = { resists = { [DamageType.FIRE] = 1 }, },
+newEntity{ theme={def=true, fire=true}, name="resist fire", points = 1, rarity = 11, level_range = {1, 50},
+	wielder = { resists = { [DamageType.FIRE] = resolvers.randartmax(3, 30), }, },
 }
-newEntity{ theme={def=true}, name="resist cold", points = 1, rarity = 11, level_range = {1, 50},
-	wielder = { resists = { [DamageType.COLD] = 1 }, },
+newEntity{ theme={def=true, cold=true}, name="resist cold", points = 1, rarity = 11, level_range = {1, 50},
+	wielder = { resists = { [DamageType.COLD] = resolvers.randartmax(3, 30), }, },
 }
-newEntity{ theme={def=true}, name="resist acid", points = 1, rarity = 11, level_range = {1, 50},
-	wielder = { resists = { [DamageType.ACID] = 1 }, },
+newEntity{ theme={def=true, venom=true}, name="resist acid", points = 1, rarity = 11, level_range = {1, 50},
+	wielder = { resists = { [DamageType.ACID] = resolvers.randartmax(3, 30), }, },
 }
-newEntity{ theme={def=true}, name="resist lightning", points = 1, rarity = 11, level_range = {1, 50},
-	wielder = { resists = { [DamageType.LIGHTNING] = 1 }, },
+newEntity{ theme={def=true, lightning=true}, name="resist lightning", points = 1, rarity = 11, level_range = {1, 50},
+	wielder = { resists = { [DamageType.LIGHTNING] = resolvers.randartmax(3, 30), }, },
 }
-newEntity{ theme={def=true}, name="resist arcane", points = 1, rarity = 11, level_range = {1, 50},
-	wielder = { resists = { [DamageType.ARCANE] = 1 }, },
+newEntity{ theme={def=true, arcane=true, sorcerous=true}, name="resist arcane", points = 5, rarity = 15, level_range = {1, 50},
+	wielder = { resists = { [DamageType.ARCANE] = resolvers.randartmax(5, 5), }, },
 }
-newEntity{ theme={def=true}, name="resist nature", points = 1, rarity = 11, level_range = {1, 50},
-	wielder = { resists = { [DamageType.NATURE] = 1 }, },
+newEntity{ theme={def=true, nature=true}, name="resist nature", points = 2, rarity = 11, level_range = {1, 50},
+	wielder = { resists = { [DamageType.NATURE] = resolvers.randartmax(3, 20), }, },
 }
-newEntity{ theme={def=true}, name="resist blight", points = 1, rarity = 11, level_range = {1, 50},
-	wielder = { resists = { [DamageType.BLIGHT] = 1 }, },
+newEntity{ theme={def=true, venom=true}, name="resist blight", points = 2, rarity = 11, level_range = {1, 50},
+	wielder = { resists = { [DamageType.BLIGHT] = resolvers.randartmax(3, 20), }, },
 }
-newEntity{ theme={def=true}, name="resist light", points = 1, rarity = 11, level_range = {1, 50},
-	wielder = { resists = { [DamageType.LIGHT] = 1 }, },
+newEntity{ theme={def=true, light=true}, name="resist light", points = 2, rarity = 11, level_range = {1, 50},
+	wielder = { resists = { [DamageType.LIGHT] = resolvers.randartmax(3, 20), }, },
 }
-newEntity{ theme={def=true}, name="resist darkness", points = 1, rarity = 11, level_range = {1, 50},
-	wielder = { resists = { [DamageType.DARKNESS] = 1 }, },
+newEntity{ theme={def=true, dark=true}, name="resist darkness", points = 2, rarity = 11, level_range = {1, 50},
+	wielder = { resists = { [DamageType.DARKNESS] = resolvers.randartmax(3, 20), }, },
 }
-newEntity{ theme={def=true}, name="resist mind", points = 1, rarity = 11, level_range = {1, 50},
-	wielder = { resists = { [DamageType.MIND] = 1 }, },
+newEntity{ theme={def=true, psionic=true}, name="resist mind", points = 2, rarity = 15, level_range = {1, 50},
+	wielder = { resists = { [DamageType.MIND] = resolvers.randartmax(3, 15), }, },
 }
 
 ----------------------------------------------------------------
 -- Saves
 ----------------------------------------------------------------
-newEntity{ theme={def=true}, name="save physical", points = 1, rarity = 11, level_range = {1, 50},
-	wielder = { combat_physresist = 1 },
+newEntity{ theme={def=true, brawny=true, nimble=true}, name="save physical", points = 1, rarity = 11, level_range = {1, 50},
+	wielder = { combat_physresist = resolvers.randartmax(3, 18), },
+}
+newEntity{ theme={def=true, sorcerous=true}, name="save spell", points = 1, rarity = 11, level_range = {1, 50},
+	wielder = { combat_spellresist = resolvers.randartmax(3, 18), },
+}
+newEntity{ theme={def=true, psionic=true}, name="save mental", points = 1, rarity = 11, level_range = {1, 50},
+	wielder = { combat_mentalresist = resolvers.randartmax(3, 18), },
+}
+
+----------------------------------------------------------------
+-- Regen
+----------------------------------------------------------------
+
+newEntity{ theme={def=true, sorcerous=true}, name="mana regeneration", points = 1, rarity = 15, level_range = {1, 50},
+	wielder = { mana_regen = resolvers.randartmax(.04, .6), },
+}
+newEntity{ theme={def=true, brawny=true, nimble=true, tireless=true}, name="stamina regeneration", points = 1, rarity = 15, level_range = {1, 50},
+	wielder = { stamina_regen = resolvers.randartmax(.2, 3), },
+}
+newEntity{ theme={def=true, tireless=true}, name="life regeneration", points = 1, rarity = 11, level_range = {1, 50},
+	wielder = { life_regen = resolvers.randartmax(.2, 3), },
+}
+
+
+----------------------------------------------------------------
+-- Life, resource pool increase
+----------------------------------------------------------------
+
+newEntity{ theme={def=true, sorcerous=true}, name="increased mana", points = 1, rarity = 14, level_range = {1, 50},
+	wielder = { max_mana = resolvers.randartmax(10, 150), },
+}
+newEntity{ theme={def=true, brawny=true, nimble=true, tireless=true}, name="increased stamina", points = 1, rarity = 14, level_range = {1, 50},
+	wielder = { max_stamina = resolvers.randartmax(5, 75), },
+}
+newEntity{ theme={def=true, brawny=true, tireless=true}, name="increased life", points = 1, rarity = 11, level_range = {1, 50},
+	wielder = { max_life = resolvers.randartmax(10, 150), },
+}
+
+----------------------------------------------------------------
+-- Other
+----------------------------------------------------------------
+
+newEntity{ theme={def=true}, name="see invisible", points = 1, rarity = 11, level_range = {1, 50},
+	wielder = { see_invisible = resolvers.randartmax(3, 24), },
+}
+newEntity{ theme={tireless=true}, name="decreased fatigue", points = 1, rarity = 15, level_range = {1, 50},
+	wielder = { fatigue = -2 },
+}
+newEntity{ theme={brawny=true, tireless=true}, name="greater max encumbrance", points = 1, rarity = 11, level_range = {1, 50},
+	wielder = { max_encumber = resolvers.randartmax(10, 100), },
+}
+newEntity{ theme={def=true, tireless=true}, name="improve heal", points = 1, rarity = 15, level_range = {1, 50},
+	wielder = { healing_factor = resolvers.randartmax(0.05, .5), },
+}
+newEntity{ theme={light=true}, name="lite radius", points = 1, rarity = 14, level_range = {1, 50},
+	wielder = { lite = resolvers.randartmax(1, 3), },
+}
+newEntity{ theme={nature=true}, name="water breathing", points = 10, rarity = 15, level_range = {1, 50},
+	wielder = { can_breath = {water=1}, },
+}
+newEntity{ theme={psionic=true}, name="telepathy", points = 60, rarity = 65, level_range = {1, 50},
+	wielder = { esp = {all=1}, },
+}
+newEntity{ theme={psionic=true}, name="orc telepathy", points = 15, rarity = 25, level_range = {1, 50},
+	wielder = { esp = {["humanoid/orc"]=1}, },
+}
+newEntity{ theme={psionic=true}, name="dragon telepathy", points = 8, rarity = 20, level_range = {1, 50},
+	wielder = { esp = {dragon=1}, },
 }
-newEntity{ theme={def=true}, name="save spell", points = 1, rarity = 11, level_range = {1, 50},
-	wielder = { combat_spellresist = 1 },
+newEntity{ theme={psionic=true}, name="demon telepathy", points = 8, rarity = 20, level_range = {1, 50},
+	wielder = { esp = {["demon/minor"]=1, ["demon/major"]=1}, },
 }
-newEntity{ theme={def=true}, name="save mental", points = 1, rarity = 11, level_range = {1, 50},
-	wielder = { combat_mentalresist = 1 },
+newEntity{ theme={unyielding=true}, name="no teleport", points = 1, rarity = 17, level_range = {1, 50},
+	copy = { no_teleport = 1, },
 }
diff --git a/game/modules/tome/resolvers.lua b/game/modules/tome/resolvers.lua
index 2dd8cf993f..04ee533f06 100644
--- a/game/modules/tome/resolvers.lua
+++ b/game/modules/tome/resolvers.lua
@@ -274,3 +274,11 @@ function resolvers.calc.sustains_at_birth(_, e)
 		end
 	end
 end
+
+--- Help creating randarts
+function resolvers.randartmax(v, max)
+	return {__resolver="randartmax", v=v, max=max}
+end
+function resolvers.calc.randartmax(t, e)
+	return t.v
+end
-- 
GitLab