From 5ec84fe7b5fc98d7aae5a6b356fe78ec84b28309 Mon Sep 17 00:00:00 2001
From: dg <dg@51575b47-30f0-44d4-a5cc-537603b46e54>
Date: Wed, 4 Apr 2012 08:01:27 +0000
Subject: [PATCH] mindstar sets added

Hydra summoning eldritch eyes can no longer spawn more then one hydra at a time
Autocasting talents will not trigger when confused/terrified



git-svn-id: http://svn.net-core.org/repos/t-engine4@5018 51575b47-30f0-44d4-a5cc-537603b46e54
---
 game/modules/tome/class/Actor.lua             |  18 +-
 game/modules/tome/class/Object.lua            |  24 +-
 game/modules/tome/class/interface/Combat.lua  |   7 +
 game/modules/tome/data/damage_types.lua       |   4 +
 .../modules/tome/data/general/npcs/horror.lua |   1 +
 .../data/general/objects/egos/mindstars.lua   | 382 +++++++++++++-----
 .../tome/data/general/objects/mindstars.lua   |   4 +-
 .../tome/data/talents/chronomancy/gravity.lua |   4 +-
 .../modules/tome/data/talents/gifts/gifts.lua |   4 +
 .../tome/data/timed_effects/physical.lua      |  18 +
 10 files changed, 346 insertions(+), 120 deletions(-)

diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua
index 55ff2485e5..d9bd0e59ba 100644
--- a/game/modules/tome/class/Actor.lua
+++ b/game/modules/tome/class/Actor.lua
@@ -488,7 +488,7 @@ function _M:act()
 
 	if self.never_act then return false end
 
-	if not game.zone.wilderness then self:automaticTalents() end
+	if not game.zone.wilderness and not self:attr("confused") and not self:attr("terrified") then self:automaticTalents() end
 
 	-- Compute bonuses based on actors in FOV
 	if self:knowTalent(self.T_MILITANT_MIND) and not self:hasEffect(self.EFF_MILITANT_MIND) then
@@ -1539,10 +1539,10 @@ function _M:onTakeHit(value, src)
 	-- Spell cooldowns on hit
 	if self:attr("reduce_spell_cooldown_on_hit") and value >= self.max_life * self:attr("reduce_spell_cooldown_on_hit") / 100 then
 		local alt = {}
-		for tid, cd in pairs(self.talents_cd) do 
+		for tid, cd in pairs(self.talents_cd) do
 			if rng.percent(self:attr("reduce_spell_cooldown_on_hit_chance")) then alt[tid] = cd - 1 end
 		end
-		for tid, cd in pairs(alt) do 
+		for tid, cd in pairs(alt) do
 			if cd <= 0 then self.talents_cd[tid] = nil
 			else self.talents_cd[tid] = cd end
 		end
@@ -1579,7 +1579,7 @@ end
 
 function _M:takeHit(value, src, death_note)
 	local dead, val = engine.interface.ActorLife.takeHit(self, value, src, death_note)
-	
+
 	if dead and src and src.attr and src:attr("overkill") and src.project then
 		local dam = (self.die_at - self.life) * src:attr("overkill") / 100
 		src:project({type="ball", radius=2, selffire=false, x=self.x, y=self.y}, self.x, self.y, DamageType.BLIGHT, dam, {type="acid"})
@@ -2936,6 +2936,16 @@ function _M:postUseTalent(ab, ret)
 		value = self.tempeffect_def[self.EFF_RAMPAGE].do_postUseTalent(self, eff, value)
 	end
 
+	if ab.is_summon and ab.is_nature and self:attr("heal_on_nature_summon") then
+		local tg = {type="ball", range=0, radius=3,}
+		self:project(tg, self.x, self.y, function(px, py)
+			local target = game.level.map(px, py, Map.ACTOR)
+			if target and self:reactionToward(target) >= 0 then
+				target:heal(self:attr("heal_on_nature_summon"))
+			end
+		end)
+	end
+
 	return true
 end
 
diff --git a/game/modules/tome/class/Object.lua b/game/modules/tome/class/Object.lua
index cbab0127a1..147ec5546d 100644
--- a/game/modules/tome/class/Object.lua
+++ b/game/modules/tome/class/Object.lua
@@ -836,21 +836,31 @@ function _M:getTextualDesc(compare_with)
 		compare_fields(w, compare_with, field, "stamina_regen", "%+.2f", "Stamina each turn: ")
 		compare_fields(w, compare_with, field, "mana_regen", "%+.2f", "Mana each turn: ")
 		compare_fields(w, compare_with, field, "hate_regen", "%+.2f", "Hate each turn: ")
+		compare_fields(w, compare_with, field, "psi_regen", "%+.2f", "Psi each turn: ")
 		compare_fields(w, compare_with, field, "positive_regen", "%+.2f", "P.Energy each turn: ")
 
 		compare_fields(w, compare_with, field, "stamina_regen_on_hit", "%+.2f", "Stamina when hit: ")
 		compare_fields(w, compare_with, field, "mana_regen_on_hit", "%+.2f", "Mana when hit: ")
 		compare_fields(w, compare_with, field, "equilibrium_regen_on_hit", "%+.2f", "Equilibrium when hit: ")
+		compare_fields(w, compare_with, field, "psi_regen_on_hit", "%+.2f", "Psi when hit: ")
+		compare_fields(w, compare_with, field, "hate_regen_on_hit", "%+.2f", "Hate when hit: ")
 
 		compare_fields(w, compare_with, field, "mana_on_crit", "%+.2f", "Mana when firing critical spell: ")
 		compare_fields(w, compare_with, field, "vim_on_crit", "%+.2f", "Vim when firing critical spell: ")
 		compare_fields(w, compare_with, field, "spellsurge_on_crit", "%+d", "Spellpower on spell critical (stacks up to 3 times): ")
+		
+		compare_fields(w, compare_with, field, "hate_on_crit", "%+.2f", "Hate when firing a critical mind attack: ")
+		compare_fields(w, compare_with, field, "psi_on_crit", "%+.2f", "Psi when firing a critical mind attack: ")
+		compare_fields(w, compare_with, field, "equilibrium_on_crit", "%+.2f", "Equilibrium when firing a critical mind attack: ")
+		
+		compare_fields(w, compare_with, field, "hate_per_kill", "+%0.2f", "Hate per kill: ")
 
 		compare_fields(w, compare_with, field, "die_at", "%+.2f life", "Only die when reaching: ", 1, true, true)
 		compare_fields(w, compare_with, field, "max_life", "%+.2f", "Maximum life: ")
 		compare_fields(w, compare_with, field, "max_mana", "%+.2f", "Maximum mana: ")
 		compare_fields(w, compare_with, field, "max_stamina", "%+.2f", "Maximum stamina: ")
 		compare_fields(w, compare_with, field, "max_hate", "%+.2f", "Maximum hate: ")
+		compare_fields(w, compare_with, field, "max_psi", "%+.2f", "Maximum psi: ")
 		compare_fields(w, compare_with, field, "max_vim", "%+.2f", "Maximum vim: ")
 		compare_fields(w, compare_with, field, "max_air", "%+.2f", "Maximum air capacity: ")
 
@@ -874,7 +884,8 @@ function _M:getTextualDesc(compare_with)
 		compare_fields(w, compare_with, field, "combat_spellspeed", "%+d%%", "Casting speed: ", 100)
 
 		compare_fields(w, compare_with, field, "healing_factor", "%+d%%", "Healing mod.: ", 100)
-
+		compare_fields(w, compare_with, field, "heal_on_nature_summon", "%+d", "Heals friendly targets nearby when you use a nature summon: ")
+		
 		compare_fields(w, compare_with, field, "life_leech_chance", "%+d%%", "Life leech chance: ")
 		compare_fields(w, compare_with, field, "life_leech_value", "%+d%%", "Life leech: ")
 
@@ -886,9 +897,14 @@ function _M:getTextualDesc(compare_with)
 		compare_fields(w, compare_with, field, "defense_on_teleport", "%+d", "Defense after a teleport: ")
 		compare_fields(w, compare_with, field, "resist_all_on_teleport", "%+d%%", "Resist all after a teleport: ")
 		compare_fields(w, compare_with, field, "effect_reduction_on_teleport", "%+d%%", "Effect duration reduction after a teleport: ")
-
+		
+		compare_fields(w, compare_with, field, "damage_resonance", "%+d%%", "Damage Resonance (when hit): ")
+		
 		compare_fields(w, compare_with, field, "size_category", "%+d", "Size category: ")
-
+		
+		compare_fields(w, compare_with, field, "nature_summon_max", "%+d", "Max wilder summons: ")
+		compare_fields(w, compare_with, field, "nature_summon_regen", "%+.2f", "Life regen bonus (wilder-summons): ")
+		
 		if w.undead then
 			desc:add("The wearer is treated as an undead.", true)
 		end
@@ -1180,6 +1196,8 @@ function _M:getPriceFlags()
 		if w.stamina_regen_on_hit then price = price + w.stamina_regen_on_hit * 3 end
 		if w.equilibrium_regen_on_hit then price = price + w.equilibrium_regen_on_hit * 3 end
 		if w.mana_regen_on_hit then price = price + w.mana_regen_on_hit * 3 end
+		if w.psi_regen_on_hit then price = price + w.psi_regen_on_hit * 3 end
+		if w.hate_regen_on_hit then price = price + w.hate_regen_on_hit * 3 end
 		if w.resource_leech_chance then price = price + w.resource_leech_chance * 10 end
 		if w.resource_leech_value then price = price + w.resource_leech_value * 10 end
 
diff --git a/game/modules/tome/class/interface/Combat.lua b/game/modules/tome/class/interface/Combat.lua
index 446e07cdd9..694d3aa624 100644
--- a/game/modules/tome/class/interface/Combat.lua
+++ b/game/modules/tome/class/interface/Combat.lua
@@ -614,6 +614,8 @@ function _M:attackTargetWith(target, weapon, damtype, mult, force_dam)
 	if hitted and not target.dead and target:attr("stamina_regen_on_hit") then target:incStamina(target.stamina_regen_on_hit) end
 	if hitted and not target.dead and target:attr("mana_regen_on_hit") then target:incMana(target.mana_regen_on_hit) end
 	if hitted and not target.dead and target:attr("equilibrium_regen_on_hit") then target:incEquilibrium(-target.equilibrium_regen_on_hit) end
+	if hitted and not target.dead and target:attr("psi_regen_on_hit") then target:incPsi(target.psi_regen_on_hit) end
+	if hitted and not target.dead and target:attr("hate_regen_on_hit") then target:incHate(target.hate_regen_on_hit) end
 
 	if hitted and self:attr("stamina_use_on_hit") then
 		self:incStamina(-self.stamina_use_on_hit)
@@ -1203,6 +1205,11 @@ function _M:mindCrit(dam, add_chance)
 		dam = dam * (1.5 + (self.combat_critical_power or 0) / 100)
 		crit = true
 		game.logSeen(self, "#{bold}#%s's mind surges with critical power!#{normal}#", self.name:capitalize())
+		
+		if self:attr("hate_on_crit") then self:incMana(self:attr("hate_on_crit")) end
+		if self:attr("psi_on_crit") then self:incMana(self:attr("psi_on_crit")) end
+		if self:attr("equilibrium_on_crit") then self:incVim(self:attr("equilibrium_on_crit")) end
+		
 	end
 	return dam, crit
 end
diff --git a/game/modules/tome/data/damage_types.lua b/game/modules/tome/data/damage_types.lua
index e569d897d2..386903b051 100644
--- a/game/modules/tome/data/damage_types.lua
+++ b/game/modules/tome/data/damage_types.lua
@@ -264,6 +264,10 @@ setDefaultProjector(function(src, x, y, type, dam, tmp, no_martyr)
 
 		if target.knowTalent and target:knowTalent(target.T_RESOLVE) then local t = target:getTalentFromId(target.T_RESOLVE) t.on_absorb(target, t, type, dam) end
 
+		if target ~= src and target.attr and target:attr("damage_resonance") and not target:hasEffect(target.EFF_RESONANCE) then
+			target:setEffect(target.EFF_RESONANCE, 5, {damtype=type, dam=target:attr("damage_resonance_on_hit")})
+		end
+		
 		if not target.dead and dam > 0 and type == DamageType.MIND and src and src.knowTalent and src:knowTalent(src.T_MADNESS) then
 			local t = src:getTalentFromId(src.T_MADNESS)
 			t.doMadness(target, t, src)
diff --git a/game/modules/tome/data/general/npcs/horror.lua b/game/modules/tome/data/general/npcs/horror.lua
index 8e07ffd749..c77302ea42 100644
--- a/game/modules/tome/data/general/npcs/horror.lua
+++ b/game/modules/tome/data/general/npcs/horror.lua
@@ -338,6 +338,7 @@ newEntity{ base = "BASE_NPC_ELDRICTH_EYE",
 	_eldritch_eye_rarity = 1,
 	equilibrium_regen = -100,
 	resists = {[DamageType.ACID] = 80},
+	nature_summon_max = -1,
 	resolvers.talents{
 		[Talents.T_HYDRA]=3,
 	},
diff --git a/game/modules/tome/data/general/objects/egos/mindstars.lua b/game/modules/tome/data/general/objects/egos/mindstars.lua
index 717fc365b8..0d7912015e 100644
--- a/game/modules/tome/data/general/objects/egos/mindstars.lua
+++ b/game/modules/tome/data/general/objects/egos/mindstars.lua
@@ -20,176 +20,304 @@
 local Stats = require "engine.interface.ActorStats"
 local Talents = require "engine.interface.ActorTalents"
 
+------------------------------------------------
+-- Mindstar Sets -------------------------------
+------------------------------------------------
+-- Wild Cards: Capable of completing other sets
 newEntity{
-	power_source = {arcane=true},
-	name = " of power", suffix=true, instant_resolve=true,
-	keywords = {power=true},
-	level_range = {1, 50},
-	rarity = 4,
-	cost = 8,
-	wielder = {
-		combat_mindpower = resolvers.mbonus_material(16, 3),
-	},
-}
-
--------------------------------------------------------
---Nature and Antimagic---------------------------------
--------------------------------------------------------
- newEntity{
-	power_source = {arcane=true},
 	power_source = {nature=true},
-	name = "summoner's	", prefix=true, instant_resolve=true,
-	keywords = {summoners=true},
-	level_range = {1, 50},
-	rarity = 4,
-	cost = 8,
+	name = "harmonious ", prefix=true, instant_resolve=true,
+	keywords = {harmonious=true},
+	level_range = {30, 50},
+	greater_ego = 1,
+	rarity = 35,
+	cost = 40,
 	wielder = {
-		combat_mindpower = resolvers.mbonus_material(16, 3),
+		equilibrium_regen_on_hit = resolvers.mbonus_material(20, 5, function(e, v) v=v/10 return 0, v end),
+		talents_types_mastery = {
+			["wild-gift/harmony"] = resolvers.mbonus_material(1, 1, function(e, v) v=v/10 return 0, v end),
+		},
 	},
-}
-
-newEntity{
-	power_source = {nature=true},
-	name = "druid's ", prefix=true, instant_resolve=true,
-	keywords = {druid=true},
-	level_range = {1, 50},
-	rarity = 4,
-	cost = 8,
-	wielder = {
-		combat_mindpower = resolvers.mbonus_material(16, 3),
+	max_power = 20, power_regen = 1,
+	use_power = { name = "completes a nature powered mindstar set", power = 1,	
+		use = function(self, who, ms_inven)
+			who:showEquipInven("Harmonize with which mindstar?", function(o) return o.subtype == "mindstar" and o.set_list and o ~= self  and o.power_source and o.power_source.nature end, function(o) 
+				-- define the mindstar so it matches the set list of the target mindstar
+				self.define_as = o.set_list[1][2]
+				-- then set the mindstar's set list as the definition of the target mindstar
+				self.set_list = { {"define_as", o.define_as} }
+				-- and copies the target mindstar's on set complete
+				self.on_set_complete = o.on_set_complete
+				-- remove the mindstar and rewear it to trigger set bonuses
+				local obj = who:takeoffObject(ms_inven, 1)
+				who:wearObject(obj, true)
+				return true
+			end)
+			return {id=true, used=true}
+		end
 	},
 }
 
-newEntity{
-	power_source = {nature=true},
-	name = "nature's ", prefix=true, instant_resolve=true,
-	keywords = {nature=true},
-	level_range = {1, 50},
-	rarity = 4,
-	cost = 8,
-	wielder = {
-		combat_mindpower = resolvers.mbonus_material(16, 3),
-	},
-}
-
-newEntity{
-	power_source = {nature=true},
-	name = "wyrmic's ", prefix=true, instant_resolve=true,
-	keywords = {wyrmic=true},
-	level_range = {1, 50},
-	rarity = 4,
-	cost = 8,
+ newEntity{
+	power_source = {psionic=true}, define_as = "MS_EGO_SET_PSIONIC", -- Can complete any psionic MS set
+	name = "resonating ", prefix=true, instant_resolve=true,
+	keywords = {resonating=true},
+	level_range = {30, 50},
+	greater_ego = 1,
+	rarity = 35,
+	cost = 40,
 	wielder = {
-		combat_mindpower = resolvers.mbonus_material(16, 3),
+		damage_resonance = resolvers.mbonus_material(20, 5),
+		psi_regen_on_hit = resolvers.mbonus_material(20, 5, function(e, v) v=v/10 return 0, v end),
 	},
-}
-
-newEntity{
-	power_source = {nature=true},
-	name = " of harmony", suffix=true, instant_resolve=true,
-	keywords = {harmony=true},
-	level_range = {1, 50},
-	rarity = 4,
-	cost = 8,
-	wielder = {
-		combat_mindpower = resolvers.mbonus_material(16, 3),
+	max_power = 20, power_regen = 1,
+	use_power = { name = "completes a nature powered mindstar set", power = 1,	
+		use = function(self, who, ms_inven)
+			who:showEquipInven("Resonate with which mindstar?", function(o) return o.subtype == "mindstar" and o.set_list and o ~= self  and o.power_source and o.power_source.psionic end, function(o) 
+				-- define the mindstar so it matches the set list of the target mindstar
+				self.define_as = o.set_list[1][2]
+				-- then set the mindstar's set list as the definition of the target mindstar
+				self.set_list = { {"define_as", o.define_as} }
+				-- and copies the target mindstar's on set complete
+				self.on_set_complete = o.on_set_complete
+				-- remove the mindstar and rewear it to trigger set bonuses
+				local obj = who:takeoffObject(ms_inven, 1)
+				who:wearObject(obj, true)
+				return true
+			end)
+			return {id=true, used=true}
+		end
 	},
 }
 
-newEntity{
-	power_source = {nature=true},
-	name = "fire-drake's ", prefix=true, instant_resolve=true,
-	keywords = {fire=true},
+-- Caller's Set: For summoners!
+ newEntity{
+	power_source = {nature=true},  define_as = "MS_EGO_SET_CALLERS",
+	name = "caller's ", prefix=true, instant_resolve=true,
+	keywords = {callers=true},
 	level_range = {30, 50},
 	greater_ego = 1,
 	rarity = 40,
 	cost = 40,
 	wielder = {
-		combat_mindpower = resolvers.mbonus_material(16, 3),
+		inc_damage = { 
+			[DamageType.FIRE] = resolvers.mbonus_material(10, 5),
+			[DamageType.ACID] = resolvers.mbonus_material(10, 5),
+			[DamageType.COLD] = resolvers.mbonus_material(10, 5),
+			[DamageType.PHYSICAL] = resolvers.mbonus_material(10, 5),
+		},
 	},
+	set_list = { {"define_as", "MS_EGO_SET_SUMMONERS"} },
+	on_set_complete = function(self, who)
+		game.logPlayer(who, "#GREEN#Your mindstars resonate with Nature's purity.")
+		self:specialSetAdd({"wielder","nature_summon_regen"}, self.material_level)
+	end,
+	on_set_broken = function(self, who)
+		game.logPlayer(who, "#SLATE#The link between the mindstars is broken.")
+	end
 }
 
-newEntity{
-	power_source = {nature=true},
-	name = "cold-drake's ", prefix=true, instant_resolve=true,
-	keywords = {cold=true},
+ newEntity{
+	power_source = {nature=true}, define_as = "MS_EGO_SET_SUMMONERS",
+	name = "summoner's ", prefix=true, instant_resolve=true,
+	keywords = {summoners=true},
 	level_range = {30, 50},
 	greater_ego = 1,
-	rarity = 40,
+	rarity = 30,
 	cost = 40,
 	wielder = {
-		combat_mindpower = resolvers.mbonus_material(16, 3),
+		combat_mindpower = resolvers.mbonus_material(10, 2),
+		combat_mindcrit = resolvers.mbonus_material(5, 1),
 	},
+	set_list = { {"define_as", "MS_EGO_SET_CALLERS"} },
+	on_set_complete = function(self, who)
+		game.logPlayer(who, "#GREEN#Your mindstars resonate with Nature's purity.")
+		self:specialSetAdd({"wielder","nature_summon_max"}, 1)
+	end,
+	on_set_broken = function(self, who)
+		game.logPlayer(who, "#SLATE#The link between the mindstars is broken.")
+	end
 }
 
-newEntity{
-	power_source = {nature=true},
-	name = "storm-drake's ", prefix=true, instant_resolve=true,
-	keywords = {storm=true},
+-- Mentalist Set: For a yet to be written psi class and/or Mindslayers
+ newEntity{
+	power_source = {psionic=true},  define_as = "MS_EGO_SET_DREAMERS",
+	name = "dreamer's ", prefix=true, instant_resolve=true,
+	keywords = {dreamers=true},
 	level_range = {30, 50},
 	greater_ego = 1,
 	rarity = 40,
 	cost = 40,
 	wielder = {
-		combat_mindpower = resolvers.mbonus_material(16, 3),
+		combat_mentalresist = resolvers.mbonus_material(8, 2),
+		max_psi = resolvers.mbonus_material(50, 10),
+		resists = { [DamageType.MIND] = resolvers.mbonus_material(20, 5), }
 	},
+	set_list = { {"define_as", "MS_EGO_SET_EPIPHANOUS"} },
+	on_set_complete = function(self, who)
+		game.logPlayer(who, "#YELLOW#Your mindstars resonate with psionic energy.")
+		self:specialSetAdd({"wielder","psi_regen"}, self.material_level / 10)
+	end,
+	on_set_broken = function(self, who)
+		game.logPlayer(who, "#SLATE#The link between the mindstars is broken.")
+	end
 }
 
-newEntity{
-	power_source = {nature=true},
-	name = "sand-drake's ", prefix=true, instant_resolve=true,
-	keywords = {storm=true},
+ newEntity{
+	power_source = {psionic=true}, define_as = "MS_EGO_SET_EPIPHANOUS",
+	name = "epiphanous ", prefix=true, instant_resolve=true,
+	keywords = {epiphanous=true},
 	level_range = {30, 50},
 	greater_ego = 1,
-	rarity = 40,
+	rarity = 30,
 	cost = 40,
 	wielder = {
-		combat_mindpower = resolvers.mbonus_material(16, 3),
+		combat_mindpower = resolvers.mbonus_material(5, 1),
+		combat_mindcrit = resolvers.mbonus_material(5, 1),
+		inc_damage = { [DamageType.MIND] = resolvers.mbonus_material(20, 5), },
 	},
+	set_list = { {"define_as", "MS_EGO_SET_DREAMERS"} },
+	on_set_complete = function(self, who)
+		game.logPlayer(who, "#YELLOW#Your mindstars resonate with psionic energy.")
+		self:specialSetAdd({"wielder","psi_on_crit"}, self.material_level)
+	end,
+	on_set_broken = function(self, who)
+		game.logPlayer(who, "#SLATE#The link between the mindstars is broken.")
+	end
 }
 
-newEntity{
+-- Mitotic Set: Single Mindstar that splits in two
+ newEntity{
 	power_source = {nature=true},
-	name = " of calling", suffix=true, instant_resolve=true,
-	keywords = {calling=true},
+	name = "mitotic ", prefix=true, instant_resolve=true,
+	keywords = {mitotic=true},
 	level_range = {30, 50},
 	greater_ego = 1,
-	rarity = 40,
-	cost = 40,
-	wielder = {
-		combat_mindpower = resolvers.mbonus_material(16, 3),
+	rarity = 45,
+	cost = 10,  -- cost is very low to discourage players from splitting them to make extra gold..  because that would be tedious and unfun
+	combat = {
+		physcrit = resolvers.mbonus_material(10, 2),
+		melee_project = { [DamageType.ACID_BLIND]= resolvers.mbonus_material(15, 5), [DamageType.SLIME]= resolvers.mbonus_material(15, 5),},
+	},
+	max_power = 1, power_regen = 1,
+	use_power = { name = "divide the mindstar in two", power = 1,
+		use = function(self, who)
+			-- Check for free slot first
+			if who:getFreeHands() == 0 then
+				game.logPlayer(who, "You must have a free hand to divide %s", self.name)
+			return 
+			end
+
+			if who:getInven("PSIONIC_FOCUS")[1] == self then
+				game.logPlayer(who, "You cannot split %s while using it as a psionic focus.", self.name)
+				return
+			end
+			
+			local weapon = who:getInven("MAINHAND") or who:getInven("OFFHAND")
+			local o = who:takeoffObject(weapon, 1)
+			
+			-- Remove some properties before cloning
+			o.cost = self.cost / 2 -- more don't split for extra gold discouragement
+			o.max_power = nil
+			o.power_regen = nil
+			o.use_power = nil
+			local o2 = o:clone()
+			
+			-- Build the item set
+			o.is_mitotic_acid = true
+			o2.is_mitotic_slime = true
+			o.set_list = { {"is_mitotic_slime", true} }
+			o2.set_list = { {"is_mitotic_acid", true} }
+
+			o.on_set_complete = function(self, who)
+				self:specialWearAdd({"combat","burst_on_crit"}, { [engine.DamageType.ACID_BLIND] = 10 * o.material_level } )
+				game.logPlayer(who, "#GREEN#The mindstars pulse with life.")
+			end
+			o.on_set_broken = function(self, who)
+				game.logPlayer(who, "#SLATE#The link between the mindstars is broken.")
+			end
+			
+			o2.on_set_complete = function(self, who)
+				self:specialWearAdd({"combat","burst_on_crit"}, { [engine.DamageType.SLIME] = 10 * o.material_level } )
+			end
+			
+			who:wearObject(o, true)
+			who:wearObject(o2, true, true)
+			
+			-- Because we're removing the use_power we're not returning that it was used; instead we'll have the actor use energy manually
+			who:useEnergy()
+		end
 	},
 }
 
+-- Wrathful Set: Geared towards Afflicted
 newEntity{
-	power_source = {nature=true},
-	name = " of the arch-druid", suffix=true, instant_resolve=true,
-	keywords = {archdruid=true},
+	power_source = {psionic=true}, define_as = "MS_EGO_SET_HATEFUL",
+	name = "hateful ", prefix=true, instant_resolve=true,
+	keywords = {hateful=true},
 	level_range = {30, 50},
-	greater_ego = 1,
-	rarity = 40,
-	cost = 40,
+	greater_ego =1,
+	rarity = 35,
+	cost = 35,
 	wielder = {
-		combat_mindpower = resolvers.mbonus_material(16, 3),
+		inc_damage={
+			[DamageType.MIND] = resolvers.mbonus_material(20, 5),
+			[DamageType.DARKNESS] = resolvers.mbonus_material(20, 5),
+		},
+		inc_damage_type = {humanoid=resolvers.mbonus_material(20, 5)},
 	},
+	set_list = { {"define_as", "MS_EGO_SET_WRATHFUL"} },
+	on_set_complete = function(self, who)
+		self:specialSetAdd({"wielder","combat_mindpower"}, 2 * self.material_level)
+		game.logPlayer(who, "#GREY#You feel a swell of hatred from your mindstars.")
+	end,
+	on_set_broken = function(self, who)
+		game.logPlayer(who, "#SLATE#The mindstar resonance has faded.")
+	end,
 }
 
-newEntity{
-	power_source = {nature=true},
-	name = " of the great-wyrm", suffix=true, instant_resolve=true,
-	keywords = {wyrm=true},
+ newEntity{
+	power_source = {psionic=true}, define_as = "MS_EGO_SET_WRATHFUL",
+	name = "wrathful ", prefix=true, instant_resolve=true,
+	keywords = {wrath=true},
 	level_range = {30, 50},
 	greater_ego = 1,
 	rarity = 40,
 	cost = 40,
 	wielder = {
-		combat_mindpower = resolvers.mbonus_material(16, 3),
+		psi_on_crit = resolvers.mbonus_material(5, 1),
+		hate_on_crit = resolvers.mbonus_material(5, 1),
+		combat_mindcrit = resolvers.mbonus_material(10, 2),
+	},
+	set_list = { {"define_as", "MS_EGO_SET_HATEFUL"} },
+	on_set_complete = function(self, who)
+		self:specialSetAdd({"wielder","max_hate"}, 2 * self.material_level)
+		game.logPlayer(who, "#GREY#You feel a swell of hatred from your mindstars.")
+	end,
+	on_set_broken = function(self, who)
+		game.logPlayer(who, "#SLATE#The mindstar resonance has faded.")
+	end,
+}
+-------------------------------------------------------
+--Nature and Antimagic---------------------------------
+-------------------------------------------------------
+ newEntity{
+	power_source = {nature=true},
+	name = "blooming ", prefix=true, instant_resolve=true,
+	keywords = {blooming=true},
+	level_range = {1, 50},
+	rarity = 8,
+	cost = 8,
+	wielder = {
+		heal_on_nature_summon = resolvers.mbonus_material(25, 5),
+		healing_factor = resolvers.mbonus_material(20, 10, function(e, v) v=v/100 return 0, v end),
 	},
 }
 
 -------------------------------------------------------
 --Psionic----------------------------------------------
 -------------------------------------------------------
+
 newEntity{
 	power_source = {psionic=true},
 	name = "gifted ", prefix=true, instant_resolve=true,
@@ -198,22 +326,56 @@ newEntity{
 	rarity = 4,
 	cost = 8,
 	wielder = {
-		combat_mindpower = resolvers.mbonus_material(16, 3),
+		combat_mindpower = resolvers.mbonus_material(10, 2),
 	},
 }
 
 newEntity{
 	power_source = {psionic=true},
-	name = "psychic's ", prefix=true, instant_resolve=true,
-	keywords = {psychic=true},
+	name = "horrifying ", prefix=true, instant_resolve=true,
+	keywords = {horrifying=true},
 	level_range = {1, 50},
 	rarity = 4,
 	cost = 8,
 	wielder = {
-		combat_mindpower = resolvers.mbonus_material(16, 3),
+		inc_damage={
+			[DamageType.MIND] = resolvers.mbonus_material(8, 2),
+			[DamageType.DARKNESS] = resolvers.mbonus_material(8, 2),
+		},
+	},
+}
+
+ newEntity{
+	power_source = {psionic=true},
+	name = "hungering ", prefix=true, instant_resolve=true,
+	keywords = {hungering=true},
+	level_range = {30, 50},
+	greater_ego = 1,
+	rarity = 30,
+	cost = 40,
+	wielder = {
+		talents_types_mastery = {
+			["psionic/voracity"] = resolvers.mbonus_material(1, 1, function(e, v) v=v/10 return 0, v end),
+			["cursed/dark-sustenance"] = resolvers.mbonus_material(1, 1, function(e, v) v=v/10 return 0, v end),
+		},
+		hate_on_kill = resolvers.mbonus_material(4, 1),
+	},
+}
+
+ newEntity{
+	power_source = {psionic=true},
+	name = "wrathful ", prefix=true, instant_resolve=true,
+	keywords = {wrath=true},
+	level_range = {1, 50},
+	rarity = 6,
+	cost = 8,
+	wielder = {
+		hate_on_crit = resolvers.mbonus_material(5, 1),
+		combat_mindcrit = resolvers.mbonus_material(5, 1),
 	},
 }
 
+--[[ Not done
 newEntity{
 	power_source = {psionic=true},
 	name = " of clarity", suffix=true, instant_resolve=true,
@@ -284,4 +446,4 @@ newEntity{
 	wielder = {
 		combat_mindpower = resolvers.mbonus_material(16, 3),
 	},
-}
\ No newline at end of file
+}]]
\ No newline at end of file
diff --git a/game/modules/tome/data/general/objects/mindstars.lua b/game/modules/tome/data/general/objects/mindstars.lua
index d48bd315cc..2924ccf817 100644
--- a/game/modules/tome/data/general/objects/mindstars.lua
+++ b/game/modules/tome/data/general/objects/mindstars.lua
@@ -70,7 +70,7 @@ newEntity{ base = "BASE_MINDSTAR",
 		dammod = {wil=1},
 	},
 	wielder = {
-		combat_mindpower = 1,
+		combat_mindpower = 2,
 		combat_mindcrit = 2,
 	},
 }
@@ -88,7 +88,7 @@ newEntity{ base = "BASE_MINDSTAR",
 		dammod = {wil=1},
 	},
 	wielder = {
-		combat_mindpower = 2,
+		combat_mindpower = 3,
 		combat_mindcrit = 3,
 	},
 }
diff --git a/game/modules/tome/data/talents/chronomancy/gravity.lua b/game/modules/tome/data/talents/chronomancy/gravity.lua
index c5e0552816..00504f61a5 100644
--- a/game/modules/tome/data/talents/chronomancy/gravity.lua
+++ b/game/modules/tome/data/talents/chronomancy/gravity.lua
@@ -47,7 +47,8 @@ newTalent{
 	info = function(self, t)
 		local damage = t.getDamage(self, t)
 		local radius = self:getTalentRadius(t)
-		return ([[Sends out a wave of repulsion in a %d radius cone, dealing %0.2f physical damage and knocking back creatures caught in the area.  Deals 50%% extra damage to pinned targets.
+		return ([[Sends out a blast wave of gravity in a %d radius cone, dealing %0.2f physical damage and knocking back creatures caught in the area.  Deals 50%% extra damage to pinned targets.
+		The blast wave may hit targets more then once depending on radius and the knockback effect.
 		The damage will scale with your Paradox and Spellpower.]]):
 		format(radius, damDesc(self, DamageType.PHYSICAL, t.getDamage(self, t)))
 	end,
@@ -142,6 +143,7 @@ newTalent{
 		local duration = t.getDuration(self, t)
 		local radius = self:getTalentRadius(t)
 		return ([[You surround yourself with a radius %d aura of gravity distortion that will knockback and deal %0.2f physical damage to all creatures.  The effect lasts %d turns.  Deals 50%% extra damage to pinned targets. 
+		The blast wave may hit targets more then once depending on radius and the knockback effect.
 		The damage will scale with your Paradox and Spellpower.]]):format(radius, damDesc(self, DamageType.PHYSICAL, damage), duration)
 	end,
 }
diff --git a/game/modules/tome/data/talents/gifts/gifts.lua b/game/modules/tome/data/talents/gifts/gifts.lua
index 455ae1f65d..46c454e826 100644
--- a/game/modules/tome/data/talents/gifts/gifts.lua
+++ b/game/modules/tome/data/talents/gifts/gifts.lua
@@ -99,6 +99,9 @@ function checkMaxSummon(self, silent)
 	end
 
 	local max = math.max(1, math.floor(self:getCun() / 10))
+	if self:attr("nature_summon_max") then
+		max = max + self:attr("nature_summon_max")
+	end
 	if nb >= max then
 		if not silent then
 			game.logPlayer(self, "#PINK#You can not summon any more; you have too many summons already (%d). You can increase the limit with higher Cunning(+1 for every 10).", nb)
@@ -122,6 +125,7 @@ function setupSummon(self, m, x, y, no_control)
 	-- Try to use stored AI talents to preserve tweaking over multiple summons
 	m.ai_talents = self.stored_ai_talents and self.stored_ai_talents[m.name] or {}
 	local main_weapon = self:getInven("MAINHAND") and self:getInven("MAINHAND")[1]
+	m.life_regen = m.life_regen + self:attr("nature_summon_regen")
 	m:attr("combat_apr", self:combatAPR(main_weapon))
 	m.inc_damage = table.clone(self.inc_damage, true)
 	m.resists_pen = table.clone(self.resists_pen, true)
diff --git a/game/modules/tome/data/timed_effects/physical.lua b/game/modules/tome/data/timed_effects/physical.lua
index 2212f35e40..c28ec3d948 100644
--- a/game/modules/tome/data/timed_effects/physical.lua
+++ b/game/modules/tome/data/timed_effects/physical.lua
@@ -1658,3 +1658,21 @@ newEffect{
 		self:removeTemporaryValue("spell_failure", eff.tmpid)
 	end,
 }
+
+newEffect{
+	name = "RESONANCE", image = "talents/alchemist_protection.png",
+	desc = "Resonance",
+	long_desc = function(self, eff) return ("+%d%% %s damage."):format(eff.dam, DamageType:get(eff.damtype).name) end,
+	type = "physical",
+	subtype = { nature=true },
+	status = "beneficial",
+	parameters = { dam=10, damtype=DamageType.ARCANE },
+	on_gain = function(self, err) return "#Target# resonates with the damage.", "+Resonance" end,
+	on_lose = function(self, err) return "#Target# is no longer resonating.", "-Resonance" end,
+	activate = function(self, eff)
+		eff.tmpid = self:addTemporaryValue("inc_damage", {[eff.damtype]=eff.dam})
+	end,
+	deactivate = function(self, eff)
+		self:removeTemporaryValue("inc_damage", eff.tmpid)
+	end,
+}
\ No newline at end of file
-- 
GitLab