Improve grenades (#349)

- Reduce collision-checking interval
- Increase initial velocity of grenade entity
- Make grenade blast damage scaling more realistic
This commit is contained in:
ANAND 2019-03-21 00:40:16 +05:30 committed by GitHub
parent 682f63d74b
commit 703a3bbc50
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 14 additions and 9 deletions

View file

@ -21,7 +21,7 @@ minetest.register_entity("shooter:grenade_entity", {
end, end,
on_step = function(self, dtime) on_step = function(self, dtime)
self.timer = self.timer + dtime self.timer = self.timer + dtime
if self.timer > 0.2 then if self.timer > 0.1 then
local pos = self.object:getpos() local pos = self.object:getpos()
local above = {x=pos.x, y=pos.y + 1, z=pos.z} local above = {x=pos.x, y=pos.y + 1, z=pos.z}
if minetest.get_node(pos).name ~= "air" then if minetest.get_node(pos).name ~= "air" then
@ -41,26 +41,25 @@ minetest.register_tool("shooter:grenade", {
inventory_image = "shooter_hand_grenade.png", inventory_image = "shooter_hand_grenade.png",
on_use = function(itemstack, user, pointed_thing) on_use = function(itemstack, user, pointed_thing)
if not minetest.settings:get_bool("creative_mode") then if not minetest.settings:get_bool("creative_mode") then
itemstack = "" itemstack:take_item()
end end
-- clarification for future readers: grenade can be used only if player points at nothing (line 47)
if pointed_thing.type ~= "nothing" then if pointed_thing.type ~= "nothing" then
local pointed = minetest.get_pointed_thing_position(pointed_thing) local pointed = minetest.get_pointed_thing_position(pointed_thing)
if vector.distance(user:getpos(), pointed) < 10 then if vector.distance(user:get_pos(), pointed) < 10 then
shooter:blast(pointed, 2, 25, 5) shooter:blast(pointed, 2, 25, 5)
return return
end end
end end
local pos = user:getpos() local pos = user:get_pos()
local dir = user:get_look_dir() local dir = user:get_look_dir()
local yaw = user:get_look_yaw() local yaw = user:get_look_yaw()
if pos and dir then if pos and dir then
pos.y = pos.y + 1.5 pos.y = pos.y + 1.5
local obj = minetest.add_entity(pos, "shooter:grenade_entity") local obj = minetest.add_entity(pos, "shooter:grenade_entity")
if obj then if obj then
obj:setvelocity({x=dir.x * 15, y=dir.y * 15, z=dir.z * 15}) obj:set_velocity({x = dir.x * 20, y = dir.y * 20, z = dir.z * 20})
obj:setacceleration({x=dir.x * -3, y=-10, z=dir.z * -3}) obj:set_acceleration({x=dir.x * -3, y=-10, z=dir.z * -3})
obj:setyaw(yaw + math.pi) obj:set_yaw(yaw + math.pi)
local ent = obj:get_luaentity() local ent = obj:get_luaentity()
if ent then if ent then
ent.player = ent.player or user ent.player = ent.player or user

View file

@ -384,6 +384,8 @@ function shooter:blast(pos, radius, fleshy, distance, user)
minetest.set_node(pos, {name="tnt:boom"}) minetest.set_node(pos, {name="tnt:boom"})
end end
end end
-- Explosion particles
if SHOOTER_ENABLE_PARTICLE_FX == true then if SHOOTER_ENABLE_PARTICLE_FX == true then
minetest.add_particlespawner(50, 0.1, minetest.add_particlespawner(50, 0.1,
p1, p2, {x=-0, y=-0, z=-0}, {x=0, y=0, z=0}, p1, p2, {x=-0, y=-0, z=-0}, {x=0, y=0, z=0},
@ -391,6 +393,8 @@ function shooter:blast(pos, radius, fleshy, distance, user)
0.1, 1, 8, 15, false, "tnt_smoke.png" 0.1, 1, 8, 15, false, "tnt_smoke.png"
) )
end end
-- Damage to objects within range
local objects = minetest.get_objects_inside_radius(pos, distance) local objects = minetest.get_objects_inside_radius(pos, distance)
for _,obj in ipairs(objects) do for _,obj in ipairs(objects) do
if (obj:is_player() and SHOOTER_ALLOW_PLAYERS == true) or if (obj:is_player() and SHOOTER_ALLOW_PLAYERS == true) or
@ -398,7 +402,7 @@ function shooter:blast(pos, radius, fleshy, distance, user)
obj:get_luaentity().name ~= "__builtin:item") then obj:get_luaentity().name ~= "__builtin:item") then
local obj_pos = obj:getpos() local obj_pos = obj:getpos()
local dist = vector.distance(obj_pos, pos) local dist = vector.distance(obj_pos, pos)
local damage = (fleshy * 0.5 ^ dist) * 3 local damage = fleshy * (0.707106 ^ dist) * 3
if dist ~= 0 then if dist ~= 0 then
obj_pos.y = obj_pos.y + SHOOTER_EYE_HEIGHT obj_pos.y = obj_pos.y + SHOOTER_EYE_HEIGHT
blast_pos = {x=pos.x, y=pos.y + 4, z=pos.z} blast_pos = {x=pos.x, y=pos.y + 4, z=pos.z}
@ -411,6 +415,8 @@ function shooter:blast(pos, radius, fleshy, distance, user)
end end
end end
end end
-- Node blasting using LVM
if SHOOTER_ALLOW_NODES and SHOOTER_ENABLE_BLASTING then if SHOOTER_ALLOW_NODES and SHOOTER_ENABLE_BLASTING then
local pr = PseudoRandom(os.time()) local pr = PseudoRandom(os.time())
local vm = VoxelManip() local vm = VoxelManip()