forked from VoxeLibre/VoxeLibre
Fix typos documentation, add ignore_gravity and liquid_drag options, use vl_projectile.register() for enter pearl, move projectile physics to vl_projectile add hook for future vl_physics support
This commit is contained in:
parent
9eefe64e90
commit
2214e6bdba
|
@ -15,11 +15,6 @@ local STUCK_RECHECK_TIME = 5
|
||||||
|
|
||||||
local YAW_OFFSET = -math.pi/2
|
local YAW_OFFSET = -math.pi/2
|
||||||
|
|
||||||
local function dir_to_pitch(dir)
|
|
||||||
local xz = math.abs(dir.x) + math.abs(dir.z)
|
|
||||||
return -math.atan2(-dir.y, xz)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function random_arrow_positions(positions, placement)
|
local function random_arrow_positions(positions, placement)
|
||||||
if positions == "x" then
|
if positions == "x" then
|
||||||
return math.random(-4, 4)
|
return math.random(-4, 4)
|
||||||
|
@ -123,6 +118,7 @@ local arrow_entity = {
|
||||||
textures = {"mcl_bows_arrow.png"},
|
textures = {"mcl_bows_arrow.png"},
|
||||||
collisionbox = {-0.19, -0.125, -0.19, 0.19, 0.125, 0.19},
|
collisionbox = {-0.19, -0.125, -0.19, 0.19, 0.125, 0.19},
|
||||||
collide_with_objects = false,
|
collide_with_objects = false,
|
||||||
|
liquid_drag = true,
|
||||||
_fire_damage_resistant = true,
|
_fire_damage_resistant = true,
|
||||||
|
|
||||||
_save_fields = {
|
_save_fields = {
|
||||||
|
@ -348,35 +344,11 @@ local arrow_entity = {
|
||||||
self._deflection_cooloff = self._deflection_cooloff - dtime
|
self._deflection_cooloff = self._deflection_cooloff - dtime
|
||||||
end
|
end
|
||||||
|
|
||||||
-- TODO: change to use vl_physics
|
|
||||||
-- TODO: move to vl_projectile
|
|
||||||
local def = minetest.registered_nodes[minetest.get_node(pos).name]
|
|
||||||
if def and def.liquidtype ~= "none" then
|
|
||||||
-- Slow down arrow in liquids
|
|
||||||
local v = def.liquid_viscosity or 0
|
|
||||||
self._viscosity = v
|
|
||||||
|
|
||||||
local vpenalty = math.max(0.1, 0.98 - 0.1 * v)
|
|
||||||
local vel = self.object:get_velocity()
|
|
||||||
if math.abs(vel.x) > 0.001 then
|
|
||||||
vel.x = vel.x * vpenalty
|
|
||||||
end
|
|
||||||
if math.abs(vel.z) > 0.001 then
|
|
||||||
vel.z = vel.z * vpenalty
|
|
||||||
end
|
|
||||||
self.object:set_velocity(vel)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Process as projectile
|
-- Process as projectile
|
||||||
vl_projectile.update_projectile(self, dtime)
|
vl_projectile.update_projectile(self, dtime)
|
||||||
|
|
||||||
-- Update yaw
|
-- Update yaw
|
||||||
local vel = self.object:get_velocity()
|
local vel = self.object:get_velocity()
|
||||||
if vel and not self._stuck then
|
|
||||||
local yaw = minetest.dir_to_yaw(vel)+YAW_OFFSET
|
|
||||||
local pitch = dir_to_pitch(vel)
|
|
||||||
self.object:set_rotation(vector.new(0,yaw,pitch))
|
|
||||||
end
|
|
||||||
end,
|
end,
|
||||||
|
|
||||||
-- Force recheck of stuck arrows when punched.
|
-- Force recheck of stuck arrows when punched.
|
||||||
|
|
|
@ -23,7 +23,7 @@ minetest.register_craftitem("mcl_throwing:ender_pearl", {
|
||||||
mcl_throwing.register_throwable_object("mcl_throwing:ender_pearl", "mcl_throwing:ender_pearl_entity", 22)
|
mcl_throwing.register_throwable_object("mcl_throwing:ender_pearl", "mcl_throwing:ender_pearl_entity", 22)
|
||||||
|
|
||||||
-- Ender pearl entity
|
-- Ender pearl entity
|
||||||
minetest.register_entity("mcl_throwing:ender_pearl_entity",{
|
vl_projectile.register("mcl_throwing:ender_pearl_entity",{
|
||||||
physical = false,
|
physical = false,
|
||||||
timer=0,
|
timer=0,
|
||||||
textures = {"mcl_throwing_ender_pearl.png"},
|
textures = {"mcl_throwing_ender_pearl.png"},
|
||||||
|
|
|
@ -10,19 +10,21 @@ Arguments:
|
||||||
* `def`: Projectile defintion. Supports all fields that standard minetest entities support.
|
* `def`: Projectile defintion. Supports all fields that standard minetest entities support.
|
||||||
Must include the field `_vl_projectile` for projectile-specific behaviors. These are the supported
|
Must include the field `_vl_projectile` for projectile-specific behaviors. These are the supported
|
||||||
fields:
|
fields:
|
||||||
|
* `ignore_gravity`: if true, the projectile will not be affected by gravity
|
||||||
|
* `liquid_drag`: if true, apply drag from liquid nodes to the projectile
|
||||||
* `survive_collision`: if this field is `false` or `nil`, the projectile will be removed after a collision.
|
* `survive_collision`: if this field is `false` or `nil`, the projectile will be removed after a collision.
|
||||||
* `sticks_in_players`: if true, the projectile will stick into players after colliding with them.
|
* `sticks_in_players`: if true, the projectile will stick into players after colliding with them.
|
||||||
* `damage_groups`: damage group information to use for `punch()`. May be a function of type `function(projectile, entity_def, projectile_def, obj)`
|
* `damage_groups`: damage group information to use for `punch()`. May be a function of type `function(projectile, entity_def, projectile_def, obj)`
|
||||||
that returns dynamic damange group information.
|
that returns dynamic damange group information.
|
||||||
* `allow_punching`: will the projectile punch entities it collieds with. May be a function of type `function(projectile, entity_def, projectile_def, obj)`.
|
* `allow_punching`: will the projectile punch entities it collides with. May be a function of type `function(projectile, entity_def, projectile_def, obj)`.
|
||||||
* `behaviors`: a list of behavior callbacks that define the projectile's behavior. This mod provides two
|
* `behaviors`: a list of behavior callbacks that define the projectile's behavior. This mod provides the following
|
||||||
behaviors: `vl_projectiles.collides_with_solids`, `vl_projectiles.collides_with_entities` and `vl_projectiles_raycast_collieds_with_entities`
|
behaviors: `vl_projectiles.collides_with_solids`, `vl_projectiles.collides_with_entities` and `vl_projectiles_raycast_collides_with_entities`
|
||||||
* `sounds`: sounds for this projectile. All fields take a table with three parameters corresponding to the
|
* `sounds`: sounds for this projectile. All fields take a table with three parameters corresponding to the
|
||||||
three parameters for `minetest.play_sound()`. Supported sounds are:
|
three parameters for `minetest.play_sound()`. Supported sounds are:
|
||||||
* `on_collision`: played when no other more specific sound is defined. May be a function of type `function(projectile, entity_def, projectile_def, type, ...)`
|
* `on_collision`: played when no other more specific sound is defined. May be a function of type `function(projectile, entity_def, projectile_def, type, ...)`
|
||||||
* `on_solid_collision`: played when the projectile collides with a solid node. May be a function of type
|
* `on_solid_collision`: played when the projectile collides with a solid node. May be a function of type
|
||||||
`funciton(projectile, entity_def, projectile_def, type, pos, node, node_def)` with `type = "node"`
|
`funciton(projectile, entity_def, projectile_def, type, pos, node, node_def)` with `type = "node"`
|
||||||
* `on_entity_collision`: played when the projectile collieds with another entity. May be a function of type
|
* `on_entity_collision`: played when the projectile collides with another entity. May be a function of type
|
||||||
`function(projectile, entity_def, projectile_def, type, entity)` with `type = "entity"`
|
`function(projectile, entity_def, projectile_def, type, entity)` with `type = "entity"`
|
||||||
* `on_collide_with_solid`: callback of type `function(projectile, pos, node, node_def)` used when the projectile collides with a solid node. Requires
|
* `on_collide_with_solid`: callback of type `function(projectile, pos, node, node_def)` used when the projectile collides with a solid node. Requires
|
||||||
`vl_projectile.collides_with_solids` in `behaviors` list.
|
`vl_projectile.collides_with_solids` in `behaviors` list.
|
||||||
|
|
|
@ -1,9 +1,64 @@
|
||||||
local mod = {}
|
local mod = {}
|
||||||
vl_projectile = mod
|
vl_projectile = mod
|
||||||
|
|
||||||
|
local vl_physics_path = minetest.get_modpath("vl_physics")
|
||||||
|
|
||||||
|
local YAW_OFFSET = -math.pi/2
|
||||||
local GRAVITY = tonumber(minetest.settings:get("movement_gravity"))
|
local GRAVITY = tonumber(minetest.settings:get("movement_gravity"))
|
||||||
local enable_pvp = minetest.settings:get_bool("enable_pvp")
|
local enable_pvp = minetest.settings:get_bool("enable_pvp")
|
||||||
|
|
||||||
|
local function dir_to_pitch(dir)
|
||||||
|
local xz = math.abs(dir.x) + math.abs(dir.z)
|
||||||
|
return -math.atan2(-dir.y, xz)
|
||||||
|
end
|
||||||
|
|
||||||
|
function mod.projectile_physics(obj, entity_def, v, a)
|
||||||
|
local le = obj:get_luaentity()
|
||||||
|
local entity_def = minetest.registered_entities[le.name]
|
||||||
|
local pos = obj:get_pos()
|
||||||
|
if not pos then return end
|
||||||
|
|
||||||
|
if vl_physics_path then
|
||||||
|
v,a = vl_physics.apply_entity_environmental_physics(obj)
|
||||||
|
else
|
||||||
|
-- Simple physics
|
||||||
|
if not v then v = obj:get_velocity() end
|
||||||
|
if not a then a = vector.zero() end
|
||||||
|
|
||||||
|
if not entity_def.ignore_gravity then
|
||||||
|
a = a + vector.new(0,-GRAVITY,0)
|
||||||
|
end
|
||||||
|
|
||||||
|
if entity_def.liquid_drag then
|
||||||
|
local def = minetest.registered_nodes[minetest.get_node(pos).name]
|
||||||
|
if def and def.liquidtype ~= "none" then
|
||||||
|
-- Slow down arrow in liquids
|
||||||
|
local visc = def.liquid_viscosity or 0
|
||||||
|
le._viscosity = visc
|
||||||
|
|
||||||
|
local vpenalty = math.max(0.1, 0.98 - 0.1 * visc)
|
||||||
|
if math.abs(v.x) > 0.001 then
|
||||||
|
v.x = v.x * vpenalty
|
||||||
|
end
|
||||||
|
if math.abs(v.z) > 0.001 then
|
||||||
|
v.z = v.z * vpenalty
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Pass to entity
|
||||||
|
if v then obj:set_velocity(v) end
|
||||||
|
if a then obj:set_acceleration(a) end
|
||||||
|
|
||||||
|
-- Update projectile yaw to match velocity direction
|
||||||
|
if v and le and not le._stuck then
|
||||||
|
local yaw = minetest.dir_to_yaw(v) + YAW_OFFSET
|
||||||
|
local pitch = dir_to_pitch(v)
|
||||||
|
obj:set_rotation(vector.new(0,yaw,pitch))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function mod.update_projectile(self, dtime)
|
function mod.update_projectile(self, dtime)
|
||||||
if self._removed then return end
|
if self._removed then return end
|
||||||
|
|
||||||
|
@ -22,6 +77,8 @@ function mod.update_projectile(self, dtime)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
mod.projectile_physics(self.object, entity_def)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function no_op()
|
local function no_op()
|
||||||
|
@ -300,14 +357,13 @@ function mod.raycast_collides_with_entities(self, dtime, entity_def, projectile_
|
||||||
end
|
end
|
||||||
|
|
||||||
function mod.create(entity_id, options)
|
function mod.create(entity_id, options)
|
||||||
local obj = minetest.add_entity(options.pos, entity_id, options.staticdata)
|
local pos = options.pos
|
||||||
|
local obj = minetest.add_entity(pos, entity_id, options.staticdata)
|
||||||
|
|
||||||
-- Set initial velocoty and acceleration
|
-- Set initial velocity and acceleration
|
||||||
obj:set_velocity(vector.multiply(options.dir or vector.zero(), options.velocity or 0))
|
local v = vector.multiply(options.dir or vector.zero(), options.velocity or 0)
|
||||||
obj:set_acceleration(vector.add(
|
local a = vector.multiply(v, -math.abs(options.drag))
|
||||||
vector.multiply(options.dir or vector.zero(), -math.abs(options.drag)),
|
mod.projectile_physics(obj, entity_def, v, a)
|
||||||
vector.new(0,-GRAVITY,0)
|
|
||||||
))
|
|
||||||
|
|
||||||
-- Update projectile parameters
|
-- Update projectile parameters
|
||||||
local luaentity = obj:get_luaentity()
|
local luaentity = obj:get_luaentity()
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
name = vl_projectile
|
name = vl_projectile
|
||||||
depends = mcl_util
|
depends = mcl_util
|
||||||
|
optional_depends = vl_physics
|
||||||
|
|
Loading…
Reference in New Issue