From c147dd61e26bcd1bcbfac65b741d55f4d20276f6 Mon Sep 17 00:00:00 2001
From: dg <dg@51575b47-30f0-44d4-a5cc-537603b46e54>
Date: Wed, 22 Aug 2012 23:08:03 +0000
Subject: [PATCH] bump 43; 4 new uber talents

git-svn-id: http://svn.net-core.org/repos/t-engine4@5552 51575b47-30f0-44d4-a5cc-537603b46e54
---
 game/engines/default/engine/Map.lua           |   1 +
 game/engines/default/engine/version.lua       |   2 +-
 game/modules/example/init.lua                 |   2 +-
 game/modules/example_realtime/init.lua        |   2 +-
 game/modules/tome/class/Actor.lua             |   7 ++-
 game/modules/tome/class/GameState.lua         |  10 ++--
 game/modules/tome/class/Player.lua            |   2 +-
 game/modules/tome/class/interface/Combat.lua  |  16 +++++-
 game/modules/tome/data/damage_types.lua       |  11 ++--
 .../modules/tome/data/general/npcs/horror.lua |   4 +-
 .../data/general/objects/boss-artifacts.lua   |   2 +-
 .../data/general/objects/egos/torques.lua     |   2 +-
 .../data/general/objects/world-artifacts.lua  |   2 +-
 .../tome/data/gfx/talents/bloodspring.png     | Bin 0 -> 3869 bytes
 .../tome/data/gfx/talents/flexible_combat.png | Bin 0 -> 2519 bytes
 .../tome/data/gfx/talents/titan_s_smash.png   | Bin 0 -> 4136 bytes
 .../tome/data/gfx/talents/windblade.png       | Bin 0 -> 3055 bytes
 game/modules/tome/data/lore/rhaloren.lua      |   2 +-
 game/modules/tome/data/talents/uber/const.lua |  29 ++++++++++
 game/modules/tome/data/talents/uber/dex.lua   |  31 +++++++++++
 game/modules/tome/data/talents/uber/str.lua   |  51 ++++++++++++++++++
 game/modules/tome/data/talents/uber/uber.lua  |  10 ++++
 game/modules/tome/data/talents/uber/wil.lua   |   2 +-
 .../tome/data/zones/wilderness/zone.lua       |   2 +-
 game/modules/tome/dialogs/UberTalent.lua      |   1 +
 game/modules/tome/init.lua                    |   4 +-
 26 files changed, 171 insertions(+), 24 deletions(-)
 create mode 100644 game/modules/tome/data/gfx/talents/bloodspring.png
 create mode 100644 game/modules/tome/data/gfx/talents/flexible_combat.png
 create mode 100644 game/modules/tome/data/gfx/talents/titan_s_smash.png
 create mode 100644 game/modules/tome/data/gfx/talents/windblade.png

diff --git a/game/engines/default/engine/Map.lua b/game/engines/default/engine/Map.lua
index 8078c0ff9d..4a2bb3d828 100644
--- a/game/engines/default/engine/Map.lua
+++ b/game/engines/default/engine/Map.lua
@@ -730,6 +730,7 @@ end
 
 --- Sets the current view area if x and y are out of bounds
 function _M:moveViewSurround(x, y, marginx, marginy, ignore_padding)
+	if not x or not y then return end
 	local omx, omy = self.mx, self.my
 
 	if ignore_padding then
diff --git a/game/engines/default/engine/version.lua b/game/engines/default/engine/version.lua
index 74575bd600..4138f28722 100644
--- a/game/engines/default/engine/version.lua
+++ b/game/engines/default/engine/version.lua
@@ -18,7 +18,7 @@
 -- darkgod@te4.org
 
 -- Engine Version
-engine.version = {0,9,42,"te4",17}
+engine.version = {0,9,43,"te4",17}
 engine.require_c_core = engine.version[5]
 engine.version_id = ("%s-%d_%d.%d.%d"):format(engine.version[4], engine.require_c_core, engine.version[1], engine.version[2], engine.version[3])
 
diff --git a/game/modules/example/init.lua b/game/modules/example/init.lua
index 3153dc177a..acccf8ded9 100644
--- a/game/modules/example/init.lua
+++ b/game/modules/example/init.lua
@@ -23,7 +23,7 @@ short_name = "example"
 author = { "DarkGod", "darkgod@te4.org" }
 homepage = "http://te4.org/modules:example"
 version = {1,0,0}
-engine = {0,9,42,"te4"}
+engine = {0,9,43,"te4"}
 description = [[
 This is *NOT* a game, just an example/template to make your own using the T-Engine4.
 ]]
diff --git a/game/modules/example_realtime/init.lua b/game/modules/example_realtime/init.lua
index 5fcfe7859e..dc93de2a16 100644
--- a/game/modules/example_realtime/init.lua
+++ b/game/modules/example_realtime/init.lua
@@ -23,7 +23,7 @@ short_name = "example_realtime"
 author = { "DarkGod", "darkgod@te4.org" }
 homepage = "http://te4.org/modules:example"
 version = {1,0,0}
-engine = {0,9,42,"te4"}
+engine = {0,9,43,"te4"}
 description = [[
 This is *NOT* a game, just an example/template to make your own using the T-Engine4.
 ]]
diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua
index a4e41ec0c8..3b235ef089 100644
--- a/game/modules/tome/class/Actor.lua
+++ b/game/modules/tome/class/Actor.lua
@@ -1607,7 +1607,7 @@ function _M:onTakeHit(value, src)
 			value = adjusted_value - self.damage_shield_absorb
 			self.damage_shield_absorb = 0
 		end
-		if reflection > 0 and reflect_damage > 0 and src.y and src.x and not src.dead then
+		if reflection and reflect_damage and reflection > 0 and reflect_damage > 0 and src.y and src.x and not src.dead then
 			local a = game.level.map(src.x, src.y, Map.ACTOR)
 			if a and self:reactionToward(a) < 0 then
 				a:takeHit(math.ceil(reflect_damage * reflection), self)
@@ -1942,6 +1942,11 @@ function _M:onTakeHit(value, src)
 		for tid, _ in pairs(self.invis_on_hit_disable) do self:forceUseTalent(tid, {ignore_energy=true}) end
 	end
 
+	-- Bloodspring
+	if value >= self.max_life * 0.20 and self:knowTalent(self.T_BLOODSPRING) then
+		self:triggerTalent(self.T_BLOODSPRING)
+	end
+
 	if self:knowTalent(self.T_DUCK_AND_DODGE) then
 		local t = self:getTalentFromId(self.T_DUCK_AND_DODGE)
 		if value >= self.max_life * t.getThreshold(self, t) then
diff --git a/game/modules/tome/class/GameState.lua b/game/modules/tome/class/GameState.lua
index 0dd8bb3c37..27f653e78a 100644
--- a/game/modules/tome/class/GameState.lua
+++ b/game/modules/tome/class/GameState.lua
@@ -656,10 +656,12 @@ function _M:displayWeatherShader(level, ps, x, y, nb_keyframes)
 	local mapcoords = {(-sx + level.map.mx * level.map.tile_w) / level.map.viewport.width , (-sy + level.map.my * level.map.tile_h) / level.map.viewport.height}
 
 	for j = 1, #ps do
-		ps[j]:setUniform("mapCoord", mapcoords)
-		ps[j].shad:use(true)
-		core.display.drawQuad(x, y, level.map.viewport.width, level.map.viewport.height, 255, 255, 255, 255)
-		ps[j].shad:use(false)
+		if ps[j].shad then
+			ps[j]:setUniform("mapCoord", mapcoords)
+			ps[j].shad:use(true)
+			core.display.drawQuad(x, y, level.map.viewport.width, level.map.viewport.height, 255, 255, 255, 255)
+			ps[j].shad:use(false)
+		end
 	end
 end
 
diff --git a/game/modules/tome/class/Player.lua b/game/modules/tome/class/Player.lua
index b71c5f75c3..164521a397 100644
--- a/game/modules/tome/class/Player.lua
+++ b/game/modules/tome/class/Player.lua
@@ -984,7 +984,7 @@ function _M:playerTakeoff()
 end
 
 function _M:playerUseItem(object, item, inven)
-	if game.zone.wilderness then game.logPlayer(self, "You cannot use items on the world map.") return end
+	if not game.zone or game.zone.wilderness then game.logPlayer(self, "You cannot use items on the world map.") return end
 
 	local use_fct = function(o, inven, item)
 		if not o then return end
diff --git a/game/modules/tome/class/interface/Combat.lua b/game/modules/tome/class/interface/Combat.lua
index 389fba0149..818c46cd47 100644
--- a/game/modules/tome/class/interface/Combat.lua
+++ b/game/modules/tome/class/interface/Combat.lua
@@ -83,7 +83,7 @@ The ToME combat system has the following attributes:
 - armor penetration: reduction of target's armor
 - damage: raw damage done
 ]]
-function _M:attackTarget(target, damtype, mult, noenergy)
+function _M:attackTarget(target, damtype, mult, noenergy, force_unharmed)
 	local speed, hit = nil, false
 	local sound, sound_miss = nil, nil
 
@@ -145,7 +145,8 @@ function _M:attackTarget(target, damtype, mult, noenergy)
 		break_stealth = true
 	end
 
-	if not speed and not self:attr("disarmed") and not self:isUnarmed() then
+	local mean
+	if not speed and not self:attr("disarmed") and not self:isUnarmed() and not force_unharmed then
 		-- All weapons in main hands
 		if self:getInven(self.INVEN_MAINHAND) then
 			for i, o in ipairs(self:getInven(self.INVEN_MAINHAND)) do
@@ -179,6 +180,7 @@ function _M:attackTarget(target, damtype, mult, noenergy)
 				end
 			end
 		end
+		mean = "weapon"
 	end
 
 	-- Barehanded ?
@@ -191,6 +193,7 @@ function _M:attackTarget(target, damtype, mult, noenergy)
 		if hit and not sound then sound = combat.sound
 		elseif not hit and not sound_miss then sound_miss = combat.sound_miss end
 		if not combat.no_stealth_break then break_stealth = true end
+		mean = "unharmed"
 	end
 
 	-- We use up our own energy
@@ -211,6 +214,15 @@ function _M:attackTarget(target, damtype, mult, noenergy)
 		t.on_attackTarget(self, t, target)
 	end
 
+	if self:attr("unharmed_attack_on_hit") then
+		local v = self:attr("unharmed_attack_on_hit")
+		self:attr("unharmed_attack_on_hit", -v)
+		if mean == "weapon" then self:attackTarget(target, nil, 1, true, true)
+		elseif mean == "unharmed" and rng.percent(60) then self:attackTarget(target, nil, 1, true, true)
+		end
+		self:attr("unharmed_attack_on_hit", v)
+	end
+
 	-- Cancel stealth!
 	if break_stealth then self:breakStealth() end
 	self:breakLightningSpeed()
diff --git a/game/modules/tome/data/damage_types.lua b/game/modules/tome/data/damage_types.lua
index d610c9f983..ef76126dde 100644
--- a/game/modules/tome/data/damage_types.lua
+++ b/game/modules/tome/data/damage_types.lua
@@ -919,12 +919,17 @@ newDamageType{
 	name = "wave", type = "WAVE",
 	projector = function(src, x, y, type, dam)
 		local srcx, srcy = dam.x, dam.y
+		local base = dam
 		dam = dam.dam
-		DamageType:get(DamageType.COLD).projector(src, x, y, DamageType.COLD, dam / 2)
-		DamageType:get(DamageType.PHYSICAL).projector(src, x, y, DamageType.PHYSICAL, dam / 2)
+		if not base.st then
+			DamageType:get(DamageType.COLD).projector(src, x, y, DamageType.COLD, dam / 2)
+			DamageType:get(DamageType.PHYSICAL).projector(src, x, y, DamageType.PHYSICAL, dam / 2)
+		else
+			DamageType:get(DamageType.BLIGHT).projector(src, x, y, DamageType.BLIGHT, dam)
+		end
 		local target = game.level.map(x, y, Map.ACTOR)
 		if target then
-			if target:checkHit(src:combatSpellpower(), target:combatPhysicalResist(), 0, 95, 15) and target:canBe("knockback") then
+			if target:checkHit(base.power or src:combatSpellpower(), target:combatPhysicalResist(), 0, 95, 15) and target:canBe("knockback") then
 				target:knockback(srcx, srcy, 1)
 				target:crossTierEffect(target.EFF_OFFBALANCE, src:combatSpellpower())
 				game.logSeen(target, "%s is knocked back!", target.name:capitalize())
diff --git a/game/modules/tome/data/general/npcs/horror.lua b/game/modules/tome/data/general/npcs/horror.lua
index 816de0dffd..fe79b83ead 100644
--- a/game/modules/tome/data/general/npcs/horror.lua
+++ b/game/modules/tome/data/general/npcs/horror.lua
@@ -938,7 +938,7 @@ newEntity{ base = "BASE_NPC_HORROR",
 	on_act = function(self)
 		if self.blades > 2 or not rng.percent(20) then return end
 		self.blades = self.blades + 1
-			self:forceUseTalent(Talents.T_ANIMATE_BLADE, {ignore_cd=true, force_level=1})
+			self:forceUseTalent(self.T_ANIMATE_BLADE, {ignore_cd=true, force_level=1})
 	end,
 	
 	resolvers.talents{
@@ -993,7 +993,7 @@ newEntity{ base="BASE_NPC_HORROR", define_as = "ANIMATED_BLADE",
 		game.logSeen(self, "A rift opens, spawning a free floating blade!")
 		game.level.map:addEffect(self,
 			self.x, self.y, 3,
-			DamageType.TEMPORAL, 25,
+			engine.DamageType.TEMPORAL, 25,
 			0,
 			5, nil,
 			{type="time_prison"},
diff --git a/game/modules/tome/data/general/objects/boss-artifacts.lua b/game/modules/tome/data/general/objects/boss-artifacts.lua
index 7f1b692d59..0edcc5d9d0 100644
--- a/game/modules/tome/data/general/objects/boss-artifacts.lua
+++ b/game/modules/tome/data/general/objects/boss-artifacts.lua
@@ -837,7 +837,7 @@ newEntity{ base = "BASE_GEM", define_as = "CRYSTAL_FOCUS",
 
 	max_power = 1, power_regen = 1,
 	use_power = { name = "combine with a weapon", power = 1, use = function(self, who, gem_inven, gem_item)
-		who:showInventory("Fuse with which weapon?", who:getInven("INVEN"), function(o) return (o.type == "weapon" or o.subtype == "hands") and o.subtype ~= "mindstar" and not o.egoed and not o.unique and not o.rare end, function(o, item)
+		who:showInventory("Fuse with which weapon?", who:getInven("INVEN"), function(o) return (o.type == "weapon" or o.subtype == "hands") and o.subtype ~= "mindstar" and not o.egoed and not o.unique and not o.rare and not o.archery end, function(o, item)
 			local oldname = o:getName{do_color=true}
 
 			-- Remove the gem
diff --git a/game/modules/tome/data/general/objects/egos/torques.lua b/game/modules/tome/data/general/objects/egos/torques.lua
index ececb2d50e..02eaffdd36 100644
--- a/game/modules/tome/data/general/objects/egos/torques.lua
+++ b/game/modules/tome/data/general/objects/egos/torques.lua
@@ -70,7 +70,7 @@ newEntity{
 
 newEntity{
 	name = "quiet ", prefix=true,
-	keywords = {quiest=true},
+	keywords = {quiet=true},
 	level_range = {30, 50},
 	rarity = 12,
 	greater_ego = 1,
diff --git a/game/modules/tome/data/general/objects/world-artifacts.lua b/game/modules/tome/data/general/objects/world-artifacts.lua
index 50717013b3..65197d0eab 100644
--- a/game/modules/tome/data/general/objects/world-artifacts.lua
+++ b/game/modules/tome/data/general/objects/world-artifacts.lua
@@ -3962,7 +3962,7 @@ newEntity{ base = "BASE_GAUNTLETS",
 	end,
 	max_power = 150, power_regen = 1,
 	use_power = { name = "destroy an arcane item", power = 1, use = function(self, who, obj_inven, obj_item)
-		local d = who:showInventory("Destroy which item?", who:getInven("INVEN"), function(o) return o.unique and o.power_source.arcane and o.power_source.arcane and o.power_source.arcane == true and o.material_level and o.material_level > self.material_level end, function(o, item, inven)
+		local d = who:showInventory("Destroy which item?", who:getInven("INVEN"), function(o) return o.unique and o.power_source and o.power_source.arcane and o.power_source.arcane and o.power_source.arcane == true and o.material_level and o.material_level > self.material_level end, function(o, item, inven)
 			if o.material_level <= self.material_level then return end
 			self.material_level=o.material_level
 			game.logPlayer(who, "You crush the %s, and the gloves take on an illustrious shine!", o:getName{do_color=true})
diff --git a/game/modules/tome/data/gfx/talents/bloodspring.png b/game/modules/tome/data/gfx/talents/bloodspring.png
new file mode 100644
index 0000000000000000000000000000000000000000..4c9338ff29dc8407a870a9a75161b99b43bbf67a
GIT binary patch
literal 3869
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

literal 0
HcmV?d00001

diff --git a/game/modules/tome/data/gfx/talents/flexible_combat.png b/game/modules/tome/data/gfx/talents/flexible_combat.png
new file mode 100644
index 0000000000000000000000000000000000000000..a44bc9503d3c243dc9d463f4580cdbea4a0f3b79
GIT binary patch
literal 2519
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

literal 0
HcmV?d00001

diff --git a/game/modules/tome/data/gfx/talents/titan_s_smash.png b/game/modules/tome/data/gfx/talents/titan_s_smash.png
new file mode 100644
index 0000000000000000000000000000000000000000..5de9fe02dd8eb9c84e8c510b297e256e993f76f9
GIT binary patch
literal 4136
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

literal 0
HcmV?d00001

diff --git a/game/modules/tome/data/gfx/talents/windblade.png b/game/modules/tome/data/gfx/talents/windblade.png
new file mode 100644
index 0000000000000000000000000000000000000000..1a0fc86ce1f52261e6beab2dd6fec99e61873c73
GIT binary patch
literal 3055
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

literal 0
HcmV?d00001

diff --git a/game/modules/tome/data/lore/rhaloren.lua b/game/modules/tome/data/lore/rhaloren.lua
index 94554e2d38..66f9540993 100644
--- a/game/modules/tome/data/lore/rhaloren.lua
+++ b/game/modules/tome/data/lore/rhaloren.lua
@@ -39,7 +39,7 @@ newLore{
 	name = "letter (rhaloren camp)",
 	lore = [[The Scintillating Caverns must be protected. Our great leader has ordered it so, and his word is more binding than any law. Our numbers are few, and we must move in secrecy, but a quiet watch will be made on the caverns. Any who are seen to interfere in them must be lured here to our place of strength, and brought before me for inquisition.
 
-More have joined our cause. Their eyes have been opened to the injustice our people have suffered, blamed by the other races for the Spellblaze and its effects. They are sick of the cowardice of the Council, who sit in silence as we are scorned and hated across the world. But most of all they are inspired by our great leader, and the powers he has gained from studying the Spellblaze. He alone realizes our full potential, he alone can see in our hearts what we are truly capable of. He has blessed me, rescued me from a tortured life and touched me me, rescued me from a tortured life and touched me with his power. Only he can lead our people! With his mastery the world will see our strength and recognise us as a true force to be reckoned with.
+More have joined our cause. Their eyes have been opened to the injustice our people have suffered, blamed by the other races for the Spellblaze and its effects. They are sick of the cowardice of the Council, who sit in silence as we are scorned and hated across the world. But most of all they are inspired by our great leader, and the powers he has gained from studying the Spellblaze. He alone realizes our full potential, he alone can see in our hearts what we are truly capable of. He has blessed me, rescued me from a tortured life and touched me with his power. Only he can lead our people! With his mastery the world will see our strength and recognise us as a true force to be reckoned with.
 
 Trust in his power, for he shall bring us all to glory.
 
diff --git a/game/modules/tome/data/talents/uber/const.lua b/game/modules/tome/data/talents/uber/const.lua
index 906e496fd2..2e30f81857 100644
--- a/game/modules/tome/data/talents/uber/const.lua
+++ b/game/modules/tome/data/talents/uber/const.lua
@@ -33,3 +33,32 @@ uberTalent{
 		:format()
 	end,
 }
+
+uberTalent{
+	name = "Bloodspring",
+	mode = "passive",
+	cooldown = 12,
+	require = { special={desc="Be close to the draconic world", fct=function(self) return self:attr("drake_touched") and self:attr("drake_touched") >= 2 end} },
+	trigger = function(self, t)
+		-- Add a lasting map effect
+		game.level.map:addEffect(self,
+			self.x, self.y, 4,
+			DamageType.WAVE, {dam=100 + self:getCon() * 3, x=self.x, y=self.y, st=DamageType.BLIGHT, power=50 + self:getCon() * 2},
+			1,
+			5, nil,
+			engine.Entity.new{alpha=100, display='', color_br=200, color_bg=60, color_bb=20},
+			function(e)
+				e.radius = e.radius + 0.5
+				return true
+			end,
+			false
+		)
+		game:playSoundNear(self, "talents/tidalwave")
+		self:startTalentCooldown(t)
+	end,
+	info = function(self, t)
+		return ([[When a single blow deals more than 20%% of your total life blood gushes of your body, creating a bloody tidal wave for 4 turns that deals %0.2f blight damage and knocks back foes.
+			Damage increases with the Constitution stat.]])
+		:format(100 + self:getCon() * 3)
+	end,
+}
diff --git a/game/modules/tome/data/talents/uber/dex.lua b/game/modules/tome/data/talents/uber/dex.lua
index 769d25fce7..0399bccf43 100644
--- a/game/modules/tome/data/talents/uber/dex.lua
+++ b/game/modules/tome/data/talents/uber/dex.lua
@@ -52,3 +52,34 @@ uberTalent{
 		:format()
 	end,
 }
+
+uberTalent{
+	name = "Windblade",
+	mode = "activated",
+	require = { special={desc="Know at least 20 talent levels of stamina using talents.", fct=function(self) return knowRessource(self, "stamina", 20) end} },
+	cooldown = 20,
+	stamina = 30,
+	radius = 2,
+	range = 1,
+	target = function(self, t)
+		return {type="ball", range=self:getTalentRange(t), selffire=false, radius=self:getTalentRadius(t)}
+	end,
+	action = function(self, t)
+		local tg = self:getTalentTarget(t)
+		self:project(tg, self.x, self.y, function(px, py, tg, self)
+			local target = game.level.map(px, py, Map.ACTOR)
+			if target and target ~= self then
+				local hit = self:attackTarget(target, nil, 1.3, true)
+				if hit and target:canBe("disarm") then
+					target:setEffect(target.EFF_DISARMED, 4, {})
+				end
+			end
+		end)
+
+		return true
+	end,
+	info = function(self, t)
+		return ([[You spin madly in a gust of wind, dealing 140%% weapon damage to all foes in a radius 2 and disarming them for 4 turns.]])
+		:format()
+	end,
+}
diff --git a/game/modules/tome/data/talents/uber/str.lua b/game/modules/tome/data/talents/uber/str.lua
index 6b06aaffdf..e963328a20 100644
--- a/game/modules/tome/data/talents/uber/str.lua
+++ b/game/modules/tome/data/talents/uber/str.lua
@@ -16,3 +16,54 @@
 --
 -- Nicolas Casalini "DarkGod"
 -- darkgod@te4.org
+
+uberTalent{
+	name = "Flexible Combat",
+	mode = "passive",
+	on_learn = function(self, t)
+		self:attr("unharmed_attack_on_hit", 1)
+	end,
+	on_unlearn = function(self, t)
+		self:attr("unharmed_attack_on_hit", -1)
+	end,
+	info = function(self, t)
+		return ([[Each time you make a melee attack you have 100%% chances to do an additional unharmed strike, if using weapons and 60%% chances if already fighting unharmed.]])
+		:format()
+	end,
+}
+
+uberTalent{
+	name = "Titan's Smash",
+	mode = "activated",
+	require = { special={desc="Be of at least size category 'huge' (also required to use it) and know at least 20 talent levels of stamina using talents.", fct=function(self) return self.size_category and self.size_category >= 5 and knowRessource(self, "stamina", 20) end} },
+	on_pre_use = function(self, t) return self.size_category and self.size_category >= 5 end,
+	cooldown = 10,
+	stamina = 20,
+	action = function(self, t)
+		local tg = {type="hit", range=self:getTalentRange(t)}
+		local x, y, target = self:getTarget(tg)
+		if not x or not y or not target then return nil end
+		if core.fov.distance(self.x, self.y, x, y) > 1 then return nil end
+
+		local hit = self:attackTarget(target, nil, 2.3, true)
+
+		if target:attr("dead") or not hit then return end
+
+		local dx, dy = (target.x - self.x), (target.y - self.y)
+		local dir = util.coordToDir(dx, dy, 0)
+		local sides = util.dirSides(dir, 0)
+
+		target:knockback(self.x, self.y, 5, function(t2)
+			local d = rng.chance(2) and sides.hard_left or sides.hard_right
+			local sx, sy = util.coordAddDir(t2.x, t2.y, d)
+			t2:knockback(sx, sy, 2)
+			if t2:canBe("stun") then t2:setEffect(t2.EFF_STUNNED, 3, {}) end
+		end)
+		if target:canBe("stun") then target:setEffect(target.EFF_STUNNED, 3, {}) end
+	end,
+	info = function(self, t)
+		return ([[You deal a massive blow to your foe, smashing it for 230%% weapon damage and knocking it back 6 tiles away.
+		All foes in its path will be knocked on the sides and stunned for 3 turns.]])
+		:format()
+	end,
+}
diff --git a/game/modules/tome/data/talents/uber/uber.lua b/game/modules/tome/data/talents/uber/uber.lua
index 69d686f2ce..8401c1d515 100644
--- a/game/modules/tome/data/talents/uber/uber.lua
+++ b/game/modules/tome/data/talents/uber/uber.lua
@@ -24,6 +24,16 @@ newTalentType{ hide = true, type="uber/magic", name = "magic", description = "Ul
 newTalentType{ hide = true, type="uber/willpower", name = "willpower", description = "Ultimate talents you may only know one." }
 newTalentType{ hide = true, type="uber/cunning", name = "cunning", description = "Ultimate talents you may only know one." }
 
+
+knowRessource = function(self, r, v)
+	local cnt = 0
+	for tid, l in pairs(self.talents) do
+		local t = self:getTalentFromId(tid)
+		if rawget(t, r) or rawget(t, "sustain_"..r) then cnt = cnt + l end
+	end
+	return cnt >= v
+end
+
 uberTalent = function(t)
 	t.type = {"uber/strength", 1}
 	t.uber = true
diff --git a/game/modules/tome/data/talents/uber/wil.lua b/game/modules/tome/data/talents/uber/wil.lua
index 93144d4873..2434f232a7 100644
--- a/game/modules/tome/data/talents/uber/wil.lua
+++ b/game/modules/tome/data/talents/uber/wil.lua
@@ -19,7 +19,7 @@
 
 uberTalent{
 	name = "Draconic Will",
-	cooldown = 20,
+	cooldown = 15,
 	no_energy = true,
 	action = function(self, t)
 		self:setEffect(self.EFF_DRACONIC_WILL, 5, {})
diff --git a/game/modules/tome/data/zones/wilderness/zone.lua b/game/modules/tome/data/zones/wilderness/zone.lua
index c4cf10ecac..58427ec5a8 100644
--- a/game/modules/tome/data/zones/wilderness/zone.lua
+++ b/game/modules/tome/data/zones/wilderness/zone.lua
@@ -19,7 +19,7 @@
 
 return {
 	name = "World of Eyal",
-	display_name = function(x, y) return game.level.map.attrs(x or game.player.x, y or game.player.y, "zonename") or "Eyal" end,
+	display_name = function(x, y) return game.level and game.level.map.attrs(x or game.player.x, y or game.player.y, "zonename") or "Eyal" end,
 	variable_zone_name = true,
 	level_range = {1, 1},
 	max_level = 1,
diff --git a/game/modules/tome/dialogs/UberTalent.lua b/game/modules/tome/dialogs/UberTalent.lua
index 1c672f23fc..d2aac74fa4 100644
--- a/game/modules/tome/dialogs/UberTalent.lua
+++ b/game/modules/tome/dialogs/UberTalent.lua
@@ -107,6 +107,7 @@ function _M:onSelect(item)
 end
 
 function _M:use(item)
+	self.actor:learnTalent(item.data.talent, true)
 end
 
 function _M:getTalentDesc(item)
diff --git a/game/modules/tome/init.lua b/game/modules/tome/init.lua
index 8151d17821..b6a9c96632 100644
--- a/game/modules/tome/init.lua
+++ b/game/modules/tome/init.lua
@@ -22,8 +22,8 @@ long_name = "Tales of Maj'Eyal: Age of Ascendancy"
 short_name = "tome"
 author = { "DarkGod", "darkgod@te4.org" }
 homepage = "http://te4.org/"
-version = {0,9,42}
-engine = {0,9,42,"te4"}
+version = {0,9,43}
+engine = {0,9,43,"te4"}
 description = [[
 Welcome to Maj'Eyal.
 
-- 
GitLab