From b586e3f37f0db7739d75c87855ae002d755e1e08 Mon Sep 17 00:00:00 2001
From: dg <dg@51575b47-30f0-44d4-a5cc-537603b46e54>
Date: Fri, 30 Jul 2010 00:20:57 +0000
Subject: [PATCH] started grushnak pride Most NPCs that have sustainable
 talents will be created with them active Changed the max life rank adjusting
 formula, this should result in more life for all actors at high level,
 specialy for bosses

git-svn-id: http://svn.net-core.org/repos/t-engine4@955 51575b47-30f0-44d4-a5cc-537603b46e54
---
 game/modules/tome/class/Actor.lua             |  15 +++----
 game/modules/tome/class/Game.lua              |   2 +-
 game/modules/tome/class/interface/Combat.lua  |   4 +-
 .../tome/data/general/grids/underground.lua   |  39 ++++++++++++++++++
 .../modules/tome/data/general/npcs/faeros.lua |   2 +
 .../tome/data/general/npcs/orc-grushnak.lua   |   1 +
 .../modules/tome/data/general/npcs/spider.lua |   1 +
 .../tome/data/general/npcs/sunwall-town.lua   |   2 +
 .../modules/tome/data/general/npcs/thieve.lua |   7 +---
 .../tome/data/general/npcs/vampire.lua        |   1 +
 game/modules/tome/data/general/npcs/wight.lua |   1 +
 .../data/gfx/terrain/underground_floor.png    | Bin 0 -> 907 bytes
 .../tome/data/zones/ardhungol/npcs.lua        |   2 +-
 .../modules/tome/data/zones/carn-dum/npcs.lua |   1 +
 game/modules/tome/data/zones/eruan/npcs.lua   |   1 +
 .../tome/data/zones/grushnak-pride/grids.lua  |   2 +-
 .../tome/data/zones/grushnak-pride/npcs.lua   |   1 +
 .../tome/data/zones/grushnak-pride/zone.lua   |  18 ++++----
 game/modules/tome/data/zones/moria/npcs.lua   |   1 +
 .../tome/data/zones/mount-doom/npcs.lua       |   3 ++
 .../tome/data/zones/rak-shor-pride/npcs.lua   |   1 +
 .../tome/data/zones/tol-falas/npcs.lua        |   1 +
 .../data/zones/town-gates-of-morning/npcs.lua |   1 +
 .../data/zones/town-sunwall-outpost/npcs.lua  |   1 +
 .../data/zones/unremarkable-cave/npcs.lua     |   2 +
 .../tome/data/zones/vor-pride/npcs.lua        |   1 +
 game/modules/tome/resolvers.lua               |  16 +++++++
 27 files changed, 101 insertions(+), 26 deletions(-)
 create mode 100644 game/modules/tome/data/general/grids/underground.lua
 create mode 100644 game/modules/tome/data/gfx/terrain/underground_floor.png

diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua
index 28105476b0..40580aaa31 100644
--- a/game/modules/tome/class/Actor.lua
+++ b/game/modules/tome/class/Actor.lua
@@ -332,12 +332,13 @@ function _M:getRankLevelAdjust()
 	end
 end
 
-function _M:getRankLifeAdjust()
-	if self.rank == 1 then return -2
-	elseif self.rank == 2 then return -0.5
-	elseif self.rank == 3 then return 1
-	elseif self.rank == 4 then return 2
-	elseif self.rank >= 5 then return 3
+function _M:getRankLifeAdjust(value)
+	local level_adjust = 1 + self.level / 40
+	if self.rank == 1 then return value * (level_adjust - 0.2)
+	elseif self.rank == 2 then return value * (level_adjust - 0.1)
+	elseif self.rank == 3 then return value * (level_adjust + 0.1)
+	elseif self.rank == 4 then return value * (level_adjust + 0.3)
+	elseif self.rank >= 5 then return value * (level_adjust + 0.5)
 	else return 0
 	end
 end
@@ -661,7 +662,7 @@ function _M:levelup()
 	if not self.fixed_rating then
 		rating = rng.range(math.floor(self.life_rating * 0.5), math.floor(self.life_rating * 1.5))
 	end
-	self.max_life = self.max_life + math.max(rating + self:getRankLifeAdjust(), 1)
+	self.max_life = self.max_life + math.max(self:getRankLifeAdjust(rating), 1)
 
 	self:incMaxMana(self.mana_rating)
 	self:incMaxStamina(self.stamina_rating)
diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua
index 624ecbf57e..85ae4ead0a 100644
--- a/game/modules/tome/class/Game.lua
+++ b/game/modules/tome/class/Game.lua
@@ -580,7 +580,7 @@ function _M:setupCommands()
 				self.player:forceLevelup(50)
 				self.player.esp.all = 1
 				self.player.esp.range = 50
-				self:changeLevel(1, "vor-pride")
+				self:changeLevel(5, "grushnak-pride")
 --				self.player:grantQuest("escort-duty")
 			end
 		end,
diff --git a/game/modules/tome/class/interface/Combat.lua b/game/modules/tome/class/interface/Combat.lua
index f84a0a1e68..dbae57b8f1 100644
--- a/game/modules/tome/class/interface/Combat.lua
+++ b/game/modules/tome/class/interface/Combat.lua
@@ -379,10 +379,10 @@ function _M:attackTargetWith(target, weapon, damtype, mult)
 		if target:checkHit(self:combatAttack(weapon), target:combatPhysicalResist(), 0, 95, 10) and target:canBe("knockback") then
 			target:knockback(self.x, self.y, self:attr("onslaught"))
 		end
-		if lt:checkHit(self:combatAttack(weapon), lt:combatPhysicalResist(), 0, 95, 10) and lt:canBe("knockback") then
+		if lt and lt:checkHit(self:combatAttack(weapon), lt:combatPhysicalResist(), 0, 95, 10) and lt:canBe("knockback") then
 			lt:knockback(self.x, self.y, self:attr("onslaught"))
 		end
-		if rt:checkHit(self:combatAttack(weapon), rt:combatPhysicalResist(), 0, 95, 10) and r+t:canBe("knockback") then
+		if rt and rt:checkHit(self:combatAttack(weapon), rt:combatPhysicalResist(), 0, 95, 10) and r+t:canBe("knockback") then
 			rt:knockback(self.x, self.y, self:attr("onslaught"))
 		end
 	end
diff --git a/game/modules/tome/data/general/grids/underground.lua b/game/modules/tome/data/general/grids/underground.lua
new file mode 100644
index 0000000000..61dbcdd1da
--- /dev/null
+++ b/game/modules/tome/data/general/grids/underground.lua
@@ -0,0 +1,39 @@
+-- ToME - Tales of Middle-Earth
+-- Copyright (C) 2009, 2010 Nicolas Casalini
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+--
+-- Nicolas Casalini "DarkGod"
+-- darkgod@te4.org
+
+newEntity{
+	define_as = "UNDERGROUND_FLOOR",
+	name = "floor", image = "terrain/underground_floor.png",
+	display = '.', color=colors.LIGHT_UMBER, back_color=colors.UMBER,
+}
+
+for i = 1, 20 do
+newEntity{
+	define_as = "UNDERGROUND_TREE"..(i > 1 and i or ""),
+	name = "tree",
+	image = "terrain/underground_floor.png",
+	add_displays = class:makeTrees("terrain/underground_tree_alpha", 7),
+	display = '#', color=colors.PURPLE, back_color=colors.UMBER,
+	always_remember = true,
+	can_pass = {pass_tree=1},
+	does_block_move = true,
+	block_sight = true,
+	dig = "UNDERGROUND_FLOOR",
+}
+end
diff --git a/game/modules/tome/data/general/npcs/faeros.lua b/game/modules/tome/data/general/npcs/faeros.lua
index 1e30bbd2b5..87e6a5a812 100644
--- a/game/modules/tome/data/general/npcs/faeros.lua
+++ b/game/modules/tome/data/general/npcs/faeros.lua
@@ -72,6 +72,7 @@ newEntity{ base = "BASE_NPC_FAEROS",
 		[Talents.T_FLAME]=4,
 		[Talents.T_FIERY_HANDS]=3,
 	},
+	resolvers.sustains_at_birth(),
 }
 
 newEntity{ base = "BASE_NPC_FAEROS",
@@ -90,4 +91,5 @@ newEntity{ base = "BASE_NPC_FAEROS",
 		[Talents.T_FLAMESHOCK]=3,
 		[Talents.T_INFERNO]=3,
 	},
+	resolvers.sustains_at_birth(),
 }
diff --git a/game/modules/tome/data/general/npcs/orc-grushnak.lua b/game/modules/tome/data/general/npcs/orc-grushnak.lua
index cb62f97fb8..d3e05b057e 100644
--- a/game/modules/tome/data/general/npcs/orc-grushnak.lua
+++ b/game/modules/tome/data/general/npcs/orc-grushnak.lua
@@ -38,6 +38,7 @@ newEntity{
 	size_category = 3,
 
 	open_door = true,
+	resolvers.sustains_at_birth(),
 
 	autolevel = "warrior",
 	ai = "dumb_talented_simple", ai_state = { talent_in=3, },
diff --git a/game/modules/tome/data/general/npcs/spider.lua b/game/modules/tome/data/general/npcs/spider.lua
index 9929a3456b..11f4c3f248 100644
--- a/game/modules/tome/data/general/npcs/spider.lua
+++ b/game/modules/tome/data/general/npcs/spider.lua
@@ -39,6 +39,7 @@ newEntity{
 	stats = { str=15, dex=15, mag=8, con=10 },
 
 	resolvers.tmasteries{ ["technique/other"]=0.3 },
+	resolvers.sustains_at_birth(),
 
 	poison_immune = 0.9,
 	resists = { [DamageType.NATURE] = 20, [DamageType.LIGHT] = -20 },
diff --git a/game/modules/tome/data/general/npcs/sunwall-town.lua b/game/modules/tome/data/general/npcs/sunwall-town.lua
index f4bb91cf27..da3cb1e8fd 100644
--- a/game/modules/tome/data/general/npcs/sunwall-town.lua
+++ b/game/modules/tome/data/general/npcs/sunwall-town.lua
@@ -86,6 +86,7 @@ newEntity{ base = "BASE_NPC_SUNWALL_TOWN",
 		[Talents.T_CHANT_OF_FORTITUDE]=2,
 		[Talents.T_SEARING_LIGHT]=2,
 	},
+	resolvers.sustains_at_birth(),
 }
 
 newEntity{ base = "BASE_NPC_SUNWALL_TOWN",
@@ -104,4 +105,5 @@ newEntity{ base = "BASE_NPC_SUNWALL_TOWN",
 		[Talents.T_SEARING_LIGHT]=3,
 		[Talents.T_FIREBEAM]=2,
 	},
+	resolvers.sustains_at_birth(),
 }
diff --git a/game/modules/tome/data/general/npcs/thieve.lua b/game/modules/tome/data/general/npcs/thieve.lua
index 6ec5ee36aa..a59ffefda0 100644
--- a/game/modules/tome/data/general/npcs/thieve.lua
+++ b/game/modules/tome/data/general/npcs/thieve.lua
@@ -40,6 +40,8 @@ newEntity{
 	rank = 2,
 	size_category = 3,
 
+	resolvers.sustains_at_birth(),
+
 	open_door = true,
 
 	autolevel = "rogue",
@@ -68,7 +70,6 @@ newEntity{ base = "BASE_NPC_THIEF",
 	rarity = 5,
 	combat_armor = 2, combat_def = 5,
 	resolvers.talents{ [Talents.T_STEALTH]=1,  },
-	on_added = function(self) self.energy.value = game.energy_to_act self:useTalent(self.T_STEALTH) end,
 	max_life = resolvers.rngavg(70,90),
 }
 
@@ -79,7 +80,6 @@ newEntity{ base = "BASE_NPC_THIEF",
 	rarity = 5,
 	combat_armor = 3, combat_def = 5,
 	resolvers.talents{ [Talents.T_STEALTH]=2,  },
-	on_added = function(self) self.energy.value = game.energy_to_act self:useTalent(self.T_STEALTH) end,
 	max_life = resolvers.rngavg(70,90),
 }
 
@@ -90,7 +90,6 @@ newEntity{ base = "BASE_NPC_THIEF", define_as = "THIEF_BANDIT",
 	rarity = 7,
 	combat_armor = 4, combat_def = 6,
 	resolvers.talents{ [Talents.T_STEALTH]=3, [Talents.T_LETHALITY]=2, },
-	on_added = function(self) self.energy.value = game.energy_to_act self:useTalent(self.T_STEALTH) end,
 	max_life = resolvers.rngavg(80,100),
 }
 
@@ -114,7 +113,6 @@ newEntity{ base = "BASE_NPC_THIEF",
 		{type="humanoid", subtype="human", name="rogue", number=2, hasxp=false},
 	},
 	resolvers.talents{ [Talents.T_STEALTH]=3, [Talents.T_SUMMON]=1, [Talents.T_LETHALITY]=3, },
-	on_added = function(self) self.energy.value = game.energy_to_act self:useTalent(self.T_STEALTH) end,
 }
 
 newEntity{ base = "BASE_NPC_THIEF", define_as = "THIEF_ASSASSIN",
@@ -124,6 +122,5 @@ newEntity{ base = "BASE_NPC_THIEF", define_as = "THIEF_ASSASSIN",
 	rarity = 12,
 	combat_armor = 3, combat_def = 10,
 	resolvers.talents{ [Talents.T_STEALTH]=3, [Talents.T_PRECISION]=3, [Talents.T_DUAL_WEAPON_TRAINING]=2, [Talents.T_DUAL_WEAPON_DEFENSE]=2, [Talents.T_DUAL_STRIKE]=1, [Talents.T_SWEEP]=1, [Talents.T_SHADOWSTRIKE]=2, [Talents.T_LETHALITY]=5, },
-	on_added = function(self) self.energy.value = game.energy_to_act self:useTalent(self.T_STEALTH) end,
 	max_life = resolvers.rngavg(70,90),
 }
diff --git a/game/modules/tome/data/general/npcs/vampire.lua b/game/modules/tome/data/general/npcs/vampire.lua
index bcacb8c046..0137581381 100644
--- a/game/modules/tome/data/general/npcs/vampire.lua
+++ b/game/modules/tome/data/general/npcs/vampire.lua
@@ -59,6 +59,7 @@ newEntity{
 	open_door = true,
 
 	resolvers.tmasteries{ ["technique/other"]=0.5, ["spell/phantasm"]=0.8, },
+	resolvers.sustains_at_birth(),
 
 	resists = { [DamageType.COLD] = 80, [DamageType.NATURE] = 80, [DamageType.LIGHT] = -50,  },
 	blind_immune = 1,
diff --git a/game/modules/tome/data/general/npcs/wight.lua b/game/modules/tome/data/general/npcs/wight.lua
index af2bd6d2db..d73895971d 100644
--- a/game/modules/tome/data/general/npcs/wight.lua
+++ b/game/modules/tome/data/general/npcs/wight.lua
@@ -49,6 +49,7 @@ newEntity{
 	open_door = true,
 
 	resolvers.tmasteries{ ["technique/other"]=0.3, ["spell/air"]=0.3, ["spell/fire"]=0.3 },
+	resolvers.sustains_at_birth(),
 
 	resists = { [DamageType.COLD] = 80, [DamageType.FIRE] = 20, [DamageType.LIGHTNING] = 40, [DamageType.PHYSICAL] = 35, [DamageType.LIGHT] = -50, },
 	poison_immune = 1,
diff --git a/game/modules/tome/data/gfx/terrain/underground_floor.png b/game/modules/tome/data/gfx/terrain/underground_floor.png
new file mode 100644
index 0000000000000000000000000000000000000000..6725c8a532a192e1f510a4f69fe399a4bb48a84c
GIT binary patch
literal 907
zcmV;619bd}P)<h;3K|Lk000e1NJLTq001BW001Be0ssI2{21+{00006bW%=J0RI60
z0RJ~w8+`x(13*bcK~zYIeOAG0BQXqpllV}Y5`1W&?4cOu+J!)WpqIJ#C;FAS=bSGH
zK883fVj02^hOh@|WZ6m9loD%f*?M|Ua`UqWj}3*+N11qRVxAVCCd>LI?)m_r3lS*R
zrxCkerY?=RGf3909CVNU4Pe&?b`3)1L_QJHi23jw4i|s8_%1{Yc~SdD+hbTdI$!bo
zSN?sz%Kp|92)t$cH|X{>;&AcHk$9!k0MjYo5kNZ0T>z{RyAU@q@F)JgeknlX^(!aG
z^WrYV=KBLHC!nuiBA+23hA9WewE*a|QI7<`iRpZVmyPq`IkZoNp}<5z!~p)ZC!Z}S
zjEvQO@Lh=8<AfD&d?KewgTX}etPzNJ+&78`D$rXwq!F$HS2r_llpYqq3U?UV=ot!E
z6GDNt<^C<x^=iDJ%7K*;rp&p{*RkucOoz#2=Oag^H>-6sDWeN<Cc%zkQcU<d>12{Y
z;*mKfekmWn>w`K`(B|*2q8-*66KOF6fc@YP7q3$QsfVhv^^|(B^v+i-E}4fpB|sBG
zMp+5YSgT}IQwo|D0S`&fD>TDwZ+^Zqh%$_bSTcpCIFnwcLe?8G>U91Gf$PTk3WkDl
z5Csi+Dq5R_h5?&H)?+0`oz6Hp{Ku)bq=x0VA$}eu1#+w;|DAF}<Er(Ef~L0U+mS}>
zVz{-tG-5T~Las1*&nla)gNf`#pfG`!`Imm6g?@Vs0BpT$J#FG0;_}(cQS96UT2NI4
zx5v=@eBCENzMUcN>Q#`m#bf2Lp`!3<zl6v9)1!T(*3+K+awOJEaq+2=OP@Lymt|#X
z3tP;J?uG&L&$nFkw@2v>ReNBktn<UgGmMKFQZL;U5QXz$d-4i<^Zij~X-ZlyIEo$>
z`l@QJ+JS<vQYv6rsE-Dln7Z3gs6G`>4aybU-Im;{2UL#%_4O!R5#uDuMju|4YkQvU
zW!9IJ^an2lcIE803JvweXRy%<s)oe|H$~$t;uekny<CiX?^-mMyFR!_UAH3DEp*i`
zeIYPe^nOma*-!+Kk~vyRtK+pPsZj_SqEyogT--c_xDqHz)$!?6c+8&&07?SVgWt#<
h-yWZX?or{X;~xkQZOBL!*T4V(002ovPDHLkV1nvct7iZJ

literal 0
HcmV?d00001

diff --git a/game/modules/tome/data/zones/ardhungol/npcs.lua b/game/modules/tome/data/zones/ardhungol/npcs.lua
index 7b2406fbfc..67ca520d52 100644
--- a/game/modules/tome/data/zones/ardhungol/npcs.lua
+++ b/game/modules/tome/data/zones/ardhungol/npcs.lua
@@ -54,7 +54,7 @@ newEntity{ define_as = "UNGOLE", base = "BASE_NPC_SPIDER",
 		[Talents.T_CORROSIVE_VAPOUR]=5,
 		[Talents.T_PHANTASMAL_SHIELD]=5,
 	},
-
+	resolvers.sustains_at_birth(),
 
 	ai = "dumb_talented_simple", ai_state = { talent_in=2, ai_move="move_astar", },
 
diff --git a/game/modules/tome/data/zones/carn-dum/npcs.lua b/game/modules/tome/data/zones/carn-dum/npcs.lua
index 197bdf3113..1e8825283a 100644
--- a/game/modules/tome/data/zones/carn-dum/npcs.lua
+++ b/game/modules/tome/data/zones/carn-dum/npcs.lua
@@ -61,6 +61,7 @@ newEntity{ define_as = "RANTHA_THE_WORM",
 		[Talents.T_ICY_SKIN]=3,
 		[Talents.T_ICE_BREATH]=4,
 	},
+	resolvers.sustains_at_birth(),
 
 	autolevel = "warriormage",
 	ai = "dumb_talented_simple", ai_state = { talent_in=1, ai_move="move_astar", },
diff --git a/game/modules/tome/data/zones/eruan/npcs.lua b/game/modules/tome/data/zones/eruan/npcs.lua
index c25f4fcb05..65d79d60a6 100644
--- a/game/modules/tome/data/zones/eruan/npcs.lua
+++ b/game/modules/tome/data/zones/eruan/npcs.lua
@@ -63,6 +63,7 @@ newEntity{ define_as = "SUN_PALADIN_GUREN",
 		[Talents.T_BARRIER]=5,
 		[Talents.T_WEAPON_OF_LIGHT]=5,
 	},
+	resolvers.sustains_at_birth(),
 
 	can_talk = "pre-mount-doom-eruan",
 }
diff --git a/game/modules/tome/data/zones/grushnak-pride/grids.lua b/game/modules/tome/data/zones/grushnak-pride/grids.lua
index 5451b7324d..6ee4c21bac 100644
--- a/game/modules/tome/data/zones/grushnak-pride/grids.lua
+++ b/game/modules/tome/data/zones/grushnak-pride/grids.lua
@@ -18,5 +18,5 @@
 -- darkgod@te4.org
 
 load("/data/general/grids/basic.lua")
-load("/data/general/grids/sand.lua")
+load("/data/general/grids/underground.lua")
 load("/data/general/grids/water.lua")
diff --git a/game/modules/tome/data/zones/grushnak-pride/npcs.lua b/game/modules/tome/data/zones/grushnak-pride/npcs.lua
index d1944f09d4..8000d951d0 100644
--- a/game/modules/tome/data/zones/grushnak-pride/npcs.lua
+++ b/game/modules/tome/data/zones/grushnak-pride/npcs.lua
@@ -75,6 +75,7 @@ newEntity{ base="BASE_NPC_ORC_GRUSHNAK", define_as = "GRUSHNAK",
 		[Talents.T_SECOND_WIND]=5,
 		[Talents.T_JUGGERNAUT]=5,
 	},
+	resolvers.sustains_at_birth(),
 
 	on_die = function(self, who)
 		game.player:resolveSource():setQuestStatus("orc-pride", engine.Quest.COMPLETED, "grushnak")
diff --git a/game/modules/tome/data/zones/grushnak-pride/zone.lua b/game/modules/tome/data/zones/grushnak-pride/zone.lua
index aa1be6efef..7de0bfdb09 100644
--- a/game/modules/tome/data/zones/grushnak-pride/zone.lua
+++ b/game/modules/tome/data/zones/grushnak-pride/zone.lua
@@ -27,20 +27,20 @@ return {
 	width = 50, height = 50,
 	persistent = "zone",
 --	all_remembered = true,
-	all_lited = true,
+--	all_lited = true,
 	ambiant_music = "Thrall's Theme.ogg",
 	generator =  {
 		map = {
-			class = "engine.generator.map.Town",
-			building_chance = 70,
-			max_building_w = 8, max_building_h = 8,
-			edge_entrances = {6,4},
-			floor = "FLOOR",
-			external_floor = "SAND",
-			wall = "WALL",
+			class = "engine.generator.map.Roomer",
+			nb_rooms = 10,
+			lite_room_chance = 20,
+--			edge_entrances = {6,4},
+			rooms = {"forest_clearing"},
+			['.'] = "UNDERGROUND_FLOOR",
+			['#'] = {"UNDERGROUND_TREE","UNDERGROUND_TREE2","UNDERGROUND_TREE3","UNDERGROUND_TREE4","UNDERGROUND_TREE5","UNDERGROUND_TREE6","UNDERGROUND_TREE7","UNDERGROUND_TREE8","UNDERGROUND_TREE9","UNDERGROUND_TREE10","UNDERGROUND_TREE11","UNDERGROUND_TREE12","UNDERGROUND_TREE13","UNDERGROUND_TREE14","UNDERGROUND_TREE15","UNDERGROUND_TREE16","UNDERGROUND_TREE17","UNDERGROUND_TREE18","UNDERGROUND_TREE19","UNDERGROUND_TREE20",},
 			up = "UP",
 			down = "DOWN",
-			door = "DOOR",
+			door = "UNDERGROUND_FLOOR",
 		},
 		actor = {
 			class = "engine.generator.actor.Random",
diff --git a/game/modules/tome/data/zones/moria/npcs.lua b/game/modules/tome/data/zones/moria/npcs.lua
index cc3f8054e7..9b86a513db 100644
--- a/game/modules/tome/data/zones/moria/npcs.lua
+++ b/game/modules/tome/data/zones/moria/npcs.lua
@@ -76,6 +76,7 @@ newEntity{ define_as = "GOLBUG",
 		[Talents.T_ICY_SKIN]=4,
 		[Talents.T_ICE_BREATH]=4,
 	},
+	resolvers.sustains_at_birth(),
 
 	autolevel = "warrior",
 	ai = "dumb_talented_simple", ai_state = { talent_in=2, ai_move="move_astar", },
diff --git a/game/modules/tome/data/zones/mount-doom/npcs.lua b/game/modules/tome/data/zones/mount-doom/npcs.lua
index 0ae20b6b54..39c0bfcdf8 100644
--- a/game/modules/tome/data/zones/mount-doom/npcs.lua
+++ b/game/modules/tome/data/zones/mount-doom/npcs.lua
@@ -199,6 +199,7 @@ newEntity{
 		[Talents.T_PHASE_DOOR]=5,
 		[Talents.T_ESSENCE_OF_SPEED]=5,
 	},
+	resolvers.sustains_at_birth(),
 
 	autolevel = "caster",
 	ai = "dumb_talented_simple", ai_state = { talent_in=1, ai_move="move_astar" },
@@ -254,6 +255,7 @@ newEntity{
 		[Talents.T_PHASE_DOOR]=5,
 		[Talents.T_ESSENCE_OF_SPEED]=5,
 	},
+	resolvers.sustains_at_birth(),
 
 	autolevel = "caster",
 	ai = "dumb_talented_simple", ai_state = { talent_in=1, ai_move="move_astar" },
@@ -286,6 +288,7 @@ This one looks even nastier and looks toward you with what seems to be disdain.
 		[Talents.T_KNOCKBACK]=5,
 		[Talents.T_STUN]=2,
 	},
+	resolvers.sustains_at_birth(),
 
 	blind_immune = 1,
 	stun_immune = 1,
diff --git a/game/modules/tome/data/zones/rak-shor-pride/npcs.lua b/game/modules/tome/data/zones/rak-shor-pride/npcs.lua
index ca8489c6d0..63d50869fd 100644
--- a/game/modules/tome/data/zones/rak-shor-pride/npcs.lua
+++ b/game/modules/tome/data/zones/rak-shor-pride/npcs.lua
@@ -64,6 +64,7 @@ newEntity{ base="BASE_NPC_ORC_RAK_SHOR", define_as = "RAK_SHOR",
 	resolvers.talents{
 		[Talents.T_SUMMON]=1,
 	},
+	resolvers.sustains_at_birth(),
 
 	on_die = function(self, who)
 		game.player:resolveSource():setQuestStatus("orc-pride", engine.Quest.COMPLETED, "rak-shor")
diff --git a/game/modules/tome/data/zones/tol-falas/npcs.lua b/game/modules/tome/data/zones/tol-falas/npcs.lua
index 2abcaab23e..fbeff1594c 100644
--- a/game/modules/tome/data/zones/tol-falas/npcs.lua
+++ b/game/modules/tome/data/zones/tol-falas/npcs.lua
@@ -81,6 +81,7 @@ newEntity{ define_as = "THE_MASTER",
 			[Talents.T_BLINDING_SPEED]=4,
 			[Talents.T_PERFECT_STRIKE]=3,
 	},
+	resolvers.sustains_at_birth(),
 
 	autolevel = "warriormage",
 	ai = "dumb_talented_simple", ai_state = { talent_in=1, ai_move="move_astar", },
diff --git a/game/modules/tome/data/zones/town-gates-of-morning/npcs.lua b/game/modules/tome/data/zones/town-gates-of-morning/npcs.lua
index f4dd2fe38c..8d830f515c 100644
--- a/game/modules/tome/data/zones/town-gates-of-morning/npcs.lua
+++ b/game/modules/tome/data/zones/town-gates-of-morning/npcs.lua
@@ -59,6 +59,7 @@ newEntity{ define_as = "HIGH_SUN_PALADIN_AERYN",
 		[Talents.T_BARRIER]=5,
 		[Talents.T_WEAPON_OF_LIGHT]=5,
 	},
+	resolvers.sustains_at_birth(),
 
 	can_talk = "gates-of-morning-welcome",
 }
diff --git a/game/modules/tome/data/zones/town-sunwall-outpost/npcs.lua b/game/modules/tome/data/zones/town-sunwall-outpost/npcs.lua
index 8a71c6a35f..93b7eda0e6 100644
--- a/game/modules/tome/data/zones/town-sunwall-outpost/npcs.lua
+++ b/game/modules/tome/data/zones/town-sunwall-outpost/npcs.lua
@@ -60,6 +60,7 @@ newEntity{ define_as = "SUN_PALADIN_TORNUK",
 		[Talents.T_BARRIER]=3,
 		[Talents.T_WEAPON_OF_LIGHT]=2,
 	},
+	resolvers.sustains_at_birth(),
 
 	on_die = function(self, who)
 		game.player:resolveSource():setQuestStatus("start-orc", engine.Quest.COMPLETED, "sunwall-outpost")
diff --git a/game/modules/tome/data/zones/unremarkable-cave/npcs.lua b/game/modules/tome/data/zones/unremarkable-cave/npcs.lua
index 19c3b67cef..649b430cbe 100644
--- a/game/modules/tome/data/zones/unremarkable-cave/npcs.lua
+++ b/game/modules/tome/data/zones/unremarkable-cave/npcs.lua
@@ -60,6 +60,7 @@ newEntity{ define_as = "FILLAREL",
 		[Talents.T_HYMN_OF_SHADOWS]=2,
 		[Talents.T_CHANT_OF_FORTITUDE]=2,
 	},
+	resolvers.sustains_at_birth(),
 
 	autolevel = "caster",
 	ai = "dumb_talented_simple", ai_state = { talent_in=1, ai_move="move_astar" },
@@ -114,6 +115,7 @@ newEntity{ define_as = "CORRUPTOR",
 		[Talents.T_HYMN_OF_SHADOWS]=2,
 		[Talents.T_CHANT_OF_FORTITUDE]=2,
 	},
+	resolvers.sustains_at_birth(),
 
 	autolevel = "caster",
 	ai = "dumb_talented_simple", ai_state = { talent_in=1, ai_move="move_astar" },
diff --git a/game/modules/tome/data/zones/vor-pride/npcs.lua b/game/modules/tome/data/zones/vor-pride/npcs.lua
index 56e8f86f0a..dd2f85bf1b 100644
--- a/game/modules/tome/data/zones/vor-pride/npcs.lua
+++ b/game/modules/tome/data/zones/vor-pride/npcs.lua
@@ -72,6 +72,7 @@ newEntity{ base="BASE_NPC_ORC_VOR", define_as = "VOR",
 		[Talents.T_SPELL_SHAPING]=5,
 		[Talents.T_ESSENCE_OF_SPEED]=1,
 	},
+	resolvers.sustains_at_birth(),
 
 	on_die = function(self, who)
 		game.player:resolveSource():setQuestStatus("orc-pride", engine.Quest.COMPLETED, "vor")
diff --git a/game/modules/tome/resolvers.lua b/game/modules/tome/resolvers.lua
index 6621f01b68..d93b49faa2 100644
--- a/game/modules/tome/resolvers.lua
+++ b/game/modules/tome/resolvers.lua
@@ -219,3 +219,19 @@ function resolvers.calc.image_material(t, e)
 	local ml = e.material_level or 1
 	return "object/"..t[1].."_"..t[2][ml]..".png"
 end
+
+--- Activates all sustains at birth
+function resolvers.sustains_at_birth()
+	return {__resolver="sustains_at_birth", __resolve_last=true}
+end
+function resolvers.calc.sustains_at_birth(_, e)
+	e.on_added = function(self)
+		for tid, _ in pairs(self.talents) do
+			local t = self:getTalentFromId(tid)
+			if t and t.mode == "sustained" then
+				self.energy.value = game.energy_to_act
+				self:useTalent(tid)
+			end
+		end
+	end
+end
-- 
GitLab