diff --git a/game/modules/tome/data/gfx/particles/circle.lua b/game/modules/tome/data/gfx/particles/circle.lua
index cd268673583c6b6571470f456fff234fb68e5fd0..96b34de066220d7d4a2c3aa3f3a6e613e61c9708 100644
--- a/game/modules/tome/data/gfx/particles/circle.lua
+++ b/game/modules/tome/data/gfx/particles/circle.lua
@@ -32,7 +32,7 @@ local nb = empty_start and -1 or 0
 
 return {
 --	blend_mode=core.particles.BLEND_ADDITIVE,
-	system_rotation = rng.range(0, 360), system_rotationv = speed,
+	system_rotation = base_rot or rng.range(0, 360), system_rotationv = speed,
 	generator = function()
 	if nb == -1 then
 		return {
diff --git a/game/modules/tome/data/gfx/particles_images/curse_gfx.png b/game/modules/tome/data/gfx/particles_images/curse_gfx.png
new file mode 100644
index 0000000000000000000000000000000000000000..9ae14077a633610a14e488b2e4f2cd9bc4553009
Binary files /dev/null and b/game/modules/tome/data/gfx/particles_images/curse_gfx.png differ
diff --git a/game/modules/tome/data/gfx/shockbolt/npc/bone_grab_pin.png b/game/modules/tome/data/gfx/shockbolt/npc/bone_grab_pin.png
new file mode 100644
index 0000000000000000000000000000000000000000..63e9b438845ab1379cda47d07eebbea9d2fdfab4
Binary files /dev/null and b/game/modules/tome/data/gfx/shockbolt/npc/bone_grab_pin.png differ
diff --git a/game/modules/tome/data/talents/corruptions/bone.lua b/game/modules/tome/data/talents/corruptions/bone.lua
index 0980ffb19167d8c7037e9c528aec01f6c008b5d2..7f8feaf84fa27c38ca2efc61d137e4307331afc3 100644
--- a/game/modules/tome/data/talents/corruptions/bone.lua
+++ b/game/modules/tome/data/talents/corruptions/bone.lua
@@ -72,7 +72,7 @@ newTalent{
 
 			DamageType:get(DamageType.PHYSICAL).projector(self, target.x, target.y, DamageType.PHYSICAL, dam)
 			if target:canBe("pin") then
-				target:setEffect(target.EFF_PINNED, t.getDuration(self, t), {apply_power=self:combatSpellpower()})
+				target:setEffect(target.EFF_BONE_GRAB, t.getDuration(self, t), {apply_power=self:combatSpellpower()})
 			else
 				game.logSeen(target, "%s resists the bone!", target.name:capitalize())
 			end
diff --git a/game/modules/tome/data/talents/corruptions/curses.lua b/game/modules/tome/data/talents/corruptions/curses.lua
index c9044081270f4e293237d49ad67bb0d50dc72614..4c549f3fb9568d609fe1593871a489aa337a9673 100644
--- a/game/modules/tome/data/talents/corruptions/curses.lua
+++ b/game/modules/tome/data/talents/corruptions/curses.lua
@@ -36,6 +36,7 @@ newTalent{
 			local target = game.level.map(tx, ty, Map.ACTOR)
 			if not target then return end
 			target:setEffect(target.EFF_CURSE_DEFENSELESSNESS, 10, {power=self:combatTalentSpellDamage(t, 30, 60), apply_power=self:combatSpellpower()})
+			game.level.map:particleEmitter(tx, ty, 1, "circle", {base_rot=0, oversize=0.7, a=130, limit_life=8, appear=8, speed=0, img="curse_gfx", radius=0})
 		end)
 		game:playSoundNear(self, "talents/slime")
 		return true
@@ -66,6 +67,7 @@ newTalent{
 			local target = game.level.map(tx, ty, Map.ACTOR)
 			if not target then return end
 			target:setEffect(target.EFF_CURSE_IMPOTENCE, 10, {power=t.imppower(self,t), apply_power=self:combatSpellpower()})
+			game.level.map:particleEmitter(tx, ty, 1, "circle", {base_rot=0, oversize=0.7, a=130, limit_life=8, appear=8, speed=0, img="curse_gfx", radius=0})
 		end)
 		game:playSoundNear(self, "talents/slime")
 		return true
@@ -95,6 +97,7 @@ newTalent{
 			local target = game.level.map(tx, ty, Map.ACTOR)
 			if not target then return end
 			target:setEffect(target.EFF_CURSE_DEATH, 10, {src=self, dam=self:combatTalentSpellDamage(t, 10, 70), apply_power=self:combatSpellpower()})
+			game.level.map:particleEmitter(tx, ty, 1, "circle", {base_rot=0, oversize=0.7, a=130, limit_life=8, appear=8, speed=0, img="curse_gfx", radius=0})
 		end)
 		game:playSoundNear(self, "talents/slime")
 		return true
@@ -124,6 +127,7 @@ newTalent{
 			local target = game.level.map(tx, ty, Map.ACTOR)
 			if not target then return end
 			target:setEffect(target.EFF_CURSE_VULNERABILITY, 7, {power=self:combatTalentSpellDamage(t, 10, 40), apply_power=self:combatSpellpower()})
+			game.level.map:particleEmitter(tx, ty, 1, "circle", {base_rot=0, oversize=0.7, a=130, limit_life=8, appear=8, speed=0, img="curse_gfx", radius=0})
 		end)
 		game:playSoundNear(self, "talents/slime")
 		return true
diff --git a/game/modules/tome/data/timed_effects/physical.lua b/game/modules/tome/data/timed_effects/physical.lua
index fcff508d5c57d3a156033cdae0057b899e41e471..d2b628b7f7a412b9d2edb3ef20c93edee1284744 100644
--- a/game/modules/tome/data/timed_effects/physical.lua
+++ b/game/modules/tome/data/timed_effects/physical.lua
@@ -878,6 +878,35 @@ newEffect{
 	end,
 }
 
+newEffect{
+	name = "BONE_GRAB", image = "talents/bone_grab.png",
+	desc = "Pinned to the ground",
+	long_desc = function(self, eff) return "The target is pinned to the ground, unable to move." end,
+	type = "physical",
+	subtype = { pin=true },
+	status = "detrimental",
+	parameters = {},
+	on_gain = function(self, err) return "#Target# is pinned to the ground.", "+Bone Grab" end,
+	on_lose = function(self, err) return "#Target# is no longer pinned.", "-Bone Grab" end,
+	activate = function(self, eff)
+		eff.tmpid = self:addTemporaryValue("never_move", 1)
+
+		if not self.add_displays then
+			self.add_displays = { Entity.new{image='npc/bone_grab_pin.png', display=' ', display_on_seen=true } }
+			eff.added_display = true
+		end
+		self:removeAllMOs()
+		game.level.map:updateMap(self.x, self.y)
+	end,
+	deactivate = function(self, eff)
+		if eff.added_display then self.add_displays = nil end
+		self:removeAllMOs()
+		game.level.map:updateMap(self.x, self.y)
+
+		self:removeTemporaryValue("never_move", eff.tmpid)
+	end,
+}
+
 newEffect{
 	name = "MIGHTY_BLOWS", image = "effects/mighty_blows.png",
 	desc = "Mighty Blows",