implement blood
This commit is contained in:
parent
82528cda36
commit
7ee24498d7
119
init.lua
119
init.lua
@ -9,6 +9,22 @@ local function clamp(num, lower, upper)
|
|||||||
return math.max(lower, math.min(upper, num))
|
return math.max(lower, math.min(upper, num))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function cross_product(a, b)
|
||||||
|
return {
|
||||||
|
x = a.y * b.z - a.z * b.y,
|
||||||
|
y = a.z * b.x - a.x * b.z,
|
||||||
|
z = a.x * b.y - a.y * b.x
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
local function dot_product(a, b)
|
||||||
|
local result = 0
|
||||||
|
for i = 1, #a do
|
||||||
|
result = result + a[i] * b[i]
|
||||||
|
end
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
local function get_player_2d_velocity_magnitude(player)
|
local function get_player_2d_velocity_magnitude(player)
|
||||||
local velocity = player:get_player_velocity()
|
local velocity = player:get_player_velocity()
|
||||||
return math.sqrt(velocity.x * velocity.x + velocity.z * velocity.z);
|
return math.sqrt(velocity.x * velocity.x + velocity.z * velocity.z);
|
||||||
@ -25,6 +41,7 @@ first_person_shooter = {}
|
|||||||
first_person_shooter.tick_rate = 60
|
first_person_shooter.tick_rate = 60
|
||||||
first_person_shooter.last_update_time = 0
|
first_person_shooter.last_update_time = 0
|
||||||
first_person_shooter.maximum_speed_smoothing_samples = 3
|
first_person_shooter.maximum_speed_smoothing_samples = 3
|
||||||
|
first_person_shooter.blood_emission_multiplier = 5
|
||||||
first_person_shooter.players_metadata = {}
|
first_person_shooter.players_metadata = {}
|
||||||
first_person_shooter.registered_weapons = {}
|
first_person_shooter.registered_weapons = {}
|
||||||
|
|
||||||
@ -263,14 +280,7 @@ first_person_shooter.on_node_hit = function(node_position, hit_info)
|
|||||||
minetest.remove_node(node_position)
|
minetest.remove_node(node_position)
|
||||||
minetest.check_for_falling(node_position)
|
minetest.check_for_falling(node_position)
|
||||||
else
|
else
|
||||||
minetest.add_entity(
|
first_person_shooter.create_bullet_hole(hit_info.hit_position, hit_info.hit_normal, node_position)
|
||||||
vector.subtract(hit_info.hit_position, vector.multiply(hit_info.muzzle_direction, 0.01)), -- compensate for z-fighting
|
|
||||||
"first_person_shooter:bullet_hole",
|
|
||||||
minetest.serialize({
|
|
||||||
attached_node_position = node_position,
|
|
||||||
rotation = hit_info.hit_normal,
|
|
||||||
})
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
first_person_shooter.play_node_sound(node, node_position)
|
first_person_shooter.play_node_sound(node, node_position)
|
||||||
@ -302,16 +312,21 @@ first_person_shooter.on_node_hit = function(node_position, hit_info)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
first_person_shooter.on_object_hit = function(object, player, damage)
|
first_person_shooter.on_object_hit = function(object, attacker, hit_info)
|
||||||
object:punch(
|
object:punch(
|
||||||
player,
|
attacker,
|
||||||
nil,
|
nil,
|
||||||
{
|
{
|
||||||
full_punch_interval = 1.0,
|
full_punch_interval = 1.0,
|
||||||
damage_groups = { fleshy = damage },
|
damage_groups = { fleshy = hit_info.weapon_metadata.damage },
|
||||||
},
|
},
|
||||||
nil
|
nil
|
||||||
)
|
)
|
||||||
|
first_person_shooter.emit_blood(
|
||||||
|
hit_info.hit_position,
|
||||||
|
hit_info.muzzle_direction,
|
||||||
|
math.ceil(hit_info.weapon_metadata.damage * hit_info.weapon_metadata.penetration_power) * first_person_shooter.blood_emission_multiplier
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
first_person_shooter.on_weapon_fire = function(player_metadata)
|
first_person_shooter.on_weapon_fire = function(player_metadata)
|
||||||
@ -335,17 +350,18 @@ first_person_shooter.on_weapon_fire = function(player_metadata)
|
|||||||
if hit_object.ref == player_metadata.player then
|
if hit_object.ref == player_metadata.player then
|
||||||
hit_object = projectile_raycast:next() or { type = "nothing" }
|
hit_object = projectile_raycast:next() or { type = "nothing" }
|
||||||
end
|
end
|
||||||
|
local hit_info = {
|
||||||
|
weapon_metadata = weapon_metadata,
|
||||||
|
muzzle_position = muzzle_position,
|
||||||
|
muzzle_direction = muzzle_direction,
|
||||||
|
hit_position = hit_object.intersection_point,
|
||||||
|
hit_normal = hit_object.intersection_normal,
|
||||||
|
}
|
||||||
if hit_object.type == "node" then
|
if hit_object.type == "node" then
|
||||||
local hit_node_position = minetest.get_pointed_thing_position(hit_object, false)
|
local hit_node_position = minetest.get_pointed_thing_position(hit_object, false)
|
||||||
first_person_shooter.on_node_hit(hit_node_position, {
|
first_person_shooter.on_node_hit(hit_node_position, hit_info)
|
||||||
weapon_metadata = weapon_metadata,
|
|
||||||
muzzle_position = muzzle_position,
|
|
||||||
muzzle_direction = muzzle_direction,
|
|
||||||
hit_position = hit_object.intersection_point,
|
|
||||||
hit_normal = hit_object.intersection_normal,
|
|
||||||
})
|
|
||||||
elseif hit_object.type == "object" then
|
elseif hit_object.type == "object" then
|
||||||
first_person_shooter.on_object_hit(hit_object.ref, player_metadata.player, weapon_metadata.damage)
|
first_person_shooter.on_object_hit(hit_object.ref, player_metadata.player, hit_info)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -357,6 +373,7 @@ minetest.register_entity("first_person_shooter:bullet_hole", {
|
|||||||
textures = { "bullet_hole.png" },
|
textures = { "bullet_hole.png" },
|
||||||
collisionbox = { 0, 0, 0, 0, 0, 0 },
|
collisionbox = { 0, 0, 0, 0, 0, 0 },
|
||||||
pointable = false,
|
pointable = false,
|
||||||
|
static_save = false,
|
||||||
},
|
},
|
||||||
on_activate = function(self, static_data)
|
on_activate = function(self, static_data)
|
||||||
if static_data == "" or static_data == nil then
|
if static_data == "" or static_data == nil then
|
||||||
@ -378,6 +395,70 @@ minetest.register_entity("first_person_shooter:bullet_hole", {
|
|||||||
_despawn_time = 30,
|
_despawn_time = 30,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
first_person_shooter.create_bullet_hole = function(position, surface_normal, attached_node_position)
|
||||||
|
minetest.add_entity(
|
||||||
|
vector.add(position, vector.multiply(surface_normal, 0.01)),
|
||||||
|
"first_person_shooter:bullet_hole",
|
||||||
|
minetest.serialize({
|
||||||
|
attached_node_position = attached_node_position,
|
||||||
|
rotation = surface_normal,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.register_entity("first_person_shooter:blood_drop", {
|
||||||
|
initial_properties = {
|
||||||
|
visual = "mesh",
|
||||||
|
mesh = "plane.obj",
|
||||||
|
visual_size = { x = 0.15, y = 0.15 },
|
||||||
|
textures = { "blood_drop.png" },
|
||||||
|
collisionbox = { 0, 0, 0, 0, 0, 0 },
|
||||||
|
pointable = false,
|
||||||
|
static_save = false,
|
||||||
|
},
|
||||||
|
on_activate = function(self, static_data)
|
||||||
|
if static_data == "" or static_data == nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
static_data = minetest.deserialize(static_data) or {}
|
||||||
|
self._attached_node_position = static_data.attached_node_position
|
||||||
|
self.object:set_rotation(vector.multiply({ x = static_data.rotation.z, y = static_data.rotation.y, z = static_data.rotation.x }, math.pi / 2))
|
||||||
|
self.object:set_armor_groups({ immortal = 1 })
|
||||||
|
end,
|
||||||
|
on_step = function(self, delta_time)
|
||||||
|
self._life_time = self._life_time + delta_time
|
||||||
|
local attached_node = minetest.get_node(self._attached_node_position or { x = 0, y = 0, z = 0 })
|
||||||
|
if self._life_time >= self._despawn_time or attached_node.name == "air" then
|
||||||
|
self.object:remove()
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
_life_time = 0,
|
||||||
|
_despawn_time = 30,
|
||||||
|
})
|
||||||
|
|
||||||
|
first_person_shooter.emit_blood = function(position, direction, amount)
|
||||||
|
for blood_drop_iteration = 0, amount do
|
||||||
|
local random_direction = vector.multiply({ x = 1 - math.random() * 2, y = 1 - math.random() * 2, z = 1 - math.random() * 2 }, math.random() * 0.25)
|
||||||
|
local blood_drop_direction = vector.add(direction, random_direction)
|
||||||
|
local blood_drop_raycast = minetest.raycast(position, vector.add(position, vector.multiply(blood_drop_direction, 2)), false, false)
|
||||||
|
local colliding_object = blood_drop_raycast:next() or { type = "nothing" }
|
||||||
|
if colliding_object.type ~= "node" then
|
||||||
|
colliding_object = blood_drop_raycast:next() or { type = "nothing" }
|
||||||
|
end
|
||||||
|
if colliding_object.type == "node" then
|
||||||
|
local attached_node_position = minetest.get_pointed_thing_position(colliding_object, false)
|
||||||
|
minetest.add_entity(
|
||||||
|
vector.add(colliding_object.intersection_point, vector.multiply(colliding_object.intersection_normal, 0.01)),
|
||||||
|
"first_person_shooter:blood_drop",
|
||||||
|
minetest.serialize({
|
||||||
|
attached_node_position = attached_node_position,
|
||||||
|
rotation = colliding_object.intersection_normal,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
--Register Weapons---------------------------------
|
--Register Weapons---------------------------------
|
||||||
|
|
||||||
first_person_shooter.register_weapon("first_person_shooter:m16a2", {
|
first_person_shooter.register_weapon("first_person_shooter:m16a2", {
|
||||||
|
BIN
textures/blood_drop.png
Normal file
BIN
textures/blood_drop.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 91 B |
Loading…
x
Reference in New Issue
Block a user