diff --git a/game/engines/default/engine/Entity.lua b/game/engines/default/engine/Entity.lua
index 8c4697774704a41cd86d0e9706d187ea3eed2c5c..f6898da2dc4f08f1983880dd77b0943c6c1d67f3 100644
--- a/game/engines/default/engine/Entity.lua
+++ b/game/engines/default/engine/Entity.lua
@@ -329,9 +329,17 @@ function _M:makeMapObject(tiles, idx)
 		if shad.shad then self._mo:shader(shad.shad) end
 	end
 
+	self._mo, self.z, last_mo = self:alterMakeMapObject(tiles, self._mo, self.z, last_mo)
+
 	return self._mo, self.z, last_mo
 end
 
+--- Allows to alter the generated map objects
+-- Does nothing by default
+function _M:alterMakeMapObject(tiles, mo, z, last_mo)
+	return mo, z, last_mo
+end
+
 --- Get all "map objects" representing this entity
 -- Do not touch unless you *KNOW* what you are doing.<br/>
 -- You do *NOT* need this, this is used by the engine.Map class automatically.<br/>
diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua
index aeb20221d16f2f5e6692b3440225bbaf1c662f57..13538a888fcf1c6807165768afa35ebf12306ce0 100644
--- a/game/modules/tome/class/Actor.lua
+++ b/game/modules/tome/class/Actor.lua
@@ -836,19 +836,14 @@ function _M:setupMinimapInfo(mo, map)
 	end
 end
 
-function _M:makeMapObject(tiles, idx)
-	local mo, z, lastmo = Actor.makeMapObject(self, tiles, idx)
-	if mo and mo:isValid() then return mo, z, lasmo end
-
-	if idx == 1 and mo then
-		local submo = core.map.newObject(self.uid, 1, self:check("display_on_seen"), self:check("display_on_remember"), self:check("display_on_unknown"), self:check("display_x") or 0, self:check("display_y") or 0, self:check("display_w") or 1, self:check("display_h") or 1, self:check("display_scale") or 1)
-		local tex, texx, texy, pos_x, pos_y = tiles:get("", 0, 0, 0, 0, 0, 0, "invis.png", false, false, true)
-		submo:texture(0, tex, false, texx, texy, pos_x, pos_y)
-		submo:chain(mo)
-		if lastmo == mo then lastmo = submo end
-		mo = submo
-		self._mo = mo
-	end
+function _M:alterMakeMapObject(tiles, mo, z, lastmo)
+	local submo = core.map.newObject(self.uid, 1, self:check("display_on_seen"), self:check("display_on_remember"), self:check("display_on_unknown"), self:check("display_x") or 0, self:check("display_y") or 0, self:check("display_w") or 1, self:check("display_h") or 1, self:check("display_scale") or 1)
+	local tex, texx, texy, pos_x, pos_y = tiles:get("", 0, 0, 0, 0, 0, 0, "invis.png", false, false, true)
+	submo:texture(0, tex, false, texx, texy, pos_x, pos_y)
+	submo:chain(mo)
+	if lastmo == mo then lastmo = submo end
+	mo = submo
+	self._mo = mo
 
 	return mo, z, lastmo
 end
diff --git a/game/modules/tome/data/gfx/particles/shader_wings.lua b/game/modules/tome/data/gfx/particles/shader_wings.lua
index 3cbfe1f6a95f0e141e2b1800f22e8c19d3aa05b4..70cb3b9cbca055d4872cd3f7868a76326d16e135 100644
--- a/game/modules/tome/data/gfx/particles/shader_wings.lua
+++ b/game/modules/tome/data/gfx/particles/shader_wings.lua
@@ -17,33 +17,38 @@
 -- Nicolas Casalini "DarkGod"
 -- darkgod@te4.org
 
-use_shader = {type="flamewings"}
+use_shader = {type="flamewings", deploy_factor=deploy_speed, flap=flap}
 base_size = 32
 
 local r = 1
 local g = 1
 local b = 1
-local a = 1
+local a = a or 1
+local infinite = infinite
+local nb = 0
 
 return { generator = function()
 	return {
 		trail = 0,
-		life = 10,
+		life = life or 10,
 		size = 64 * (size_factor or 1), sizev = 0, sizea = 0,
 
 		x = 0, xv = 0, xa = 0,
-		y = -20, yv = 0, ya = 0,
+		y = -25, yv = 0, ya = 0,
 		dir = 0, dirv = dirv, dira = 0,
 		vel = 0, velv = 0, vela = 0,
 
 		r = r, rv = 0, ra = 0,
 		g = g, gv = 0, ga = 0,
 		b = b, bv = 0, ba = 0,
-		a = a, av = -0.02, aa = 0.005,
+		a = a, av = 0, aa = fade or 0,
 	}
 end, },
 function(self)
-	self.ps:emit(1)
+	if nb == 0 or infinite then
+		self.ps:emit(1)
+		nb = 1
+	end
 end,
 1,
 "particles_images/"..(img or "wings")
diff --git a/game/modules/tome/data/gfx/particles_images/bloodwings.png b/game/modules/tome/data/gfx/particles_images/bloodwings.png
new file mode 100644
index 0000000000000000000000000000000000000000..d411df081cb2e192bb0df20ee56f9a8db76bd77b
Binary files /dev/null and b/game/modules/tome/data/gfx/particles_images/bloodwings.png differ
diff --git a/game/modules/tome/data/gfx/particles_images/darkwings.png b/game/modules/tome/data/gfx/particles_images/darkwings.png
new file mode 100644
index 0000000000000000000000000000000000000000..35efdf2d4f5682b46dc29891e1cd6c00c03f2a7d
Binary files /dev/null and b/game/modules/tome/data/gfx/particles_images/darkwings.png differ
diff --git a/game/modules/tome/data/gfx/particles_images/sickwings.png b/game/modules/tome/data/gfx/particles_images/sickwings.png
new file mode 100644
index 0000000000000000000000000000000000000000..baae36c1f1d4f220ea55aaf048116715971a1d66
Binary files /dev/null and b/game/modules/tome/data/gfx/particles_images/sickwings.png differ
diff --git a/game/modules/tome/data/gfx/shaders/flamewings.frag b/game/modules/tome/data/gfx/shaders/flamewings.frag
index ab9448c151ea83d168d562df2ddd8e26fb288535..585f19337022a18446f0219164a65b3f6b976f88 100644
--- a/game/modules/tome/data/gfx/shaders/flamewings.frag
+++ b/game/modules/tome/data/gfx/shaders/flamewings.frag
@@ -4,6 +4,8 @@ uniform float aadjust;
 uniform vec3 color;
 uniform float time_factor;
 uniform float tick_start;
+uniform float deploy_factor;
+uniform float flap;
 
 uniform float ellipsoidalFactor = 1.7; //1 is perfect circle, >1 is ellipsoidal
 uniform float oscillationSpeed = 0.0; //oscillation between ellipsoidal and spherical form
@@ -148,8 +150,8 @@ void main(void)
 	pos.x = 0.5 + (pos.x - 0.5) * ellipsoidalFactor;
 	pos = vec2(0.5, 0.5) + (pos - vec2(0.5, 0.5)) * 1.1;
 	
-	float foldRatio = max(0.0, min(1.0, (tick - tick_start) / time_factor * 5.0));
-	//foldRatio = (1.0 + sin(tick / time_factor * 20.0)) * 0.5;
+	float foldRatio = max(0.0, min(1.0, (tick - tick_start) / time_factor * deploy_factor));
+	if (flap > 0.0) foldRatio = (1.0 + sin(tick / time_factor * flap)) * 0.5;
 	foldRatio *= 0.95 + 0.05 * sin(tick / time_factor * 15.0);
 	
 	float radius = 0.25 * (foldRatio * 0.5 + 0.5);
@@ -199,5 +201,5 @@ void main(void)
 		gl_FragColor.a *= min(1.0, max(0.0, (1.0 - planarPoint.x) * antialiasingCoef));
 		//gl_FragColor.a *= min(1.0, max(0.0, (1.0 - planarPoint.y) * antialiasingCoef));
 	}
-	gl_FragColor.a *= 1.0 - pow(1.0 - foldRatio, 3.0);
+	gl_FragColor.a *= (1.0 - pow(1.0 - foldRatio, 3.0)) * gl_Color.a;
 }
diff --git a/game/modules/tome/data/gfx/shaders/flamewings.lua b/game/modules/tome/data/gfx/shaders/flamewings.lua
index 377de4ebdfdae3ab745236dfd52a76d9f251954d..89900241b496f78a449829517320d7a0bae2adc8 100644
--- a/game/modules/tome/data/gfx/shaders/flamewings.lua
+++ b/game/modules/tome/data/gfx/shaders/flamewings.lua
@@ -22,10 +22,11 @@ return {
 	vert = nil,
 	args = {
 		tex = { texture = 0 },
-		time_factor = 6000,
-		ellipsoidalFactor = 1.7, --1 is perfect circle, >1 is ellipsoidal
-		oscillationSpeed = 0.0, --oscillation between ellipsoidal and spherical form
-		growRatio = 1.0,
+		time_factor = time_factor or 6000,
+		deploy_factor = deploy_factor or 5,
+		ellipsoidalFactor = ellipsoidalFactor or 1.7, --1 is perfect circle, >1 is ellipsoidal
+		oscillationSpeed = oscillationSpeed or 0.0, --oscillation between ellipsoidal and spherical form
+		flap = flap or 0.0,
 	},
 	resetargs = {
 		tick_start = function() return core.game.getTime() end,
diff --git a/game/modules/tome/data/gfx/shaders/shadowfire.lua b/game/modules/tome/data/gfx/shaders/shadowfire.lua
index 842f8ebccd459b67b1819dfd11def7a42276bcdb..ba40bb18d7c1c0680ebb3645678d0b7b3f17721b 100644
--- a/game/modules/tome/data/gfx/shaders/shadowfire.lua
+++ b/game/modules/tome/data/gfx/shaders/shadowfire.lua
@@ -25,7 +25,7 @@ return {
 		mainfbo = { texture = 1 },
 		color = color or {0.4, 0.7, 1.0},
 		time_factor = time_factor or 25000,
-		aadjust = aadjust or 10,
+		aadjust = aadjust or 5,
 		ellipsoidalFactor = 1.5,
 		oscillationSpeed = 20.0,
 		antialiasingRadius = 0.6,
diff --git a/game/modules/tome/data/talents/corruptions/shadowflame.lua b/game/modules/tome/data/talents/corruptions/shadowflame.lua
index 1138b5a2bf44d6625533c43cbcc1655aca8e05b8..2b3e95f6e7ce12fde4ec6aa5daec5bac0c105f7b 100644
--- a/game/modules/tome/data/talents/corruptions/shadowflame.lua
+++ b/game/modules/tome/data/talents/corruptions/shadowflame.lua
@@ -223,10 +223,17 @@ newTalent{
 			level.allow_demon_plane_damage = true
 		end)
 
+		local particle
+		if core.shader.active(4) then
+			local p = Particles.new("shader_wings", 1, {infinite=1, img="bloodwings", flap=28, a=0.6})
+			p.toback = true
+			particle = self:addParticles(p)
+		end
 		local ret = {
 			vim = self:addTemporaryValue("vim_regen", -5),
 			target = target,
 			x = self.x, y = self.y,
+			particle = particle,
 		}
 		return ret
 	end,
@@ -234,6 +241,7 @@ newTalent{
 		-- If we're a clone of the original fearscapper, just deactivate
 		if not self.on_die then return true end
 		
+		if p.particle then self:removeParticles(p.particle) end
 		self:removeTemporaryValue("vim_regen", p.vim)
 
 		game:onTickEnd(function()
diff --git a/game/modules/tome/data/talents/gifts/cold-drake.lua b/game/modules/tome/data/talents/gifts/cold-drake.lua
index 9d8d9029dbaeb1e13c27c01a42b7c59c616d2453..63030005d2b13e2196aab40391175a61c7cf50af 100644
--- a/game/modules/tome/data/talents/gifts/cold-drake.lua
+++ b/game/modules/tome/data/talents/gifts/cold-drake.lua
@@ -172,6 +172,12 @@ newTalent{
 		self:project(tg, x, y, DamageType.ICE, self:mindCrit(self:combatTalentStatDamage(t, "str", 30, 430)))
 		game.level.map:particleEmitter(self.x, self.y, tg.radius, "breath_cold", {radius=tg.radius, tx=x-self.x, ty=y-self.y})
 		game:playSoundNear(self, "talents/breath")
+		
+		if core.shader.active(4) then
+			local p = Particles.new("shader_wings", 1, {life=18, fade=-0.003, deploy_speed=14})
+			p.toback = true
+			self:addParticles(p)
+		end
 		return true
 	end,
 	info = function(self, t)
diff --git a/game/modules/tome/data/talents/gifts/fire-drake.lua b/game/modules/tome/data/talents/gifts/fire-drake.lua
index d5b161146375b71808c146099b13be35df30586c..f3a7a835f225dcdaca38e09db6bc7b15f3c5ecc0 100644
--- a/game/modules/tome/data/talents/gifts/fire-drake.lua
+++ b/game/modules/tome/data/talents/gifts/fire-drake.lua
@@ -79,6 +79,12 @@ newTalent{
 		if not x or not y then return nil end
 		self:project(tg, x, y, DamageType.PHYSKNOCKBACK, {dam=self:mindCrit(self:combatTalentStatDamage(t, "str", 15, 90)), dist=4})
 		game:playSoundNear(self, "talents/breath")
+
+		if core.shader.active(4) then
+			local p = Particles.new("shader_wings", 1, {life=18, fade=-0.003, deploy_speed=14})
+			p.toback = true
+			self:addParticles(p)
+		end
 		return true
 	end,
 	info = function(self, t)
@@ -165,6 +171,12 @@ newTalent{
 		if not x or not y then return nil end
 		self:project(tg, x, y, DamageType.FIREBURN, {dam=self:mindCrit(self:combatTalentStatDamage(t, "str", 30, 550)), dur=3, initial=70})
 		game.level.map:particleEmitter(self.x, self.y, tg.radius, "breath_fire", {radius=tg.radius, tx=x-self.x, ty=y-self.y})
+
+		if core.shader.active(4) then
+			local p = Particles.new("shader_wings", 1, {life=18, fade=-0.003, deploy_speed=14})
+			p.toback = true
+			self:addParticles(p)
+		end
 		game:playSoundNear(self, "talents/breath")
 		return true
 	end,
diff --git a/game/modules/tome/data/talents/gifts/higher-draconic.lua b/game/modules/tome/data/talents/gifts/higher-draconic.lua
index f58d3ea7970045f5ba214baff02332381f52ec89..f502dfccad2f0430f2654a07ba5975ef588cca22 100644
--- a/game/modules/tome/data/talents/gifts/higher-draconic.lua
+++ b/game/modules/tome/data/talents/gifts/higher-draconic.lua
@@ -121,6 +121,12 @@ newTalent{
 		self:project(tg, x, y, DamageType.INSIDIOUS_POISON, {dam=self:mindCrit(t.getDamage(self,t)), dur=6, heal_factor=t.getEffect(self,t)})
 		game.level.map:particleEmitter(self.x, self.y, tg.radius, "breath_slime", {radius=tg.radius, tx=x-self.x, ty=y-self.y})
 		game:playSoundNear(self, "talents/breath")
+		
+		if core.shader.active(4) then
+			local p = Particles.new("shader_wings", 1, {life=18, fade=-0.003, deploy_speed=14})
+			p.toback = true
+			self:addParticles(p)
+		end
 		return true
 	end,
 	info = function(self, t)
diff --git a/game/modules/tome/data/talents/gifts/sand-drake.lua b/game/modules/tome/data/talents/gifts/sand-drake.lua
index 09879b93fc731fcb43f673988ca7eedacc937f16..33e1743659e5e43b87dbd3e03f87bd771a7f4f0b 100644
--- a/game/modules/tome/data/talents/gifts/sand-drake.lua
+++ b/game/modules/tome/data/talents/gifts/sand-drake.lua
@@ -157,6 +157,12 @@ newTalent{
 		self:project(tg, x, y, DamageType.SAND, {dur=t.getDuration(self, t), dam=self:mindCrit(t.getDamage(self, t))})
 		game.level.map:particleEmitter(self.x, self.y, tg.radius, "breath_earth", {radius=tg.radius, tx=x-self.x, ty=y-self.y})
 		game:playSoundNear(self, "talents/breath")
+		
+		if core.shader.active(4) then
+			local p = Particles.new("shader_wings", 1, {life=18, fade=-0.003, deploy_speed=14})
+			p.toback = true
+			self:addParticles(p)
+		end
 		return true
 	end,
 	info = function(self, t)
diff --git a/game/modules/tome/data/talents/gifts/storm-drake.lua b/game/modules/tome/data/talents/gifts/storm-drake.lua
index 8f1bcc888b09b8e9ff2287a820c837e1151fa8fc..36a1ce269bea243b4ae40ea7a67fc050c4f42824 100644
--- a/game/modules/tome/data/talents/gifts/storm-drake.lua
+++ b/game/modules/tome/data/talents/gifts/storm-drake.lua
@@ -210,6 +210,12 @@ newTalent{
 		else game.level.map:particleEmitter(self.x, self.y, tg.radius, "breath_lightning", {radius=tg.radius, tx=x-self.x, ty=y-self.y})
 		end
 
+		
+		if core.shader.active(4) then
+			local p = Particles.new("shader_wings", 1, {img="lightningwings",infinite=1, life=18, fade=0*-0.003, deploy_speed=14})
+			p.toback = true
+			self:addParticles(p)
+		end
 		game:playSoundNear(self, "talents/breath")
 		return true
 	end,
diff --git a/game/modules/tome/data/talents/gifts/venom-drake.lua b/game/modules/tome/data/talents/gifts/venom-drake.lua
index f8f40a28ff444b7ddb1676708d19be99179844fb..64e2c9dd8e0e83056bba2fb82a1e03e76df9d013 100644
--- a/game/modules/tome/data/talents/gifts/venom-drake.lua
+++ b/game/modules/tome/data/talents/gifts/venom-drake.lua
@@ -182,6 +182,12 @@ newTalent{
 		self:project(tg, x, y, DamageType.ACID_DISARM, self:mindCrit(self:combatTalentStatDamage(t, "str", 30, 420)))
 		game.level.map:particleEmitter(self.x, self.y, tg.radius, "breath_acid", {radius=tg.radius, tx=x-self.x, ty=y-self.y})
 		game:playSoundNear(self, "talents/breath")
+		
+		if core.shader.active(4) then
+			local p = Particles.new("shader_wings", 1, {life=18, fade=-0.003, deploy_speed=14})
+			p.toback = true
+			self:addParticles(p)
+		end
 		return true
 	end,
 	info = function(self, t)
diff --git a/game/modules/tome/data/talents/spells/grave.lua b/game/modules/tome/data/talents/spells/grave.lua
index 989d9ac8f0a3ed26a5a0e24f4a91166d50ae5c0f..87ebb50ddae4ea0e701eece762a4809bafd5d8b2 100644
--- a/game/modules/tome/data/talents/spells/grave.lua
+++ b/game/modules/tome/data/talents/spells/grave.lua
@@ -274,9 +274,7 @@ newTalent{
 
 		local tg = {type="ball", nolock=true, pass_terrain=false, nowarning=true, friendly_fire=true, default_target=self, range=range, radius=radius, talent=t}
 		local x, y = self:getTarget(tg)
-		print("====1")
 		if not x or not y then return nil end
-		print("====2")
 		local _ _, _, _, x, y = self:canProject(tg, x, y)
 
 		-- get locations in line of movement from center
@@ -298,7 +296,6 @@ newTalent{
 		end end
 
 		darkCount = math.min(darkCount, #locations)
-		print("====3", darkCount)
 		if darkCount == 0 then return false end
 
 		for i = 1, darkCount do
@@ -332,13 +329,21 @@ newTalent{
 	activate = function(self, t)
 		local chance, val = t.getParams(self, t)
 		game:playSoundNear(self, "talents/spell_generic2")
+		local particle
+		if core.shader.active(4) then
+			local p = Particles.new("shader_wings", 1, {infinite=1, img="darkwings"})
+			p.toback = true
+			particle = self:addParticles(p)
+		end
 		local ret = {
 			chance = self:addTemporaryValue("life_leech_chance", chance),
 			val = self:addTemporaryValue("life_leech_value", val),
+			particle = particle,
 		}
 		return ret
 	end,
 	deactivate = function(self, t, p)
+		if p.particle then self:removeParticles(p.particle) end
 		self:removeTemporaryValue("life_leech_chance", p.chance)
 		self:removeTemporaryValue("life_leech_value", p.val)
 		return true
diff --git a/game/modules/tome/data/talents/spells/wildfire.lua b/game/modules/tome/data/talents/spells/wildfire.lua
index ab983ffcb952b841372100e9f9ecf3e897151804..7ff2a020025badaf1a89b760e988a8da73353f8d 100644
--- a/game/modules/tome/data/talents/spells/wildfire.lua
+++ b/game/modules/tome/data/talents/spells/wildfire.lua
@@ -124,10 +124,9 @@ newTalent{
 
 		local particle
 		if core.shader.active(4) then
-			local p = Particles.new("shader_wings", 1)
+			local p = Particles.new("shader_wings", 1, {infinite=1})
 			p.toback = true
 			particle = self:addParticles(p)
---			particle = self:addParticles(Particles.new("shader_ring_rotating", 1, {radius=1.1}, {type="flames", hide_center=0, xy={self.x, self.y}}))
 		else
 			particle = self:addParticles(Particles.new("wildfire", 1))
 		end