diff --git a/game/engines/default/data/gfx/target_arrow.png b/game/engines/default/data/gfx/target_arrow.png
new file mode 100644
index 0000000000000000000000000000000000000000..e8e90bed8ab2f7ff09d5213a8a435edb4d2b2cc2
Binary files /dev/null and b/game/engines/default/data/gfx/target_arrow.png differ
diff --git a/game/engines/default/engine/Target.lua b/game/engines/default/engine/Target.lua
index 3b34a9ec3938f154534a569a6b8193de8be71ab7..39e36865eb5b166796c0b235b61b337423122d2e 100644
--- a/game/engines/default/engine/Target.lua
+++ b/game/engines/default/engine/Target.lua
@@ -31,6 +31,7 @@ function _M:init(map, source_actor)
 	self.target_type = {}
 
 	self.cursor = engine.Tiles:loadImage("target_cursor.png"):glTexture()
+	self.arrow = engine.Tiles:loadImage("target_arrow.png"):glTexture()
 
 	--Use power of two (pot) width and height, rounded up
 	local pot_width = math.pow(2, math.ceil(math.log(map.tile_w-0.1) / math.log(2.0)))
@@ -61,6 +62,21 @@ function _M:init(map, source_actor)
 --	setmetatable(self.target, {__mode='v'})
 end
 
+function _M:displayArrow(sx, sy, tx, ty, full)
+	local x, y = (tx*2.5 + sx) / 3.5, (ty*2.5 + sy) / 3.5
+
+	if full then x, y = (tx*3.5 + sx) / 4.5, (ty*3.5 + sy) / 4.5 end
+
+	core.display.glMatrix(true)
+	core.display.glTranslate(self.display_x + (x - game.level.map.mx) * self.tile_w * Map.zoom + self.tile_w * Map.zoom / 2, self.display_y + (y - game.level.map.my + util.hexOffset(x)) * self.tile_h * Map.zoom + self.tile_h * Map.zoom / 2, 0)
+	core.display.glRotate(180, 1, 0, 0)
+	core.display.glRotate(90+util.dirToAngle(util.getDir(tx, ty, sx, sy)), 0, 0, 1)
+
+	self.arrow:toScreenFull(- self.tile_w * Map.zoom / 2, - self.tile_h * Map.zoom / 2, self.tile_w * Map.zoom, self.tile_h * Map.zoom, self.tile_w * Map.zoom, self.tile_h * Map.zoom, 1, 1, 1, full and 1 or 0.85)
+
+	core.display.glMatrix(false)
+end
+
 function _M:display(dispx, dispy)
 	-- Make sure we have a source
 	if not self.target_type.source_actor then
@@ -124,6 +140,8 @@ function _M:display(dispx, dispy)
 	local stopped = false
 	local block, hit, hit_radius
 
+	local firstx, firsty = lx, ly
+
 	-- Being completely blocked by the corner of an adjacent tile is annoying, so let's make it a special case and hit it instead
 	if blocked_corner_x then
 		block = true
@@ -187,7 +205,9 @@ function _M:display(dispx, dispy)
 		end
 
 	end
-	self.cursor:toScreen(self.display_x + (self.target.x - game.level.map.mx) * self.tile_w * Map.zoom, self.display_y + (self.target.y - game.level.map.my + util.hexOffset(self.target.x)) * self.tile_h * Map.zoom, self.tile_w * Map.zoom, self.tile_h * Map.zoom)
+	if not self.target_type.immediate_keys or firstx then
+		self.cursor:toScreen(self.display_x + (self.target.x - game.level.map.mx) * self.tile_w * Map.zoom, self.display_y + (self.target.y - game.level.map.my + util.hexOffset(self.target.x)) * self.tile_h * Map.zoom, self.tile_w * Map.zoom, self.tile_h * Map.zoom)
+	end
 
 	if self.target_type.ball and self.target_type.ball > 0 then
 		core.fov.calc_circle(
@@ -256,6 +276,12 @@ function _M:display(dispx, dispy)
 		nil)
 	end
 
+	if self.target_type.immediate_keys then
+		for dir, spot in pairs(util.adjacentCoords(self.target_type.start_x, self.target_type.start_y)) do
+			self:displayArrow(self.target_type.start_x, self.target_type.start_y, spot[1], spot[2], firstx == spot[1] and firsty == spot[2])
+		end
+	end
+
 	self.display_x, self.display_y = ox, oy
 end
 
diff --git a/game/engines/default/engine/utils.lua b/game/engines/default/engine/utils.lua
index 54c20b9d596c5837249c1fd50ddbc5ccff900dcd..dcc8bf9ab6c8017a727062a156888b28b1f81af7 100644
--- a/game/engines/default/engine/utils.lua
+++ b/game/engines/default/engine/utils.lua
@@ -1376,7 +1376,7 @@ function util.isHex()
 	return is_hex == 1
 end
 
-function util.dirToAngle(dir, sx, sy)
+function util.dirToAngle(dir)
 	return is_hex == 0 and dir_to_angle[dir] or hex_dir_to_angle[dir]
 end
 
diff --git a/game/modules/tome/class/Player.lua b/game/modules/tome/class/Player.lua
index 78cdf198f39c985cde60f4921dba5c3f2fff5197..aa296f24d11f575bcf42a880aee047d31d2e7002 100644
--- a/game/modules/tome/class/Player.lua
+++ b/game/modules/tome/class/Player.lua
@@ -658,6 +658,12 @@ function _M:getTarget(typ)
 			return
 		end
 	else
+		if type(typ) == "table" and typ.range and typ.range == 1 and config.settings.tome.immediate_melee_keys then
+			typ = table.clone(typ)
+			typ.first_target = "friend"
+			typ.immediate_keys = true
+			typ.default_target = self
+		end
 		return game:targetGetForPlayer(typ)
 	end
 end
diff --git a/game/modules/tome/data/talents/gifts/fungus.lua b/game/modules/tome/data/talents/gifts/fungus.lua
index 20baeeb86d123c42f0555e771dc33d843207a85d..51d97d8bf7e4cabe7c69db562d5f64962009fc5e 100644
--- a/game/modules/tome/data/talents/gifts/fungus.lua
+++ b/game/modules/tome/data/talents/gifts/fungus.lua
@@ -46,7 +46,7 @@ newTalent{
 	end,
 	info = function(self, t)
 		local dur = t.getDur(self, t)
-		return ([[Surround yourself with a myriad of tiny, nearly invisible, healing fungus.
+		return ([[Surround yourself with a myriad of tiny, nearly invisible, healing fungi.
 		Any regeneration effect active on you will have its duration increased by +%d turns.]]):
 		format(dur)
 	end,
diff --git a/game/modules/tome/data/talents/techniques/unarmed-training.lua b/game/modules/tome/data/talents/techniques/unarmed-training.lua
index a6e7d5554db1dcca0fc9d11defbdfe39616e9f06..5b94621238d4648001080472d08daec27a6972cd 100644
--- a/game/modules/tome/data/talents/techniques/unarmed-training.lua
+++ b/game/modules/tome/data/talents/techniques/unarmed-training.lua
@@ -65,7 +65,7 @@ newTalent{
 	info = function(self, t)
 		local defense = t.getDefense(self, t)
 		local saves = t.getMental(self, t)
-		return ([[Superior cunning and training allows you to outthink and outwit your opponents' physical and mental assualts.  Increases Defense by %d and Mental Save by %d.
+		return ([[Superior cunning and training allows you to outthink and outwit your opponents' physical and mental assaults.  Increases Defense by %d and Mental Save by %d.
 		The Defense bonus will scale with your Dexterity, and the save bonus with your Cunning.]]):
 		format(defense, saves)
 	end,
diff --git a/game/modules/tome/data/timed_effects/mental.lua b/game/modules/tome/data/timed_effects/mental.lua
index 754c19134d14fd44203f5b9b33a29f3a7b9057a3..8dabca52f9f55f44fb834c254328ef64b9cf566e 100644
--- a/game/modules/tome/data/timed_effects/mental.lua
+++ b/game/modules/tome/data/timed_effects/mental.lua
@@ -2787,7 +2787,7 @@ newEffect{
 
 newEffect{
 	name = "HIDDEN_RESOURCES", image = "talents/hidden_resources.png",
-	desc = "Hidden Ressources",
+	desc = "Hidden Resources",
 	long_desc = function(self, eff) return "The target does not consume any resources." end,
 	type = "mental",
 	subtype = { willpower=true },
diff --git a/game/modules/tome/data/timed_effects/physical.lua b/game/modules/tome/data/timed_effects/physical.lua
index 3a922187e406a4a3c3915ee99a565b91b501bcb2..ab89f43cf27f2c492d2bb5d13a7ab687db8cff9d 100644
--- a/game/modules/tome/data/timed_effects/physical.lua
+++ b/game/modules/tome/data/timed_effects/physical.lua
@@ -560,7 +560,7 @@ newEffect{
 newEffect{
 	name = "FROZEN", image = "talents/freeze.png",
 	desc = "Frozen",
-	long_desc = function(self, eff) return ("The target is encased in ice. All damage done to it will be split, 40%% absorbed by the ice and 60%% by it. The target's defense is nullified while in the ice, and it may only attack the ice, but it is also immune to any new detrimental status effects. The target cannot teleport or heal while frozen. %d HP on the iceblock remaining."):format(eff.hp) end,
+	long_desc = function(self, eff) return ("The target is encased in ice. All damage done to it will be split, 40%% absorbed by the ice and 60%% by the target. The target's defense is nullified while in the ice, and it may only attack the ice, but it is also immune to any new detrimental status effects. The target cannot teleport or heal while frozen. %d HP on the iceblock remaining."):format(eff.hp) end,
 	type = "physical", -- Frozen has some serious effects beyond just being frozen, no healing, no teleport, etc.  But it can be applied by clearly non-magical sources i.e. Ice Breath
 	subtype = { cold=true, stun=true },
 	status = "detrimental",
diff --git a/game/modules/tome/dialogs/GameOptions.lua b/game/modules/tome/dialogs/GameOptions.lua
index fa3b7203869052f41bc15f8beb74e9551be87d5e..a93537914bf465e90b303a79dd6f7713ef76bf80 100644
--- a/game/modules/tome/dialogs/GameOptions.lua
+++ b/game/modules/tome/dialogs/GameOptions.lua
@@ -199,6 +199,15 @@ function _M:generateList()
 		self.c_list:drawItem(item)
 	end,}
 
+	local zone = Textzone.new{width=self.c_desc.w, height=self.c_desc.h, text=string.toTString"Enables quick melee targetting.\nTalents that require a melee target will automatically target when pressing a direction key instead of requiring a confirmation.#WHITE#"}
+	list[#list+1] = { zone=zone, name=string.toTString"#GOLD##{bold}#Quick melee targetting#WHITE##{normal}#", status=function(item)
+		return tostring(config.settings.tome.immediate_melee_keys and "enabled" or "disabled")
+	end, fct=function(item)
+		config.settings.tome.immediate_melee_keys = not config.settings.tome.immediate_melee_keys
+		game:saveSettings("tome.immediate_melee_keys", ("tome.immediate_melee_keys = %s\n"):format(tostring(config.settings.tome.immediate_melee_keys)))
+		self.c_list:drawItem(item)
+	end,}
+
 	local zone = Textzone.new{width=self.c_desc.w, height=self.c_desc.h, text=string.toTString"How many seconds before log and chat lines begin to fade away.\nIf set to 0 the logs will never fade away."}
 	list[#list+1] = { zone=zone, name=string.toTString"#GOLD##{bold}#Log fade time#WHITE##{normal}#", status=function(item)
 		return tostring(config.settings.tome.log_fade)
diff --git a/game/modules/tome/load.lua b/game/modules/tome/load.lua
index b4e4cc03fd2ec482ba99a6a0bf2e4c6ac6d01b8d..9ebf0826c5681f4d3426e85ddac85e3b5f6a369b 100644
--- a/game/modules/tome/load.lua
+++ b/game/modules/tome/load.lua
@@ -79,6 +79,7 @@ if type(config.settings.tome.actor_based_movement_mode) == "nil" then config.set
 if type(config.settings.tome.rest_before_explore) == "nil" then config.settings.tome.rest_before_explore = true end
 if type(config.settings.tome.lore_popup) == "nil" then config.settings.tome.lore_popup = true end
 if type(config.settings.tome.auto_hotkey_object) == "nil" then config.settings.tome.auto_hotkey_object = true end
+if type(config.settings.tome.immediate_melee_keys) == "nil" then config.settings.tome.immediate_melee_keys = true end
 if not config.settings.tome.fonts then config.settings.tome.fonts = {type="fantasy", size="normal"} end
 if not config.settings.tome.ui_theme2 then config.settings.tome.ui_theme2 = "metal" end
 if not config.settings.tome.uiset_mode then config.settings.tome.uiset_mode = "Minimalist" end