diff --git a/game/engines/default/engine/Projectile.lua b/game/engines/default/engine/Projectile.lua
index a5dfaad67649c91b50490c8f749a7c23e2e91bfb..a6e9c3fab2a3c0a9eb5d4464bcfd1e82715a54b7 100644
--- a/game/engines/default/engine/Projectile.lua
+++ b/game/engines/default/engine/Projectile.lua
@@ -63,7 +63,16 @@ function _M:move(x, y, force)
 	map(x, y, Map.PROJECTILE, self)
 
 	if self.travel_particle then
-		self:addParticles(Particles.new(self.travel_particle, 1, nil))
+		if self.project then
+			local args = table.clone(self.travel_particle_args or {})
+			args.src_x = self.old_x
+			args.src_y = self.old_y
+			args.proj_x = self.project.def.x
+			args.proj_y = self.project.def.y
+			self:addParticles(Particles.new(self.travel_particle, 1, args))
+		else
+			self:addParticles(Particles.new(self.travel_particle, 1, self.travel_particle_args))
+		end
 		self.travel_particle = nil
 	end
 	if self.trail_particle then
@@ -232,6 +241,7 @@ function _M:makeProject(src, display, def, do_move, do_act, do_stop)
 		name = name,
 		display = display.display or ' ', color = display.color or colors.WHITE, image = display.image or nil,
 		travel_particle = display.particle,
+		travel_particle_args = display.particle_args,
 		trail_particle = display.trail,
 		src = src,
 		src_x = src.x, src_y = src.y,
@@ -255,6 +265,7 @@ function _M:makeHoming(src, display, def, target, count, on_move, on_hit)
 		name = name,
 		display = display.display or ' ', color = display.color or colors.WHITE, image = display.image or nil,
 		travel_particle = display.particle,
+		travel_particle_args = display.particle_args,
 		trail_particle = display.trail,
 		src = src,
 		def = def,
diff --git a/game/modules/tome/class/Actor.lua b/game/modules/tome/class/Actor.lua
index 5152c8069bac4df764716a0d9029b7f73a534063..04bd405458df724f7e6f980e98ad376ccacb4b9f 100644
--- a/game/modules/tome/class/Actor.lua
+++ b/game/modules/tome/class/Actor.lua
@@ -1098,6 +1098,12 @@ function _M:onTakeHit(value, src)
 		end
 	end
 
+	if self:hasEffect(self.EFF_BONE_SHIELD) then
+		local e = self.tempeffect_def[self.EFF_BONE_SHIELD]
+		e.absorb(self, self.tmp[self.EFF_BONE_SHIELD])
+		value = 0
+	end
+
 	if self:isTalentActive(self.T_BONE_SHIELD) then
 		local t = self:getTalentFromId(self.T_BONE_SHIELD)
 		t.absorb(self, t, self:isTalentActive(self.T_BONE_SHIELD))
diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua
index 1053a585db5759ff1f2ea58762b6c8207404e16e..597fa5dfad1610e28bd7f1dfc3a9a7bb6d4bbccf 100644
--- a/game/modules/tome/class/Game.lua
+++ b/game/modules/tome/class/Game.lua
@@ -971,15 +971,7 @@ function _M:setupCommands()
 --]]
 		end end,
 		[{"_g","ctrl"}] = function() if config.settings.cheat then
-			game.player:learnLore("shertul-fortress-9")
-			game.player:learnLore("shertul-fortress-8")
-			game.player:learnLore("shertul-fortress-7")
-			game.player:learnLore("shertul-fortress-6")
-			game.player:learnLore("shertul-fortress-5")
-			game.player:learnLore("shertul-fortress-4")
-			game.player:learnLore("shertul-fortress-3")
-			game.player:learnLore("shertul-fortress-2")
-			game.player:learnLore("shertul-fortress-1")
+			game.player:setEffect(game.player.EFF_BONE_SHIELD, 30, {nb=3})
 --			self.state:debugRandomZone()
 --			local m = game.zone:makeEntity(game.level, "actor", {random_boss=true}, nil, true)
 --			if m then game.zone:addEntity(game.level, m, "actor", game.player.x, game.player.y + 1) end
diff --git a/game/modules/tome/class/interface/Archery.lua b/game/modules/tome/class/interface/Archery.lua
index f4e6bde451678307f585527237fd62ea13597422..8d2e06e0d95cc4afa88ea2957665d294f1c15321 100644
--- a/game/modules/tome/class/interface/Archery.lua
+++ b/game/modules/tome/class/interface/Archery.lua
@@ -213,7 +213,7 @@ function _M:archeryShoot(targets, talent, tg, params)
 	tg.talent = tg.talent or talent
 
 	if not tg.range then tg.range=weapon.range or 6 end
-	tg.display = tg.display or {display='/', trail="generictrail"}
+	tg.display = tg.display or {display=' ', particle="arrow", particle_args={tile="shockbolt/"..(ammo.proj_image or realweapon.proj_image):gsub("%.png$", "")}}
 	tg.speed = (tg.speed or 20) * (ammo.travel_speed or 100) / 100
 	tg.archery = params or {}
 	tg.archery.weapon = weapon
diff --git a/game/modules/tome/data/general/objects/bows.lua b/game/modules/tome/data/general/objects/bows.lua
index 5775831b99e313279d23297573073c4d9ce34504..069d50babe259491b08e9fbca7a2eff756e94d6e 100644
--- a/game/modules/tome/data/general/objects/bows.lua
+++ b/game/modules/tome/data/general/objects/bows.lua
@@ -28,7 +28,8 @@ newEntity{
 	rarity = 5,
 	combat = { talented = "bow", sound = "actions/arrow", sound_miss = "actions/arrow",},
 	archery = "bow",
-	basic_ammo = { talented = "bow", damrange = 1.4},
+	proj_image = resolvers.image_material("arrow", "wood"),
+	basic_ammo = { talented = "bow", damrange = 1.4  },
 	desc = [[Longbows are used to shoot arrows at your foes.]],
 	randart_able = { attack=40, physical=80, spell=20, def=10, misc=10 },
 	egos = "/data/general/objects/egos/bow.lua", egos_chance = { prefix=resolvers.mbonus(40, 5), suffix=resolvers.mbonus(40, 5) },
@@ -135,6 +136,7 @@ newEntity{
 	encumber = 0.03,
 	rarity = 11,
 	combat = { talented = "bow", damrange = 1.4},
+	proj_image = resolvers.image_material("arrow", "wood"),
 	archery_ammo = "bow",
 	desc = [[Arrows are used with bows to pierce your foes to death.]],
 	generate_stack = resolvers.rngavg(100,200),
diff --git a/game/modules/tome/data/general/objects/slings.lua b/game/modules/tome/data/general/objects/slings.lua
index e32c713de3ea677c5a5e9bf1a97d2fc56691154d..87bafbe7f24c127f02560bc99636edb36b7850fe 100644
--- a/game/modules/tome/data/general/objects/slings.lua
+++ b/game/modules/tome/data/general/objects/slings.lua
@@ -27,6 +27,7 @@ newEntity{
 	rarity = 5,
 	combat = { talented = "sling", sound = "actions/arrow", sound_miss = "actions/arrow", },
 	archery = "sling",
+	proj_image = resolvers.image_material("shot_s", "metal"),
 	basic_ammo = { talented = "sling", damrange = 1.2},
 	desc = [[Slings are used to hurl stones or metal shots at your foes.]],
 	randart_able = { attack=40, physical=80, spell=20, def=10, misc=10 },
@@ -134,6 +135,7 @@ newEntity{
 	encumber = 0.03,
 	rarity = 11,
 	combat = { talented = "sling", damrange = 1.2},
+	proj_image = resolvers.image_material("shot_s", "metal"),
 	archery_ammo = "sling",
 	desc = [[Shots are used with slings to pummel your foes to death.]],
 	generate_stack = resolvers.rngavg(100,200),
diff --git a/game/modules/tome/data/gfx/lore/fortress_takeoff.png b/game/modules/tome/data/gfx/lore/fortress_takeoff.png
new file mode 100644
index 0000000000000000000000000000000000000000..d096c68771577cec8c012a873209c25a356f6053
Binary files /dev/null and b/game/modules/tome/data/gfx/lore/fortress_takeoff.png differ
diff --git a/game/modules/tome/data/gfx/shockbolt/object/shot_s_dsteel.png b/game/modules/tome/data/gfx/shockbolt/object/shot_s_dsteel.png
new file mode 100644
index 0000000000000000000000000000000000000000..e131b5e4943763ff580ed8f0b0d3c1fdf832bdae
Binary files /dev/null and b/game/modules/tome/data/gfx/shockbolt/object/shot_s_dsteel.png differ
diff --git a/game/modules/tome/data/gfx/shockbolt/object/shot_s_iron.png b/game/modules/tome/data/gfx/shockbolt/object/shot_s_iron.png
new file mode 100644
index 0000000000000000000000000000000000000000..87fa91bed7d0ef15e61d336ed2ec35dbe6771912
Binary files /dev/null and b/game/modules/tome/data/gfx/shockbolt/object/shot_s_iron.png differ
diff --git a/game/modules/tome/data/gfx/shockbolt/object/shot_s_steel.png b/game/modules/tome/data/gfx/shockbolt/object/shot_s_steel.png
new file mode 100644
index 0000000000000000000000000000000000000000..5707775d8133a8ef0574cf3765bacdb3aa9db583
Binary files /dev/null and b/game/modules/tome/data/gfx/shockbolt/object/shot_s_steel.png differ
diff --git a/game/modules/tome/data/gfx/shockbolt/object/shot_s_stralite.png b/game/modules/tome/data/gfx/shockbolt/object/shot_s_stralite.png
new file mode 100644
index 0000000000000000000000000000000000000000..0c9cca2c5de64cd5040bff3c6c626417040e0fd8
Binary files /dev/null and b/game/modules/tome/data/gfx/shockbolt/object/shot_s_stralite.png differ
diff --git a/game/modules/tome/data/gfx/shockbolt/object/shot_s_voratun.png b/game/modules/tome/data/gfx/shockbolt/object/shot_s_voratun.png
new file mode 100644
index 0000000000000000000000000000000000000000..26e9a36d4b2bc522517e8232445a2cb57e3ab6ce
Binary files /dev/null and b/game/modules/tome/data/gfx/shockbolt/object/shot_s_voratun.png differ
diff --git a/game/modules/tome/data/gfx/shockbolt/terrain/shertul_flying_castle.png b/game/modules/tome/data/gfx/shockbolt/terrain/shertul_flying_castle.png
new file mode 100644
index 0000000000000000000000000000000000000000..bb1378aafe7ef5b89d0ff510c54ee0f494af7d40
Binary files /dev/null and b/game/modules/tome/data/gfx/shockbolt/terrain/shertul_flying_castle.png differ
diff --git a/game/modules/tome/data/quests/shertul-fortress.lua b/game/modules/tome/data/quests/shertul-fortress.lua
index c34f7b2ed13d7e75014f01ce7b2b6436a732206f..20f30c77344eb8d09ac1b1c3174e95b46c03d9ef 100644
--- a/game/modules/tome/data/quests/shertul-fortress.lua
+++ b/game/modules/tome/data/quests/shertul-fortress.lua
@@ -45,6 +45,13 @@ desc = function(self, who)
 			desc[#desc+1] = "The fortress shadow has asked that you come back as soon as possible."
 		end
 	end
+	if self:isCompleted("flight") then
+		if self:isCompleted("flight-done") then
+			desc[#desc+1] = "You have re-enabled the Fortress flight systems, you can now fly around in your fortress!"
+		else
+			desc[#desc+1] = "The fortress shadow has asked that you find an Ancient Storm Saphir, along with at least 250 energy, to re-enable the Fortress flight systems."
+		end
+	end
 	if self.shertul_energy > 0 then
 		desc[#desc+1] = ("The Fortress current energy level is: %d."):format(self.shertul_energy)
 	end
@@ -89,6 +96,12 @@ gain_energy = function(self, energy)
 		local Dialog = require "engine.ui.Dialog"
 		Dialog:simpleLongPopup("Fortress Shadow", "Master, you have sent enough energy to activate the exploratory farportal.\nHowever there seems to be a disturbance in that room, please return as soon as possible.", 400)
 	end
+
+	if self.shertul_energy >= 250 and not self:isCompleted("flight") then
+		game.player:setQuestStatus(self.id, self.COMPLETED, "flight")
+		local Dialog = require "engine.ui.Dialog"
+		Dialog:simpleLongPopup("Fortress Shadow", "Master, you have sent enough energy to activate the flight systems.\nHowever one control crystal is broken, you need to find a #GOLD#Ancient Storm Saphir#WHITE#.", 400)
+	end
 end
 
 exploratory_energy = function(self, check_only)
diff --git a/game/modules/tome/data/talents/spells/advanced-necrotic-minions.lua b/game/modules/tome/data/talents/spells/advanced-necrotic-minions.lua
index 089154b9b3142b516d7d80d2b811b049e8bb9466..e0ff2c9a1c386839482a9f36fbe52b426385a4dd 100644
--- a/game/modules/tome/data/talents/spells/advanced-necrotic-minions.lua
+++ b/game/modules/tome/data/talents/spells/advanced-necrotic-minions.lua
@@ -185,7 +185,9 @@ newTalent{
 		return true
 	end,
 	info = function(self, t)
-		return ([[]]):
+		return ([[
+		bone shield ?
+		]]):
 		format()
 	end,
 }
diff --git a/game/modules/tome/data/timed_effects.lua b/game/modules/tome/data/timed_effects.lua
index a8d0bf16aef3644ea30e01a976b0920e9eeefdab..426f3ee8570d2572289eed4e34188db061b8d533 100644
--- a/game/modules/tome/data/timed_effects.lua
+++ b/game/modules/tome/data/timed_effects.lua
@@ -4127,3 +4127,31 @@ newEffect{
 		self:removeTemporaryValue("combat_spellcrit", eff.scritid)
 	end,
 }
+
+newEffect{
+	name = "BONE_SHIELD",
+	desc = "Bone Shield",
+	long_desc = function(self, eff) return ("Fully protects from %d damaging actions."):format(#eff.particles) end,
+	type = "magical",
+	status = "beneficial",
+	parameters = { nb=3 },
+	on_gain = function(self, err) return "#Target# protected by flying bones.", "+Bone Shield" end,
+	on_lose = function(self, err) return "#Target# flying bones crumble.", "-Bone Shield" end,
+	absorb = function(self, eff)
+		game.logPlayer(self, "Your bone shield absorbs the damage!")
+		local pid = table.remove(eff.particles)
+		if pid then self:removeParticles(pid) end
+		if #eff.particles <= 0 then
+			eff.dur = 0
+		end
+	end,
+	activate = function(self, eff)
+		local nb = eff.nb
+		local ps = {}
+		for i = 1, nb do ps[#ps+1] = self:addParticles(Particles.new("bone_shield", 1)) end
+		eff.particles = ps
+	end,
+	deactivate = function(self, eff)
+		for i, particle in ipairs(eff.particles) do self:removeParticles(particle) end
+	end,
+}