Skip to content

Commit 291e773

Browse files
committed
Add player knockback on punch to builtin
1 parent cf64054 commit 291e773

File tree

3 files changed

+56
-0
lines changed

3 files changed

+56
-0
lines changed

builtin/game/init.lua

+1
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,6 @@ dofile(gamepath .. "features.lua")
3333
dofile(gamepath .. "voxelarea.lua")
3434
dofile(gamepath .. "forceloading.lua")
3535
dofile(gamepath .. "statbars.lua")
36+
dofile(gamepath .. "knockback.lua")
3637

3738
profiler = nil

builtin/game/knockback.lua

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
-- can be overriden by mods
2+
function core.calculate_knockback(player, hitter, time_from_last_punch, tool_capabilities, dir, distance, damage)
3+
if damage == 0 or player:get_armor_groups().immortal then
4+
return 0.0
5+
end
6+
7+
local m = 8
8+
-- solve m - m*e^(k*4) = 4 for k
9+
local k = -0.17328
10+
local res = m - m * math.exp(k * damage)
11+
12+
if distance < 2.0 then
13+
res = res * 1.1 -- more knockback when closer
14+
elseif distance > 4.0 then
15+
res = res * 0.9 -- less when far away
16+
end
17+
return res
18+
end
19+
20+
local function vector_absmax(v)
21+
local max, abs = math.max, math.abs
22+
return max(max(abs(v.x), abs(v.y)), abs(v.z))
23+
end
24+
25+
core.register_on_punchplayer(function(player, hitter, time_from_last_punch, tool_capabilities, unused_dir, damage)
26+
if player:get_hp() == 0 then
27+
return -- RIP
28+
end
29+
30+
-- Server::handleCommand_Interact() adds eye offset to one but not the other
31+
-- so the direction is slightly off, calculate it ourselves
32+
local dir = vector.subtract(player:get_pos(), hitter:get_pos())
33+
local d = vector.length(dir)
34+
if d ~= 0.0 then
35+
dir = vector.divide(dir, d)
36+
end
37+
38+
local k = core.calculate_knockback(player, hitter, time_from_last_punch, tool_capabilities, dir, d, damage)
39+
40+
local kdir = vector.multiply(dir, k)
41+
if vector_absmax(kdir) < 1.0 then
42+
return -- barely noticeable, so don't even send
43+
end
44+
45+
player:add_player_velocity(kdir)
46+
end)

doc/lua_api.txt

+9
Original file line numberDiff line numberDiff line change
@@ -5019,6 +5019,15 @@ Misc.
50195019
of the creative mode setting, checks for "sneak" to set the `invert_wall`
50205020
parameter and `prevent_after_place` set to `true`.
50215021

5022+
* `minetest.calculate_knockback(player, hitter, time_from_last_punch,
5023+
tool_capabilities, dir, distance, damage)`
5024+
* Returns the amount of knockback applied on the punched player.
5025+
* Arguments are equivalent to `register_on_punchplayer`, except the following:
5026+
* `distance`: distance between puncher and punched player
5027+
* This function can be overriden by mods that wish to modify this behaviour.
5028+
* You may want to cache and call the old function to allow multiple mods to
5029+
change knockback behaviour.
5030+
50225031
* `minetest.forceload_block(pos[, transient])`
50235032
* forceloads the position `pos`.
50245033
* returns `true` if area could be forceloaded

0 commit comments

Comments
 (0)