diff --git a/game/engine/Target.lua b/game/engine/Target.lua
index e76e46e2029551ccb1f4ce9ab62a9f505c74742f..ecd004fbdac7292268c351b652a45059b26bb675 100644
--- a/game/engine/Target.lua
+++ b/game/engine/Target.lua
@@ -44,6 +44,7 @@ function _M:display()
 	local s = self.sb
 	local l = line.new(self.source_actor.x, self.source_actor.y, self.target.x, self.target.y)
 	local lx, ly = l()
+	local initial_dir = lx and coord_to_dir[lx - self.source_actor.x][ly - self.source_actor.y] or 5
 	local stopx, stopy = self.source_actor.x, self.source_actor.y
 	while lx and ly do
 		if not self.target_type.no_restrict then
@@ -65,6 +66,11 @@ function _M:display()
 			self.sg:toScreen(self.display_x + (lx - game.level.map.mx) * self.tile_w, self.display_y + (ly - game.level.map.my) * self.tile_h)
 			if not self.target_type.no_restrict and game.level.map:checkEntity(lx, ly, Map.TERRAIN, "block_move") then return true end
 		end, function()end, self)
+	elseif self.target_type.cone then
+		core.fov.calc_beam(stopx, stopy, self.target_type.cone, initial_dir, self.target_type.cone_angle, function(self, lx, ly)
+			self.sg:toScreen(self.display_x + (lx - game.level.map.mx) * self.tile_w, self.display_y + (ly - game.level.map.my) * self.tile_h)
+			if not self.target_type.no_restrict and game.level.map:checkEntity(lx, ly, Map.TERRAIN, "block_move") then return true end
+		end, function()end, self)
 	end
 end
 
@@ -87,7 +93,7 @@ function _M:getType(t)
 	elseif t.type == "ball" then
 		return {range=t.range, friendlyfire=t.friendlyfire, no_restrict=t.no_restrict, ball=t.radius}
 	elseif t.type == "cone" then
-		return {range=t.range, friendlyfire=t.friendlyfire, no_restrict=t.no_restrict, cone=t.radius}
+		return {range=t.range, friendlyfire=t.friendlyfire, no_restrict=t.no_restrict, cone=t.radius, cone_angle=t.cone_angle or 55}
 	else
 		return {}
 	end
diff --git a/game/engine/interface/ActorLife.lua b/game/engine/interface/ActorLife.lua
index 5db416298c9d14c4b397b40d2fc113f1971654a5..8486cb15e70e3f362d0b1cd5992c9994cc77deb5 100644
--- a/game/engine/interface/ActorLife.lua
+++ b/game/engine/interface/ActorLife.lua
@@ -65,7 +65,7 @@ end
 -- @param dam damage to be done
 -- @param particles particles effect configuration, or nil
 function _M:project(t, x, y, damtype, dam, particles)
-	if dam < 0 then return end
+	if type(dam) == "number" and dam < 0 then return end
 	local typ = Target:getType(t)
 
 	local grids = {}
@@ -78,6 +78,7 @@ function _M:project(t, x, y, damtype, dam, particles)
 	local lx, ly = x, y
 	local l = line.new(self.x, self.y, x, y)
 	lx, ly = l()
+	local initial_dir = lx and coord_to_dir[lx - self.x][ly - self.y] or 5
 	while lx and ly do
 		if not typ.no_restrict then
 			if typ.stop_block and game.level.map:checkAllEntities(lx, ly, "block_move") then break
@@ -95,12 +96,18 @@ function _M:project(t, x, y, damtype, dam, particles)
 
 	if typ.ball then
 		core.fov.calc_circle(lx, ly, typ.ball, function(self, px, py)
-			-- Deam damage: ball
+			-- Deal damage: ball
 			addGrid(px, py)
 			if not typ.no_restrict and game.level.map:checkEntity(px, py, Map.TERRAIN, "block_move") then return true end
 		end, function()end, self)
 		addGrid(lx, ly)
 	elseif typ.cone then
+		core.fov.calc_beam(lx, ly, typ.cone, initial_dir, typ.cone_angle, function(self, px, py)
+			-- Deal damage: cone
+			addGrid(px, py)
+			if not typ.no_restrict and game.level.map:checkEntity(px, py, Map.TERRAIN, "block_move") then return true end
+		end, function()end, self)
+		addGrid(lx, ly)
 	else
 		-- Deam damage: single
 		addGrid(lx, ly)
diff --git a/game/modules/tome/data/damage_types.lua b/game/modules/tome/data/damage_types.lua
index 3cb04b70ec06dd693d2c8e281fb2cbf24cc97393..59dce71c0a735d61543e568dd4579366b341e0ea 100644
--- a/game/modules/tome/data/damage_types.lua
+++ b/game/modules/tome/data/damage_types.lua
@@ -130,6 +130,17 @@ newDamageType{
 		end
 	end,
 }
+-- Fire DOT + Stun
+newDamageType{
+	name = "flameshock", type = "FLAMESHOCK",
+	projector = function(src, x, y, type, dam)
+		local target = game.level.map(x, y, Map.ACTOR)
+		if target then
+			-- Set on fire!
+			target:setEffect(target.EFF_BURNING_SHOCK, dam.dur, {src=src, power=dam.dam / dam.dur})
+		end
+	end,
+}
 
 -- Cold damage + freeze chance
 newDamageType{
diff --git a/game/modules/tome/data/talents/spells/fire.lua b/game/modules/tome/data/talents/spells/fire.lua
index a360221254509b6f9ca29d54205bb8be0c7a3b60..35853fa13a54b94407ebd71a20dbec26cbce3b5e 100644
--- a/game/modules/tome/data/talents/spells/fire.lua
+++ b/game/modules/tome/data/talents/spells/fire.lua
@@ -23,10 +23,34 @@ newTalent{
 }
 
 newTalent{
-	name = "Fireflash",
+	name = "Flameshock",
 	type = {"spell/fire",2},
 	require = spells_req2,
 	points = 5,
+	mana = 30,
+	cooldown = 18,
+	tactical = {
+		ATTACKAREA = 10,
+	},
+	range = 1,
+	action = function(self, t)
+		local tg = {type="cone", range=0, radius=3 + self:getTalentLevelRaw(t), friendlyfire=false}
+		local x, y = self:getTarget(tg)
+		if not x or not y then return nil end
+		self:project(tg, x, y, DamageType.FLAMESHOCK, {dur=self:getTalentLevelRaw(t), dam=self:spellCrit(10 + self:combatSpellpower(0.2) * self:getTalentLevel(t))}, {type="flame"})
+		return true
+	end,
+	info = function(self, t)
+		return ([[Conjures up a cone of flame. Any target caught in the area will take %0.2f fire damage and be stunned over %d turns.
+		The damage will increase with the Magic stat]]):format(10 + self:combatSpellpower(0.2) * self:getTalentLevel(t), self:getTalentLevelRaw(t))
+	end,
+}
+
+newTalent{
+	name = "Fireflash",
+	type = {"spell/fire",3},
+	require = spells_req3,
+	points = 5,
 	mana = 40,
 	cooldown = 8,
 	tactical = {
diff --git a/game/modules/tome/data/timed_effects.lua b/game/modules/tome/data/timed_effects.lua
index c8efcb38adcd7ede85775e27f2c1361d8f70beaa..0f5f97028b02b9108bbb1c2cf9073057a8b7f6b5 100644
--- a/game/modules/tome/data/timed_effects.lua
+++ b/game/modules/tome/data/timed_effects.lua
@@ -103,9 +103,26 @@ newEffect{
 	end,
 }
 
+newEffect{
+	name = "BURNING_SHOCK",
+	desc = "Burning Shock",
+	type = "magical",
+	status = "detrimental",
+	parameters = {},
+	on_gain = function(self, err) return "#Target# is stunned by the burning flame!", "+Burning Shock" end,
+	on_lose = function(self, err) return "#Target# is not stunned anymore.", "-Burning Shock" end,
+	activate = function(self, eff)
+		self.energy.value = 0
+	end,
+	on_timeout = function(self, eff)
+		self.energy.value = 0
+		DamageType:get(DamageType.FIRE).projector(eff.src, self.x, self.y, DamageType.FIRE, eff.power)
+	end,
+}
+
 newEffect{
 	name = "STUNNED",
-	desc = "STUN",
+	desc = "Stunned",
 	type = "physical",
 	status = "detrimental",
 	parameters = {},
diff --git a/ideas/spells.ods b/ideas/spells.ods
index abe9adb2d43cfe1efffcead3838162ca90aeca7a..4f36601614189396df662294c1be92544947a39d 100644
Binary files a/ideas/spells.ods and b/ideas/spells.ods differ