diff --git a/game/engines/default/engine/Zone.lua b/game/engines/default/engine/Zone.lua
index 48b286974d146401351a298d20c70b63221504bc..33144e38e8a037cb509b767a931cf0b300c4f2f2 100644
--- a/game/engines/default/engine/Zone.lua
+++ b/game/engines/default/engine/Zone.lua
@@ -476,8 +476,9 @@ function _M:applyEgo(e, ego, type, no_name_change)
 	ego = ego:clone()
 	local newname = e.name
 	if not no_name_change then
-		if ego.prefix then newname = ego.name .. e.name
-		else newname = e.name .. ego.name end
+		local display = ego.display_string or ego.name
+		if ego.prefix or ego.display_prefix then newname = display .. e.name
+		else newname = e.name .. display end
 	end
 	print("applying ego", ego.name, "to ", e.name, "::", newname, "///", e.unided_name, ego.unided_name)
 	ego.unided_name = nil
@@ -495,12 +496,15 @@ function _M:applyEgo(e, ego, type, no_name_change)
 	table.ruleMergeAppendAdd(e, ego, self.ego_rules[type] or {})
 	
 	e.name = newname
-	e.egoed = true
+	if not ego.fake_ego then
+		e.egoed = true
+	end
 	e.ego_list = e.ego_list or {}
 	e.ego_list[#e.ego_list + 1] = {orig_ego, type, no_name_change}
 end
 
-local function reapplyEgos(e)
+-- WARNING the thing may be in need of re-identifying after this
+local function reapplyEgos(self, e)
 	if not e.__original then return e end
 	local brandNew = e.__original -- it will be cloned upon first ego application
 	if e.ego_list and #e.ego_list > 0 then
@@ -521,7 +525,7 @@ function _M:removeEgo(e, ego)
 	end
 	if not idx then return end
 	table.remove(e.ego_list, idx)
-	reapplyEgos(e)
+	reapplyEgos(self, e)
 	return ego
 end
 
@@ -537,6 +541,12 @@ function _M:removeEgoByName(e, ego_name)
 	end
 end
 
+function _M:setEntityEgoList(e, list)
+	e.ego_list = table.clone(list)
+	reapplyEgos(self, e)
+	return e
+end
+
 --- Finishes generating an entity
 function _M:finishEntity(level, type, e, ego_filter)
 	e = e:clone()
diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua
index 1de836527181749ded3eb229d415c29740264354..5d6f1e21f7429380d10996efb6d4fa088427fab8 100644
--- a/game/modules/tome/class/Actor.lua
+++ b/game/modules/tome/class/Actor.lua
@@ -6347,8 +6347,12 @@ end
 function _M:doTakeoffTinker(base_o, oldo)
 	if base_o.tinker ~= oldo then return end
 
+	local _, base_inven
 	local mustwear = base_o.wielded
-	if mustwear then self:onTakeoff(base_o, true) end
+	if mustwear then
+		_, _, base_inven = self:findInAllInventoriesByObject(base_o)
+		self:onTakeoff(base_o, base_inven, true)
+	end
 	base_o.tinker = nil
 	local forbid = oldo:check("on_untinker", base_o, self)
 	if oldo.tinkered then
@@ -6359,7 +6363,9 @@ function _M:doTakeoffTinker(base_o, oldo)
 		end
 	end
 	oldo.tinkered = nil
-	if mustwear then self:onWear(base_o, true) end
+	if mustwear then
+		self:onWear(base_o, base_inven, true)
+	end
 
 	self:addObject(self.INVEN_INVEN, oldo)
 	game.logPlayer(self, "You detach %s from your %s.", oldo:getName{do_color=true}, base_o:getName{do_color=true})
@@ -6396,7 +6402,7 @@ function _M:doWearTinker(wear_inven, wear_item, wear_o, base_inven, base_item, b
 	end
 
 	local mustwear = base_o.wielded
-	if mustwear then self:onTakeoff(base_o, true) end
+	if mustwear then self:onTakeoff(base_o, base_inven, true) end
 
 	wear_o.tinkered = {}
 	local forbid = wear_o:check("on_tinker", base_o, self)
@@ -6406,7 +6412,7 @@ function _M:doWearTinker(wear_inven, wear_item, wear_o, base_inven, base_item, b
 		end
 	end
 
-	if mustwear then self:onWear(base_o, true) end
+	if mustwear then self:onWear(base_o, base_inven, true) end
 
 	if not forbid then
 		base_o.tinker = wear_o
diff --git a/game/modules/tome/class/GameState.lua b/game/modules/tome/class/GameState.lua
index f65ed3d05c6a9c3d3f8dac85624f5bf080084564..ece6537e15afedd639ef0458e5f71f162a086e7b 100644
--- a/game/modules/tome/class/GameState.lua
+++ b/game/modules/tome/class/GameState.lua
@@ -597,7 +597,6 @@ function _M:generateRandart(data)
 	end
 	-- Re-resolve with the (possibly) new resolvers
 	o:resolve()
-	o:resolve(nil, true)
 
 	-----------------------------------------------------------
 	-- Imbue random powers into the randart according to themes
@@ -674,7 +673,8 @@ function _M:generateRandart(data)
 		game.zone:applyEgo(o, ego, "object", true)
 	end
 
-	o:resolve() o:resolve(nil, true)
+	o:resolve()
+	o:resolve(nil, true)
 
 	-- Always assign at least one power source based on themes and restrictions
 	if not o.power_source then
diff --git a/game/modules/tome/class/Player.lua b/game/modules/tome/class/Player.lua
index 3415b276d88ebd28a28eab541facea34d037227f..01b9a30417216b0cb90bec003cafbfaa8143ef96 100644
--- a/game/modules/tome/class/Player.lua
+++ b/game/modules/tome/class/Player.lua
@@ -1260,8 +1260,8 @@ end
 
 --- Call when an object is worn
 -- This doesnt call the base interface onWear, it copies the code because we need some tricky stuff
-function _M:onWear(o, bypass_set, slot)
-	mod.class.Actor.onWear(self, o, bypass_set, slot)
+function _M:onWear(o, slot, bypass_set)
+	mod.class.Actor.onWear(self, o, slot, bypass_set)
 
 	if not self.no_power_reset_on_wear then
 		o:forAllStack(function(so)
diff --git a/game/modules/tome/data/general/objects/boss-artifacts-maj-eyal.lua b/game/modules/tome/data/general/objects/boss-artifacts-maj-eyal.lua
index 54fd596e0d19efbff22d3de6a68316f3b392c750..8f1252d9e0d045b6521192ea6ddb63f3a3ef9710 100644
--- a/game/modules/tome/data/general/objects/boss-artifacts-maj-eyal.lua
+++ b/game/modules/tome/data/general/objects/boss-artifacts-maj-eyal.lua
@@ -877,49 +877,56 @@ newEntity{ base = "BASE_GEM", define_as = "CRYSTAL_FOCUS",
 			who:removeObject(gem_inven, gem_item)
 			who:sortInven(gem_inven)
 
-			-- Change the weapon
-			o.name = "Crystalline "..o.name:capitalize()
-			o.unique = o.name
-			o.no_unique_lore = true
-			if o.combat and o.combat.dam then
-				o.combat.dam = o.combat.dam * 1.25
-				o.combat.damtype = engine.DamageType.ARCANE
-			elseif o.wielder.combat and o.wielder.combat.dam then
-				o.wielder.combat.dam = o.wielder.combat.dam * 1.25
-				o.wielder.combat.convert_damage = o.wielder.combat.convert_damage or {}
-				o.wielder.combat.convert_damage[engine.DamageType.ARCANE] = 100
-			end
-			o.is_crystalline_weapon = true
-			o.power_source = o.power_source or {}
-			o.power_source.arcane = true
-			o.wielder = o.wielder or {}
-			o.wielder.combat_spellpower = (o.wielder.combat_spellpower or 0) + 12
-			o.wielder.combat_dam = (o.wielder.combat_dam or 0) + 12
-			o.wielder.inc_stats = o.wielder.inc_stats or {}
-			o.wielder.inc_stats[engine.interface.ActorStats.STAT_WIL] = 3
-			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
-			if o.wielder.learn_talent then o.wielder.learn_talent[who.T_COMMAND_STAFF] = nil end
-
-			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} }
-				if(self.combat) then self.combat.talent_on_hit = { T_MANATHRUST = {level=3, chance=10} }
-				else self.wielder.combat.talent_on_hit = { T_MANATHRUST = {level=3, chance=10} }
-				end
-				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
-				if (self.combat) then self.combat.talent_on_hit = nil
-				else self.wielder.combat.talent_on_hit = nil
-				end
-				game.logPlayer(who, "#GOLD#The humming from the crystalline artifacts fades as they are separated.")
-			end
+			local Entity = require("engine.Entity")
+			local ActorStats = require("engine.interface.ActorStats")
+			local crystalline_ego = Entity.new{
+				name = "crystalline weapon",
+				no_unique_lore = true,
+				is_crystalline_weapon = true,
+				power_source = {arcane=true},
+				wielder = {
+					combat_spellpower = 12,
+					combat_dam = 12,
+					inc_stats = {
+						[ActorStats.STAT_WIL] = 3,
+						[ActorStats.STAT_CON] = 3,
+					},
+					inc_damage = {ARCANE=10},
+				},
+				set_list = { {"is_crystalline_armor", true} },
+				on_set_complete = function(self, wearer)
+					self.talent_on_spell = { {chance=10, talent="T_MANATHRUST", level=3} }
+					if(self.combat) then self.combat.talent_on_hit = { T_MANATHRUST = {level=3, chance=10} }
+					else self.wielder.combat.talent_on_hit = { T_MANATHRUST = {level=3, chance=10} }
+					end
+					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(wearer, "#GOLD#As the crystalline weapon and armour are brought together, they begin to emit a constant humming.")
+				end,
+				on_set_broken = function(self, wearer)
+					self.talent_on_spell = nil
+					if (self.combat) then self.combat.talent_on_hit = nil
+					else self.wielder.combat.talent_on_hit = nil
+					end
+					game.logPlayer(wearer, "#GOLD#The humming from the crystalline artifacts fades as they are separated.")
+				end,
+				resolvers.generic(function(o) o.name = "Crystalline "..o.name:capitalize() o.unique = o.name end),
+				resolvers.generic(function(o)
+					if o.combat and o.combat.dam then
+						o.combat.dam = o.combat.dam * 1.25
+						o.combat.damtype = engine.DamageType.ARCANE
+					elseif o.wielder.combat and o.wielder.combat.dam then
+						o.wielder.combat.dam = o.wielder.combat.dam * 1.25
+						o.wielder.combat.convert_damage = o.wielder.combat.convert_damage or {}
+						o.wielder.combat.convert_damage[engine.DamageType.ARCANE] = 100
+					end
+				end),
+				resolvers.genericlast(function(o) if o.wielder.learn_talent then o.wielder.learn_talent["T_COMMAND_STAFF"] = nil end end),
+				fake_ego = true,
+			}
+			game.zone:applyEgo(o, crystalline_ego, "object", true)
+			o:resolve()
 
 			who:sortInven()
 			who.changed = true
@@ -952,35 +959,41 @@ newEntity{ base = "BASE_GEM", define_as = "CRYSTAL_HEART",
 			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.power_source = o.power_source or {}
-			o.power_source.arcane = 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 = 0.6
-			o.wielder.disease_immune = 0.6
-
-			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
+			local Entity = require("engine.Entity")
+			local ActorStats = require("engine.interface.ActorStats")
+			local crystalline_ego = Entity.new{
+				name = "crystalline armour",
+				no_unique_lore = true,
+				is_crystalline_armor = true,
+				power_source = {arcane=true},
+				wielder = {
+					combat_spellresist = 35,
+					combat_physresist = 25,
+					inc_stats = {
+						[ActorStats.STAT_MAG] = 8,
+						[ActorStats.STAT_CON] = 8,
+						[ActorStats.STAT_LCK] = 12,
+					},
+					resists = {ARCANE=35, PHYSICAL=15},
+					poison_immune=0.6,
+					disease_immune=0.6,
+				},
+				set_list = { {"is_crystalline_weapon", true} },
+				on_set_complete = function(self, who)
+					self:specialSetAdd({"wielder","stun_immune"}, 0.5)
+					self:specialSetAdd({"wielder","blind_immune"}, 0.5)
+				end,
+				resolvers.generic(function(o) o.name = "Crystalline "..o.name:capitalize() o.unique = o.name end),
+				resolvers.generic(function(o)
+					-- 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
+				end),
+			}
+			game.zone:applyEgo(o, crystalline_ego, "object", true)
+			o:resolve()
+
 			who:sortInven()
 			who.changed = true
 
diff --git a/game/modules/tome/data/talents/cursed/cursed-aura.lua b/game/modules/tome/data/talents/cursed/cursed-aura.lua
index 5a5a7399c79c69644a788cbd6a88bc3737932003..1dd5ec558714f99a6137e6b067b08f26fd3bb355 100644
--- a/game/modules/tome/data/talents/cursed/cursed-aura.lua
+++ b/game/modules/tome/data/talents/cursed/cursed-aura.lua
@@ -18,6 +18,7 @@
 -- darkgod@te4.org
 
 local Object = require "engine.Object"
+local Entity = require "engine.Entity"
 local Dialog = require "engine.ui.Dialog"
 
 local curses_detrimental
@@ -71,18 +72,24 @@ newTalent{
 		if item.curse then return end
 		if not t.canCurseItem(self, t, item) then return end
 
+		local curse
 		-- apply the curse
 		if item.define_as == "CLOAK_DECEPTION" then
 			-- cloak of deception is always Corpses..
-			item.curse = self.EFF_CURSE_OF_CORPSES
+			curse = self.EFF_CURSE_OF_CORPSES
 		else
 			local curses = t.getCurses(self, t)
-			item.curse = rng.table(curses)
+			curse = rng.table(curses)
 		end
 
-		local def = self.tempeffect_def[item.curse]
-		item.special = true
-		item.add_name = (item.add_name or "").." ("..def.short_desc..")"
+		local def = self.tempeffect_def[curse]
+		local ego = Entity.new{
+			name = "curse",
+			display_string = " ("..def.short_desc..")",
+			curse = curse,
+			fake_ego = true, unvault_ego = true,
+		}
+		game.zone:applyEgo(item, ego, "object")
 	end,
 	-- curses all items on the floor
 	curseFloor = function(self, t, x, y)
diff --git a/game/modules/tome/data/talents/psionic/finer-energy-manipulations.lua b/game/modules/tome/data/talents/psionic/finer-energy-manipulations.lua
index e59131e7403dd21e3024719e6e6d737424d97d18..f9ee68e1c43cd37eb0cc276f6f027e8fcbf4a51e 100644
--- a/game/modules/tome/data/talents/psionic/finer-energy-manipulations.lua
+++ b/game/modules/tome/data/talents/psionic/finer-energy-manipulations.lua
@@ -132,13 +132,14 @@ newTalent{
 			if force_reshape or old_atk < atk_boost or old_dam < dam_boost then
 				local new_ego = Entity.new{
 					name = "reshape weapon",
-					been_reshaped = "reshaped("..tostring(atk_boost)..","..tostring(dam_boost)..") ",
-					special = true,
+					display_string = "reshaped("..tostring(atk_boost)..","..tostring(dam_boost)..") ", display_prefix = true,
+					been_reshaped = true,
 					combat = {atk=atk_boost, dam=dam_boost},
-					old_atk = atk_boost, old_dam = dam_boost, orig_atk = o.combat.atk, orig_dam = o.combat.dam  -- Backwards compatibility
+					old_atk = atk_boost, old_dam = dam_boost, orig_atk = o.combat.atk, orig_dam = o.combat.dam,  -- Easier this way
+					fake_ego = true, unvault_ego = true,
 				}
 				game.logPlayer(self, "You reshape your %s.", o:getName{do_colour=true, no_count=true})
-				game.zone:applyEgo(o, new_ego, "object", true)
+				game.zone:applyEgo(o, new_ego, "object")
 				if in_dialog then self:talentDialogReturn(true) end
 			else
 				if old_ego then game.zone:applyEgo(o, old_ego, "object", true) end -- nothing happened
@@ -171,11 +172,12 @@ newTalent{
 				else real_fat = min(fat, e.wielder.fatigue) end
 				local new_ego = Entity.new{
 					name = "reshape armour",
-					been_reshaped = "reshaped["..tostring(armour)..","..tostring(real_fat).."%] ",
-					special = true,
+					display_string = "reshaped["..tostring(armour)..","..tostring(real_fat).."%] ", display_prefix = true,
+					been_reshaped = true,
 					wielder = {combat_armour=arm, fatigue=-real_fat},
 					fatigue_reduction = fat,
-					old_fat = fat, orig_fat = o.wielder.fatigue, orig_arm = o.wielder.armour  -- Backwards compatibility
+					old_fat = fat, orig_fat = o.wielder.fatigue, orig_arm = o.wielder.armour,  -- Easier this way
+					fake_ego = true, unvault_ego = true,
 				}
 				game.logPlayer(self, "You reshape your %s.", o:getName{do_colour=true, no_count=true})
 				if o.orig_name then o.name = o.orig_name end --Fix name for items affected by older versions of this talent
diff --git a/game/modules/tome/data/talents/spells/stone-alchemy.lua b/game/modules/tome/data/talents/spells/stone-alchemy.lua
index b32a4505bb3534565894fc94c5dce0ad70a735d6..21c00a38209c066ea8062b3ff154a0cc8c8860d0 100644
--- a/game/modules/tome/data/talents/spells/stone-alchemy.lua
+++ b/game/modules/tome/data/talents/spells/stone-alchemy.lua
@@ -130,13 +130,14 @@ newTalent{
 				local Entity = require("engine.Entity")
 				local ego = Entity.new{
 					name = "imbue "..gem.name,
-					been_imbued = " <"..gem.name..">",
-					special = true,
+					display_string = " <"..gem.name..">",
+					been_imbued = true,
 					wielder = table.clone(gem.imbue_powers),
 					talent_on_spell = gem.talent_on_spell,
+					fake_ego = true, unvault_ego = true,
 				}
 				local name = o:getName{do_colour=true, no_count=true}
-				game.zone:applyEgo(o, ego, "object", true)
+				game.zone:applyEgo(o, ego, "object")
 				game.logPlayer(self, "You imbue your %s with %s.", name, gem:getName{do_colour=true, no_count=true})
 				self:talentDialogReturn(true)
 				game:unregisterDialog(self:talentDialogGet())