diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index 192e2b6cbc3a7697c8a05585d9c38d3101ae429f..e6119cd6cc61232568bf8da6e11ba91108f6de2a 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -956,7 +956,7 @@ static int lib_pPlayerCanDamage(lua_State *L)
 {
 	player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
 	mobj_t *thing = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ));
-	//HUDSAFE
+	NOHUD // was hud safe but then i added a lua hook
 	INLEVEL
 	if (!player)
 		return LUA_ErrInvalid(L, "player_t");
diff --git a/src/lua_hook.h b/src/lua_hook.h
index 9fcc365940a785ca021f524eb5587d2c0e021b1e..45e116c344243ec23a78f05eb1d0581160747d52 100644
--- a/src/lua_hook.h
+++ b/src/lua_hook.h
@@ -48,6 +48,7 @@ enum hook {
 	hook_MobjMoveBlocked,
 	hook_MapThingSpawn,
 	hook_FollowMobj,
+	hook_PlayerCanDamage,
 	hook_PlayerQuit,
 
 	hook_MAX // last hook
@@ -87,7 +88,8 @@ boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8
 #define LUAh_ShieldSpecial(player) LUAh_PlayerHook(player, hook_ShieldSpecial) // Hook for shield abilities
 #define LUAh_MobjMoveBlocked(mo) LUAh_MobjHook(mo, hook_MobjMoveBlocked) // Hook for P_XYMovement (when movement is blocked)
 boolean LUAh_MapThingSpawn(mobj_t *mo, mapthing_t *mthing); // Hook for P_SpawnMapThing by mobj type
-boolean LUAh_FollowMobj(player_t *player, mobj_t *mo); // Hook for P_PlayerAfterThink Smiles mobj-following
+boolean LUAh_FollowMobj(player_t *player, mobj_t *mobj); // Hook for P_PlayerAfterThink Smiles mobj-following
+UINT8 LUAh_PlayerCanDamage(player_t *player, mobj_t *mobj); // Hook for P_PlayerCanDamage
 void LUAh_PlayerQuit(player_t *plr, int reason); // Hook for player quitting
 
 #endif
diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c
index de8d29be46b7944f9cecc505220ace634fb99d19..7f7e8adc672d19dcb6276bcff0075bc51f56bfb8 100644
--- a/src/lua_hooklib.c
+++ b/src/lua_hooklib.c
@@ -59,6 +59,7 @@ const char *const hookNames[hook_MAX+1] = {
 	"MobjMoveBlocked",
 	"MapThingSpawn",
 	"FollowMobj",
+	"PlayerCanDamage",
 	"PlayerQuit",
 	NULL
 };
@@ -200,6 +201,7 @@ static int lib_addHook(lua_State *L)
 	case hook_JumpSpinSpecial:
 	case hook_PlayerSpawn:
 	case hook_FollowMobj:
+	case hook_PlayerCanDamage:
 	case hook_ShieldSpawn:
 	case hook_ShieldSpecial:
 		lastp = &playerhooks;
@@ -1247,6 +1249,51 @@ boolean LUAh_FollowMobj(player_t *player, mobj_t *mobj)
 	return hooked;
 }
 
+// Hook for P_PlayerCanDamage
+UINT8 LUAh_PlayerCanDamage(player_t *player, mobj_t *mobj)
+{
+	hook_p hookp;
+	UINT8 shouldCollide = 0; // 0 = default, 1 = force yes, 2 = force no.
+	if (!gL || !(hooksAvailable[hook_PlayerCanDamage/8] & (1<<(hook_PlayerCanDamage%8))))
+		return 0;
+
+	lua_settop(gL, 0);
+
+	for (hookp = playerhooks; hookp; hookp = hookp->next)
+	{
+		if (hookp->type != hook_PlayerCanDamage)
+			continue;
+
+		if (lua_gettop(gL) == 0)
+		{
+			LUA_PushUserdata(gL, player, META_PLAYER);
+			LUA_PushUserdata(gL, mobj, META_MOBJ);
+		}
+		lua_pushfstring(gL, FMT_HOOKID, hookp->id);
+		lua_gettable(gL, LUA_REGISTRYINDEX);
+		lua_pushvalue(gL, -3);
+		lua_pushvalue(gL, -3);
+		if (lua_pcall(gL, 2, 1, 0)) {
+			if (!hookp->error || cv_debug & DBG_LUA)
+				CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
+			lua_pop(gL, 1);
+			hookp->error = true;
+			continue;
+		}
+		if (!lua_isnil(gL, -1))
+		{ // if nil, leave shouldCollide = 0.
+			if (lua_toboolean(gL, -1))
+				shouldCollide = 1; // Force yes
+			else
+				shouldCollide = 2; // Force no
+		}
+		lua_pop(gL, 1);
+	}
+
+	lua_settop(gL, 0);
+	return shouldCollide;
+}
+
 void LUAh_PlayerQuit(player_t *plr, int reason)
 {
 	hook_p hookp;
diff --git a/src/p_user.c b/src/p_user.c
index b1b755204d9d12dc85df02a16fd93a6fcaf0ad02..9a5d315a32114846d79b2402d8127abc03e95c7f 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -987,6 +987,18 @@ boolean P_PlayerCanDamage(player_t *player, mobj_t *thing)
 	if (!player->mo || player->spectator || !thing || P_MobjWasRemoved(thing))
 		return false;
 
+#ifdef HAVE_BLUA
+	{
+		UINT8 shouldCollide = LUAh_PlayerCanDamage(player, thing);
+		if (P_MobjWasRemoved(thing))
+			return false; // removed???
+		if (shouldCollide == 1)
+			return true; // force yes
+		else if (shouldCollide == 2)
+			return false; // force no
+	}
+#endif
+
 	if ((player->powers[pw_carry] == CR_NIGHTSMODE) && (player->pflags & PF_DRILLING))
 		return true;