diff --git a/game/engines/default/engine/interface/ActorInventory.lua b/game/engines/default/engine/interface/ActorInventory.lua
index a151efe2ddf67c7c722a9bf581015a2c727f837e..c8c236b174c3b66b6a8e7018cd11f9f2514f1678 100644
--- a/game/engines/default/engine/interface/ActorInventory.lua
+++ b/game/engines/default/engine/interface/ActorInventory.lua
@@ -98,7 +98,6 @@ function _M:addObject(inven_id, o)
 	-- Do whatever is needed when wearing this object
 	if inven.worn then
 		self:onWear(o)
-		o:check("on_wear", self)
 	end
 
 	self:onAddObject(o)
@@ -169,7 +168,6 @@ function _M:removeObject(inven, item, no_unstack)
 	-- Do whatever is needed when taking off this object
 	if inven.worn then
 		self:onTakeoff(o)
-		o:check("on_takeoff", self)
 	end
 
 	self:onRemoveObject(o)
@@ -377,6 +375,7 @@ end
 function _M:onWear(o)
 	-- Apply wielder properties
 	o.wielded = {}
+	o:check("on_wear", self)
 	if o.wielder then
 		for k, e in pairs(o.wielder) do
 			o.wielded[k] = self:addTemporaryValue(k, e)
@@ -395,6 +394,7 @@ function _M:onTakeoff(o)
 			end
 		end
 	end
+	o:check("on_takeoff", self)
 	o.wielded = nil
 end
 
diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua
index 5f89423bbbcf37ac2f700e5f3a4aed3b052db938..262b204eda21032230d246c40ed76e0d24a2faf5 100644
--- a/game/modules/tome/class/Actor.lua
+++ b/game/modules/tome/class/Actor.lua
@@ -1791,8 +1791,36 @@ function _M:updateModdableTile()
 end
 
 --- Call when an object is worn
-function _M:onWear(o)
-	engine.interface.ActorInventory.onWear(self, o)
+-- This doesnt call the base interface onWear, it copies the code because we need some tricky stuff
+function _M:onWear(o, bypass_set)
+	o.wielded = {}
+
+	if o.set_list and not bypass_set then
+		local list = {}
+		for i, d in ipairs(o.set_list) do
+			local po, item, inven_id = self:findInAllInventoriesBy(d[1], d[2])
+			if po and self:getInven(inven_id).worn then
+				list[#list+1] = po
+			end
+		end
+		if #list == #o.set_list then
+			for i, po in ipairs(list) do
+				self:onTakeoff(po, true)
+				po:check("on_set_complete", self)
+				self:onWear(po, true)
+				po.set_complete = true
+			end
+			o:check("on_set_complete", self)
+			o.set_complete = true
+		end
+	end
+
+	o:check("on_wear", self)
+	if o.wielder then
+		for k, e in pairs(o.wielder) do
+			o.wielded[k] = self:addTemporaryValue(k, e)
+		end
+	end
 
 	if o.talent_on_spell then
 		self.talent_on_spell = self.talent_on_spell or {}
@@ -1807,9 +1835,39 @@ function _M:onWear(o)
 end
 
 --- Call when an object is taken off
-function _M:onTakeoff(o)
+function _M:onTakeoff(o, bypass_set)
 	engine.interface.ActorInventory.onTakeoff(self, o)
 
+	if o.set_list and o.set_complete and not bypass_set then
+		local list = {}
+		for i, d in ipairs(o.set_list) do
+			local po, item, inven_id = self:findInAllInventoriesBy(d[1], d[2])
+			if po then
+				self:onTakeoff(po, true)
+				po:check("on_set_broken", self)
+				if po._special_set then
+					for k, id in pairs(po._special_set) do
+						po:removeTemporaryValue(k, id)
+					end
+					po._special_set = nil
+				end
+				self:onWear(po, true)
+				po.set_complete = nil
+			end
+		end
+		o:check("on_set_broken", self)
+		if o._special_set then
+			for k, id in pairs(o._special_set) do o:removeTemporaryValue(k, id) end
+			o._special_set = nil
+		end
+		o.set_complete = nil
+	end
+
+	if o._special_wear then
+		for k, id in pairs(o._special_wear) do o:removeTemporaryValue(k, id) end
+		o._special_wear = nil
+	end
+
 	if o.talent_on_spell then
 		self.talent_on_spell = self.talent_on_spell or {}
 		for i = 1, #o.talent_on_spell do
diff --git a/game/modules/tome/class/Object.lua b/game/modules/tome/class/Object.lua
index b2f37d8107ac438ee659ef1e5c4f4c3999146dfc..d233cd24f7fc5810744a697167cfe49b531e5c7e 100644
--- a/game/modules/tome/class/Object.lua
+++ b/game/modules/tome/class/Object.lua
@@ -238,6 +238,11 @@ function _M:getTextualDesc(compare_with)
 	if self.slot_forbid == "OFFHAND" then desc:add("It must be held with both hands.", true) end
 	desc:add(true)
 
+	if self.set_list then
+		desc:add({"color","GREEN"}, "It is part of a set of items.", {"color","LAST"}, true)
+		if self.set_complete then desc:add({"color","LIGHT_GREEN"}, "The set is complete.", {"color","LAST"}, true) end
+	end
+
 	-- Stop here if unided
 	if not self:isIdentified() then return desc end
 
@@ -867,7 +872,7 @@ function _M:getTextualDesc(compare_with)
 	for tid, data in pairs(talents) do
 		desc:add(talents[tid][3] and {"color","GREEN"} or {"color","WHITE"}, ("Talent on hit(spell): %s (%d%% chance level %d)."):format(self:getTalentFromId(tid).name, talents[tid][1], talents[tid][2]), {"color","LAST"}, true)
 	end
-	
+
 	if self.extra_description then
 		desc:add({"color", "LIGHT_UMBER"}, self.extra_description, {"color","LAST"}, true)
 	end
@@ -1111,3 +1116,15 @@ function _M:on_identify()
 		game.player:learnLore(self.unique)
 	end
 end
+
+--- Add some special properties right before wearing it
+function _M:specialWearAdd(prop, value)
+	self._special_wear = self._special_wear or {}
+	self._special_wear[prop] = self:addTemporaryValue(prop, value)
+end
+
+--- Add some special properties right when completting a set
+function _M:specialSetAdd(prop, value)
+	self._special_set = self._special_set or {}
+	self._special_set[prop] = self:addTemporaryValue(prop, value)
+end
diff --git a/game/modules/tome/data/general/objects/boss-artifacts.lua b/game/modules/tome/data/general/objects/boss-artifacts.lua
index 67375df36f97be6d33b6b502dd2e65072f23b88b..2f707cd170f42617b9194f68b00d034242861255 100644
--- a/game/modules/tome/data/general/objects/boss-artifacts.lua
+++ b/game/modules/tome/data/general/objects/boss-artifacts.lua
@@ -776,6 +776,34 @@ newEntity{ base = "BASE_GLOVES", define_as = "FLAMEWROUGHT",
 	use_talent = { id = Talents.T_RITCH_FLAMESPITTER_BOLT, level = 2, power = 6 },
 }
 
+-- The crystal set
+local crystal_activate_pair = function(w, a, who)
+	local DamageType = require "engine.DamageType"
+	w.paired = {}
+	a.paired = {}
+
+	-- The weapon's bonuses
+	w.talent_on_spell = { {chance=10, talent="T_MANATHRUST", level=3} }
+	w.combat.talent_on_hit = { T_MANATHRUST = {level=3, chance=10} }
+	w.paired._special1 = {who, "combat_spellcrit", who:addTemporaryValue("combat_spellcrit", 10)}
+	w.paired._special2 = {who, "combat_physcrit", who:addTemporaryValue("combat_physcrit", 10)}
+	w.paired._special3 = {who, "resists_pen", who:addTemporaryValue("resists_pen", {[DamageType.ARCANE]=20})}
+	-- The armor's bonuses
+	a.paired._special1 = {who, "stun_immune", who:addTemporaryValue("stun_immune", 0.5)}
+	a.paired._special2 = {who, "blind_immune", who:addTemporaryValue("blind_immune", 0.5)}
+	game.logPlayer(who, "#GOLD#As the crystalline weapon and armour are brought together, they begin to emit a constant humming.")
+end
+local crystal_deactivate_pair = function(w, a, who)
+	-- Remove the paired bonusese
+	for k, id in pairs(w) do id[1]:removeTemporaryValue(id[2], id[3]) end
+	for k, id in pairs(a) do id[1]:removeTemporaryValue(id[2], id[3]) end
+	w.talent_on_spell = nil
+	w.combat.talent_on_hit = nil
+	w.paired = nil
+	a.paired = nil
+	game.logPlayer(who, "#GOLD#The humming from the crystalline artifacts fades as they are separated.")
+end
+
 newEntity{ base = "BASE_GEM", define_as = "CRYSTAL_FOCUS",
 	power_source = {arcane=true},
 	unique = true,
@@ -805,6 +833,7 @@ newEntity{ base = "BASE_GEM", define_as = "CRYSTAL_FOCUS",
 				o.combat.dam = o.combat.dam * 1.25
 				o.combat.damtype = engine.DamageType.ARCANE
 			end
+			o.is_crystalline_weapon = true
 			o.wielder = o.wielder or {}
 			o.wielder.combat_spellpower = 12
 			o.wielder.combat_dam = 12
@@ -813,11 +842,83 @@ newEntity{ base = "BASE_GEM", define_as = "CRYSTAL_FOCUS",
 			o.wielder.inc_stats[engine.interface.ActorStats.STAT_CON] = 3
 			o.wielder.inc_damage = o.wielder.inc_damage or {}
 			o.wielder.inc_damage[engine.DamageType.ARCANE] = 10
+
+			o.set_list = { {"is_crystalline_armor", true} }
+			o.on_set_complete = function(self, who)
+				self.talent_on_spell = { {chance=10, talent="T_MANATHRUST", level=3} }
+				self.combat.talent_on_hit = { T_MANATHRUST = {level=3, chance=10} }
+				self:specialSetAdd({"wielder","combat_spellcrit"}, 10)
+				self:specialSetAdd({"wielder","combat_physcrit"}, 10)
+				self:specialSetAdd({"wielder","resists_pen"}, {[engine.DamageType.ARCANE]=20, [engine.DamageType.PHYSICAL]=15})
+				game.logPlayer(who, "#GOLD#As the crystalline weapon and armour are brought together, they begin to emit a constant humming.")
+			end
+			o.on_set_broken = function(self, who)
+				self.talent_on_spell = nil
+				self.combat.talent_on_hit = nil
+				game.logPlayer(who, "#GOLD#The humming from the crystalline artifacts fades as they are separated.")
+			end
+
+			who:sortInven()
+			who.changed = true
+
+			game.logPlayer(who, "You fix the crystal on the %s and create the %s.", oldname, o:getName{do_color=true})
+		end)
+	end },
+}
+
+newEntity{ base = "BASE_GEM", define_as = "CRYSTAL_HEART",
+	power_source = {arcane=true},
+	unique = true,
+	unided_name = "coruscating crystal",
+	name = "Crystal Heart", subtype = "multi-hued",
+	color = colors.RED, image="object/ruby.png",
+	level_range = {35, 42},
+	desc = [[This crystal is huge, easily the size of your head. It sparkles brilliantly almost of its own accord.]],
+	rarity = 250,
+	cost = 200,
+	material_level = 5,
+
+	max_power = 1, power_regen = 1,
+	use_power = { name = "combine with a suit of body armor", power = 1, use = function(self, who, gem_inven, gem_item)
+		-- Body armour only, can be cloth, light, heavy, or massive though. No clue if o.slot works for this.
+		who:showInventory("Fuse with which armor?", who:getInven("INVEN"), function(o) return o.type == "armor" and o.slot == "BODY" and not o.egoed and not o.unique end, function(o, item)
+			local oldname = o:getName{do_color=true}
+
+			-- Remove the gem
+			who:removeObject(gem_inven, gem_item)
+			who:sortInven(gem_inven)
+
+			-- Change the weapon... err, armour. No, I'm not copy/pasting here, honest!
+			o.name = "Crystalline "..o.name:capitalize()
+			o.unique = o.name
+			o.no_unique_lore = true
+			o.is_crystalline_armor = true
+
+			o.wielder = o.wielder or {}
+			-- This is supposed to add 1 def for crap cloth robes if for some reason you choose it instead of better robes, and then multiply by 1.25.
+			o.wielder.combat_def = ((o.wielder.combat_def or 0) + 2) * 1.7
+			-- Same for armour. Yay crap cloth!
+			o.wielder.combat_armor = ((o.wielder.combat_armor or 0) + 3) * 1.7
+			o.wielder.combat_spellresist = 35
+			o.wielder.combat_physresist = 25
+			o.wielder.inc_stats = o.wielder.inc_stats or {}
+			o.wielder.inc_stats[engine.interface.ActorStats.STAT_MAG] = 8
+			o.wielder.inc_stats[engine.interface.ActorStats.STAT_CON] = 8
+			o.wielder.inc_stats[engine.interface.ActorStats.STAT_LCK] = 12
+			o.wielder.resists = o.wielder.resists or {}
+			o.wielder.resists = { [engine.DamageType.ARCANE] = 35, [engine.DamageType.PHYSICAL] = 15 }
+			o.wielder.poison_immune = 1
+			o.wielder.disease_immune = 1
+
+			o.set_list = { {"is_crystalline_weapon", true} }
+			o.on_set_complete = function(self, who)
+				self:specialSetAdd({"wielder","stun_immune"}, 0.5)
+				self:specialSetAdd({"wielder","blind_immune"}, 0.5)
+			end
 			who:sortInven()
 			who.changed = true
 
 			game.logPlayer(who, "You fix the crystal on the %s and create the %s.", oldname, o:getName{do_color=true})
---			return true
 		end)
 	end },
 }
diff --git a/game/modules/tome/data/general/objects/world-artifacts.lua b/game/modules/tome/data/general/objects/world-artifacts.lua
index 754c2384ab505b74a7e7abd86eaf9c2e8c1345d5..abe489b7f997cbe9692ca0368e05761e220a9beb 100644
--- a/game/modules/tome/data/general/objects/world-artifacts.lua
+++ b/game/modules/tome/data/general/objects/world-artifacts.lua
@@ -858,36 +858,6 @@ newEntity{ base = "BASE_KNIFE",
 	},
 }
 
--- The Twin blades Moon and Star
-local activate_pair = function(moon, star, who)
-	local DamageType = require "engine.DamageType"
-	moon.paired = {}
-	star.paired = {}
-
-	-- The Moon knife's bonuses
-	moon.paired._special1 = {who, "lite", who:addTemporaryValue("lite", 1)}
-	moon.paired._special2 = {moon, "combat", moon:addTemporaryValue("combat", {melee_project={[DamageType.RANDOM_CONFUSION]=3}})}
-	moon.paired._special3 = {who, {"inc_damage", DamageType.DARKNESS}, who:addTemporaryValue({"inc_damage", DamageType.DARKNESS}, 10)}
-	-- The Star knife's bonuses
-	star.paired._special1 = {who, "lite", who:addTemporaryValue("lite", 1)}
-	star.paired._special2 = {star, "combat", star:addTemporaryValue("combat", {melee_project={[DamageType.RANDOM_BLIND]=3}})}
-	star.paired._special3 = {who, "inc_damage", who:addTemporaryValue("inc_damage", {[DamageType.LIGHT]=10}) }
-	game.logPlayer(who, "The two blades glow brightly as they are brought close together.")
-end
-
-local deactivate_pair = function(moon, star, who)
-	-- Remove the paired bonusese
-	for k, id in pairs(moon.paired) do
-		id[1]:removeTemporaryValue(id[2], id[3])
-	end
-	for k, id in pairs(star.paired) do
-		id[1]:removeTemporaryValue(id[2], id[3])
-	end
-	moon.paired = nil
-	star.paired = nil
-	game.logPlayer(who, "The light from the two blades fades as they are separated.")
-end
-
 newEntity{ base = "BASE_KNIFE", define_as = "ART_PAIR_MOON",
 	power_source = {arcane=true},
 	unique = true,
@@ -912,22 +882,15 @@ newEntity{ base = "BASE_KNIFE", define_as = "ART_PAIR_MOON",
 			[DamageType.DARKNESS] = 10,
 		},
 	},
-	activate_pair = activate_pair,
-	deactivate_pair = deactivate_pair,
-	on_wear = function(self, who)
-		-- Look for the Moon knife
-		local o, item, inven_id = who:findInAllInventoriesBy("define_as", "ART_PAIR_STAR")
-		if o and who:getInven(inven_id).worn then
-			self.activate_pair(o, self, who)
-		end
+	set_list = { {"define_as","ART_PAIR_STAR"} },
+	on_set_complete = function(self, who)
+		self:specialSetAdd({"wielder","lite"}, 1)
+		self:specialSetAdd({"combat","melee_project"}, {[engine.DamageType.RANDOM_CONFUSION]=3})
+		self:specialSetAdd({"wielder","inc_damage"}, {[engine.DamageType.DARKNESS]=10})
+		game.logSeen(who, "#ANTIQUE_WHITE#The two blades glow brightly as they are brought close together.")
 	end,
-	on_takeoff = function(self, who)
-		if self.paired then
-			local o, item, inven_id = who:findInAllInventoriesBy("define_as", "ART_PAIR_STAR")
-			if o and who:getInven(inven_id).worn then
-				self.deactivate_pair(o, self, who)
-			end
-		end
+	on_set_broken = function(self, who)
+		game.logPlayer(who, "#ANTIQUE_WHITE#The light from the two blades fades as they are separated.")
 	end,
 }
 
@@ -955,23 +918,13 @@ newEntity{ base = "BASE_KNIFE", define_as = "ART_PAIR_STAR",
 			[DamageType.LIGHT] = 10,
 		},
 	},
-	activate_pair = activate_pair,
-	deactivate_pair = deactivate_pair,
-	on_wear = function(self, who)
-		-- Look for the Moon knife
-		local o, item, inven_id = who:findInAllInventoriesBy("define_as", "ART_PAIR_MOON")
-		if o and who:getInven(inven_id).worn then
-			self.activate_pair(o, self, who)
-		end
-	end,
-	on_takeoff = function(self, who)
-		if self.paired then
-			local o, item, inven_id = who:findInAllInventoriesBy("define_as", "ART_PAIR_MOON")
-			if o and who:getInven(inven_id).worn then
-				self.deactivate_pair(o, self, who)
-			end
-		end
+	set_list = { {"define_as","ART_PAIR_MOON"} },
+	on_set_complete = function(self, who)
+		self:specialSetAdd({"wielder","lite"}, 1)
+		self:specialSetAdd({"combat","melee_project"}, {[engine.DamageType.RANDOM_BLIND]=3})
+		self:specialSetAdd({"wielder","inc_damage"}, {[engine.DamageType.LIGHT]=10})
 	end,
+
 }
 
 newEntity{ base = "BASE_RING",
@@ -1346,9 +1299,9 @@ It was made by Humans for Humans; only they can harness the true power of the ro
 			local Stats = require "engine.interface.ActorStats"
 			local DamageType = require "engine.DamageType"
 
-			self.wielded._special1 = {"inc_stats", who:addTemporaryValue("inc_stats", { [Stats.STAT_MAG] = 3, [Stats.STAT_CUN] = 9, }) }
-			self.wielded._special2 = {"inc_damage", who:addTemporaryValue("inc_damage", {[DamageType.ARCANE]=7}) }
-			self.wielded._special3 = {"combat_spellcrit", who:addTemporaryValue("combat_spellcrit", 2) }
+			self:specialWearAdd({"wielder","inc_stats"}, { [Stats.STAT_MAG] = 3, [Stats.STAT_CUN] = 9, })
+			self:specialWearAdd({"wielder","inc_damage"}, {[DamageType.ARCANE]=7})
+			self:specialWearAdd({"wielder","combat_spellcrit"}, 2)
 			game.logPlayer(who, "#LIGHT_BLUE#You feel as surge of power as you wear the vestments of the old Human Conclave!")
 		end
 	end,
@@ -1556,9 +1509,9 @@ newEntity{ base = "BASE_BATTLEAXE",
 		if who.descriptor and who.descriptor.race == "Dwarf" then
 			local Stats = require "engine.interface.ActorStats"
 
-			self.wielded._special1 = {"inc_stats", who:addTemporaryValue("inc_stats", { [Stats.STAT_CON] = 4, [Stats.STAT_DEX] = 4, }) }
-			self.wielded._special2 = {"stun_immune", who:addTemporaryValue("stun_immune", 0.5) }
-			self.wielded._special3 = {"knockback_immune", who:addTemporaryValue("knockback_immune", 0.5) }
+			self:specialWearAdd({"wielder","inc_stats"}, { [Stats.STAT_CON] = 7, [Stats.STAT_DEX] = 7, })
+			self:specialWearAdd({"wielder","stun_immune"}, 0.5)
+			self:specialWearAdd({"wielder","knockback_immune"}, 0.5)
 			game.logPlayer(who, "#LIGHT_BLUE#You feel as surge of power as you wield the axe of your ancestors!")
 		end
 	end,
diff --git a/game/modules/tome/data/zones/scintillating-caves/npcs.lua b/game/modules/tome/data/zones/scintillating-caves/npcs.lua
index f1cf2b1fb06e3e599b6605211ab54eb5a62aa197..01faa622ca7c8b0aed2c3b7b156098f1700517b6 100644
--- a/game/modules/tome/data/zones/scintillating-caves/npcs.lua
+++ b/game/modules/tome/data/zones/scintillating-caves/npcs.lua
@@ -74,7 +74,8 @@ newEntity{ base="BASE_NPC_CRYSTAL", define_as = "SPELLBLAZE_SIMULACRUM",
 	desc = [[A formation of purple crystal, but where the others could only be described as polyhedral, this construct seems to strangely resemble... you, if you were several orders of magnitude larger.]],
 	killer_message = "and vaporised into nothingness",
 	level_range = {35, nil}, exp_worth = 3,
-	max_life = 300, life_rating = 15, fixed_rating = true,
+	max_life = 300, life_rating = 25, fixed_rating = true,
+	life_regen = 0,
 	mana_regen = 20,
 	stats = { str=15, dex=15, cun=20, mag=35, con=15 },
 	rank = 4,
@@ -82,12 +83,15 @@ newEntity{ base="BASE_NPC_CRYSTAL", define_as = "SPELLBLAZE_SIMULACRUM",
 	infravision = 10,
 	see_invisible = 10,
 	blind_immune = 1,
+	poison_immune = 1,
+	disease_immune = 1,
 	instakill_immune = 1,
 
 	body = { INVEN = 10, MAINHAND=1, OFFHAND=1, BODY=1 },
-	resolvers.drops{chance=100, nb=1, {defined="GOLEM_HEART", random_art_replace={chance=75}} },
+	resolvers.drops{chance=100, nb=1, {defined="CRYSTAL_HEART", random_art_replace={chance=75}} },
 	resolvers.drops{chance=100, nb=3, {tome_drops="boss"} },
 
+	inc_damage = { all=70 },
 	resolvers.talents{
 		[Talents.T_ARCANE_POWER]=5,
 		[Talents.T_FLAME]={base=3, every=7, max=5},
@@ -98,7 +102,7 @@ newEntity{ base="BASE_NPC_CRYSTAL", define_as = "SPELLBLAZE_SIMULACRUM",
 		[Talents.T_ICE_STORM]={base=3, every=7, max=5},
 	},
 	resolvers.sustains_at_birth(),
-	resolvers.inscriptions(4, {}),
+	resolvers.inscriptions(4, "rune"),
 
 	autolevel = "caster",
 	ai = "tactical", ai_state = { talent_in=1, ai_move="move_astar", },