diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua
index cff8b6c5902fcce80969fd57c3968c01a2e1b6c0..ecf436664a0d9e288f41fa79cad3c72a793bdcc8 100644
--- a/game/modules/tome/class/Actor.lua
+++ b/game/modules/tome/class/Actor.lua
@@ -80,6 +80,7 @@ function _M:init(t, no_default)
 	self.combat_spellcrit = 0
 	self.combat_spellpower = 0
 	self.combat_mindpower = 0
+	self.combat_mindcrit = 0
 
 	self.combat_physresist = 0
 	self.combat_spellresist = 0
@@ -1069,6 +1070,11 @@ function _M:onTakeHit(value, src)
 		game.logPlayer(self, "#AQUAMARINE#You leech a part of %s vim.", src.name:capitalize())
 	end
 
+	if value >= self.max_life * 0.15 and self:attr("invis_on_hit") and rng.percent(self:attr("invis_on_hit")) then
+		self:setEffect(self.EFF_INVISIBILITY, 5, {power=self:attr("invis_on_hit_power")})
+		for tid, _ in pairs(self.invis_on_hit_disable) do self:forceUseTalent(tid, {ignore_energy=true}) end
+	end
+
 	return value
 end
 
diff --git a/game/modules/tome/data/talents/misc/races.lua b/game/modules/tome/data/talents/misc/races.lua
index fcf9443951ef6652b0def3199417d9632cee01e7..ed069ebe235ddca6958ed4ee95cffb0e379de4e5 100644
--- a/game/modules/tome/data/talents/misc/races.lua
+++ b/game/modules/tome/data/talents/misc/races.lua
@@ -134,14 +134,15 @@ newTalent{
 ------------------------------------------------------------------
 -- Shaloren's powers
 ------------------------------------------------------------------
-newTalentType{ type="race/shalore", name = "shalore", generic = true, description = "The various racial bonuses a character can have." }
+newTalentType{ type="race/shalore", name = "shalore", generic = true, is_spell=true, description = "The various racial bonuses a character can have." }
 newTalent{
 	short_name = "SHALOREN_SPEED",
 	name = "Grace of the Eternals",
 	type = {"race/shalore", 1},
 	require = racial_req1,
+	points = 5,
 	no_energy = true,
-	cooldown = function(self, t) return 50 - self:getTalentLevel(t) * 5 end,
+	cooldown = function(self, t) return 50 - self:getTalentLevel(t) * 4 end,
 	tactical = { DEFEND = 1 },
 	action = function(self, t)
 		local power = 0.1 + self:getDex() / 210
@@ -154,6 +155,126 @@ newTalent{
 	end,
 }
 
+newTalent{
+	name = "Magic of the Eternals",
+	type = {"race/shalore", 2},
+	require = racial_req2,
+	points = 5,
+	mode = "passive",
+	on_learn = function(self, t)
+		self.combat_physcrit = self.combat_physcrit + 2
+		self.combat_spellcrit = self.combat_spellcrit + 2
+		self.combat_mindcrit = self.combat_mindscrit + 2
+	end,
+	on_unlearn = function(self, t)
+		self.combat_physcrit = self.combat_physcrit - 2
+		self.combat_spellcrit = self.combat_spellcrit - 2
+		self.combat_mindcrit = self.combat_mindscrit - 2
+	end,
+	info = function(self, t)
+		return ([[Reality bends slightly in the presence of a Shaloren due to their inherent magical nature.
+		Increases critical chance by %d%%.]]):format(self:getTalentLevelRaw(t) * 2)
+	end,
+}
+
+newTalent{
+	name = "Secrets of the Eternals",
+	type = {"race/shalore", 3},
+	require = racial_req3,
+	points = 5,
+	cooldown = 50,
+	mode = "sustained",
+	activate = function(self, t)
+		self.invis_on_hit_disable = self.invis_on_hit_disable or {}
+		game:playSoundNear(self, "talents/spell_generic2")
+		local ret = {
+			invis = self:addTemporaryValue("invis_on_hit", self:getTalentLevelRaw(t) * 5),
+			power = self:addTemporaryValue("invis_on_hit_power", 5 + self:getMag(20)),
+			talent = self:addTemporaryValue("invis_on_hit_disable", {[t.id]=1}),
+		}
+		return ret
+	end,
+	deactivate = function(self, t, p)
+		self:removeTemporaryValue("invis_on_hit", p.invis)
+		self:removeTemporaryValue("invis_on_hit_power", p.power)
+		self:removeTemporaryValue("invis_on_hit_disable", p.talent)
+		return true
+	end,
+	info = function(self, t)
+		return ([[As the only immortal race of Eyal, Shaloren have learnt to use their innate inner magic to protect themselves.
+		%d%% chances to become invisible (power %d) for 5 turns when hit by a blow doing at least 15%% of their total life.]]):
+		format(self:getTalentLevelRaw(t) * 5, 5 + self:getMag(20))
+	end,
+}
+
+newTalent{
+	name = "Timeless",
+	type = {"race/shalore", 4},
+	require = racial_req4,
+	points = 5,
+	no_energy = true,
+	cooldown = function(self, t) return 50 - self:getTalentLevel(t) * 3 end,
+	tactical = { ATTACK = 2 },
+	action = function(self, t)
+		local tg = {type="bolt", nowarning=true, range=self:getTalentRange(t), nolock=true, talent=t}
+		local tx, ty, target = self:getTarget(tg)
+		if not tx or not ty then return nil end
+		local _ _, tx, ty = self:canProject(tg, tx, ty)
+		target = game.level.map(tx, ty, Map.ACTOR)
+		if target == self then target = nil end
+
+		-- Find space
+		for i = 1, 2 do
+			local x, y = util.findFreeGrid(tx, ty, 5, true, {[Map.ACTOR]=true})
+			if not x then
+				game.logPlayer(self, "Not enough space to summon!")
+				return
+			end
+
+			local NPC = require "mod.class.NPC"
+			local m = NPC.new{
+				type = "immovable", subtype = "plants",
+				display = "#",
+				name = "treant", color=colors.GREEN,
+				desc = "A very strong near-sentient tree.",
+
+				body = { INVEN = 10, MAINHAND=1, OFFHAND=1, BODY=1 },
+
+				rank = 3,
+				life_rating = 13,
+				max_life = resolvers.rngavg(50,80),
+				infravision = 20,
+
+				autolevel = "none",
+				ai = "summoned", ai_real = "tactical", ai_state = { talent_in=2, },
+				stats = {str=0, dex=0, con=0, cun=0, wil=0, mag=0},
+				combat = { dam=resolvers.levelup(resolvers.rngavg(15,25), 1, 1.3), atk=resolvers.levelup(resolvers.rngavg(15,25), 1, 1.3), dammod={str=1.1} },
+				inc_stats = { str=25 + self:getWil() * self:getTalentLevel(t) / 5, dex=18, con=10 + self:getTalentLevel(t) * 2, },
+
+				level_range = {1, nil}, exp_worth = 0,
+				silent_levelup = true,
+
+				combat_armor = 13, combat_def = 8,
+				resolvers.talents{ [Talents.T_STUN]=3, [Talents.T_KNOCKBACK]=2, },
+
+				faction = self.faction,
+				summoner = self, summoner_gain_exp=true,
+				summon_time = 6,
+				ai_target = {actor=target}
+			}
+			setupSummon(self, m, x, y)
+		end
+
+		game:playSoundNear(self, "talents/spell_generic")
+		return true
+	end,
+	info = function(self, t)
+		return ([[Nature is with you, you can always feel the call of the woods.
+		Summons two elite Treants to your side for 6 turns.
+		Their strength increase with your Willpower stat]]):format()
+	end,
+}
+
 ------------------------------------------------------------------
 -- Thaloren powers
 ------------------------------------------------------------------
@@ -294,6 +415,7 @@ newTalent{
 	name = "Resilience of the Dwarves",
 	type = {"race/dwarf", 1},
 	require = racial_req1,
+	points = 5,
 	no_energy = true,
 	cooldown = function(self, t) return 50 - self:getTalentLevel(t) * 5 end,
 	tactical = { DEFEND = 2 },
@@ -320,6 +442,7 @@ newTalent{
 	name = "Luck of the Little Folk",
 	type = {"race/halfling", 1},
 	require = racial_req1,
+	points = 5,
 	no_energy = true,
 	cooldown = function(self, t) return 50 - self:getTalentLevel(t) * 5 end,
 	tactical = { ATTACK = 2 },
@@ -345,6 +468,7 @@ newTalent{
 	name = "Orcish Fury",
 	type = {"race/orc", 1},
 	require = racial_req1,
+	points = 5,
 	no_energy = true,
 	cooldown = function(self, t) return 50 - self:getTalentLevel(t) * 5 end,
 	tactical = { ATTACK = 2 },
@@ -367,6 +491,7 @@ newTalent{
 	name = "Dominant Will",
 	type = {"race/yeek", 1},
 	require = racial_req1,
+	points = 5,
 	no_energy = true,
 	cooldown = function(self, t) return 50 - self:getTalentLevel(t) * 3 end,
 	range = 4,
diff --git a/game/modules/tome/data/timed_effects.lua b/game/modules/tome/data/timed_effects.lua
index e1e79dc2d2c100fc94b0f43ab1e6c5358b26732c..72a0e904794c3f2bdbcc48f79855dacb264f044e 100644
--- a/game/modules/tome/data/timed_effects.lua
+++ b/game/modules/tome/data/timed_effects.lua
@@ -2013,6 +2013,18 @@ newEffect{
 	parameters = { hp=10, regen=10 },
 	on_gain = function(self, err) return nil, "+Bloodbath" end,
 	on_lose = function(self, err) return nil, "-Bloodbath" end,
+	on_merge = function(self, old_eff, new_eff)
+		self:removeTemporaryValue("max_life", old_eff.life_id)
+		self:removeTemporaryValue("life_regen", old_eff.life_regen_id)
+		self:removeTemporaryValue("stamina_regen", old_eff.stamina_regen_id)
+
+		-- Take the new values, dont heal, otherwise you get a free heal each crit .. which is totaly broken
+		local v = new_eff.hp * self.max_life / 100
+		new_eff.life_id = self:addTemporaryValue("max_life", v)
+		new_eff.life_regen_id = self:addTemporaryValue("life_regen", new_eff.regen * self.life_regen / 100)
+		new_eff.stamina_regen_id = self:addTemporaryValue("stamina_regen", new_eff.regen * self.stamina_regen / 100)
+		return new_eff
+	end,
 	activate = function(self, eff)
 		local v = eff.hp * self.max_life / 100
 		eff.life_id = self:addTemporaryValue("max_life", v)
diff --git a/ideas/races.ods b/ideas/races.ods
index 1b21044c6ad18fc6be08b6ec121dc89fb2d22b68..f1f1cb96e4816ab94252b4f4c46d06e79c9ce60c 100644
Binary files a/ideas/races.ods and b/ideas/races.ods differ